1
/**********************************************************************
3
* Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
9
* This program is distributed in the hope it will be useful but, except
10
* as otherwise stated in writing, without any warranty; without even the
11
* implied warranty of merchantability or fitness for a particular purpose.
12
* See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along with
15
* this program; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
* The full GNU General Public License is included in this distribution in
19
* the file called "COPYING".
21
* Contact Information:
22
* Imagination Technologies Ltd. <gpl-support@imgtec.com>
23
* Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25
******************************************************************************/
27
#include "services_headers.h"
31
#include "osperproc.h"
33
#define HASH_TAB_INIT_SIZE 32
35
static HASH_TABLE *psHashTab = IMG_NULL;
37
static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
40
IMG_UINTPTR_T uiPerProc;
42
PVR_ASSERT(psPerProc != IMG_NULL);
44
if (psPerProc == IMG_NULL)
46
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
47
return PVRSRV_ERROR_INVALID_PARAMS;
50
uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
53
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
55
PVR_ASSERT(psPerProc->ui32PID == 0);
59
PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
60
PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
64
if (psPerProc->psHandleBase != IMG_NULL)
66
eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
67
if (eError != PVRSRV_OK)
69
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
75
if (psPerProc->hPerProcData != IMG_NULL)
77
eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
79
if (eError != PVRSRV_OK)
81
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
87
eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
88
if (eError != PVRSRV_OK)
90
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
94
eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
97
psPerProc->hBlockAlloc);
99
if (eError != PVRSRV_OK)
101
PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
109
PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
111
PVRSRV_PER_PROCESS_DATA *psPerProc;
113
PVR_ASSERT(psHashTab != IMG_NULL);
116
psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
121
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID)
123
PVRSRV_PER_PROCESS_DATA *psPerProc;
124
IMG_HANDLE hBlockAlloc;
125
PVRSRV_ERROR eError = PVRSRV_OK;
127
PVR_ASSERT(psHashTab != IMG_NULL);
130
psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
132
if (psPerProc == IMG_NULL)
135
eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
137
(IMG_PVOID *)&psPerProc,
140
if (eError != PVRSRV_OK)
142
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
145
OSMemSet(psPerProc, 0, sizeof(*psPerProc));
146
psPerProc->hBlockAlloc = hBlockAlloc;
148
if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
150
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
151
eError = PVRSRV_ERROR_GENERIC;
155
psPerProc->ui32PID = ui32PID;
156
psPerProc->ui32RefCount = 0;
159
eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
160
if (eError != PVRSRV_OK)
162
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
167
eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
168
&psPerProc->hPerProcData,
170
PVRSRV_HANDLE_TYPE_PERPROC_DATA,
171
PVRSRV_HANDLE_ALLOC_FLAG_NONE);
172
if (eError != PVRSRV_OK)
174
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
179
eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
180
if (eError != PVRSRV_OK)
182
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
187
eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
188
if (eError != PVRSRV_OK)
190
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
195
eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
196
if (eError != PVRSRV_OK)
198
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
203
psPerProc->ui32RefCount++;
204
PVR_DPF((PVR_DBG_MESSAGE,
205
"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
206
ui32PID, psPerProc->ui32RefCount));
211
(IMG_VOID)FreePerProcessData(psPerProc);
216
IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID)
219
PVRSRV_PER_PROCESS_DATA *psPerProc;
221
PVR_ASSERT(psHashTab != IMG_NULL);
223
psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
224
if (psPerProc == IMG_NULL)
226
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
230
psPerProc->ui32RefCount--;
231
if (psPerProc->ui32RefCount == 0)
233
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
234
"Last close from process 0x%x received", ui32PID));
237
PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
240
eError = FreePerProcessData(psPerProc);
241
if (eError != PVRSRV_OK)
243
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
248
eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
249
if (eError != PVRSRV_OK)
251
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
256
PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
258
PVR_ASSERT(psHashTab == IMG_NULL);
261
psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
262
if (psHashTab == IMG_NULL)
264
PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
265
return PVRSRV_ERROR_GENERIC;
271
PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
274
if (psHashTab != IMG_NULL)
277
HASH_Delete(psHashTab);
278
psHashTab = IMG_NULL;