123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- #include "comdef.h"
- #include "OSAL.h"
- #include "OSAL_Memory.h"
- #include "OnBoard.h"
- #include "hal_assert.h"
- #define OSALMEM_IN_USE 0x8000
- #if (MAXMEMHEAP & OSALMEM_IN_USE)
- #error MAXMEMHEAP is too big to manage!
- #endif
- #define OSALMEM_HDRSZ sizeof(osalMemHdr_t)
- #define OSALMEM_ROUND(X) ((((X) + OSALMEM_HDRSZ - 1) / OSALMEM_HDRSZ) * OSALMEM_HDRSZ)
- #if !defined OSALMEM_MIN_BLKSZ
- #define OSALMEM_MIN_BLKSZ (OSALMEM_ROUND((OSALMEM_HDRSZ * 2)))
- #endif
- #if !defined OSALMEM_LL_BLKSZ
- #if defined NONWK
- #define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(6) + (1 * OSALMEM_HDRSZ))
- #else
- #if defined ZCL_KEY_ESTABLISH
- #define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(526) + (32 * OSALMEM_HDRSZ))
- #elif defined TC_LINKKEY_JOIN
- #define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(454) + (21 * OSALMEM_HDRSZ))
- #elif ((defined SECURE) && (SECURE != 0))
- #define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(418) + (19 * OSALMEM_HDRSZ))
- #else
- #define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(417) + (19 * OSALMEM_HDRSZ))
- #endif
- #endif
- #endif
- #if !defined OSALMEM_SMALL_BLKSZ
- #define OSALMEM_SMALL_BLKSZ (OSALMEM_ROUND(16))
- #endif
- #if !defined OSALMEM_SMALL_BLKCNT
- #define OSALMEM_SMALL_BLKCNT 8
- #endif
- #define OSALMEM_SMALLBLK_BUCKET ((OSALMEM_SMALL_BLKSZ * OSALMEM_SMALL_BLKCNT) + OSALMEM_LL_BLKSZ)
- #define OSALMEM_SMALLBLK_HDRCNT (OSALMEM_SMALLBLK_BUCKET / OSALMEM_HDRSZ)
- #define OSALMEM_BIGBLK_IDX (OSALMEM_SMALLBLK_HDRCNT + 1)
- #define OSALMEM_BIGBLK_SZ (MAXMEMHEAP - OSALMEM_SMALLBLK_BUCKET - OSALMEM_HDRSZ*2)
- #define OSALMEM_LASTBLK_IDX ((MAXMEMHEAP / OSALMEM_HDRSZ) - 1)
- #if !defined OSALMEM_PROFILER
- #define OSALMEM_PROFILER FALSE
- #endif
- #if !defined OSALMEM_PROFILER_LL
- #define OSALMEM_PROFILER_LL FALSE
- #endif
- #if OSALMEM_PROFILER
- #define OSALMEM_INIT 'X'
- #define OSALMEM_ALOC 'A'
- #define OSALMEM_REIN 'F'
- #endif
- typedef struct {
-
- unsigned len : 15;
-
- unsigned inUse : 1;
- } osalMemHdrHdr_t;
- typedef union {
-
- halDataAlign_t alignDummy;
- uint16 val;
- osalMemHdrHdr_t hdr;
- } osalMemHdr_t;
- static __no_init osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ];
- static __no_init osalMemHdr_t *ff1;
- static uint8 osalMemStat;
- #if OSALMEM_METRICS
- static uint16 blkMax;
- static uint16 blkCnt;
- static uint16 blkFree;
- static uint16 memAlo;
- static uint16 memMax;
- #endif
- #if OSALMEM_PROFILER
- #define OSALMEM_PROMAX 8
- static uint16 proCnt[OSALMEM_PROMAX] = {
- OSALMEM_SMALL_BLKSZ, 48, 112, 176, 192, 224, 256, 65535 };
- static uint16 proCur[OSALMEM_PROMAX] = { 0 };
- static uint16 proMax[OSALMEM_PROMAX] = { 0 };
- static uint16 proTot[OSALMEM_PROMAX] = { 0 };
- static uint16 proSmallBlkMiss;
- #endif
- #ifdef DPRINTF_HEAPTRACE
- extern int dprintf(const char *fmt, ...);
- #endif
- void osal_mem_init(void)
- {
- HAL_ASSERT(((OSALMEM_MIN_BLKSZ % OSALMEM_HDRSZ) == 0));
- HAL_ASSERT(((OSALMEM_LL_BLKSZ % OSALMEM_HDRSZ) == 0));
- HAL_ASSERT(((OSALMEM_SMALL_BLKSZ % OSALMEM_HDRSZ) == 0));
- #if OSALMEM_PROFILER
- (void)osal_memset(theHeap, OSALMEM_INIT, MAXMEMHEAP);
- #endif
-
- theHeap[OSALMEM_LASTBLK_IDX].val = 0;
-
- ff1 = theHeap;
- ff1->val = OSALMEM_SMALLBLK_BUCKET;
-
-
- theHeap[OSALMEM_SMALLBLK_HDRCNT].val = (OSALMEM_HDRSZ | OSALMEM_IN_USE);
-
- theHeap[OSALMEM_BIGBLK_IDX].val = OSALMEM_BIGBLK_SZ;
- #if ( OSALMEM_METRICS )
-
- blkCnt = blkFree = 2;
- #endif
- }
- void osal_mem_kick(void)
- {
- halIntState_t intState;
- osalMemHdr_t *tmp = osal_mem_alloc(1);
- HAL_ASSERT((tmp != NULL));
- HAL_ENTER_CRITICAL_SECTION(intState);
-
- ff1 = tmp - 1;
- osal_mem_free(tmp);
- osalMemStat = 0x01;
- HAL_EXIT_CRITICAL_SECTION(intState);
- }
- #ifdef DPRINTF_OSALHEAPTRACE
- void *osal_mem_alloc_dbg( uint16 size, const char *fname, unsigned lnum )
- #else
- void *osal_mem_alloc( uint16 size )
- #endif
- {
- osalMemHdr_t *prev = NULL;
- osalMemHdr_t *hdr;
- halIntState_t intState;
- uint8 coal = 0;
- size += OSALMEM_HDRSZ;
-
- if ( sizeof( halDataAlign_t ) == 2 )
- {
- size += (size & 0x01);
- }
- else if ( sizeof( halDataAlign_t ) != 1 )
- {
- const uint8 mod = size % sizeof( halDataAlign_t );
- if ( mod != 0 )
- {
- size += (sizeof( halDataAlign_t ) - mod);
- }
- }
- HAL_ENTER_CRITICAL_SECTION( intState );
-
-
- if ((osalMemStat == 0) || (size <= OSALMEM_SMALL_BLKSZ))
- {
- hdr = ff1;
- }
- else
- {
- hdr = (theHeap + OSALMEM_BIGBLK_IDX);
- }
- do
- {
- if ( hdr->hdr.inUse )
- {
- coal = 0;
- }
- else
- {
- if ( coal != 0 )
- {
- #if ( OSALMEM_METRICS )
- blkCnt--;
- blkFree--;
- #endif
- prev->hdr.len += hdr->hdr.len;
- if ( prev->hdr.len >= size )
- {
- hdr = prev;
- break;
- }
- }
- else
- {
- if ( hdr->hdr.len >= size )
- {
- break;
- }
- coal = 1;
- prev = hdr;
- }
- }
- hdr = (osalMemHdr_t *)((uint8 *)hdr + hdr->hdr.len);
- if ( hdr->val == 0 )
- {
- hdr = NULL;
- break;
- }
- } while (1);
- if ( hdr != NULL )
- {
- uint16 tmp = hdr->hdr.len - size;
-
- if ( tmp >= OSALMEM_MIN_BLKSZ )
- {
-
- osalMemHdr_t *next = (osalMemHdr_t *)((uint8 *)hdr + size);
- next->val = tmp;
- hdr->val = (size | OSALMEM_IN_USE);
- #if ( OSALMEM_METRICS )
- blkCnt++;
- if ( blkMax < blkCnt )
- {
- blkMax = blkCnt;
- }
- memAlo += size;
- #endif
- }
- else
- {
- #if ( OSALMEM_METRICS )
- memAlo += hdr->hdr.len;
- blkFree--;
- #endif
- hdr->hdr.inUse = TRUE;
- }
- #if ( OSALMEM_METRICS )
- if ( memMax < memAlo )
- {
- memMax = memAlo;
- }
- #endif
- #if ( OSALMEM_PROFILER )
- #if !OSALMEM_PROFILER_LL
- if (osalMemStat != 0)
- #endif
- {
- uint8 idx;
- for ( idx = 0; idx < OSALMEM_PROMAX; idx++ )
- {
- if ( hdr->hdr.len <= proCnt[idx] )
- {
- break;
- }
- }
- proCur[idx]++;
- if ( proMax[idx] < proCur[idx] )
- {
- proMax[idx] = proCur[idx];
- }
- proTot[idx]++;
-
- if ((hdr->hdr.len <= OSALMEM_SMALL_BLKSZ) && (hdr >= (theHeap + OSALMEM_BIGBLK_IDX)))
- {
- proSmallBlkMiss++;
- }
- }
- (void)osal_memset((uint8 *)(hdr+1), OSALMEM_ALOC, (hdr->hdr.len - OSALMEM_HDRSZ));
- #endif
- if ((osalMemStat != 0) && (ff1 == hdr))
- {
- ff1 = (osalMemHdr_t *)((uint8 *)hdr + hdr->hdr.len);
- }
- hdr++;
- }
- HAL_EXIT_CRITICAL_SECTION( intState );
- #pragma diag_suppress=Pe767
- HAL_ASSERT(((halDataAlign_t)hdr % sizeof(halDataAlign_t)) == 0);
- #pragma diag_default=Pe767
- #ifdef DPRINTF_OSALHEAPTRACE
- dprintf("osal_mem_alloc(%u)->%lx:%s:%u\n", size, (unsigned) hdr, fname, lnum);
- #endif
- return (void *)hdr;
- }
- #ifdef DPRINTF_OSALHEAPTRACE
- void osal_mem_free_dbg(void *ptr, const char *fname, unsigned lnum)
- #else
- void osal_mem_free(void *ptr)
- #endif
- {
- osalMemHdr_t *hdr = (osalMemHdr_t *)ptr - 1;
- halIntState_t intState;
- #ifdef DPRINTF_OSALHEAPTRACE
- dprintf("osal_mem_free(%lx):%s:%u\n", (unsigned) ptr, fname, lnum);
- #endif
- HAL_ASSERT(((uint8 *)ptr >= (uint8 *)theHeap) && ((uint8 *)ptr < (uint8 *)theHeap+MAXMEMHEAP));
- HAL_ASSERT(hdr->hdr.inUse);
- HAL_ENTER_CRITICAL_SECTION( intState );
- hdr->hdr.inUse = FALSE;
- if (ff1 > hdr)
- {
- ff1 = hdr;
- }
- #if OSALMEM_PROFILER
- #if !OSALMEM_PROFILER_LL
- if (osalMemStat != 0)
- #endif
- {
- uint8 idx;
- for (idx = 0; idx < OSALMEM_PROMAX; idx++)
- {
- if (hdr->hdr.len <= proCnt[idx])
- {
- break;
- }
- }
- proCur[idx]--;
- }
- (void)osal_memset((uint8 *)(hdr+1), OSALMEM_REIN, (hdr->hdr.len - OSALMEM_HDRSZ) );
- #endif
- #if OSALMEM_METRICS
- memAlo -= hdr->hdr.len;
- blkFree++;
- #endif
- HAL_EXIT_CRITICAL_SECTION( intState );
- }
- #if OSALMEM_METRICS
- uint16 osal_heap_block_max( void )
- {
- return blkMax;
- }
- uint16 osal_heap_block_cnt( void )
- {
- return blkCnt;
- }
- uint16 osal_heap_block_free( void )
- {
- return blkFree;
- }
- uint16 osal_heap_mem_used( void )
- {
- return memAlo;
- }
- #endif
- #if defined (ZTOOL_P1) || defined (ZTOOL_P2)
- uint16 osal_heap_high_water( void )
- {
- #if ( OSALMEM_METRICS )
- return memMax;
- #else
- return MAXMEMHEAP;
- #endif
- }
- #endif
|