123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- /**************************************************************************************************
- Filename: OSAL_Memory.c
- Revised: $Date: 2010-09-20 14:59:43 -0700 (Mon, 20 Sep 2010) $
- Revision: $Revision: 23848 $
- Description: OSAL Heap Memory management functions. There is an Application Note that
- should be read before studying and/or modifying this module:
- SWRA204 "Heap Memory Management"
- Copyright 2004-2010 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- **************************************************************************************************/
- /* ------------------------------------------------------------------------------------------------
- * Includes
- * ------------------------------------------------------------------------------------------------
- */
- #include "comdef.h"
- #include "OSAL.h"
- #include "OSAL_Memory.h"
- #include "OnBoard.h"
- #include "hal_assert.h"
- /* ------------------------------------------------------------------------------------------------
- * Constants
- * ------------------------------------------------------------------------------------------------
- */
- #define OSALMEM_IN_USE 0x8000
- #if (MAXMEMHEAP & OSALMEM_IN_USE)
- #error MAXMEMHEAP is too big to manage!
- #endif
- #define OSALMEM_HDRSZ sizeof(osalMemHdr_t)
- // Round a value up to the ceiling of OSALMEM_HDRSZ for critical dependencies on even multiples.
- #define OSALMEM_ROUND(X) ((((X) + OSALMEM_HDRSZ - 1) / OSALMEM_HDRSZ) * OSALMEM_HDRSZ)
- /* Minimum wasted bytes to justify splitting a block before allocation.
- * Adjust accordingly to attempt to balance the tradeoff of wasted space and runtime throughput
- * spent splitting blocks into sizes that may not be practically usable when sandwiched between
- * two blocks in use (and thereby not able to be coalesced.)
- * Ensure that this size is an even multiple of 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
- /*
- * Profiling the sample apps with default settings shows the following long-lived allocations
- * which should live at the bottom of the small-block bucket so that they are never iterated over
- * by osal_mem_alloc/free(), nor ever considered for coalescing, etc. This saves significant
- * run-time throughput (on 8051 SOC if not also MSP). This is dynamic "dead space" and is not
- * available to the small-block bucket heap.
- *
- * Adjust this size accordingly to accomodate application-specific changes including changing the
- * size of long-lived objects profiled by sample apps and long-lived objects added by application.
- */
- #if defined ZCL_KEY_ESTABLISH // Attempt to capture worst-case for SE sample apps.
- #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
- /* Adjust accordingly to attempt to accomodate the block sizes of the vast majority of
- * very high frequency allocations/frees by profiling the system runtime.
- * This default of 16 accomodates the OSAL timers block, osalTimerRec_t, and many others.
- * Ensure that this size is an even multiple of OSALMEM_MIN_BLKSZ for run-time efficiency.
- */
- #if !defined OSALMEM_SMALL_BLKSZ
- #define OSALMEM_SMALL_BLKSZ (OSALMEM_ROUND(16))
- #endif
- #if !defined OSALMEM_SMALL_BLKCNT
- #define OSALMEM_SMALL_BLKCNT 8
- #endif
- /*
- * These numbers setup the size of the small-block bucket which is reserved at the front of the
- * heap for allocations of OSALMEM_SMALL_BLKSZ or smaller.
- */
- // Size of the heap bucket reserved for small block-sized allocations.
- // Adjust accordingly to attempt to accomodate the vast majority of very high frequency operations.
- #define OSALMEM_SMALLBLK_BUCKET ((OSALMEM_SMALL_BLKSZ * OSALMEM_SMALL_BLKCNT) + OSALMEM_LL_BLKSZ)
- // Index of the first available osalMemHdr_t after the small-block heap which will be set in-use in
- // order to prevent the small-block bucket from being coalesced with the wilderness.
- #define OSALMEM_SMALLBLK_HDRCNT (OSALMEM_SMALLBLK_BUCKET / OSALMEM_HDRSZ)
- // Index of the first available osalMemHdr_t after the small-block heap which will be set in-use in
- #define OSALMEM_BIGBLK_IDX (OSALMEM_SMALLBLK_HDRCNT + 1)
- // The size of the wilderness after losing the small-block heap, the wasted header to block the
- // small-block heap from being coalesced, and the wasted header to mark the end of the heap.
- #define OSALMEM_BIGBLK_SZ (MAXMEMHEAP - OSALMEM_SMALLBLK_BUCKET - OSALMEM_HDRSZ*2)
- // Index of the last available osalMemHdr_t at the end of the heap which will be set to zero for
- // fast comparisons with zero to determine the end of the heap.
- #define OSALMEM_LASTBLK_IDX ((MAXMEMHEAP / OSALMEM_HDRSZ) - 1)
- // For information about memory profiling, refer to SWRA204 "Heap Memory Management", section 1.5.
- #if !defined OSALMEM_PROFILER
- #define OSALMEM_PROFILER FALSE // Enable/disable the memory usage profiling buckets.
- #endif
- #if !defined OSALMEM_PROFILER_LL
- #define OSALMEM_PROFILER_LL FALSE // Special profiling of the Long-Lived bucket.
- #endif
- #if OSALMEM_PROFILER
- #define OSALMEM_INIT 'X'
- #define OSALMEM_ALOC 'A'
- #define OSALMEM_REIN 'F'
- #endif
- /* ------------------------------------------------------------------------------------------------
- * Typedefs
- * ------------------------------------------------------------------------------------------------
- */
- typedef struct {
- // The 15 LSB's of 'val' indicate the total item size, including the header, in 8-bit bytes.
- unsigned len : 15;
- // The 1 MSB of 'val' is used as a boolean to indicate in-use or freed.
- unsigned inUse : 1;
- } osalMemHdrHdr_t;
- typedef union {
- /* Dummy variable so compiler forces structure to alignment of largest element while not wasting
- * space on targets when the halDataAlign_t is smaller than a UINT16.
- */
- halDataAlign_t alignDummy;
- uint16 val;
- osalMemHdrHdr_t hdr;
- } osalMemHdr_t;
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- static __no_init osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ];
- static __no_init osalMemHdr_t *ff1; // First free block in the small-block bucket.
- static uint8 osalMemStat; // Discrete status flags: 0x01 = kicked.
- #if OSALMEM_METRICS
- static uint16 blkMax; // Max cnt of all blocks ever seen at once.
- static uint16 blkCnt; // Current cnt of all blocks.
- static uint16 blkFree; // Current cnt of free blocks.
- static uint16 memAlo; // Current total memory allocated.
- static uint16 memMax; // Max total memory ever allocated at once.
- #endif
- #if OSALMEM_PROFILER
- #define OSALMEM_PROMAX 8
- /* The profiling buckets must differ by at least OSALMEM_MIN_BLKSZ; the
- * last bucket must equal the max alloc size. Set the bucket sizes to
- * whatever sizes necessary to show how your application is using memory.
- */
- 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
- /* ------------------------------------------------------------------------------------------------
- * Global Variables
- * ------------------------------------------------------------------------------------------------
- */
- #ifdef DPRINTF_HEAPTRACE
- extern int dprintf(const char *fmt, ...);
- #endif /* DPRINTF_HEAPTRACE */
- /**************************************************************************************************
- * @fn osal_mem_init
- *
- * @brief This function is the OSAL heap memory management initialization callback.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- */
- 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
- // Setup a NULL block at the end of the heap for fast comparisons with zero.
- theHeap[OSALMEM_LASTBLK_IDX].val = 0;
- // Setup the small-block bucket.
- ff1 = theHeap;
- ff1->val = OSALMEM_SMALLBLK_BUCKET; // Set 'len' & clear 'inUse' field.
- // Set 'len' & 'inUse' fields - this is a 'zero data bytes' lifetime allocation to block the
- // small-block bucket from ever being coalesced with the wilderness.
- theHeap[OSALMEM_SMALLBLK_HDRCNT].val = (OSALMEM_HDRSZ | OSALMEM_IN_USE);
- // Setup the wilderness.
- theHeap[OSALMEM_BIGBLK_IDX].val = OSALMEM_BIGBLK_SZ; // Set 'len' & clear 'inUse' field.
- #if ( OSALMEM_METRICS )
- /* Start with the small-block bucket and the wilderness - don't count the
- * end-of-heap NULL block nor the end-of-small-block NULL block.
- */
- blkCnt = blkFree = 2;
- #endif
- }
- /**************************************************************************************************
- * @fn osal_mem_kick
- *
- * @brief This function is the OSAL task initialization callback.
- * @brief Kick the ff1 pointer out past the long-lived OSAL Task blocks.
- * Invoke this once after all long-lived blocks have been allocated -
- * presently at the end of osal_init_system().
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- */
- void osal_mem_kick(void)
- {
- halIntState_t intState;
- osalMemHdr_t *tmp = osal_mem_alloc(1);
- HAL_ASSERT((tmp != NULL));
- HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts.
- /* All long-lived allocations have filled the LL block reserved in the small-block bucket.
- * Set 'osalMemStat' so searching for memory in this bucket from here onward will only be done
- * for sizes meeting the OSALMEM_SMALL_BLKSZ criteria.
- */
- ff1 = tmp - 1; // Set 'ff1' to point to the first available memory after the LL block.
- osal_mem_free(tmp);
- osalMemStat = 0x01; // Set 'osalMemStat' after the free because it enables memory profiling.
- HAL_EXIT_CRITICAL_SECTION(intState); // Re-enable interrupts.
- }
- /**************************************************************************************************
- * @fn osal_mem_alloc
- *
- * @brief This function implements the OSAL dynamic memory allocation functionality.
- *
- * input parameters
- *
- * @param size - the number of bytes to allocate from the HEAP.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- */
- #ifdef DPRINTF_OSALHEAPTRACE
- void *osal_mem_alloc_dbg( uint16 size, const char *fname, unsigned lnum )
- #else /* DPRINTF_OSALHEAPTRACE */
- void *osal_mem_alloc( uint16 size )
- #endif /* DPRINTF_OSALHEAPTRACE */
- {
- osalMemHdr_t *prev = NULL;
- osalMemHdr_t *hdr;
- halIntState_t intState;
- uint8 coal = 0;
- size += OSALMEM_HDRSZ;
- // Calculate required bytes to add to 'size' to align to halDataAlign_t.
- 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 ); // Hold off interrupts.
- // Smaller allocations are first attempted in the small-block bucket, and all long-lived
- // allocations are channeled into the LL block reserved within this bucket.
- 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;
- // Determine whether the threshold for splitting is met.
- if ( tmp >= OSALMEM_MIN_BLKSZ )
- {
- // Split the block before allocating it.
- osalMemHdr_t *next = (osalMemHdr_t *)((uint8 *)hdr + size);
- next->val = tmp; // Set 'len' & clear 'inUse' field.
- hdr->val = (size | OSALMEM_IN_USE); // Set 'len' & 'inUse' field.
- #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) // Don't profile until after the LL block is filled.
- #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]++;
- /* A small-block could not be allocated in the small-block bucket.
- * When this occurs significantly frequently, increase the size of the
- * bucket in order to restore better worst case run times. Set the first
- * profiling bucket size in proCnt[] to the small-block bucket size and
- * divide proSmallBlkMiss by the corresponding proTot[] size to get % miss.
- * Best worst case time on TrasmitApp was achieved at a 0-15% miss rate
- * during steady state Tx load, 0% during idle and steady state Rx load.
- */
- 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 ); // Re-enable interrupts.
- #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 /* DPRINTF_OSALHEAPTRACE */
- return (void *)hdr;
- }
- /**************************************************************************************************
- * @fn osal_mem_free
- *
- * @brief This function implements the OSAL dynamic memory de-allocation functionality.
- *
- * input parameters
- *
- * @param ptr - A valid pointer (i.e. a pointer returned by osal_mem_alloc()) to the memory to free.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- */
- #ifdef DPRINTF_OSALHEAPTRACE
- void osal_mem_free_dbg(void *ptr, const char *fname, unsigned lnum)
- #else /* DPRINTF_OSALHEAPTRACE */
- void osal_mem_free(void *ptr)
- #endif /* DPRINTF_OSALHEAPTRACE */
- {
- 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 /* DPRINTF_OSALHEAPTRACE */
- HAL_ASSERT(((uint8 *)ptr >= (uint8 *)theHeap) && ((uint8 *)ptr < (uint8 *)theHeap+MAXMEMHEAP));
- HAL_ASSERT(hdr->hdr.inUse);
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- hdr->hdr.inUse = FALSE;
- if (ff1 > hdr)
- {
- ff1 = hdr;
- }
- #if OSALMEM_PROFILER
- #if !OSALMEM_PROFILER_LL
- if (osalMemStat != 0) // Don't profile until after the LL block is filled.
- #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 ); // Re-enable interrupts.
- }
- #if OSALMEM_METRICS
- /*********************************************************************
- * @fn osal_heap_block_max
- *
- * @brief Return the maximum number of blocks ever allocated at once.
- *
- * @param none
- *
- * @return Maximum number of blocks ever allocated at once.
- */
- uint16 osal_heap_block_max( void )
- {
- return blkMax;
- }
- /*********************************************************************
- * @fn osal_heap_block_cnt
- *
- * @brief Return the current number of blocks now allocated.
- *
- * @param none
- *
- * @return Current number of blocks now allocated.
- */
- uint16 osal_heap_block_cnt( void )
- {
- return blkCnt;
- }
- /*********************************************************************
- * @fn osal_heap_block_free
- *
- * @brief Return the current number of free blocks.
- *
- * @param none
- *
- * @return Current number of free blocks.
- */
- uint16 osal_heap_block_free( void )
- {
- return blkFree;
- }
- /*********************************************************************
- * @fn osal_heap_mem_used
- *
- * @brief Return the current number of bytes allocated.
- *
- * @param none
- *
- * @return Current number of bytes allocated.
- */
- uint16 osal_heap_mem_used( void )
- {
- return memAlo;
- }
- #endif
- #if defined (ZTOOL_P1) || defined (ZTOOL_P2)
- /*********************************************************************
- * @fn osal_heap_high_water
- *
- * @brief Return the highest byte ever allocated in the heap.
- *
- * @param none
- *
- * @return Highest number of bytes ever used by the stack.
- */
- uint16 osal_heap_high_water( void )
- {
- #if ( OSALMEM_METRICS )
- return memMax;
- #else
- return MAXMEMHEAP;
- #endif
- }
- #endif
- /**************************************************************************************************
- */
|