return PVRSRV_OK;
}
+static inline
+void get_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
+{
+ syncinfo->refcount++;
+}
+
+static inline
+void put_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
+{
+ struct PVRSRV_DEVICE_NODE *dev = syncinfo->dev_cookie;
+
+ syncinfo->refcount--;
+
+ if (!syncinfo->refcount) {
+ HASH_Remove(dev->sync_table,
+ syncinfo->phys_addr.uiAddr);
+ PVRSRVFreeSyncInfoKM(syncinfo);
+ }
+}
+
+static inline
+enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
+ void *mem_context_handle,
+ struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
+ struct IMG_SYS_PHYADDR *phys_addr)
+{
+ enum PVRSRV_ERROR error;
+ struct PVRSRV_DEVICE_NODE *dev;
+
+ dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;
+
+ *syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
+ HASH_Retrieve(dev->sync_table,
+ phys_addr->uiAddr);
+
+ if (!*syncinfo) {
+ /* Dont' have one so create one */
+ error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
+ syncinfo);
+
+ if (error != PVRSRV_OK)
+ return error;
+
+ /* Setup our extra data */
+ (*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
+ (*syncinfo)->dev_cookie = dev_cookie;
+ (*syncinfo)->refcount = 1;
+
+ if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
+ (u32) *syncinfo)) {
+ PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
+ "Failed to add syncobject to hash table");
+ return PVRSRV_ERROR_GENERIC;
+ }
+ } else
+ get_syncinfo(*syncinfo);
+
+ return PVRSRV_OK;
+}
+
static enum PVRSRV_ERROR FreeDeviceMemCallBack(void *pvParam, u32 ui32Param)
{
enum PVRSRV_ERROR eError = PVRSRV_OK;
hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
if (psMemInfo->psKernelSyncInfo)
- eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
+ put_syncinfo(psMemInfo->psKernelSyncInfo);
if (psMemInfo->sMemBlk.psIntSysPAddr) {
int page_count;
psBMHeap = (struct BM_HEAP *)hDevMemHeap;
hDevMemContext = (void *) psBMHeap->pBMContext;
- eError = PVRSRVAllocSyncInfoKM(hDevCookie,
- hDevMemContext,
- &psMemInfo->psKernelSyncInfo);
+ eError = alloc_or_reuse_syncinfo(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo,
+ psExtSysPAddr);
if (eError != PVRSRV_OK)
goto ErrorExitPhase4;
#include "pvr_events.h"
#include "pvrversion.h"
+
+#define HASH_TAB_INIT_SIZE 32
enum PVRSRV_ERROR AllocateDeviceID(struct SYS_DATA *psSysData, u32 *pui32DevID)
{
struct SYS_DEVICE_ID *psDeviceWalker;
}
}
+ psDeviceNode->sync_table = HASH_Create(HASH_TAB_INIT_SIZE);
+ if (psDeviceNode->sync_table == NULL) {
+ PVR_DPF(PVR_DBG_ERROR, "InitDevInfo: "
+ "Couldn't create syncobject hash table");
+ eError = PVRSRV_ERROR_GENERIC;
+ return eError;
+ }
+
return PVRSRV_OK;
}
return eError;
}
+ HASH_Delete(psDeviceNode->sync_table);
+
ResManFreeResByCriteria(psDeviceNode->hResManContext,
RESMAN_CRITERIA_RESTYPE,
RESMAN_TYPE_DEVICEMEM_ALLOCATION,