/*************************************************************************** * Copyright (c) 2003-2009, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: bmem_test.c $ * $brcm_Revision: Hydra_Software_Devel/11 $ * $brcm_Date: 5/26/09 4:24p $ * * Module Description: * * Revision History: * * $brcm_Log: /magnum/basemodules/mem/test/bmem_test.c $ * * Hydra_Software_Devel/11 5/26/09 4:24p albertl * PR55389: Replaced uintptr_t with uint32_t. * * Hydra_Software_Devel/10 4/27/05 6:04p jasonh * PR 15059: Changed debug application to remove newlines and add some * more information. * * Hydra_Software_Devel/9 5/28/04 11:37a hongtaoz * PR10059: added alignment test; took heap error counts into test result * judgement; * * Hydra_Software_Devel/8 5/27/04 7:38p hongtaoz * PR10059: added more debug messages; enhanced with random free/alloc * loops to test complex scenarioes. * * Hydra_Software_Devel/7 5/26/04 6:59p hongtaoz * PR10059: sorted the freed heap in size ascending order; fixed compile * error for bmem test; dump heap map before destroying the heap for bmem * test; * * Hydra_Software_Devel/6 12/31/03 12:02p jasonh * PR 8940: Changed return type of destroyheap to void. Removed use of * DEBUG macro and printf. * * Hydra_Software_Devel/5 11/11/03 11:19a jasonh * PR 8589: removed leaked resource check and added offset to sample heap. * * Hydra_Software_Devel/4 9/15/03 5:25p jasonh * Re-wrote test from scratch. * * Hydra_Software_Devel/3 3/21/03 6:03p erickson * added printInfo for debug * * Hydra_Software_Devel/2 3/20/03 3:51p erickson * renamed all MEM_ to BMEM_ * * Hydra_Software_Devel/1 3/20/03 3:24p erickson * initial bmem work, taken from SetTop/memorylib * ***************************************************************************/ #include "bstd.h" #include "bkni.h" #include "bkni_multi.h" #include "bdbg.h" BDBG_MODULE(memorymanagertest); #include "bmem.h" #include "bmem_debug.h" #include "bmem_config.h" #include "bmem_test.h" static uint8_t s_aBytes[1024 * 1024]; static BERR_Code BMEM_Test_CheckAlloc( BMEM_Handle heap, unsigned int uiHeapAlignment, void *pAddr, size_t ulAddrSize, unsigned int uiAddrAlignment, unsigned int uiAddrBoundary ) { BERR_Code err = BERR_SUCCESS; uint32_t ulAddr = (uint32_t)pAddr; uint32_t ulConvertedOffset; void *pConvertedAddr; /* fill allocated block with non-guardbanding value */ BKNI_Memset(pAddr, 0xFF, ulAddrSize); /* doesn't match heap alignment? */ if ((((UINT32_C(1) << uiHeapAlignment) - 1) & ulAddr) != 0) { /* failed to match heap alignment */ err = BERR_TRACE(BERR_UNKNOWN); BDBG_ERR(("BMEM_Test_CheckAlloc: Failed heap alignment")); goto done; } /* doesn't match address alignment? */ if ((((UINT32_C(1) << uiAddrAlignment) - 1) & ulAddr) != 0) { /* failed to match address alignment */ err = BERR_TRACE(BERR_UNKNOWN); BDBG_ERR(("BMEM_Test_CheckAlloc: Failed address alignment")); goto done; } /* check boundary */ /* convert address -> offset */ err = BERR_TRACE(BMEM_ConvertAddressToOffset(heap, pAddr, &ulConvertedOffset)); if (err != BERR_SUCCESS) { /* unable to convert address -> offset */ BDBG_ERR(("BMEM_Test_CheckAlloc: Failed address -> offset conversion")); goto done; } /* convert offset -> address */ err = BERR_TRACE(BMEM_ConvertOffsetToAddress(heap, ulConvertedOffset, &pConvertedAddr)); if (err != BERR_SUCCESS) { /* unable to convert address -> offset */ BDBG_ERR(("BMEM_Test_CheckAlloc: Failed offset -> address conversion")); goto done; } /* insure that addresses are the same */ if (pAddr != pConvertedAddr) { /* addresses did not match */ err = BERR_TRACE(BERR_UNKNOWN); BDBG_ERR(("BMEM_Test_CheckAlloc: Failed address match")); goto done; } /* validate heap */ err = BERR_TRACE(BMEM_ValidateHeap(heap)); if (err != BERR_SUCCESS) { /* invalid heap */ BDBG_ERR(("BMEM_Test_CheckAlloc: Invalid heap")); goto done; } done: /* return status */ return err; } void BMEM_Test_DisplayConfig( void ) { /* header */ BKNI_Printf("BMEM compile-time configuration:\n\n"); /* safety config */ BKNI_Printf("BMEM_SAFETY_CONFIG = "); #if (BMEM_SAFETY_CONFIG == BMEM_CONFIG_FASTEST) BKNI_Printf("BMEM_CONFIG_FASTEST\n"); #elif (BMEM_SAFETY_CONFIG == BMEM_CONFIG_NORMAL) BKNI_Printf("BMEM_CONFIG_NORMAL\n"); #elif (BMEM_SAFETY_CONFIG == BMEM_CONFIG_TRACK) BKNI_Printf("BMEM_CONFIG_TRACK\n"); #elif (BMEM_SAFETY_CONFIG == BMEM_CONFIG_SAFE) BKNI_Printf("BMEM_CONFIG_SAFE\n"); #elif (BMEM_SAFETY_CONFIG == BMEM_CONFIG_SAFEST) BKNI_Printf("BMEM_CONFIG_SAFEST\n"); #else BKNI_Printf("***UNKNOWN***\n"); #endif /* bookkeeping config */ BKNI_Printf("BMEM_BOOKKEEPING_CONFIG = "); #if (BMEM_BOOKKEEPING_CONFIG == BMEM_BOOKKEEPING_LOCAL) BKNI_Printf("BMEM_BOOKKEEPING_LOCAL\n"); #elif (BMEM_BOOKKEEPING_CONFIG == BMEM_BOOKKEEPING_SYSTEM) BKNI_Printf("BMEM_BOOKKEEPING_SYSTEM\n"); #else BKNI_Printf("***UNKNOWN***\n"); #endif /* reentrant config */ BKNI_Printf("BMEM_REENTRANT = "); #if (BMEM_REENTRANT_CONFIG == BMEM_REENTRANT) BKNI_Printf("BMEM_REENTRANT\n"); #elif (BMEM_REENTRANT_CONFIG == BMEM_NOT_REENTRANT) BKNI_Printf("BMEM_NOT_REENTRANT\n"); #else BKNI_Printf("***UNKNOWN***\n"); #endif /* test header */ BKNI_Printf("------------------------------------------------\n"); } BERR_Code BMEM_Test_DoTest1( void ) { BERR_Code err = BERR_SUCCESS; BMEM_Handle heap; void *apvAlloced[1024 * 128]; unsigned int uiNumAlloc = 0; size_t zSize; unsigned int i; uint32_t ulConvertOffset; uint32_t ulErrCnt; /* set global debug level */ BDBG_SetLevel(BDBG_eWrn); #ifdef BMEM_TEST_DEBUG BDBG_SetModuleLevel("memorymanagertest", BDBG_eMsg); BDBG_SetModuleLevel("BMEM", BDBG_eMsg); #else BDBG_SetModuleLevel("BMEM", BDBG_eWrn); #endif /* Create heap */ BKNI_Printf("Allocate 1024x1024 bytes at offset 0x2000000 as the heap.\n"); err = BERR_TRACE(BMEM_CreateHeap(&heap, (void *)s_aBytes, 0x2000000, 1024*1024, 0)); if (err != BERR_SUCCESS) { /* error creating heap */ BDBG_ERR(("BMEM_Test_DoTest1: Failed heap create")); goto done; } do { /* allocate various sizes until failure */ while (uiNumAlloc + 3 < 1024 * 128) { /* allocate tiny */ apvAlloced[uiNumAlloc] = BMEM_Alloc(heap, 4); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate any more of this size */ break; } /* check tiny */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], 4, 0, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- tiny alloc(4-byte) #%d.", uiNumAlloc)); uiNumAlloc++; /* allocate small */ apvAlloced[uiNumAlloc] = BMEM_AllocAligned(heap, 64, 2, 0); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate any more of this size */ break; } /* check small */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], 64, 2, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- small alloc(64-byte) #%d.", uiNumAlloc)); uiNumAlloc++; /* allocate medium */ apvAlloced[uiNumAlloc] = BMEM_AllocAligned(heap, 1024, 4, 0); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate any more of this size */ break; } /* check medium */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], 1024, 4, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- medium alloc(1024-byte) #%d.", uiNumAlloc)); uiNumAlloc++; /* allocate large */ apvAlloced[uiNumAlloc] = BMEM_AllocAligned(heap, 16 * 1024, 5, 0); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate any more of this size */ break; } /* check large */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], 16 * 1024, 5, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- large alloc(16kbyte) #%d.", uiNumAlloc)); uiNumAlloc++; /* allocate huge */ apvAlloced[uiNumAlloc] = BMEM_AllocAligned(heap, 64 * 1024, 8, 0); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate any more of this size */ break; } /* check huge */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], 64 * 1024, 8, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- huge alloc(64kbyte) #%d.", uiNumAlloc)); uiNumAlloc++; BMEM_ConvertAddressToOffset(heap, apvAlloced[uiNumAlloc - 4], &ulConvertOffset); BDBG_MSG(("==== free #%d at 0x%x.", uiNumAlloc-4, ulConvertOffset)); BMEM_Free(heap, apvAlloced[uiNumAlloc - 4]); apvAlloced[uiNumAlloc - 4] = NULL; BMEM_ConvertAddressToOffset(heap, apvAlloced[uiNumAlloc - 2], &ulConvertOffset); BDBG_MSG(("==== free #%d at 0x%x.\n", uiNumAlloc-2, ulConvertOffset)); BMEM_Free(heap, apvAlloced[uiNumAlloc - 2]); apvAlloced[uiNumAlloc - 2] = NULL; } /* allocate remaining slots */ while (uiNumAlloc < 1024 * 128) { /* get largest available block */ zSize = BMEM_GetLargestAvailableBlockSize(heap); /* no blocks to allocate? */ if (zSize == 0) { /* no more blocks to allocate */ BDBG_MSG(("No more blocks to allocate")); break; } /* allocate block */ apvAlloced[uiNumAlloc] = BMEM_Alloc(heap, zSize); if (!apvAlloced[uiNumAlloc]) { /* unable to allocate (should have) */ err = BERR_TRACE(BERR_UNKNOWN); BDBG_ERR(("BMEM_Test_DoTest1: Failed largest block alloc")); goto done; } /* check allocation */ err = BERR_TRACE(BMEM_Test_CheckAlloc(heap, 0, apvAlloced[uiNumAlloc], zSize, 0, 0)); if (err != BERR_SUCCESS) { /* error */ goto done; } BDBG_MSG(("---- remaining block alloc (%d-byte) #%d.", zSize, uiNumAlloc)); uiNumAlloc++; } /* free random allocations */ for (i=0; i