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"
30 #include "buffer_manager.h"
33 #include <linux/kernel.h>
37 #define MINIMUM_HASH_SIZE (64)
49 struct _BT_ *pNextSegment;
50 struct _BT_ *pPrevSegment;
52 struct _BT_ *pNextFree;
53 struct _BT_ *pPrevFree;
55 BM_MAPPING *psMapping;
57 typedef struct _BT_ BT;
65 IMG_BOOL(*pImportAlloc) (void *,
67 IMG_SIZE_T * pActualSize,
68 BM_MAPPING ** ppsMapping,
69 IMG_UINT32 uFlags, IMG_UINTPTR_T * pBase);
70 void (*pImportFree) (void *, IMG_UINTPTR_T, BM_MAPPING * psMapping);
71 void (*pBackingStoreFree) (void *, IMG_UINT32, IMG_UINT32, IMG_HANDLE);
75 #define FREE_TABLE_LIMIT 32
77 BT *aHeadFree[FREE_TABLE_LIMIT];
82 HASH_TABLE *pSegmentHash;
85 RA_STATISTICS sStatistics;
88 #if defined(CONFIG_PROC_FS) && defined(DEBUG)
89 #define PROC_NAME_SIZE 32
90 char szProcInfoName[PROC_NAME_SIZE];
91 char szProcSegsName[PROC_NAME_SIZE];
95 void RA_Dump(RA_ARENA * pArena);
97 #if defined(CONFIG_PROC_FS) && defined(DEBUG)
99 RA_DumpSegs(char *page, char **start, off_t off, int count, int *eof,
101 static int RA_DumpInfo(char *page, char **start, off_t off, int count, int *eof,
107 _RequestAllocFail(void *_h,
109 IMG_SIZE_T * _pActualSize,
110 BM_MAPPING ** _ppsMapping,
111 IMG_UINT32 _uFlags, IMG_UINTPTR_T * _pBase)
113 PVR_UNREFERENCED_PARAMETER(_h);
114 PVR_UNREFERENCED_PARAMETER(_uSize);
115 PVR_UNREFERENCED_PARAMETER(_pActualSize);
116 PVR_UNREFERENCED_PARAMETER(_ppsMapping);
117 PVR_UNREFERENCED_PARAMETER(_uFlags);
118 PVR_UNREFERENCED_PARAMETER(_pBase);
123 static IMG_UINT32 pvr_log2(IMG_SIZE_T n)
135 _SegmentListInsertAfter(RA_ARENA * pArena, BT * pInsertionPoint, BT * pBT)
137 PVR_ASSERT(pArena != IMG_NULL);
138 PVR_ASSERT(pInsertionPoint != IMG_NULL);
140 pBT->pNextSegment = pInsertionPoint->pNextSegment;
141 pBT->pPrevSegment = pInsertionPoint;
142 if (pInsertionPoint->pNextSegment == IMG_NULL)
143 pArena->pTailSegment = pBT;
145 pInsertionPoint->pNextSegment->pPrevSegment = pBT;
146 pInsertionPoint->pNextSegment = pBT;
149 static void _SegmentListInsert(RA_ARENA * pArena, BT * pBT)
152 if (pArena->pHeadSegment == IMG_NULL) {
153 pArena->pHeadSegment = pArena->pTailSegment = pBT;
154 pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL;
157 pBTScan = pArena->pHeadSegment;
158 while (pBTScan->pNextSegment != IMG_NULL
159 && pBT->base >= pBTScan->pNextSegment->base)
160 pBTScan = pBTScan->pNextSegment;
161 _SegmentListInsertAfter(pArena, pBTScan, pBT);
165 static void _SegmentListRemove(RA_ARENA * pArena, BT * pBT)
167 if (pBT->pPrevSegment == IMG_NULL)
168 pArena->pHeadSegment = pBT->pNextSegment;
170 pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
172 if (pBT->pNextSegment == IMG_NULL)
173 pArena->pTailSegment = pBT->pPrevSegment;
175 pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
178 static BT *_SegmentSplit(RA_ARENA * pArena, BT * pBT, IMG_SIZE_T uSize)
182 PVR_ASSERT(pArena != IMG_NULL);
184 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
186 (IMG_VOID **) & pNeighbour, IMG_NULL) != PVRSRV_OK) {
190 pNeighbour->pPrevSegment = pBT;
191 pNeighbour->pNextSegment = pBT->pNextSegment;
192 if (pBT->pNextSegment == IMG_NULL)
193 pArena->pTailSegment = pNeighbour;
195 pBT->pNextSegment->pPrevSegment = pNeighbour;
196 pBT->pNextSegment = pNeighbour;
198 pNeighbour->type = btt_free;
199 pNeighbour->uSize = pBT->uSize - uSize;
200 pNeighbour->base = pBT->base + uSize;
201 pNeighbour->psMapping = pBT->psMapping;
206 static void _FreeListInsert(RA_ARENA * pArena, BT * pBT)
209 uIndex = pvr_log2(pBT->uSize);
210 pBT->type = btt_free;
211 pBT->pNextFree = pArena->aHeadFree[uIndex];
212 pBT->pPrevFree = IMG_NULL;
213 if (pArena->aHeadFree[uIndex] != IMG_NULL)
214 pArena->aHeadFree[uIndex]->pPrevFree = pBT;
215 pArena->aHeadFree[uIndex] = pBT;
218 static void _FreeListRemove(RA_ARENA * pArena, BT * pBT)
221 uIndex = pvr_log2(pBT->uSize);
222 if (pBT->pNextFree != IMG_NULL)
223 pBT->pNextFree->pPrevFree = pBT->pPrevFree;
224 if (pBT->pPrevFree == IMG_NULL)
225 pArena->aHeadFree[uIndex] = pBT->pNextFree;
227 pBT->pPrevFree->pNextFree = pBT->pNextFree;
230 static BT *_BuildSpanMarker(IMG_UINTPTR_T base, IMG_SIZE_T uSize)
234 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
236 (IMG_VOID **) & pBT, IMG_NULL) != PVRSRV_OK) {
240 pBT->type = btt_span;
243 pBT->psMapping = IMG_NULL;
248 static BT *_BuildBT(IMG_UINTPTR_T base, IMG_SIZE_T uSize)
252 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
254 (IMG_VOID **) & pBT, IMG_NULL) != PVRSRV_OK) {
258 pBT->type = btt_free;
265 static BT *_InsertResource(RA_ARENA * pArena, IMG_UINTPTR_T base,
269 PVR_ASSERT(pArena != IMG_NULL);
270 pBT = _BuildBT(base, uSize);
271 if (pBT != IMG_NULL) {
272 _SegmentListInsert(pArena, pBT);
273 _FreeListInsert(pArena, pBT);
275 pArena->sStatistics.uTotalResourceCount += uSize;
276 pArena->sStatistics.uFreeResourceCount += uSize;
277 pArena->sStatistics.uSpanCount++;
283 static BT *_InsertResourceSpan(RA_ARENA * pArena, IMG_UINTPTR_T base,
290 PVR_ASSERT(pArena != IMG_NULL);
292 PVR_DPF((PVR_DBG_MESSAGE,
293 "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
294 pArena->name, base, uSize));
296 pSpanStart = _BuildSpanMarker(base, uSize);
297 if (pSpanStart == IMG_NULL) {
300 pSpanEnd = _BuildSpanMarker(base + uSize, 0);
301 if (pSpanEnd == IMG_NULL) {
305 pBT = _BuildBT(base, uSize);
306 if (pBT == IMG_NULL) {
310 _SegmentListInsert(pArena, pSpanStart);
311 _SegmentListInsertAfter(pArena, pSpanStart, pBT);
312 _FreeListInsert(pArena, pBT);
313 _SegmentListInsertAfter(pArena, pBT, pSpanEnd);
315 pArena->sStatistics.uTotalResourceCount += uSize;
320 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
322 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
327 static void _FreeBT(RA_ARENA * pArena, BT * pBT, IMG_BOOL bFreeBackingStore)
330 IMG_UINTPTR_T uOrigBase;
331 IMG_SIZE_T uOrigSize;
333 PVR_ASSERT(pArena != IMG_NULL);
334 PVR_ASSERT(pBT != IMG_NULL);
337 pArena->sStatistics.uLiveSegmentCount--;
338 pArena->sStatistics.uFreeSegmentCount++;
339 pArena->sStatistics.uFreeResourceCount += pBT->uSize;
342 uOrigBase = pBT->base;
343 uOrigSize = pBT->uSize;
345 pNeighbour = pBT->pPrevSegment;
346 if (pNeighbour != IMG_NULL
347 && pNeighbour->type == btt_free
348 && pNeighbour->base + pNeighbour->uSize == pBT->base) {
349 _FreeListRemove(pArena, pNeighbour);
350 _SegmentListRemove(pArena, pNeighbour);
351 pBT->base = pNeighbour->base;
352 pBT->uSize += pNeighbour->uSize;
353 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour,
356 pArena->sStatistics.uFreeSegmentCount--;
360 pNeighbour = pBT->pNextSegment;
361 if (pNeighbour != IMG_NULL
362 && pNeighbour->type == btt_free
363 && pBT->base + pBT->uSize == pNeighbour->base) {
364 _FreeListRemove(pArena, pNeighbour);
365 _SegmentListRemove(pArena, pNeighbour);
366 pBT->uSize += pNeighbour->uSize;
367 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour,
370 pArena->sStatistics.uFreeSegmentCount--;
374 if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore) {
375 IMG_UINTPTR_T uRoundedStart, uRoundedEnd;
378 (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
380 if (uRoundedStart < pBT->base) {
381 uRoundedStart += pArena->uQuantum;
385 ((uOrigBase + uOrigSize + pArena->uQuantum -
386 1) / pArena->uQuantum) * pArena->uQuantum;
388 if (uRoundedEnd > (pBT->base + pBT->uSize)) {
389 uRoundedEnd -= pArena->uQuantum;
392 if (uRoundedStart < uRoundedEnd) {
393 pArena->pBackingStoreFree(pArena->pImportHandle,
394 uRoundedStart, uRoundedEnd,
399 if (pBT->pNextSegment != IMG_NULL && pBT->pNextSegment->type == btt_span
400 && pBT->pPrevSegment != IMG_NULL
401 && pBT->pPrevSegment->type == btt_span) {
402 BT *next = pBT->pNextSegment;
403 BT *prev = pBT->pPrevSegment;
404 _SegmentListRemove(pArena, next);
405 _SegmentListRemove(pArena, prev);
406 _SegmentListRemove(pArena, pBT);
407 pArena->pImportFree(pArena->pImportHandle, pBT->base,
410 pArena->sStatistics.uSpanCount--;
411 pArena->sStatistics.uExportCount++;
412 pArena->sStatistics.uFreeSegmentCount--;
413 pArena->sStatistics.uFreeResourceCount -= pBT->uSize;
414 pArena->sStatistics.uTotalResourceCount -= pBT->uSize;
416 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL);
417 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
418 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
420 _FreeListInsert(pArena, pBT);
424 _AttemptAllocAligned(RA_ARENA * pArena,
426 BM_MAPPING ** ppsMapping,
428 IMG_UINT32 uAlignment,
429 IMG_UINT32 uAlignmentOffset, IMG_UINTPTR_T * base)
432 PVR_ASSERT(pArena != IMG_NULL);
434 PVR_UNREFERENCED_PARAMETER(uFlags);
437 uAlignmentOffset %= uAlignment;
439 uIndex = pvr_log2(uSize);
442 while (uIndex < FREE_TABLE_LIMIT
443 && pArena->aHeadFree[uIndex] == IMG_NULL)
446 while (uIndex < FREE_TABLE_LIMIT) {
447 if (pArena->aHeadFree[uIndex] != IMG_NULL) {
451 pBT = pArena->aHeadFree[uIndex];
452 while (pBT != IMG_NULL) {
453 IMG_UINTPTR_T aligned_base;
457 (pBT->base + uAlignmentOffset +
459 1) / uAlignment * uAlignment -
462 aligned_base = pBT->base;
463 PVR_DPF((PVR_DBG_MESSAGE,
464 "RA_AttemptAllocAligned: pBT-base=0x%x "
465 "pBT-size=0x%x alignedbase=0x%x size=0x%x",
466 pBT->base, pBT->uSize, aligned_base,
469 if (pBT->base + pBT->uSize >=
470 aligned_base + uSize) {
472 || pBT->psMapping->ui32Flags ==
474 _FreeListRemove(pArena, pBT);
476 PVR_ASSERT(pBT->type ==
485 uFreeResourceCount -=
489 if (aligned_base > pBT->base) {
500 PVR_DPF((PVR_DBG_ERROR, "_AttemptAllocAligned: Front split failed"));
509 _FreeListInsert(pArena,
521 if (pBT->uSize > uSize) {
530 PVR_DPF((PVR_DBG_ERROR, "_AttemptAllocAligned: Back split failed"));
539 _FreeListInsert(pArena,
551 pBT->type = btt_live;
554 (pArena->pSegmentHash,
556 (IMG_UINTPTR_T) pBT)) {
562 if (ppsMapping != IMG_NULL)
570 PVR_DPF((PVR_DBG_MESSAGE,
571 "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x",
577 pBT = pBT->pNextFree;
587 RA_ARENA *RA_Create(IMG_CHAR * name,
590 BM_MAPPING * psMapping,
592 IMG_BOOL(*alloc) (IMG_VOID *, IMG_SIZE_T uSize,
593 IMG_SIZE_T * pActualSize,
594 BM_MAPPING ** ppsMapping,
595 IMG_UINT32 _flags, IMG_UINTPTR_T * pBase),
596 IMG_VOID(*free) (IMG_VOID *, IMG_UINTPTR_T,
597 BM_MAPPING * psMapping),
598 IMG_VOID(*backingstore_free) (IMG_VOID *, IMG_UINT32,
599 IMG_UINT32, IMG_HANDLE),
600 IMG_VOID * pImportHandle)
606 PVR_DPF((PVR_DBG_MESSAGE,
607 "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x",
608 name, base, uSize, alloc, free));
610 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
612 (IMG_VOID **) & pArena, IMG_NULL) != PVRSRV_OK) {
617 pArena->pImportAlloc = alloc != IMG_NULL ? alloc : _RequestAllocFail;
618 pArena->pImportFree = free;
619 pArena->pBackingStoreFree = backingstore_free;
620 pArena->pImportHandle = pImportHandle;
621 for (i = 0; i < FREE_TABLE_LIMIT; i++)
622 pArena->aHeadFree[i] = IMG_NULL;
623 pArena->pHeadSegment = IMG_NULL;
624 pArena->pTailSegment = IMG_NULL;
625 pArena->uQuantum = uQuantum;
628 pArena->sStatistics.uSpanCount = 0;
629 pArena->sStatistics.uLiveSegmentCount = 0;
630 pArena->sStatistics.uFreeSegmentCount = 0;
631 pArena->sStatistics.uFreeResourceCount = 0;
632 pArena->sStatistics.uTotalResourceCount = 0;
633 pArena->sStatistics.uCumulativeAllocs = 0;
634 pArena->sStatistics.uCumulativeFrees = 0;
635 pArena->sStatistics.uImportCount = 0;
636 pArena->sStatistics.uExportCount = 0;
639 #if defined(CONFIG_PROC_FS) && defined(DEBUG)
640 if (strcmp(pArena->name, "") != 0) {
641 sprintf(pArena->szProcInfoName, "ra_info_%s", pArena->name);
642 CreateProcEntry(pArena->szProcInfoName, RA_DumpInfo, 0, pArena);
643 sprintf(pArena->szProcSegsName, "ra_segs_%s", pArena->name);
644 CreateProcEntry(pArena->szProcSegsName, RA_DumpSegs, 0, pArena);
648 pArena->pSegmentHash = HASH_Create(MINIMUM_HASH_SIZE);
649 if (pArena->pSegmentHash == IMG_NULL) {
653 uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
654 pBT = _InsertResource(pArena, base, uSize);
655 if (pBT == IMG_NULL) {
658 pBT->psMapping = psMapping;
664 HASH_Delete(pArena->pSegmentHash);
666 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
671 void RA_Delete(RA_ARENA * pArena)
675 PVR_ASSERT(pArena != IMG_NULL);
676 PVR_DPF((PVR_DBG_MESSAGE, "RA_Delete: name='%s'", pArena->name));
678 for (uIndex = 0; uIndex < FREE_TABLE_LIMIT; uIndex++)
679 pArena->aHeadFree[uIndex] = IMG_NULL;
681 while (pArena->pHeadSegment != IMG_NULL) {
682 BT *pBT = pArena->pHeadSegment;
683 PVR_ASSERT(pBT->type == btt_free);
684 _SegmentListRemove(pArena, pBT);
685 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
687 pArena->sStatistics.uSpanCount--;
690 #if defined(CONFIG_PROC_FS) && defined(DEBUG)
691 RemoveProcEntry(pArena->szProcInfoName);
692 RemoveProcEntry(pArena->szProcSegsName);
694 HASH_Delete(pArena->pSegmentHash);
695 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
698 IMG_BOOL RA_Add(RA_ARENA * pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
700 PVR_ASSERT(pArena != IMG_NULL);
702 PVR_DPF((PVR_DBG_MESSAGE,
703 "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base,
707 (uSize + pArena->uQuantum -
708 1) / pArena->uQuantum * pArena->uQuantum;
709 return ((IMG_BOOL) (_InsertResource(pArena, base, uSize) != IMG_NULL));
713 RA_Alloc(RA_ARENA * pArena,
714 IMG_SIZE_T uRequestSize,
715 IMG_SIZE_T * pActualSize,
716 BM_MAPPING ** ppsMapping,
718 IMG_UINT32 uAlignment,
719 IMG_UINT32 uAlignmentOffset, IMG_UINTPTR_T * base)
721 IMG_BOOL bResult = IMG_FALSE;
722 IMG_SIZE_T uSize = uRequestSize;
724 PVR_ASSERT(pArena != IMG_NULL);
727 if (pActualSize != IMG_NULL)
728 *pActualSize = uSize;
730 PVR_DPF((PVR_DBG_MESSAGE,
731 "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x",
732 pArena->name, uSize, uRequestSize, uAlignment,
735 bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags,
736 uAlignment, uAlignmentOffset, base);
738 BM_MAPPING *psImportMapping;
739 IMG_UINTPTR_T import_base;
740 IMG_SIZE_T uImportSize = uSize;
742 if (uAlignment > pArena->uQuantum) {
743 uImportSize += (uAlignment - 1);
747 ((uImportSize + pArena->uQuantum -
748 1) / pArena->uQuantum) * pArena->uQuantum;
751 pArena->pImportAlloc(pArena->pImportHandle, uImportSize,
752 &uImportSize, &psImportMapping, uFlags,
757 _InsertResourceSpan(pArena, import_base,
760 if (pBT == IMG_NULL) {
762 pArena->pImportFree(pArena->pImportHandle,
765 PVR_DPF((PVR_DBG_MESSAGE,
766 "RA_Alloc: name='%s', size=0x%x failed!",
767 pArena->name, uSize));
771 pBT->psMapping = psImportMapping;
773 pArena->sStatistics.uFreeSegmentCount++;
774 pArena->sStatistics.uFreeResourceCount += uImportSize;
775 pArena->sStatistics.uImportCount++;
776 pArena->sStatistics.uSpanCount++;
779 _AttemptAllocAligned(pArena, uSize, ppsMapping,
781 uAlignmentOffset, base);
783 PVR_DPF((PVR_DBG_MESSAGE,
784 "RA_Alloc: name='%s' uAlignment failed!",
791 pArena->sStatistics.uCumulativeAllocs++;
794 PVR_DPF((PVR_DBG_MESSAGE,
795 "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d",
796 pArena->name, uSize, *base, bResult));
801 void RA_Free(RA_ARENA * pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore)
805 PVR_ASSERT(pArena != IMG_NULL);
808 PVR_DPF((PVR_DBG_MESSAGE,
809 "RA_Free: name='%s', base=0x%x", pArena->name, base));
811 pBT = (BT *) HASH_Remove(pArena->pSegmentHash, base);
812 PVR_ASSERT(pBT != IMG_NULL);
815 PVR_ASSERT(pBT->base == base);
818 pArena->sStatistics.uCumulativeFrees++;
821 _FreeBT(pArena, pBT, bFreeBackingStore);
825 IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena,
826 RA_SEGMENT_DETAILS * psSegDetails)
830 if (psSegDetails->hSegment) {
831 pBT = (BT *) psSegDetails->hSegment;
833 RA_ARENA *pArena = (RA_ARENA *) hArena;
835 pBT = pArena->pHeadSegment;
838 while (pBT != IMG_NULL) {
839 if (pBT->type == btt_live) {
840 psSegDetails->uiSize = pBT->uSize;
841 psSegDetails->sCpuPhyAddr.uiAddr = pBT->base;
842 psSegDetails->hSegment = (IMG_HANDLE) pBT->pNextSegment;
847 pBT = pBT->pNextSegment;
850 psSegDetails->uiSize = 0;
851 psSegDetails->sCpuPhyAddr.uiAddr = 0;
852 psSegDetails->hSegment = (IMG_HANDLE) - 1;
858 #if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS)
859 static char *_BTType(int eType)
873 #if defined(CONFIG_PROC_FS) && defined(DEBUG)
875 RA_DumpSegs(char *page, char **start, off_t off, int count, int *eof,
880 RA_ARENA *pArena = (RA_ARENA *) data;
889 return printAppend(page, count, 0,
890 "Arena \"%s\"\nBase Size Type Ref\n",
893 for (pBT = pArena->pHeadSegment; --off && pBT;
894 pBT = pBT->pNextSegment) ;
896 len = printAppend(page, count, 0, "%08x %8x %4s %08x\n",
897 (unsigned int)pBT->base,
898 (unsigned int)pBT->uSize, _BTType(pBT->type),
899 (unsigned int)pBT->psMapping);
907 RA_DumpInfo(char *page, char **start, off_t off, int count, int *eof,
911 RA_ARENA *pArena = (RA_ARENA *) data;
921 printAppend(page, count, 0, "quantum\t\t\t%lu\n",
926 printAppend(page, count, 0, "import_handle\t\t%08X\n",
927 (unsigned int)pArena->pImportHandle);
932 printAppend(page, count, 0, "span count\t\t%lu\n",
933 pArena->sStatistics.uSpanCount);
937 printAppend(page, count, 0, "live segment count\t%lu\n",
938 pArena->sStatistics.uLiveSegmentCount);
942 printAppend(page, count, 0, "free segment count\t%lu\n",
943 pArena->sStatistics.uFreeSegmentCount);
947 printAppend(page, count, 0,
948 "free resource count\t%lu (0x%x)\n",
949 pArena->sStatistics.uFreeResourceCount,
950 (unsigned int)pArena->sStatistics.
955 printAppend(page, count, 0, "total allocs\t\t%lu\n",
956 pArena->sStatistics.uCumulativeAllocs);
960 printAppend(page, count, 0, "total frees\t\t%lu\n",
961 pArena->sStatistics.uCumulativeFrees);
965 printAppend(page, count, 0, "import count\t\t%lu\n",
966 pArena->sStatistics.uImportCount);
970 printAppend(page, count, 0, "export count\t\t%lu\n",
971 pArena->sStatistics.uExportCount);
984 PVRSRV_ERROR RA_GetStats(RA_ARENA * pArena,
985 IMG_CHAR ** ppszStr, IMG_UINT32 * pui32StrLen)
987 IMG_CHAR *pszStr = *ppszStr;
988 IMG_UINT32 ui32StrLen = *pui32StrLen;
992 CHECK_SPACE(ui32StrLen);
993 i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name);
994 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
996 CHECK_SPACE(ui32StrLen);
998 OSSNPrintf(pszStr, 100,
999 " allocCB=%08X freeCB=%08X handle=%08X quantum=%d\n",
1000 pArena->pImportAlloc, pArena->pImportFree,
1001 pArena->pImportHandle, pArena->uQuantum);
1002 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1004 CHECK_SPACE(ui32StrLen);
1006 OSSNPrintf(pszStr, 100, "span count\t\t%lu\n",
1007 pArena->sStatistics.uSpanCount);
1008 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1010 CHECK_SPACE(ui32StrLen);
1012 OSSNPrintf(pszStr, 100, "live segment count\t%lu\n",
1013 pArena->sStatistics.uLiveSegmentCount);
1014 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1016 CHECK_SPACE(ui32StrLen);
1018 OSSNPrintf(pszStr, 100, "free segment count\t%lu\n",
1019 pArena->sStatistics.uFreeSegmentCount);
1020 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1022 CHECK_SPACE(ui32StrLen);
1023 i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%lu (0x%x)\n",
1024 pArena->sStatistics.uFreeResourceCount,
1025 (unsigned int)pArena->sStatistics.
1026 uFreeResourceCount);
1027 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1029 CHECK_SPACE(ui32StrLen);
1031 OSSNPrintf(pszStr, 100, "total allocs\t\t%lu\n",
1032 pArena->sStatistics.uCumulativeAllocs);
1033 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1035 CHECK_SPACE(ui32StrLen);
1037 OSSNPrintf(pszStr, 100, "total frees\t\t%lu\n",
1038 pArena->sStatistics.uCumulativeFrees);
1039 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1041 CHECK_SPACE(ui32StrLen);
1043 OSSNPrintf(pszStr, 100, "import count\t\t%lu\n",
1044 pArena->sStatistics.uImportCount);
1045 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1047 CHECK_SPACE(ui32StrLen);
1049 OSSNPrintf(pszStr, 100, "export count\t\t%lu\n",
1050 pArena->sStatistics.uExportCount);
1051 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1053 CHECK_SPACE(ui32StrLen);
1054 i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n");
1055 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1057 if (pArena->pHeadSegment != IMG_NULL &&
1058 pArena->pHeadSegment->pPrevSegment != IMG_NULL) {
1059 CHECK_SPACE(ui32StrLen);
1061 OSSNPrintf(pszStr, 100,
1062 " error: head boundary tag has invalid pPrevSegment\n");
1063 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1066 if (pArena->pTailSegment != IMG_NULL &&
1067 pArena->pTailSegment->pNextSegment != IMG_NULL) {
1068 CHECK_SPACE(ui32StrLen);
1070 OSSNPrintf(pszStr, 100,
1071 " error: tail boundary tag has invalid pNextSegment\n");
1072 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1075 for (pBT = pArena->pHeadSegment; pBT != IMG_NULL;
1076 pBT = pBT->pNextSegment) {
1077 CHECK_SPACE(ui32StrLen);
1079 OSSNPrintf(pszStr, 100,
1080 "\tbase=0x%x size=0x%x type=%s ref=%08X\n",
1081 (unsigned long)pBT->base, pBT->uSize,
1082 _BTType(pBT->type), pBT->psMapping);
1083 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1087 *pui32StrLen = ui32StrLen;