blob: 8b009725ec9314a03c86aec757ffd6dee96bf02e [file] [log] [blame]
/*************************************************************************/ /*!
@Title Services reference count debugging
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License Strictly Confidential.
*/ /**************************************************************************/
#if defined(PVRSRV_REFCOUNT_DEBUG)
#include "services_headers.h"
#ifndef __linux__
#warning Reference count debugging is not thread-safe on this platform
#define PVRSRV_LOCK_CCB()
#define PVRSRV_UNLOCK_CCB()
#else /* __linux__ */
#include <linux/mutex.h>
static DEFINE_MUTEX(gsCCBLock);
#define PVRSRV_LOCK_CCB() mutex_lock(&gsCCBLock)
#define PVRSRV_UNLOCK_CCB() mutex_unlock(&gsCCBLock)
#endif /* __linux__ */
#define PVRSRV_REFCOUNT_CCB_MAX 512
#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80
#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0)
#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1)
#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2)
#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3)
#if defined(__linux__)
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 4)
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 5)
#else
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0
#endif
#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U
/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/
static const IMG_UINT guiDebugMask =
PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO |
PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2;
typedef struct
{
const IMG_CHAR *pszFile;
IMG_INT iLine;
IMG_UINT32 ui32PID;
IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX];
}
PVRSRV_REFCOUNT_CCB;
static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX];
static IMG_UINT giOffset;
static const IMG_CHAR gszHeader[] =
/* 10 20 30 40 50 60 70
* 345678901234567890123456789012345678901234567890123456789012345678901
*/
"TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID";
/* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */
#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x"
IMG_INTERNAL
void PVRSRVDumpRefCountCCB(void)
{
int i;
PVRSRV_LOCK_CCB();
PVR_LOG(("%s", gszHeader));
for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++)
{
PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry =
&gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX];
/* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */
if(!psRefCountCCBEntry->pszFile)
break;
PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg,
psRefCountCCBEntry->ui32PID,
psRefCountCCBEntry->pszFile,
psRefCountCCBEntry->iLine));
}
PVRSRV_UNLOCK_CCB();
}
IMG_INTERNAL
void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"SYNCINFO",
psKernelSyncInfo,
psKernelMemInfo,
NULL,
(psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
psKernelSyncInfo->ui32RefCount,
psKernelSyncInfo->ui32RefCount + 1,
(psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psKernelSyncInfo->ui32RefCount++;
}
IMG_INTERNAL
void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"SYNCINFO",
psKernelSyncInfo,
psKernelMemInfo,
(psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
NULL,
psKernelSyncInfo->ui32RefCount,
psKernelSyncInfo->ui32RefCount - 1,
(psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psKernelSyncInfo->ui32RefCount--;
}
IMG_INTERNAL
void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MEMINFO",
psKernelMemInfo->psKernelSyncInfo,
psKernelMemInfo,
psKernelMemInfo->sMemBlk.hOSMemHandle,
NULL,
psKernelMemInfo->ui32RefCount,
psKernelMemInfo->ui32RefCount + 1,
psKernelMemInfo->uAllocSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psKernelMemInfo->ui32RefCount++;
}
IMG_INTERNAL
void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MEMINFO",
psKernelMemInfo->psKernelSyncInfo,
psKernelMemInfo,
psKernelMemInfo->sMemBlk.hOSMemHandle,
NULL,
psKernelMemInfo->ui32RefCount,
psKernelMemInfo->ui32RefCount - 1,
psKernelMemInfo->uAllocSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psKernelMemInfo->ui32RefCount--;
}
IMG_INTERNAL
void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"BM_BUF",
NULL,
NULL,
BM_HandleToOSMemHandle(pBuf),
pBuf,
pBuf->ui32RefCount,
pBuf->ui32RefCount + 1,
(pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
pBuf->ui32RefCount++;
}
IMG_INTERNAL
void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"BM_BUF",
NULL,
NULL,
BM_HandleToOSMemHandle(pBuf),
pBuf,
pBuf->ui32RefCount,
pBuf->ui32RefCount - 1,
(pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
pBuf->ui32RefCount--;
}
IMG_INTERNAL
void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"BM_BUF2",
NULL,
NULL,
BM_HandleToOSMemHandle(pBuf),
pBuf,
pBuf->ui32ExportCount,
pBuf->ui32ExportCount + 1,
(pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
pBuf->ui32ExportCount++;
}
IMG_INTERNAL
void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"BM_BUF2",
NULL,
NULL,
BM_HandleToOSMemHandle(pBuf),
pBuf,
pBuf->ui32ExportCount,
pBuf->ui32ExportCount - 1,
(pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
pBuf->ui32ExportCount--;
}
#if defined(__linux__)
/* mmap refcounting is Linux specific */
IMG_INTERNAL
void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PKV_OFFSET_STRUCT psOffsetStruct)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MMAP",
NULL,
NULL,
psOffsetStruct->psLinuxMemArea,
psOffsetStruct,
psOffsetStruct->ui32RefCount,
psOffsetStruct->ui32RefCount + 1,
psOffsetStruct->ui32RealByteSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psOffsetStruct->ui32RefCount++;
}
IMG_INTERNAL
void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PKV_OFFSET_STRUCT psOffsetStruct)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MMAP",
NULL,
NULL,
psOffsetStruct->psLinuxMemArea,
psOffsetStruct,
psOffsetStruct->ui32RefCount,
psOffsetStruct->ui32RefCount - 1,
psOffsetStruct->ui32RealByteSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psOffsetStruct->ui32RefCount--;
}
IMG_INTERNAL
void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
PKV_OFFSET_STRUCT psOffsetStruct)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MMAP2",
NULL,
NULL,
psOffsetStruct->psLinuxMemArea,
psOffsetStruct,
psOffsetStruct->ui32Mapped,
psOffsetStruct->ui32Mapped + 1,
psOffsetStruct->ui32RealByteSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psOffsetStruct->ui32Mapped++;
}
IMG_INTERNAL
void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
PKV_OFFSET_STRUCT psOffsetStruct)
{
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
goto skip;
PVRSRV_LOCK_CCB();
gsRefCountCCB[giOffset].pszFile = pszFile;
gsRefCountCCB[giOffset].iLine = iLine;
gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
snprintf(gsRefCountCCB[giOffset].pcMesg,
PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
PVRSRV_REFCOUNT_CCB_FMT_STRING,
"MMAP2",
NULL,
NULL,
psOffsetStruct->psLinuxMemArea,
psOffsetStruct,
psOffsetStruct->ui32Mapped,
psOffsetStruct->ui32Mapped - 1,
psOffsetStruct->ui32RealByteSize);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
PVRSRV_UNLOCK_CCB();
skip:
psOffsetStruct->ui32Mapped--;
}
#endif /* defined(__linux__) */
#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */