source: svn/trunk/newcon3bcm2_21bu/magnum/basemodules/mem/bmem_system.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 19.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2002-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bmem_system.c $
11 * $brcm_Revision: Hydra_Software_Devel/33 $
12 * $brcm_Date: 2/7/12 6:37p $
13 *
14 * Module Description:
15 *
16 * This module provides the basic functions used to implement a memory
17 * manager which stores bookkeeping information in OS-allocated memory. This
18 * is advantageous when the memory being managed has significant access time
19 * penalties. If accessing the managed memory has no access time penalties,
20 * do NOT use this module; it is algorithmically slower than direct access
21 * because of the additional overhead needed.
22 *
23 * All of the bookeeping information close to the CPU, in "system memory".
24 * To do this, there needs to be some way of associating managed memory
25 * block with info about the managed memory block. In the local allocator,
26 * this is done by physically locating the BlockInfo in front of the managed
27 * block. This same approach can't be used if the BlockInfo lives in system
28 * memory.
29 *
30 * Instead, a hash table is used to index the BlockInfo structures. The
31 * has index is based upon the lowest significant bits of the managed memory
32 * address of the block. A linked list is used in each hash bucket to handle
33 * collisions. The nodes in thist list are not ordered in any way.
34 *
35 * When looking up a BlockInfo for a manged memory address, the address is
36 * shifted and masked to give the hash key. The list of nodes at that hash
37 * key is iterated over until a match is found. If we find that the lists
38 * grow to an unreasonable length, then the number of hash buckets can be
39 * increased. This is not done dynamically.
40 *
41 * Revision History:
42 *
43 * $brcm_Log: /magnum/basemodules/mem/bmem_system.c $
44 *
45 * Hydra_Software_Devel/33   2/7/12 6:37p albertl
46 * SW7425-2345: Changed total allocation and number of allocation tracking
47 * to work in eFastest.
48 *
49 * Hydra_Software_Devel/32   11/14/11 2:22p albertl
50 * SW7425-1293: Fixed use of uncached address when cached addresses exist
51 * during heap creation.  Fixed coverity issues.
52 *
53 * Hydra_Software_Devel/31   9/9/11 7:10p albertl
54 * SW7346-201: Moved watermark calculation to alloc and free for accurate
55 * calculation.
56 *
57 * Hydra_Software_Devel/30   9/7/11 2:05p albertl
58 * SW7408-258: Fixed memory leak.
59 *
60 * Hydra_Software_Devel/29   3/29/11 4:16p albertl
61 * SW7425-247: Changed BDBG_OBJECT_DESTROY to BDBG_OBJECT_UNSET.
62 *
63 * Hydra_Software_Devel/28   3/28/11 5:13p albertl
64 * SW7425-247: Incorporated BDBG_OBJECT handle validation.
65 *
66 * Hydra_Software_Devel/27   1/10/11 3:32p albertl
67 * SW7408-193: BMEM_Heapinfo now includes high watermark.  Added
68 * BMEM_Heap_ResetHighWatermark().
69 *
70 * Hydra_Software_Devel/26   11/8/10 4:48p albertl
71 * SW7420-1155: Fixed size calculation to match fixed implementation of
72 * pEnd.
73 *
74 * Hydra_Software_Devel/25   11/4/10 7:40p albertl
75 * SW7420-1155: Fixed pEnd to really be last available byte and addrEnd to
76 * be last byte in chunk rather than byte after that.
77 *
78 * Hydra_Software_Devel/24   5/26/09 5:57p albertl
79 * PR55389: Fixed mangled file.
80 *
81 * Hydra_Software_Devel/23   5/26/09 5:52p albertl
82 * PR55389: Replaced uintptr_t with uint32_t.
83 *
84 * Hydra_Software_Devel/22   5/12/08 4:21p erickson
85 * PR42628: free all mem in BMEM_P_SystemDestroyHeap
86 *
87 * Hydra_Software_Devel/21   7/12/07 6:26p albertl
88 * PR31066:  Updated warning message to give platform and user specified
89 * uiAlignment size.
90 *
91 * Hydra_Software_Devel/20   7/6/07 6:54p albertl
92 * PR31066:  Changed BMEM_HEAP_ALIGNMENT to 6 for 7400 B0 and later and
93 * 7405.  Added warnings when user specified alignment is less than and
94 * forced to BMEM_HEAP_ALIGNMENT.
95 *
96 * Hydra_Software_Devel/19   3/15/07 7:24p albertl
97 * PR28682:  Changed BMEM_GUARD_SIZE_BYTES to be dynamically calculated
98 * based on runtime safety config.
99 *
100 * Hydra_Software_Devel/18   6/21/06 3:12p albertl
101 * PR20247:  Moved safety config table to bmem.c  BMEM_P_Heap now uses a
102 * BMEM_P_SafetyConfigInfo pointer to track safety configuration settings
103 * instead of tracking each configuration separately.
104 *
105 * Hydra_Software_Devel/17   6/16/06 3:23p albertl
106 * PR20247, PR20276, PR20354:  Added the ability to control debug
107 * configuration at runtime.  Added address and offset checking to
108 * conversion functions.  BMEM_SetCache can now only be called before
109 * heaps are allocated from.  Added BMEM_Heap functions.
110 *
111 * Hydra_Software_Devel/16   10/7/05 3:53p jasonh
112 * PR 17374: Allowed GetHeapInfo to return original creation parameters.
113 *
114 * Hydra_Software_Devel/15   3/17/05 6:12p pntruong
115 * PR14494: Add preliminary software support to 3560 A0, remove linux
116 * build warings.
117 *
118 * Hydra_Software_Devel/14   3/10/05 5:05p albertl
119 * PR13677:  Both local and system bookkeeping made available at heap
120 * creation though functions BMEM_CreateHeapSystem and
121 * BMEM_CreateHeapLocal.
122 *
123 * Hydra_Software_Devel/13   3/2/05 3:50p jasonh
124 * PR 14322: Fixing debug message argument.
125 *
126 * Hydra_Software_Devel/12   1/31/05 9:54a erickson
127 * PR13097: if there's a leak, dump the heap (requires msg level)
128 *
129 * Hydra_Software_Devel/11   1/21/05 4:23p albertl
130 * PR13717:  Replaced BMEM_DBG_ENTER with BDBG_ENTER.  Moved printouts to
131 * DBG_MSG, fixed pvHeap.
132 *
133 * Hydra_Software_Devel/10   11/2/04 5:27p pntruong
134 * PR13076: Initialized new members added.
135 *
136 * Hydra_Software_Devel/9   4/30/04 3:32p hongtaoz
137 * PR8761: fixed C++ compile error.
138 *
139 * Hydra_Software_Devel/8   4/1/04 12:49p vsilyaev
140 * PR 10201: Added memory monitor
141 *
142 * Hydra_Software_Devel/7   12/31/03 12:02p jasonh
143 * PR 8940: Changed return type of destroyheap to void. Removed use of
144 * DEBUG macro and printf.
145 *
146 * Hydra_Software_Devel/6   9/15/03 5:24p jasonh
147 * Fixed create heap to store offset and address. Fixed return codes.
148 * Added system specific destroy heap.
149 *
150 * Hydra_Software_Devel/5   9/5/03 5:48p hongtaoz
151 * fixed compile errors.
152 *
153 * Hydra_Software_Devel/4   9/5/03 1:39p jasonh
154 * Wrapped unused arguments with BSTD_UNUSED
155 *
156 * Hydra_Software_Devel/3   9/2/03 1:48p vadim
157 * Some magnum updates.
158 *
159 * Hydra_Software_Devel/1   3/20/03 3:24p erickson
160 * initial bmem work, taken from SetTop/memorylib
161 *
162 * SanJose_DVTSW_Devel/5   8/12/02 10:26a poz
163 * Changed to kernel interface abstractions for malloc and free.
164 *
165 * SanJose_DVTSW_Devel\4   4/15/02 6:22p zinc
166 * Fixed missed rename of HeapCheck.
167 *
168 * SanJose_DVTSW_Devel\3   4/15/02 3:34p poz
169 * Updated function name to bcmHeapCreate.
170 *
171 * SanJose_DVTSW_Devel\2   4/15/02 2:30p poz
172 * Modified to get semaphore when MEM_REENTRANT.
173 *
174 * SanJose_DVTSW_Devel\1   4/15/02 1:36p poz
175 * Implementation of system-memory heap manager.
176 *
177 ***************************************************************************/
178
179#include "bstd.h"
180#include "bmem.h"
181#include "bmem_config.h"
182#include "bmem_priv.h"
183#include "bmem_debug.h"
184#include "bkni.h"
185
186BDBG_MODULE(BMEM);
187
188/* The number of hash buckets to be used to store BlockInfo blocks */
189#define BMEM_SYS_NUM_BUCKETS 256 /* must be a power of two */
190
191/* Calculates the hash key given a managed memory address */
192#define BUCKET_IDX(addr) (((addr) >> pshi->uiAlignment) & (BMEM_SYS_NUM_BUCKETS-1))
193
194
195/***************************************************************************
196 * BMEM_P_BINode - Stores managed block info for the system heap manger.
197 *
198 * Contains information about the managed block (the BlockInfo) as well as
199 * members traversing the system-memory data structures.
200 *
201 */
202typedef struct BMEM_P_BINode BMEM_P_BINode;
203struct BMEM_P_BINode
204{
205        BMEM_P_BlockInfo pbi;   /* Managed block info. */
206                               /* Must be the first entry in this struct! */
207
208        uint32_t addr;         /* Managed memory block base address */
209        BMEM_P_BINode *pbiNext; /* Pointer to next node in the hash bucket */
210        BMEM_P_BINode *pbiPrev; /* Pointer to previous node in the hash bucket */
211};
212
213/***************************************************************************
214 * BMEM_P_SystemHeapInfo - Stores heap-wide info for the system heap manager.
215 *
216 * Heap-wide information specific to the System heap manager.
217 *
218 */
219typedef struct BMEM_P_SystemHeapInfo
220{
221        unsigned int uiAlignment;
222        BMEM_P_BINode *anodes[BMEM_SYS_NUM_BUCKETS];
223} BMEM_P_SystemHeapInfo;
224
225/**********************************************************************func*
226 * BMEM_P_SystemGetAddress - Get the managed memory base address for a
227 *                           block.
228 *
229 * Returns:
230 *    0 if a NULL BlockInfo is given, otherwise the base address.
231 */
232
233uint32_t BMEM_P_SystemGetAddress
234(
235        BMEM_Handle pheap,
236        BMEM_P_BlockInfo *pbi
237)
238{
239        BSTD_UNUSED( pheap );
240
241        if( pbi == NULL )
242        {
243                return 0;
244        }
245
246        /* We'll take advantage of BINode having the BlockInfo right at the
247         * front and just magically cast it.
248         */
249        return ((BMEM_P_BINode *) pbi)->addr;
250}
251
252/**********************************************************************func*
253 * BMEM_P_SystemGetBlockInfo - Get the bookkeeping info for a managed base
254 *                             address.
255 *
256 * This function finds the bookeeping information for a given base address.
257 * If the given base address has no bookkeeping information assigned to it,
258 * a new BlockInfo is allocated from the system heap and added to the hash.
259 * The new BlockInfo is then returned.
260 *
261 * Returns:
262 *    On success, a pointer to the BlockInfo for the managed base address.
263 *    On failure (which can occur if the system heap is full), NULL.
264 *
265 */
266
267BMEM_P_BlockInfo *BMEM_P_SystemGetBlockInfo
268(
269        BMEM_Handle pheap,
270        uint32_t addr
271)
272{
273        BMEM_P_SystemHeapInfo *pshi = (BMEM_P_SystemHeapInfo *)(pheap->pvData);
274        int idx = BUCKET_IDX(addr);
275
276        BMEM_P_BINode *pbinode = pshi->anodes[idx];
277
278        while(pbinode!=NULL && pbinode->addr!=addr)
279        {
280                pbinode = pbinode->pbiNext;
281        }
282
283        if(pbinode == NULL)
284        {
285                /* No entry found. Make a new one */
286                pbinode = (BMEM_P_BINode *)BKNI_Malloc(sizeof(BMEM_P_BINode));
287                if(pbinode == NULL)
288                {
289                        BDBG_ERR(("Out of system memory. Can't allocate bookkeeping!"));
290                        return NULL;
291                }
292                pbinode->addr = addr;
293                pbinode->pbiNext = pshi->anodes[idx];
294                pbinode->pbiPrev = NULL;
295                pshi->anodes[idx] = pbinode;
296
297                if(pbinode->pbiNext!=NULL)
298                {
299                        pbinode->pbiNext->pbiPrev = pbinode;
300                }
301        }
302
303        /* We'll take advantage of BINode having the BlockInfo right at the
304         * front and just magically cast it.
305         */
306        return (BMEM_P_BlockInfo *)pbinode;
307}
308
309/**********************************************************************func*
310 * BMEM_P_SystemDropBlockInfo -
311 *    Free up the bookkeeping info for a managed memory base address
312 *
313 * Returns:
314 *    void
315 */
316
317void BMEM_P_SystemDropBlockInfo
318(
319        BMEM_Handle pheap,
320        BMEM_P_BlockInfo *pbi
321)
322{
323        BMEM_P_SystemHeapInfo *pshi = (BMEM_P_SystemHeapInfo *)pheap->pvData;
324        /* We'll take advantage of BINode having the BlockInfo right at the
325         * front and just magically cast it.
326         */
327        BMEM_P_BINode *pbinode = (BMEM_P_BINode *) pbi;
328        int idx = BUCKET_IDX(pbinode->addr);
329
330        /* Remove the BINode from the list in the hash table. */
331        if(pbinode->pbiPrev != NULL)
332        {
333                pbinode->pbiPrev->pbiNext = pbinode->pbiNext;
334        }
335        if(pbinode->pbiNext != NULL)
336        {
337                pbinode->pbiNext->pbiPrev = pbinode->pbiPrev;
338        }
339
340        if(pshi->anodes[idx] == pbinode)
341        {
342                pshi->anodes[idx] = pbinode->pbiNext;
343        }
344
345        BKNI_Free(pbinode);
346}
347
348/**********************************************************************func*
349 * bcmHeapCreate - Initializes the heap with local bookkeeping.
350 *
351 * This function inititalizes a heap at a given location and size.
352 * Any previous allocations in the chunk of memory handed over to this
353 * function are lost. Every heap has a base minimum alignment for all of
354 * the allocations within that heap. (However, you can specify a greater
355 * alignment when actually doing an allocation.)
356 *
357 * In this implementation, memory in the CPU's system heap is used to store
358 * the bookkeeping information for the heap.
359 *
360 * Returns:
361 *   Returns true if heap is initialized, or false if the size of the heap
362 *   is too small to manage or there isn't enough system memory to allocate
363 *   bookkeeping information.
364 *
365 */
366BERR_Code BMEM_CreateHeapSystem
367(
368        BMEM_Handle  *ppHeap,      /* Address to store pointer of new heap info structure */
369        void         *pvHeap,      /* Pointer to beginning of memory chunk to manage */
370        uint32_t      ulOffset,    /* Device offset of initial location */
371        size_t        zSize,       /* Size of chunk to manage in bytes */
372        unsigned int  uiAlignment  /* Minimum alignment for all allocations in the heap */
373)
374{
375        BMEM_Heap_Settings stHeapSettings;
376        BMEM_Heap_Settings *pHeapSettings = &stHeapSettings;
377
378        BMEM_Heap_GetDefaultSettings(pHeapSettings);
379
380        pHeapSettings->uiAlignment = uiAlignment;
381        pHeapSettings->eBookKeeping = BMEM_BOOKKEEPING_SYSTEM;
382
383        return BMEM_Heap_Create(NULL, pvHeap, ulOffset, zSize, pHeapSettings, ppHeap);
384}
385
386BERR_Code BMEM_P_SystemCreateHeap
387(
388        BMEM_Handle        *ppHeap,      /* Address to store pointer of new heap info structure */
389        void               *pvHeap,      /* Pointer to beginning of memory chunk to manage */
390        uint32_t            ulOffset,    /* Device offset of initial location */
391        size_t              zSize,       /* Size of chunk to manage in bytes */
392        BMEM_Heap_Settings *pHeapSettings
393)
394{
395        BERR_Code              err = BERR_SUCCESS;
396        BMEM_P_SystemHeapInfo *pshi;
397        BMEM_P_BlockInfo      *pbi;
398        BMEM_P_Heap           *pheap;
399        uint32_t               addrHeap = (uint32_t)pvHeap;
400        uint32_t               addrEnd = (uint32_t)pvHeap + zSize - 1;
401        int                    i;
402        unsigned int           uiAlignment = pHeapSettings->uiAlignment;
403        size_t                 ulAlignedSize;
404        uint32_t               eSafetyConfig = pHeapSettings->eSafetyConfig;
405
406        BDBG_ENTER(BMEM_P_SystemCreateHeap);
407        BDBG_MSG(("BMEM_P_SystemCreateHeap(%p, %p, %lu, %d)",
408                ppHeap, pvHeap, zSize, (int)uiAlignment));
409
410        if (pHeapSettings->eSafetyConfig > BMEM_P_SafetyTableSize)
411        {
412                /* Invalid safety config. */
413                err = BERR_TRACE(BERR_INVALID_PARAMETER);
414                goto done;
415        }
416
417        if (pHeapSettings->eSafetyConfig > BMEM_SAFETY_CONFIG)
418        {
419                /* Invalid run-time safety config. */
420                        BDBG_ERR(("Run-time safety config cannot be higher than compiled safety config!"));
421                        err = BERR_TRACE(BERR_INVALID_PARAMETER);
422                goto done;
423        }
424
425        /* allocate heap structure */
426        *ppHeap = (BMEM_P_Heap*) BKNI_Malloc( sizeof (BMEM_P_Heap) );
427        if( *ppHeap == NULL )
428        {
429                err = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
430                BDBG_ERR(( "Out of system memory. Can't allocate bookkeeping!" ));
431                goto done;
432        }
433
434        /* initialize heap structure */
435        pheap = (BMEM_P_Heap *) *ppHeap;
436        BDBG_OBJECT_SET(pheap, BMEM_Heap);
437        pheap->pFreeTop = NULL;
438        pheap->pAllocTop = NULL;
439        pheap->ulAlignMask = 0;
440        pheap->pStart = NULL;
441        pheap->pEnd = NULL;
442        pheap->ulNumErrors = 0;
443        pheap->pvData = NULL;
444        pheap->pvHeap = pvHeap;
445        pheap->ulOffset = ulOffset;
446        pheap->monitor = NULL;
447        pheap->pvCache = pHeapSettings->pCachedAddress;
448        pheap->pfFlushCb = pHeapSettings->flush;
449        pheap->pfFlushCb_isr = pHeapSettings->flush_isr;
450        pheap->zSize = zSize;
451        pheap->ulNumAllocated = 0;
452        pheap->ulTotalAllocated = 0;
453        pheap->ulHighWatermark = 0;
454
455        pheap->pSafetyConfigInfo = &(BMEM_P_SafetyConfigTbl[eSafetyConfig]);
456        pheap->ulGuardSizeBytes  = pheap->pSafetyConfigInfo->iGuardSize * BMEM_GUARD_UNIT_BYTES;
457
458        pheap->eBookKeeping = pHeapSettings->eBookKeeping;
459        pheap->bCacheLocked = false;
460
461        pheap->pGetAddressFunc = &BMEM_P_SystemGetAddress;
462        pheap->pGetBlockInfoFunc = &BMEM_P_SystemGetBlockInfo;
463        pheap->pDropBlockInfoFunc = &BMEM_P_SystemDropBlockInfo;
464        pheap->pDestroyHeapFunc = &BMEM_P_SystemDestroyHeap;
465
466#if (BMEM_REENTRANT_CONFIG==BMEM_REENTRANT)
467        /* create mutex for re-entrant control */
468        err = BERR_TRACE(BKNI_CreateMutex(&(pheap->pMutex)));
469        if (err != BERR_SUCCESS)
470        {
471                goto done;
472        }
473#endif
474
475
476        /* Force at least the minimum heap alignment */
477        if(uiAlignment < BMEM_HEAP_ALIGNMENT)
478        {
479                BDBG_WRN(("uiAlignment %d less than platform minimum %d.  Setting alignment to minimum.", uiAlignment, BMEM_HEAP_ALIGNMENT));
480                uiAlignment = BMEM_HEAP_ALIGNMENT;
481        }
482        pheap->uiAlignment = uiAlignment;
483        pheap->ulAlignMask = (1L << uiAlignment) - 1;
484
485        /* Align the heap to be on the requested alignment. */
486        pheap->pStart = (uint8_t *)((addrHeap+pheap->ulAlignMask) & ~pheap->ulAlignMask);
487        /* Last usable byte after alignment. */
488        pheap->pEnd = (uint8_t *)(((addrEnd + 1) & ~pheap->ulAlignMask) - 1);
489
490        /* Allocate the hash buckets for storing the BlockInfos */
491        pheap->pvData = BKNI_Malloc(sizeof(BMEM_P_SystemHeapInfo));
492        if(pheap->pvData == NULL)
493        {
494                /* unable to allocate */
495                err = BERR_OUT_OF_SYSTEM_MEMORY;
496                BDBG_ERR(("Out of system memory. Can't allocate hash table!"));
497                goto done;
498        }
499        pshi = (BMEM_P_SystemHeapInfo *)pheap->pvData;
500
501        /* initialize table */
502        for(i = 0; i<BMEM_SYS_NUM_BUCKETS; ++i)
503        {
504                pshi->anodes[i] = NULL;
505        }
506        pshi->uiAlignment = uiAlignment;
507
508        /*
509         * Starting here, it's safe to make calls to the other heap management
510         * functions.
511         */
512
513        /* Make the first block, which represents the remaining (free) heap */
514        pbi = BMEM_P_SystemGetBlockInfo(pheap, (uint32_t)pheap->pStart);
515       
516        ulAlignedSize = pheap->pEnd-pheap->pStart+1;
517
518        /* heap size greater than bookkeeping? */
519        if(ulAlignedSize > BMEM_BOOKKEEPING_SIZE_SYSTEM)
520        {
521                /* Create a free block representing the entire heap. */
522                pbi->ulSize = ulAlignedSize;
523                pbi->ulFrontScrap = 0;
524                pbi->ulBackScrap = 0;
525                pbi->pnext = NULL;
526                BMEM_P_FillGuard(pheap, pbi);
527
528                pheap->pFreeTop = pbi;
529
530        /* memory isn't even large enough for bookkeeping */
531        } else
532        {
533                /* cannot create heap from this memory */
534                pheap->pFreeTop = NULL;
535                err = BERR_INVALID_PARAMETER;
536        }
537
538#if BMEM_CHECK_ALL_GUARDS
539        if (pheap->pSafetyConfigInfo->bCheckAllGuards)
540        {
541                /* heap has been created? */
542                if (err == BERR_SUCCESS)
543                {
544                        /* validate heap */
545                        err = BMEM_ValidateHeap(pheap);
546                }
547        }
548#endif
549
550done:
551        /* free heap if error occured */
552        if ((err != BERR_SUCCESS) && *ppHeap!=NULL)
553        {
554                /* destroy heap */
555                BMEM_DestroyHeap(*ppHeap);
556                *ppHeap = NULL;
557        }
558
559        /* return status */
560        BDBG_MSG(("BMEM_P_SystemCreateHeap = %ul", err));
561        BDBG_LEAVE(BMEM_P_SystemCreateHeap);
562        return err;
563}
564
565/***************************************************************************/
566void BMEM_P_SystemDestroyHeap
567(
568        BMEM_Handle pheap
569)
570{
571#if BMEM_CHECK_ALL_GUARDS
572        BERR_Code err;
573#endif
574        BMEM_P_SystemHeapInfo *pshi;
575        unsigned i;
576
577        BDBG_OBJECT_ASSERT(pheap, BMEM_Heap);
578
579#if BMEM_CHECK_ALL_GUARDS
580        if (pheap->pSafetyConfigInfo->bCheckAllGuards)
581        {
582                /* validate heap */
583                err = BERR_TRACE(BMEM_ValidateHeap(pheap));
584                if (err != BERR_SUCCESS)
585                {
586                        /* error validating heap */
587                        goto done;
588                }
589        }
590#endif
591
592        /* blocks still allocated? */
593        if (pheap->pAllocTop)
594        {
595                /* leaked resource */
596                BDBG_ERR(("Leaked resource -- unfreed blocks detected"));
597                BMEM_Dbg_DumpHeap(pheap);
598        }
599
600        /* free system hash table (should be empty since there
601           are no outstanding allocations) */
602        pshi = (BMEM_P_SystemHeapInfo *)(pheap->pvData);
603        for (i=0;i<BMEM_SYS_NUM_BUCKETS;i++) {
604                BMEM_P_BINode *pbi = pshi->anodes[i];
605                BMEM_P_BINode *pbiNext;
606                while(pbi) {
607                        pbiNext = pbi->pbiNext;
608                        BKNI_Free(pbi);
609                        pbi = pbiNext;
610                }
611        }
612
613        BKNI_Free(pheap->pvData);
614
615#if (BMEM_REENTRANT_CONFIG==BMEM_REENTRANT)
616        /* destroy mutex */
617        BKNI_DestroyMutex(pheap->pMutex);
618#endif
619
620        /* free heap handle */
621        BDBG_OBJECT_UNSET(pheap, BMEM_Heap);
622        BKNI_Free(pheap);
623
624done:
625        /* return */
626        return;
627}
628
629/* End of File */
Note: See TracBrowser for help on using the repository browser.