1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
20 /********************************************************************20**
22 Name: Common Memory Manager
26 Desc: C source code for the Commom Memory Manager module.
30 *********************************************************************21*/
33 /************************************************************************
35 The following functions are provided in this file.
37 cmMmRegInit Memory Region Initialization.
38 cmMmRegDeInit Memory Region Deinitialization.
40 ************************************************************************/
44 /* header include files (.h) */
45 #include "envopt.h" /* environment options */
46 #include "envdep.h" /* environment dependent */
47 #include "envind.h" /* environment independent */
49 #include "gen.h" /* general */
50 #include "ssi.h" /* system services */
51 #include "cm_mem.h" /* Common memory manager cm_mem_c_001.main_15 */
53 #ifdef SS_MEM_LEAK_STS
56 #ifdef SS_MEM_LEAK_SOL
59 #include <sys/machelf.h>
60 #else /* SS_MEM_LEAK_SOL */
62 #endif /* SS_MEM_LEAK_SOL */
63 #include <sys/types.h>
64 #endif /* SS_MEM_LEAK_STS */
67 #ifdef SS_MULTICORE_SUPPORT /* cm_mem_c_001.main_14 */
68 #include "ss_dep.h" /* implementation-specific */
69 #include "ss_queue.h" /* queues */
70 #include "ss_task.h" /* tasking */
72 #ifdef SS_MULTICORE_SUPPORT
73 #include "ss_dep.h" /* implementation-specific */
74 #include "ss_queue.h" /* queues */
75 #include "ss_task.h" /* tasking */
79 /* header/extern include files (.x) */
80 #include "gen.x" /* general */
81 #include "ssi.x" /* system services */
82 #ifdef SS_MULTICORE_SUPPORT
83 #include "ss_dep.x" /* implementation-specific */
84 #include "ss_queue.x" /* queues */
85 #include "ss_task.x" /* system services */
87 #include "cm_hash.x" /* common hash functions */
89 #include "cm_mem_wl.x" /* Common memory manager */
90 /* cm_mem_c_001.main_15: Addition */
91 #include "cm_lib.x" /* common library functions */
97 #ifdef SS_MULTICORE_SUPPORT
98 #include "ss_dep.x" /* implementation-specific */
99 #include "ss_queue.x" /* queues */
100 #include "ss_task.x" /* system services */
105 #endif /* USE_PURE */
107 #include <execinfo.h>
110 #include <sys/time.h>
112 #ifdef SS_USE_ICC_MEMORY
114 #endif /* SS_USE_ICC_MEMORY */
117 #include "mt_plat_t33.h"
125 /*ccpu00142274 - UL mem based flow control changes */
126 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
128 uint32_t gMemoryAlarm;
129 static uint32_t memoryCheckCounter;
131 #define NUM_CALLS_TO_CHECK_MEM_AGAIN 80 /* Number of calls after which need to check mem */
133 #ifdef T2200_2GB_DDR_CHANGES
134 #define ICC_MEM_UPPER_THRESHOLD 20 /* Only 20% of the available memory blocks are free */
135 #define ICC_MEM_LOWER_THRESHOLD 10 /* Only 10% of the available memory blocks are free */
137 #define ICC_MEM_UPPER_THRESHOLD 10 /* Only 20% of the available memory blocks are free */
138 #define ICC_MEM_LOWER_THRESHOLD 8 /* Only 10% of the available memory blocks are free */
141 #define ICC_MEM_UPPER_THRESHOLD 9 /* Only 20% of the available memory blocks are free */
142 #define ICC_MEM_LOWER_THRESHOLD 12 /* Only 30% of the available memory blocks are free */
144 #define ICC_POOL_ZERO_SIZE 384
145 #define ICC_POOL_ONE_SIZE 1920
146 #define ICC_POOL_TWO_SIZE 3968
147 #ifdef T2200_2GB_DDR_CHANGES
148 #define ICC_POOL_THREE_SIZE 16256
150 #define ICC_POOL_THREE_SIZE 8064
153 #ifdef T2200_2GB_DDR_CHANGES
154 #define ICC_POOL_ZERO_TOTAL_BLKS 139809 /* this and the next should be dynamic*/
155 #define ICC_POOL_ONE_TOTAL_BLKS 209714
156 #define ICC_POOL_TWO_TOTAL_BLKS 27961
157 #define ICC_POOL_THREE_TOTAL_BLKS 27961
159 #define ICC_POOL_ZERO_TOTAL_BLKS 55106 /* this and the next should be dynamic*/
160 #define ICC_POOL_ONE_TOTAL_BLKS 68567
161 #define ICC_POOL_TWO_TOTAL_BLKS 13819
162 #define ICC_POOL_THREE_TOTAL_BLKS 10902
165 /* The below configuration used for icc_part_size=573M in boot args, if icc part
166 * size changes then need to change the below configuration values*/
168 #define ICC_POOL_ZERO_TOTAL_BLKS 78232
169 #define ICC_POOL_ONE_TOTAL_BLKS 117349
170 #define ICC_POOL_TWO_TOTAL_BLKS 15645
171 #define ICC_POOL_THREE_TOTAL_BLKS 15645
173 #define ICC_POOL_ZERO_TOTAL_BLKS 79437
174 #define ICC_POOL_ONE_TOTAL_BLKS 80009
175 #define ICC_POOL_TWO_TOTAL_BLKS 16864
176 #define ICC_POOL_THREE_TOTAL_BLKS 11970
185 /* forward references */
186 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
187 /* cm_mem_c_001.main_15: Addition */
188 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler*/
193 CmHashListCp memDoubleFree; /* Added to find the double free */
194 SLockId memDoubleFreeLock;
195 #define NUM_BT_TRACES 12
196 typedef struct cmMemFreeInfo
200 void *btArr[NUM_BT_TRACES];
201 struct timeval timeStamp;
205 #define NUM_FREE_BUFFERS 128
206 typedef struct cmBtInfo
209 CmMemFreeInfo btInfo[NUM_FREE_BUFFERS];
213 CmBtInfo *allocBtInfo;
215 typedef struct cmMemDoubleFree
217 CmHashListEnt tmpListEnt;
218 CmMemFreeInfo traceInfo;
223 uint8_t stopBtInfo = FALSE;
225 Buffer *mtTskBuffer1;
226 Buffer *mtTskBuffer2;
228 #ifdef SS_USE_ICC_MEMORY
229 static pthread_mutex_t iccAllocFreeLock;
231 static pthread_mutex_t dynAllocFreeLock;
232 #endif /* SS_USE_ICC_MEMORY */
234 #ifdef SS_MEM_WL_DEBUG
235 static S16 cmInitBtInfo ARGS((void));
238 #ifdef SS_USE_ICC_MEMORY
239 #ifdef T2K_MEM_LEAK_DBG
240 static S16 cmIccAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, char*, uint32_t));
241 static S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
242 static S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, char*, uint32_t));
243 static S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
244 void InsertToT2kMemLeakInfo ARGS((uint32_t address, uint32_t size, uint32_t lineNo, char* fileName));
245 void RemoveFromT2kMemLeakInfo ARGS((uint32_t address, char *file, uint32_t line));
246 static uint32_t getT2kMemLeakIndex ARGS((uint32_t address));
248 static S16 cmIccAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
249 static S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size));
250 static S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
251 static S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size));
253 #else /* SS_USE_ICC_MEMORY */
254 static S16 cmDynAllocWithLock ARGS((Void *regionCb,Size *size,uint32_t flags,Data **ptr));
255 static S16 cmDynFreeWithLock ARGS((Void *regionCb,Data *ptr, Size size));
256 static S16 cmDynAlloc ARGS((Void *regionCb,Size *size,uint32_t flags,Data **ptr));
257 static S16 cmDynFree ARGS((Void *regionCb,Data *ptr, Size size));
258 #endif /* SS_USE_ICC_MEMORY */
261 #ifdef T2K_MEM_LEAK_DBG
262 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t));
263 static S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
265 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t));
266 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
268 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
269 static S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
271 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
272 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size));
274 #ifdef T2K_MEM_LEAK_DBG
275 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t);
276 static S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t);
278 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
279 static S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
282 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
283 static S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
285 static S16 cmCtl ARGS((Void *regionCb, Event event, SMemCtl *memCtl));
286 static Void cmMmHeapInit ARGS((Data *memAddr, CmMmHeapCb *heapCb, Size size));
288 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler */
293 /* public variable declarations */
296 #endif /* USE_PURE */
297 /* cm_mem_c_001.main_15:Additions */
298 #ifdef SS_MEM_LEAK_STS
299 MemUsrMdlStr memUsrMdlStr[]=
301 MEMRAW2STR(DEFAULT, STACK),
302 MEMRAW2STR(tc, PDCP_LAYER),
303 MEMRAW2STR(Tc, PDCP_LAYER),
304 MEMRAW2STR(mg, GCP_LAYER),
305 MEMRAW2STR(Mg, GCP_LAYER),
310 #endif /* SS_MEM_LEAK_STS */
312 /* cm_mem_c_008.104 - Addition for memory calculator tool */
314 static Txt prntBuf[200]; /* print buffer */
315 static uint8_t tryHeap=0;
318 /* cm_mem_c_001.main_12 - addition for ssi enhancements prints */
319 /* cm_mem_c_001.main_20 Additions */
320 #if (defined(SSI_DEBUG_LEVEL1) || defined(SS_HISTOGRAM_SUPPORT))
322 static Txt dbgPrntBuf[200]; /* print buffer */
324 #endif /*SSI_DEBUG_LEVEL1 || SS_HISTOGRAM_SUPPORT */
326 #ifdef T2K_MEM_LEAK_DBG
327 /* convert to decimal (0x(end_addr - start_addr)>>8)*2 */
328 #define T2K_MEM_LEAK_INFO_TABLE_SIZE 3670014 /* New Sercomm Board*/
329 //#define T2K_MEM_LEAK_INFO_TABLE_SIZE 3145726 /*Old Sercomm Board*/
330 /* 0x94200000 is the starting address allocated by ICC,
331 * whenever that changes pleasse change here */
332 //#define T2K_MEM_LEAK_START_ADDR 0x9d400000 /*Old Sercomm Board*/
333 #define T2K_MEM_LEAK_START_ADDR 0x9d200000 /*New Sercomm Board*/
336 uint32_t num_times = 0;
337 pthread_t tmpRegTidMap[20];
339 void DumpLayersDebugInformation()
341 DumpSSIDemandQDebugInformation();
342 /* dump layers information only after we start receiving the TTIs */
346 if (clusterMode == RADIO_CLUSTER_MODE)
348 DumpRLCDlDebugInformation();
350 #ifndef UL_RLC_NET_CLUSTER
351 DumpRLCUlDebugInformation();
357 #ifdef UL_RLC_NET_CLUSTER
358 DumpRLCUlDebugInformation();
360 DumpPDCPDlDebugInformation();
361 DumpPDCPUlDebugInformation();
364 //DumpPDCPDlDebugInformation();
365 //DumpPDCPUlDebugInformation();
366 #ifndef ODU_TEST_STUB
367 DumpRLCDlDebugInformation();
368 DumpRLCUlDebugInformation();
370 //printSchCellInfo();
375 /* private variable declarations */
378 * Fun: cmMmStatBktInit
380 * Desc: Initialize the bucket and the map table.
383 * Ret: ROK - successful,
384 * RFAILED - unsuccessful.
386 * Notes: This function is called by the cmMmRegInit.
391 static Void cmMmStatBktInit
404 /* cm_mem_c_001.main_12 - addition for temporary variables */
405 #ifdef SSI_DEBUG_LEVEL1
406 CmMmBlkHdr **nextBlk;
410 #endif /* SSI_DEBUG_LEVEL1 */
414 size = cfg->bktCfg[bktIdx].size;
415 numBlks = cfg->bktCfg[bktIdx].numBlks;
417 /* cm_mem_c_001.main_12 - addition for header initialization */
418 #ifdef SSI_DEBUG_LEVEL1
419 /* Reset the next block pointer */
420 regCb->bktTbl[bktIdx].nextBlk = NULLP;
422 /* Initialize the link list of the memory block */
423 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
425 for (cnt = 0; cnt < numBlks; cnt++)
427 *nextBlk = (CmMmBlkHdr *)*memAddr;
429 /* initialize the memory block header */
430 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
432 (*nextBlk)->trSignature[sigCnt] = 0xAB;
435 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
436 (*nextBlk)->requestedSize = 0;
437 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
438 nextBlk = &((*nextBlk)->nextBlk);
444 /* Initialize the bucket linked list */
446 /* Reset the next pointer */
447 regCb->bktTbl[bktIdx].next = NULLP;
449 /* Initialize the link list of the memory block */
450 next = &(regCb->bktTbl[bktIdx].next);
451 for (cnt = 0; cnt < numBlks; cnt++)
454 next = (CmMmEntry **)(*memAddr);
455 *memAddr = (*memAddr) + size;
460 #endif /* SSI_DEBUG_LEVEL1 */
462 /* Initialize the Map entry */
463 idx = size / cfg->bktQnSize;
466 * Check if the size is multiple of quantum size. If not we need to initialize
467 * one more map table entry.
469 if(size % cfg->bktQnSize)
474 while ( *lstMapIdx < idx)
476 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
478 #if (ERRCLASS & ERRCLS_DEBUG)
479 regCb->mapTbl[*lstMapIdx].numReq = 0;
480 regCb->mapTbl[*lstMapIdx].numFailure = 0;
486 /* Initialize the bucket structure */
487 regCb->bktTbl[bktIdx].size = size;
488 regCb->bktTbl[bktIdx].numBlks = numBlks;
489 regCb->bktTbl[bktIdx].numAlloc = 0;
490 regCb->bktTbl[bktIdx].maxAlloc = 0;
492 /* Update the total bucket size */
493 /* cm_mem_c_001.main_12 - addition for considering the header size */
494 #ifdef SSI_DEBUG_LEVEL1
495 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
497 regCb->bktSize += (size * numBlks);
498 #endif /* SSI_DEBUG_LEVEL1 */
500 regCb->bktTbl[bktIdx].bktFailCnt = 0;
501 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
503 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
504 #ifdef SSI_DEBUG_LEVEL1
505 /* Initialize other required pointers */
506 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
507 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
508 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
509 regCb->bktTbl[bktIdx].staticMemUsed = 0;
510 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
511 regCb->bktTbl[bktIdx].trampleCount = 0;
512 #endif /*SSI_DEBUG_LEVEL1*/
513 /* cm_mem_c_001.main_15 : Additions */
514 #ifdef SS_HISTOGRAM_SUPPORT
515 /* Initialise the memory histogram hash list */
516 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
517 #endif /* SS_HISTOGRAM_SUPPORT */
520 } /* end of cmMmStatBktInit */
524 * Fun: cmMmStatRegInit
526 * Desc: Configure the memory region for allocation. The function
527 * registers the memory region with System Service by calling
531 * Ret: ROK - successful,
532 * RFAILED - unsuccessful.
534 * Notes: The memory owner calls this function to initialize the memory
535 * manager with the information of the memory region. Before
536 * calling this function, the memory owner should allocate memory
537 * for the memory region. The memory owner should also provide the
538 * memory for the control block needed by the memory manager. The
539 * memory owner should allocate the memory for the region control
540 * block as cachable memory. This may increase the average
541 * throughput in allocation and deallocation as the region control
542 * block is mostly accessed by the CMM.
558 #if (ERRCLASS & ERRCLS_INT_PAR)
561 Txt errMsg[256] = {'\0'};
565 #if (ERRCLASS & ERRCLS_INT_PAR)
567 /* error check on parameters */
568 if ((regCb == NULLP) || (cfg == NULLP))
573 /* Error check on the configuration fields */
574 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
575 (cfg->numBkts > CMM_MAX_BKT_ENT))
579 /* Check if the quantum size is power of 2 */
580 if ((cfg->numBkts) &&
581 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
583 /* cm_mem_c_001.main_20 Addition */
584 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
590 * Check if the size of the memory region is enough, whether bucket sizes
591 * are multiples of quantumn size, and also whether two consecutive buckets
592 * falls within same quanta.
594 lstQnSize = cfg->bktQnSize;
597 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
599 /* check if bucket size is mutiple of quantum size */
600 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
602 /* cm_mem_c_001.main_20 Addition */
603 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
605 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
606 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
608 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
609 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
615 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
618 * Two consecutive buckets are not separated by quantum size.
620 /* cm_mem_c_001.main_20 Addition */
621 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
625 /* cm_mem_c_001.main_20 Addition */
626 if (((cfg->bktCfg[bktIdx].size) /\
627 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
629 /* Error check whether the size of the mapping table is sufficient */
630 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
632 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
633 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
635 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
636 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
643 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
644 cfg->bktCfg[bktIdx].numBlks);
646 if (regCb->bktSize > cfg->size)
648 /* Size of the memory region is less than the required size */
650 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
655 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
660 /* Initialize the region control block */
661 regCb->region = region;
662 regCb->regInfo.regCb = regCb;
663 regCb->regInfo.start = cfg->vAddr;
664 regCb->regInfo.size = cfg->size;
667 avail_size = cfg->size;
668 #endif /* USE_PURE */
670 if ( cfg->chFlag & CMM_REG_OUTBOARD)
672 /* Out_of_board memory */
673 regCb->regInfo.flags = CMM_REG_OUTBOARD;
677 regCb->regInfo.flags = 0;
682 if(region == SS_MAX_REGS - 1)
684 regCb->regInfo.alloc = cmAlloc;
685 regCb->regInfo.free = cmFree;
686 regCb->regInfo.ctl = cmCtl;
690 regCb->regInfo.alloc = cmAllocWL;
691 regCb->regInfo.free = cmFreeWL;
692 regCb->regInfo.ctl = cmCtl;
695 regCb->regInfo.alloc = cmAlloc;
696 regCb->regInfo.free = cmFree;
697 regCb->regInfo.ctl = cmCtl;
700 /* Initialize the physical address */
701 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
703 regCb->pAddr = cfg->pAddr;
706 /* Initial address of the memory region block */
707 memAddr = cfg->vAddr;
709 /* Initialize the fields related to the bucket pool */
710 regCb->bktMaxBlkSize = 0;
715 /* Last bucket has the maximum size */
716 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
718 /* Get the power of the bktQnSize */
720 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
725 /* Initilaize the bktIndex of the map entries to FF */
726 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
728 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
732 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
734 /* Allocate the lock for the bucket pool */
735 cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
738 /* Used while freeing the bktLock in cmMmRegDeInit */
739 regCb->numBkts = cfg->numBkts;
743 * Initialize the heap pool if size the memory region region is more
744 * than the size of the bucket pool
747 regCb->heapFlag = FALSE;
749 /* Align the memory address */
750 memAddr = (Data *)(PTRALIGN(memAddr));
752 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
755 * Round the heap size so that the heap size is multiple
758 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
762 /* Allocate the lock for the heap pool */
763 regCb->heapFlag = TRUE;
764 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
767 /* Call SRegRegion to register the memory region with SSI */
768 if (SRegRegion(region, ®Cb->regInfo) != ROK)
774 } /* end of cmMmRegInit*/
779 * Fun: cmMmGlobRegInit
781 * Desc: Configure the memory region for allocation. The function
782 * registers the memory region with System Service by calling
786 * Ret: ROK - successful,
787 * RFAILED - unsuccessful.
802 uint16_t bucketSetSize;
805 CmMmBlkSetElement *blkLstElem;
808 #if (ERRCLASS & ERRCLS_INT_PAR)
811 Txt errMsg[256] = {'\0'};
815 #ifdef SS_MEM_WL_DEBUG
816 if (cmInitBtInfo() == RFAILED)
821 for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
823 /* Initial address of the memory region block */
824 memAddr = ®Cb->bktTbl[bktIdx].startAddr;
825 bucketSetSize = regCb->bktTbl[bktIdx].bucketSetSize;
826 size = regCb->bktTbl[bktIdx].size;
828 /* Initialize the bucket linked list */
829 cmLListInit(®Cb->bktTbl[bktIdx].listValidBktSet);
830 cmLListInit(®Cb->bktTbl[bktIdx].listFreeBktSet);
831 SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
833 /* Initialize the link list of the memory block */
834 next = &(regCb->bktTbl[bktIdx].next);
836 numBlks = regCb->bktTbl[bktIdx].numBlks;
837 for (cnt = 1; cnt <= numBlks; cnt++)
840 next = (CmMmEntry **)(*memAddr);
841 *memAddr = (*memAddr) + size;
843 /* Maintain the list Cb */
844 if(!(cnt % bucketSetSize))
846 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
847 blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
848 blkLstElem->numFreeBlks = bucketSetSize;
849 blkLstElem->memSetNode.node = (PTR)blkLstElem;
850 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
851 next = &(regCb->bktTbl[bktIdx].next);
858 } /* end of cmMmGlobRegInit*/
860 #ifdef SS_USE_ICC_MEMORY
863 * Fun: cmIccAllocWithLock
865 * Desc: Allocate a memory block for use by dynamic buffers.
866 * This handler uses the lock to avoid the two thread
867 * trying to allocate the memory at same time. This
868 * handler must be used only for non-data plane thread
869 * it causes delay due to lock.
872 * Ret: ROK - successful
873 * RFAILED - unsuccessful.
880 #ifdef T2K_MEM_LEAK_DBG
881 static S16 cmIccAllocWithLock
883 Void *regionCb, /* Pointer to a region */
884 Size *size, /* size needs to be allocated */
885 uint32_t flags, /* Flags used */
886 Data **ptr, /* Reference to pointer for which need to be allocate */
891 static S16 cmIccAllocWithLock
893 Void *regionCb, /* Pointer to a region */
894 Size *size, /* size needs to be allocated */
895 uint32_t flags, /* Flags used */
896 Data **ptr /* Reference to pointer for which need to be allocate */
904 regCb = (CmMmDynRegCb *)regionCb;
906 if((SLock(&iccAllocFreeLock)) != ROK)
908 printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
912 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
914 if((SUnlock(&iccAllocFreeLock)) != ROK)
916 printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
920 if ((memPtr) == NULLP)
923 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
924 printf("Exiting...\n");
929 #ifdef T2K_MEM_LEAK_DBG
930 if(((uint32_t)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
932 printf("Address returned is %p size = %ld\n",memPtr,*size);
935 InsertToT2kMemLeakInfo((uint32_t)memPtr,*size,line,file);
941 } /* end of cmIccAllocWithLock */
945 * Fun: cmIccFreeWithLock
947 * Desc: Return the Dynamic memory block for the memory region.
948 * This handler uses the lock to avoid the two thread
949 * trying to free the memory at same time. This
950 * handler must be used only for non-data plane thread
951 * it causes delay due to lock.
953 * Ret: ROK - successful
954 * RFAILED - unsuccessful.
962 #ifdef T2K_MEM_LEAK_DBG
963 static S16 cmIccFreeWithLock
965 Void *regionCb, /* Pointer to region cb */
966 Data *ptr, /* Memory block needs to be freed */
967 Size size, /* Size of the block */
972 static S16 cmIccFreeWithLock
974 Void *regionCb, /* Pointer to region cb */
975 Data *ptr, /* Memory block needs to be freed */
976 Size size /* Size of the block */
983 regCb = (CmMmDynRegCb *)regionCb;
985 if((SLock(&iccAllocFreeLock)) != ROK)
987 printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
991 #ifdef T2K_MEM_LEAK_DBG
992 RemoveFromT2kMemLeakInfo((uint32_t)ptr - ((uint32_t)ptr % 512),file,line);
995 TL_Free(regCb->iccHdl, ptr);
997 if((SUnlock(&iccAllocFreeLock)) != ROK)
999 printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1004 } /* end of cmIccFree */
1010 * Desc: Allocate a memory block for use by dynamic buffers
1013 * Ret: ROK - successful
1014 * RFAILED - unsuccessful.
1021 #ifdef T2K_MEM_LEAK_DBG
1022 static S16 cmIccAlloc
1024 Void *regionCb, /* Pointer to a region */
1025 Size *size, /* size needs to be allocated */
1026 uint32_t flags, /* Flags used */
1027 Data **ptr, /* Reference to pointer for which need to be allocate */
1032 static S16 cmIccAlloc
1034 Void *regionCb, /* Pointer to a region */
1035 Size *size, /* size needs to be allocated */
1036 uint32_t flags, /* Flags used */
1037 Data **ptr /* Reference to pointer for which need to be allocate */
1042 CmMmDynRegCb *regCb;
1046 regCb = (CmMmDynRegCb *)regionCb;
1048 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1050 if ((memPtr) == NULLP)
1053 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1054 printf("Exiting...\n");
1058 #ifdef T2K_MEM_LEAK_DBG
1059 if(((uint32_t)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1061 printf("Address returned is %p size = %ld\n",memPtr,*size);
1064 InsertToT2kMemLeakInfo((uint32_t)memPtr,*size,line,file);
1067 *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1069 *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1074 } /* end of cmIccAlloc */
1080 * Desc: Return the Dynamic memory block for the memory region.
1083 * Ret: ROK - successful
1084 * RFAILED - unsuccessful.
1092 #ifdef T2K_MEM_LEAK_DBG
1093 static S16 cmIccFree
1095 Void *regionCb, /* Pointer to region cb */
1096 Data *ptr, /* Memory block needs to be freed */
1097 Size size, /* Size of the block */
1102 static S16 cmIccFree
1104 Void *regionCb, /* Pointer to region cb */
1105 Data *ptr, /* Memory block needs to be freed */
1106 Size size /* Size of the block */
1110 CmMmDynRegCb *regCb;
1112 regCb = (CmMmDynRegCb *)regionCb;
1115 // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1117 #ifdef T2K_MEM_LEAK_DBG
1118 RemoveFromT2kMemLeakInfo((uint32_t)ptr - ((uint32_t)ptr % 512),file,line);
1122 TL_Free(regCb->iccHdl, ptr);
1124 /* memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1126 TL_Free(regCb->iccHdl, memPtr);
1128 /*TL_Free(regCb->iccHdl, ptr);*/
1132 } /* end of cmIccFree */
1136 * Fun: cmMmDynRegInit
1138 * Desc: Configure the memory region for allocation. The function
1139 * registers the memory region with System Service by calling
1143 * Ret: ROK - successful,
1144 * RFAILED - unsuccessful.
1146 * Notes: The memory owner calls this function to initialize the memory
1147 * manager with the information of the memory region. Before
1148 * calling this function, the memory owner should allocate memory
1149 * for the memory region. The memory owner should also provide the
1150 * memory for the control block needed by the memory manager. The
1151 * memory owner should allocate the memory for the region control
1152 * block as cachable memory. This may increase the average
1153 * throughput in allocation and deallocation as the region control
1154 * block is mostly accessed by the CMM.
1165 #ifdef T2200_2GB_DDR_CHANGES
1166 Txt regIccStr[10] = {'\0'};
1168 Txt regIccStr[64] = {'\0'};
1172 /* Register the region/memory with ICC and get the handler for same. The id is starting
1173 * from region+1 as the zero is used by PHY code */
1174 #ifdef T2200_2GB_DDR_CHANGES
1175 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1178 if(clusterMode == RADIO_CLUSTER_MODE)
1180 if(regCb->region == 3)
1181 {/* ICC packet receiver */
1182 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1185 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1186 //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1190 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1191 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1192 //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1195 #ifdef T2200_2GB_DDR_CHANGES
1196 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1198 sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1202 printf(" %s \n",regIccStr);
1203 regCb->iccHdl = TL_Open(regIccStr, 0);
1205 printf("\nICC Region is %d\n",regCb->region);
1207 /* Call SRegRegion to register the memory region with SSI */
1208 memset(®Info, 0, sizeof(regInfo));
1210 /* Register the lock region for SS_MAX_REGS - 1 region */
1211 if((SS_MAX_REGS - 1) == regCb->region)
1213 regInfo.alloc = cmIccAllocWithLock;
1214 regInfo.free = cmIccFreeWithLock;
1215 regInfo.regCb = regCb;
1216 if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1218 printf("Failed to initialize the lock region lock\n");
1223 regInfo.alloc = cmIccAlloc;
1224 regInfo.free = cmIccFree;
1225 regInfo.regCb = regCb;
1228 if (SRegDynRegion(regCb->region, ®Info) != ROK)
1234 } /* end of cmMmDynRegInit*/
1236 #else /* SS_USE_ICC_MEMORY */
1240 * Fun: cmMmDynRegInit
1242 * Desc: Configure the memory region for allocation. The function
1243 * registers the memory region with System Service by calling
1247 * Ret: ROK - successful,
1248 * RFAILED - unsuccessful.
1250 * Notes: The memory owner calls this function to initialize the memory
1251 * manager with the information of the memory region. Before
1252 * calling this function, the memory owner should allocate memory
1253 * for the memory region. The memory owner should also provide the
1254 * memory for the control block needed by the memory manager. The
1255 * memory owner should allocate the memory for the region control
1256 * block as cachable memory. This may increase the average
1257 * throughput in allocation and deallocation as the region control
1258 * block is mostly accessed by the CMM.
1272 CmMmBlkSetElement *blkLstElem;
1274 Size bktQnSize = MT_BKTQNSIZE;
1280 /* Initialize the region control block */
1281 region = regCb->region;
1282 numBkts = regCb->numBkts;
1284 /* Initilaize the bktIndex of the map entries to FF */
1285 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1287 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1292 for(cnt = 0; cnt < numBkts; cnt++)
1294 /* Initialize the Map entry */
1295 size = regCb->bktTbl[cnt].size;
1296 idx = size / bktQnSize;
1299 * Check if the size is multiple of quantum size. If not we need to initialize
1300 * one more map table entry.
1302 if(size % bktQnSize)
1307 while ( lstMapIdx < idx)
1309 regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1314 regCb->bktQnPwr = 0;
1316 while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1321 /* Initialize the bucket structure */
1322 for(idx = 0; idx < numBkts; idx++)
1324 regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1326 for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1328 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1329 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1330 cmLListAdd2Tail((®Cb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1334 /* Call SRegRegion to register the memory region with SSI */
1335 memset(®Info, 0, sizeof(regInfo));
1336 if((SS_MAX_REGS - 1) == regCb->region)
1338 regInfo.alloc = cmDynAllocWithLock;
1339 regInfo.free = cmDynFreeWithLock;
1340 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1342 printf("Failed to initialize the lock region lock\n");
1347 regInfo.alloc = cmDynAlloc;
1348 regInfo.free = cmDynFree;
1351 regInfo.regCb = regCb;
1353 if (SRegDynRegion(region, ®Info) != ROK)
1359 } /* end of cmMmDynRegInit*/
1361 #endif /* SS_USE_ICC_MEMORY */
1366 * Fun: cmMmRegDeInit
1368 * Desc: Deinitialize the memory region. The function call SDeregRegion
1369 * to deregister the memory region with System Service.
1372 * Ret: ROK - successful
1373 * RFAILED - unsuccessful.
1375 * Notes: The memory owner calls this function to deinitialize the region.
1376 * The memory manager does not return the memory to the system.
1377 * Before calling this function, the memory owner must be sure that
1378 * no layer is using any memory block from this region. On
1379 * successful return from the function, any request to the memory
1380 * manager to allocate/deallocate memory will fail. The memory owner
1381 * can reuse the memory for other region or return the memory to the
1382 * system memory pool.
1389 S16 cmMmRegDeInit(CmMmRegCb *regCb)
1394 #if (ERRCLASS & ERRCLS_INT_PAR)
1396 /* error check on parameters */
1404 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1405 #ifdef SSI_DEBUG_LEVEL1
1406 /* Deinitialize the hash table used for debug info storage at region level */
1407 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
1411 #endif /* SSI_DEBUG_LEVEL1 */
1413 /* Call SDeregRegion first to deregister the memory region with SSI */
1414 (Void) SDeregRegion (regCb->region);
1418 /* Bucket pool is configured */
1420 /* Free the initialzed locks of the buckets */
1421 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1423 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1424 WTDestroyLock for NT */
1425 /* cm_mem_c_001.main_24 fix for memory corruption*/
1428 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1430 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1432 /* cm_mem_c_001.main_15:Additions */
1433 #ifdef SS_HISTOGRAM_SUPPORT
1434 /* De-initialise the memory histogram hash list */
1435 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1436 #endif /* SS_HISTOGRAM_SUPPORT */
1440 if (regCb->heapFlag)
1442 /* Heap pool is configured */
1444 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1445 WTDestroyLock for NT */
1447 WTDestroyLock(®Cb->heapCb.heapLock);
1449 SDestroyLock(®Cb->heapCb.heapLock);
1455 } /* end of cmMmRegDeInit */
1458 #ifndef SS_USE_ICC_MEMORY
1461 * Fun: cmGetMemBlkSetForAlloc
1463 * Desc: Retruns the pointer to the element which is used for
1464 * allocating the buffer. Also, it does the threshold check
1465 * and get the additional memory block set from the global
1469 * Ret: Pointer to memory block set - successful
1470 * NULL - unsuccessful.
1473 * Current implementation of the is function is made assuming that
1474 * there will maximum two set of nodes only.
1480 static CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1482 uint8_t bucketIndex, /* Index to the bucket list */
1483 CmMmDynBktCb *bkt /* Bucket list control block */
1486 CmMmBlkSetElement *memBlkSetElem;
1487 CmMmBlkSetElement *nextMemBlkSetElem;
1488 CmLList *memSetNode;
1489 CmLList *nextMemSetNode;
1491 /* Check if we are coming here for the first time, if yes get a new
1492 * block set from global region */
1493 if(bkt->crntMemBlkSetElem == NULLP)
1495 /* set the current index to initial one and get the bucket set from
1497 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1499 /* Check if the element exits or not */
1500 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1505 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1506 /* Get the new block set from the gloabl region and return the same */
1507 ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1508 return (bkt->crntMemBlkSetElem);
1510 /* If this is not the first time, take the bucket list CB from the
1512 memBlkSetElem = bkt->crntMemBlkSetElem;
1513 /* If the current index doesnot have any free buckets, it check in
1514 * the next bucket node */
1515 if(memBlkSetElem->numFreeBlks == 0)
1517 /* Get the next element in the list and if it is not present, then
1518 * get the first node */
1519 memSetNode = cmLListNext(&bkt->memBlkSetElem);
1521 if(memSetNode == NULLP)
1523 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1525 memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1527 /* if next node also empty, return failure */
1528 if(memBlkSetElem->numFreeBlks == 0)
1532 /* store the new index in the current node which will be
1533 * used in the next time. */
1534 bkt->crntMemBlkSetElem = memBlkSetElem;
1537 /* If we have reached the threshold value, get the next set of buckets from
1538 * the global region and place it */
1539 if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1541 /* Get the next element for the threshold check. If next is not present,
1542 * get the first one. Here, we are not using the cmLList macros to get
1543 * to the next node or first node as those macros are working on the crnt
1544 * node and will change the crnt. As we dont want to change the crnt node
1545 * at this point, we are directly using the listCp prameter to get next
1547 nextMemSetNode = memBlkSetElem->memSetNode.next;
1549 if(nextMemSetNode == NULLP)
1551 nextMemSetNode = bkt->memBlkSetElem.first;
1554 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1556 if(nextMemBlkSetElem->numFreeBlks == 0)
1558 /* The last parameter is used wheather to block for the block set aquiring
1559 or not. Here, the logic is such that, when the current node number of
1560 free blocks becomes one and the next node has zero free blocks,
1561 we must get the block set from global region.
1562 For example, if acquire threashold is 20 and current node has only one
1563 free block and next node has zero free blocks we block to aquire lock
1564 and get the set from global region else, we try for lock, if we get
1565 the lock, the get the block set else it is get in next go
1567 ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1568 (memBlkSetElem->numFreeBlks - 1));
1572 /* On successful, return the bucket node to calling function */
1573 return (memBlkSetElem);
1574 } /* cmGetMemBlkSetForAlloc */
1579 * Fun: cmGetMemBlkSetForFree
1581 * Desc: Retruns the pointer to the element which is used for
1582 * freeing the buffer. Also, it does the threshold check
1583 * and release the additional memory block set to the global
1587 * Ret: Pointer to memory block set - successful
1588 * NULL - unsuccessful.
1591 * Current implementation of the is function is made assuming that
1592 * there will maximum two set of nodes only.
1598 static CmMmBlkSetElement* cmGetMemBlkSetForFree
1600 uint8_t bucketIndex, /* Index to the bucket list */
1601 CmMmDynBktCb *bkt /* Bucket list control block */
1604 CmMmBlkSetElement *memBlkSetElem;
1605 CmMmBlkSetElement *nextMemBlkSetElem;
1606 CmLList *memSetNode;
1607 CmLList *nextMemSetNode;
1609 /* Check if we are coming here for the first time, if yes get a new
1610 * block set from global region */
1611 if(bkt->crntMemBlkSetElem == NULLP)
1613 /* set the current index to initial one */
1614 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1616 /* Check if the element exits or not */
1617 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1621 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1622 return (bkt->crntMemBlkSetElem);
1624 /* If this is not the first time, take the bucket list CB from the
1626 memBlkSetElem = bkt->crntMemBlkSetElem;
1627 /* If the current index doesnot have any free buckets, it check in
1628 * the next bucket node */
1629 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1631 /* Get the next element in the list and if it is not present, then
1632 * get the first node */
1633 nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1635 if(nextMemSetNode == NULLP)
1637 nextMemSetNode = cmLListFirst(&bkt->memBlkSetElem);
1639 memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1641 /* if next node also empty, return failure */
1642 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1646 /* store the new index in the current node which will be
1647 * used in the next time. */
1648 bkt->crntMemBlkSetElem = memBlkSetElem;
1651 /* If we have reached the threshold value and have additional block set,
1652 * release the additional block set back to global region */
1653 if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold)
1655 /* Get the next element for the threshold check. If next is not present,
1656 * get the first one. Here, we are not using the cmLList macros to get
1657 * to the next node or first node as those macros are working on the crnt
1658 * node and will change the crnt. As we dont want to change the crnt node
1659 * at this point, we are directly using the listCp prameter to get next
1661 nextMemSetNode = memBlkSetElem->memSetNode.next;
1662 if(nextMemSetNode == NULLP)
1664 nextMemSetNode = bkt->memBlkSetElem.first;
1667 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1668 if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
1670 /* The last parameter is used wheather to block for the block set aquiring
1671 or not. Here, the logic is such that, when the current node number of
1672 free blocks becomes one less than the bucket set size and the next node
1673 is has full free blocks, we must free the block set back to global region
1674 For example, if bucket set size if 100 and release threashold is 80 and
1675 current node has number of free blocks 99 and next node has 100 free blocks
1676 we block to aquire lock and free it back to global region else, we try for
1677 lock, if we get the lock, the block set is freed else its freed in next go
1679 ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1680 (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
1684 /* On successful, return the bucket node to calling function */
1685 return (memBlkSetElem);
1687 #endif /* SS_USE_ICC_MEMORY */
1688 #endif /* USE_PURE */
1690 #ifdef SS_MEM_WL_DEBUG
1693 * Fun: cmRemoveAllocPtrFromList
1695 * Desc: Remove a node with Free PTR from hashlist. The memory
1696 * of the node is Freed to the same region
1699 * Ret: ROK - successful
1700 * RFAILED - unsuccessful.
1708 static S16 cmRemoveAllocPtrFromList
1710 CmMmDynRegCb *regionCb, /* Pointer to a region */
1715 CmMemDoubleFree *memNode = NULLP;
1717 SLock(&memDoubleFreeLock);
1718 if((cmHashListFind(&(memDoubleFree), (uint8_t*)&ptr,
1719 sizeof(uint32_t), 0, (PTR *)&memNode)) != ROK)
1726 tmpBtSize = backtrace(tmpBtArr, 10);
1727 strings = backtrace_symbols(tmpBtArr, tmpBtSize);
1728 printf("**** Trying to free non allocated block BT is: \n");
1729 for(idx = 0; idx < tmpBtSize; idx++)
1731 printf("%s\n", strings[idx]);
1733 printf("*****************************************\n");
1734 printf("Analysis from Array storing BT for freeing and allocation\n");
1735 cmAnalyseBtInfo(ptr, regionCb->region);
1736 SUnlock(&memDoubleFreeLock);
1740 if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
1742 SUnlock(&memDoubleFreeLock);
1745 SUnlock(&memDoubleFreeLock);
1746 SPutSBuf(regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
1753 * Fun: cmInsertAllocPtrToList
1755 * Desc: Insert a node with allocated PTR into hashlist. The memory
1756 * for the node is allocated from the same region
1759 * Ret: ROK - successful
1760 * RFAILED - unsuccessful.
1768 static S16 cmInsertAllocPtrToList
1770 CmMmDynRegCb *regionCb, /* Pointer to a region */
1775 CmMemDoubleFree *memNode;
1777 SGetSBuf(regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
1778 if(memNode == NULLP)
1783 memNode->memBlkPtr = ptr;
1784 SLock(&memDoubleFreeLock);
1785 if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (uint8_t*)&memNode->memBlkPtr,
1786 sizeof(PTR))) != ROK)
1788 SUnlock(&memDoubleFreeLock);
1791 SUnlock(&memDoubleFreeLock);
1798 #ifndef SS_USE_ICC_MEMORY
1801 * Fun: cmDynAllocWithLock
1803 * Desc: Allocate a memory block for use by dynamic buffers
1806 * Ret: ROK - successful
1807 * RFAILED - unsuccessful.
1814 /* cm_mem_c_001.main_15 : Additions */
1816 static S16 cmDynAllocWithLock
1818 Void *regionCb, /* Pointer to a region */
1819 Size *size, /* size needs to be allocated */
1820 uint32_t flags, /* Flags used */
1821 Data **ptr /* Reference to pointer for which need to be allocate */
1827 if((SLock(&dynAllocFreeLock)) != ROK)
1829 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1833 ret = cmDynAlloc (regionCb, size,flags,ptr);
1835 if((SUnlock(&dynAllocFreeLock)) != ROK)
1837 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1842 } /* end of cmDynAlloc */
1848 * Desc: Allocate a memory block for use by dynamic buffers
1851 * Ret: ROK - successful
1852 * RFAILED - unsuccessful.
1859 /* cm_mem_c_001.main_15 : Additions */
1861 static S16 cmDynAlloc
1863 Void *regionCb, /* Pointer to a region */
1864 Size *size, /* size needs to be allocated */
1865 uint32_t flags, /* Flags used */
1866 Data **ptr /* Reference to pointer for which need to be allocate */
1869 CmMmDynRegCb *regCb;
1872 regCb = (CmMmDynRegCb *)regionCb;
1874 #ifdef SS_MEM_WL_DEBUG
1875 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
1881 #if (ERRCLASS & ERRCLS_INT_PAR)
1883 /* error check on parameters */
1884 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
1893 * Check if the requested size is less than or equal to the maximum block
1894 * size in the bucket.
1897 #ifdef SS_MEM_WL_DEBUG
1898 if ( (*size + 4) <= regCb->bktMaxBlkSize)
1900 if ( (*size) <= regCb->bktMaxBlkSize)
1904 CmMmBlkSetElement *dynMemElem;
1908 /* Get the map to the mapping table */
1909 #ifdef SS_MEM_WL_DEBUG
1910 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
1912 idx = (((*size) - 1) >> regCb->bktQnPwr);
1915 #if (ERRCLASS & ERRCLS_DEBUG)
1916 if (regCb->mapTbl[idx].bktIdx == 0xFF)
1918 printf("Failed to get the buffer of size %d\n", *size);
1919 /* Some fatal error in the map table initialization. */
1927 /* Dequeue the memory block and return it to the user */
1928 bktIdx = regCb->mapTbl[idx].bktIdx;
1929 bkt = &(regCb->bktTbl[bktIdx]);
1930 #ifdef SS_MEM_WL_DEBUG
1931 if(bkt->size < (*size+4))
1933 if(bkt->size < (*size))
1937 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
1940 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
1942 /* Check if the bucket index, if its not valid, return failure */
1943 if(dynMemElem == NULLP)
1946 printf("Failed to get the buffer of size %ld\n", *size);
1948 printf("Failed to get the buffer of size %d\n", *size);
1953 #ifdef SS_MEM_WL_DEBUG
1954 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
1960 /* Get the bucket node from the index returned and allocate the memory */
1961 *ptr = dynMemElem->nextBktPtr;
1966 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
1967 dynMemElem->numFreeBlks--;
1969 #ifdef SS_MEM_WL_DEBUG
1970 prvAllocPtr[regCb->region] = *ptr;
1972 **ptr = (uint8_t) bktIdx;
1976 *ptr += sizeof (uint32_t);
1978 if ((bktIdx == 0) && (!stopBtInfo))
1982 btInfo = &allocBtInfo[regCb->region];
1983 btIdx = btInfo->btInfoIdx;
1984 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
1986 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
1988 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
1991 btIdx &= (NUM_FREE_BUFFERS - 1);
1993 btInfo->btInfo[btIdx].ptr = (PTR)0;
1994 btInfo->btInfo[btIdx].btSize = 0;
1995 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
1996 btInfo->btInfoIdx = btIdx;
2003 /* If the size is not matching, return failure to caller */
2005 printf("Failed to get the buffer of size %ld\n", *size);
2007 printf("Failed to get the buffer of size %d\n", *size);
2011 #else /* use pure is on */
2013 #ifdef SS_4GMX_LCORE
2014 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2015 memset(ptr, 0, *size);
2017 /* *ptr = (Data*) malloc(*size); */
2019 *ptr = (Data *)malloc(*size);
2021 if ( (*ptr) == NULLP)
2023 /* avail_size -= *size; */
2025 #endif /* USE_PURE */
2027 } /* end of cmDynAlloc */
2028 #endif /* SS_USE_ICC_MEMORY */
2031 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2033 int g_overused[5] = {0};
2040 * Desc: Allocate a memory block for the memory region.
2043 * Ret: ROK - successful
2044 * RFAILED - unsuccessful.
2047 * The function allocates a memory block of size atleast equal to
2048 * the requested size. The size parameter will be updated with the
2049 * actual size of the memory block allocated for the request. The
2050 * CMM tries to allocate the memory block form the bucket pool. If
2051 * there is no memory in the bucket the CMM allocates the memory
2052 * block form the heap pool. This function is always called by the
2053 * System Service module.
2055 * The caller of the function should try to use the out value of
2056 * the size while returning the memory block to the region. However
2057 * the current design of the memory manager does not enforce to pass
2058 * the actual size of the memory block. (Due to the SGetSBuf
2059 * semantics the layer will not able to pass the correct size of the
2060 * memory block while calling SPutSBuf).
2066 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2068 /* cm_mem_c_001.main_15 : Additions */
2069 #ifdef T2K_MEM_LEAK_DBG
2080 #ifdef SS_HISTOGRAM_SUPPORT
2081 #ifdef SSI_DEBUG_LEVEL1
2106 #endif /* SSI_DEBUG_LEVEL1 */
2110 #ifdef SSI_DEBUG_LEVEL1
2129 #endif /* SSI_DEBUG_LEVEL1 */
2130 /* cm_mem_c_001.main_15: Additions */
2131 #endif /* SS_HISTOGRAM_SUPPORT */
2134 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2141 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2145 /* cm_mem_c_001.main_15 : Additions */
2146 #ifdef SS_MEM_LEAK_STS
2148 #endif /* SS_MEM_LEAK_STS */
2149 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2150 #ifdef SSI_DEBUG_LEVEL1
2151 CmMmBlkHdr *alocBlk;
2152 #endif /* SSI_DEBUG_LEVEL1 */
2153 /* cm_mem_c_001.main_15 : Additions */
2154 #ifdef SS_HISTOGRAM_SUPPORT
2156 #endif /* SS_HISTOGRAM_SUPPORT */
2162 /* cm_mem_c_001.main_15 : Additions */
2163 #ifdef SS_MEM_LEAK_STS
2165 #endif /* SS_MEM_LEAK_STS */
2167 regCb = (CmMmRegCb *)regionCb;
2169 #if (ERRCLASS & ERRCLS_INT_PAR)
2171 /* error check on parameters */
2172 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2178 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2179 #ifdef SSI_DEBUG_LEVEL1
2180 #if (ERRCLASS & ERRCLS_INT_PAR)
2181 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2185 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2186 #endif /* SSI_DEBUG_LEVEL1 */
2193 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2194 #ifdef SSI_DEBUG_LEVEL1
2195 /* Update the hash list */
2196 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2198 /* display that, this entry could not be made in the hash list */
2200 /* display an error message here */
2201 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2203 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2204 *size, regCb->region);
2206 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2207 *size, regCb->region);
2209 SDisplay(0, dbgPrntBuf);
2212 #endif /* SSI_DEBUG_LEVEL1 */
2215 * Check if the requested size is less than or equal to the maximum block
2216 * size in the bucket.
2218 if ( *size <= regCb->bktMaxBlkSize)
2220 /* Get the map to the mapping table */
2221 idx = ((*size - 1) >> regCb->bktQnPwr);
2223 #if (ERRCLASS & ERRCLS_DEBUG)
2224 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2226 /* Some fatal error in the map table initialization. */
2231 /* Dequeue the memory block and return it to the user */
2232 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2235 /* While loop is introduced to use the "break statement inside */
2239 * Check if the size request is not greater than the size available
2242 if (*size > bkt->size)
2244 /* Try to go to the next bucket if available */
2245 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2246 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2248 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2252 /* This is the last bucket, try to allocate from heap */
2257 /* Acquire the bucket lock */
2258 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2260 (Void) WTLock(&(bkt->bktLock));
2262 (Void) SLock(&(bkt->bktLock));
2265 #if (ERRCLASS & ERRCLS_DEBUG)
2266 regCb->mapTbl[idx].numReq++;
2267 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2269 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2270 #ifdef SSI_DEBUG_LEVEL1
2271 /* increment the allocation attempt counter at bucket level */
2272 bkt->numAllocAttempts++;
2274 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2275 the allocation is always from (bkt->nextBlk) */
2278 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2280 /* detected a trampled memory block in this bucket */
2282 /* display an error message here */
2283 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2285 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2286 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2288 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2289 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2291 SDisplay(0, dbgPrntBuf);
2294 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2296 /* Release the lock */
2297 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2299 (Void) WTUnlock(&(bkt->bktLock));
2301 (Void) SUnlock(&(bkt->bktLock));
2303 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2304 return (RTRAMPLINGNOK);
2308 /* Release the lock */
2309 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2311 (Void) WTUnlock(&(bkt->bktLock));
2313 (Void) SUnlock(&(bkt->bktLock));
2315 /* return RFAILED */
2321 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2323 if ((*ptr = bkt->next))
2324 #endif /* SSI_DEBUG_LEVEL1 */
2326 /* cm_mem_c_001.main_12 - addition for header */
2327 #ifdef SSI_DEBUG_LEVEL1
2328 /* point to next block header */
2329 alocBlk = bkt->nextBlk;
2330 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2332 bkt->next = *((CmMmEntry **)(bkt->next));
2333 #endif /* SSI_DEBUG_LEVEL1 */
2336 * Increment the statistics variable of number of memory block
2340 if (bkt->numAlloc > bkt->maxAlloc)
2342 bkt->maxAlloc = bkt->numAlloc;
2345 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2347 g_overused[bktIdx] = 1;
2348 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2352 /* cm_mem_c_001.main_12 - addition for header manipulation */
2353 #ifdef SSI_DEBUG_LEVEL1
2354 /* update the size for which this memory block has been allocated */
2355 alocBlk->requestedSize = *size;
2356 /* update the memory block header */
2357 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2358 if (memType == CMM_STATIC_MEM_FLAG)
2360 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2361 /* add it to the static memory allocated */
2362 bkt->staticMemUsed += bkt->size;
2366 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2367 /* add it to the dynamic memory allocated */
2368 bkt->dynamicMemUsed += bkt->size;
2370 #endif /* SSI_DEBUG_LEVEL1 */
2372 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2376 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2379 "[MEM_CAL_CNTA] %u bytes request not fitted in bkt %d [size %u bytes] %u times\n", *size, regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktNoFitCnt++);
2382 "[MEM_CAL_CNTA] %lu bytes request not fitted in bkt %d [size %lu bytes] %lu times\n", *size, regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktNoFitCnt++);
2384 SDisplay(0, prntBuf);
2392 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2393 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2394 SDisplay(0, prntBuf);
2396 #endif /* MEMCAL_DEBUG */
2397 /* cm_mem_c_001.main_15 : Additions */
2398 #ifdef SS_HISTOGRAM_SUPPORT
2399 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2400 * information into the hash list */
2403 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2405 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2410 #endif /* SS_HISTOGRAM_SUPPORT */
2412 /* Update the size parameter */
2414 #ifdef SS_MEM_LEAK_STS
2415 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2416 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2417 regCb->mapTbl[idx].bktIdx);
2418 #endif /* SS_MEM_LEAK_STS */
2420 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2422 /* Release the lock */
2423 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2425 (Void) WTUnlock(&(bkt->bktLock));
2427 (Void) SUnlock(&(bkt->bktLock));
2436 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2439 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2442 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2444 SDisplay(0, prntBuf);
2448 #if (ERRCLASS & ERRCLS_DEBUG)
2449 regCb->mapTbl[idx].numFailure++;
2450 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2452 /* Release the lock */
2453 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2455 (Void) WTUnlock(&(bkt->bktLock));
2457 (Void) SUnlock(&(bkt->bktLock));
2466 regCb->heapCb.heapAllocCnt++;
2468 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2471 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2472 regCb->heapCb.heapAllocCnt);
2475 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2476 regCb->heapCb.heapAllocCnt);
2478 SDisplay(0, prntBuf);
2483 /* Memory not available in the bucket pool */
2484 if (regCb->heapFlag && (*size < regCb->heapSize))
2487 if (flags) tryHeap = 1;
2490 * The heap memory block is available. Allocate the memory block from
2493 /* cm_mem_c_001.main_15: Additions */
2494 #ifdef SS_HISTOGRAM_SUPPORT
2495 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2496 #ifdef SSI_DEBUG_LEVEL1
2497 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2499 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2500 #endif /* SSI_DEBUG_LEVEL1 */
2502 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2503 #ifdef SSI_DEBUG_LEVEL1
2504 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2506 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2507 #endif /* SSI_DEBUG_LEVEL1 */
2508 #endif /* SS_HISTOGRAM_SUPPORT */
2511 /* No memory available */
2513 #else /* use pure is on */
2514 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2515 #ifdef SS_4GMX_LCORE
2516 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2517 memset(ptr, 0, *size);
2519 *ptr = (Data*) malloc(*size);
2521 if ( (*ptr) == NULLP)
2523 avail_size -= *size;
2525 #endif /* USE_PURE */
2527 } /* end of cmAlloc */
2529 #ifdef SS_MEM_WL_DEBUG
2532 * Fun: cmInitDoubleFreeList
2534 * Desc: Initialize the hashlist used for detecting double free
2536 * Ret: ROK - successful
2537 * RFAILED - unsuccessful.
2545 S16 cmInitDoubleFreeList(void)
2548 CmMemDoubleFree memNode;
2550 offset = (uint16_t)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2552 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2553 CM_HASH_KEYTYPE_UINT32_MOD, 0, 0)) != ROK);
2557 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2562 #ifdef SS_MEM_WL_DEBUG
2567 * Desc: Return the Dynamic memory block for the memory region.
2570 * Ret: ROK - successful
2571 * RFAILED - unsuccessful.
2579 static S16 cmInitBtInfo()
2581 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2582 if (regBtInfo == NULLP)
2586 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2587 if(allocBtInfo == NULLP)
2594 #endif /* SS_MEM_WL_DEBUG */
2597 * Fun: cmAnalyseBtInfo
2599 * Desc: Return the Dynamic memory block for the memory region.
2602 * Ret: ROK - successful
2603 * RFAILED - unsuccessful.
2611 Void cmAnalyseBtInfo
2613 PTR ptr, /* Memory block needs to be freed */
2622 /* for(regIdx = 0; regIdx < 8; regIdx++)
2625 btInfo = &allocBtInfo[idx];
2626 btIdx = btInfo->btInfoIdx;
2628 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
2630 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
2631 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
2632 if(btInfo->btInfo[btIdx].btSize != 0)
2636 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2637 printf("*** Last Allocation Region = %d PTR %x Timestamp sec = (%ld) usec = (%ld) ***\n", idx, ptr, btInfo->btInfo[btIdx].timeStamp.tv_sec, btInfo->btInfo[btIdx].timeStamp.tv_usec);
2638 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2640 printf("%s\n", strings[i]);
2642 printf("*******************************************************\n");
2650 btIdx = NUM_FREE_BUFFERS - 1;
2659 #ifndef SS_USE_ICC_MEMORY
2662 * Fun: cmDynFreeWithLock
2664 * Desc: Return the Dynamic memory block for the memory region.
2667 * Ret: ROK - successful
2668 * RFAILED - unsuccessful.
2676 static S16 cmDynFreeWithLock
2678 Void *regionCb, /* Pointer to region cb */
2679 Data *ptr, /* Memory block needs to be freed */
2680 Size size /* Size of the block */
2685 if((SLock(&dynAllocFreeLock)) != ROK)
2687 printf("dynAllocWithLock: Failed to get the DYN lock\n");
2691 ret = cmDynFree(regionCb, ptr,size);
2693 if((SUnlock(&dynAllocFreeLock)) != ROK)
2695 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2701 } /* end of cmDynFree */
2707 * Desc: Return the Dynamic memory block for the memory region.
2710 * Ret: ROK - successful
2711 * RFAILED - unsuccessful.
2719 static S16 cmDynFree
2721 Void *regionCb, /* Pointer to region cb */
2722 Data *ptr, /* Memory block needs to be freed */
2723 Size size /* Size of the block */
2726 CmMmDynRegCb *regCb;
2730 CmMmDynBktCb *bkt = NULLP;
2731 CmMmBlkSetElement *dynMemElem;
2733 #ifdef SS_MEM_WL_DEBUG
2739 regCb = (CmMmDynRegCb *)regionCb;
2740 #ifdef SS_MEM_WL_DEBUG
2741 if((tmpRegTidMap[regCb->region] != (pthread_self())))
2748 #if (ERRCLASS & ERRCLS_INT_PAR)
2749 /* error check on parameters */
2750 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2755 /* Check if the memory block is from the memory region */
2756 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2757 ((CmMmRegCb *)regCb)->regInfo.size)
2761 /* cm_mem_c_001.main_20 Addition */
2762 if (ptr < regCb->regInfo.start)
2769 #ifdef SS_MEM_WL_DEBUG
2770 ptr -= sizeof (uint32_t);
2773 /* The memory block was allocated from the bucket pool */
2775 /* Get the map to the mapping table */
2776 idx = ((size - 1) >> regCb->bktQnPwr);
2778 #if (ERRCLASS & ERRCLS_DEBUG)
2779 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2781 /* Some fatal error in the map table initialization. */
2786 /* Enqueue the memory block and return it to the user */
2787 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2790 * Check if the size is not greater than the size available
2791 * in the bucket. If so, then the buffer must have been allocated
2792 * from next bucket. We don't need to check the validity of the
2793 * next bucket, otherwise buffer must have been allocated from heap
2796 #ifdef SS_MEM_WL_DEBUG
2797 if (size > bkt->size)
2799 printf("Size = %d bucket size = %d\n", size, bkt->size);
2801 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
2803 if(size > bkt->size)
2805 printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
2807 uint8_t *tmpptr = NULLP;
2808 printf("Bucket Size wrong \n");
2813 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
2815 /* Check if the bucket index, if its not valid, return failure */
2816 if(dynMemElem == NULLP)
2821 #ifdef SS_MEM_WL_DEBUG
2822 tmpBktIdx = (uint8_t)*ptr;
2823 tmpVal = (uint8_t)*(ptr+1);
2825 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
2827 uint8_t *tmpptr = NULLP;
2828 printf("bktIdx wrong \n");
2832 if ((bktIdx == 0) && (!stopBtInfo))
2836 btInfo = ®BtInfo[regCb->region];
2837 btIdx = btInfo->btInfoIdx;
2838 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
2840 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2842 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2845 btIdx &= (NUM_FREE_BUFFERS - 1);
2847 btInfo->btInfo[btIdx].ptr = (PTR)0;
2848 btInfo->btInfo[btIdx].btSize = 0;
2849 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2850 btInfo->btInfoIdx = btIdx;
2853 if(prvAllocPtr[regCb->region] == ptr)
2855 prvAllocPtr[regCb->region] = NULLP;
2858 memset(ptr, (regCb->region+1), bkt->size);
2861 /* Get the bucket node from the index returned and allocate the memory */
2862 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
2863 dynMemElem->nextBktPtr = ptr;
2864 dynMemElem->numFreeBlks++;
2868 #else /* use pure is on */
2869 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2870 #ifdef SS_4GMX_LCORE
2871 (Void)MxHeapFree(SsiHeap, ptr);
2873 /* (Void)free(ptr); */
2875 /* avail_size += size; */
2879 #endif /* USE_PURE */
2882 } /* end of cmDynFree */
2883 #endif /* SS_USE_ICC_MEMORY */
2891 * Desc: Return the memory block for the memory region.
2894 * Ret: ROK - successful
2895 * RFAILED - unsuccessful.
2897 * Notes: The user calls this function to return the previously allocated
2898 * memory block to the memory region. The memory manager does not
2899 * check the validity of the state of the memory block(like whether
2900 * it was allocated earlier). The caller must be sure that, the
2901 * address specified in the parameter 'ptr' is valid and was
2902 * allocated previously from same region.
2909 /* cm_mem_c_001.main_15 : Additions */
2910 #ifdef T2K_MEM_LEAK_DBG
2920 #ifdef SS_HISTOGRAM_SUPPORT
2939 /* cm_mem_c_001.main_15 : Additions */
2940 #endif /* SS_HISTOGRAM_SUPPORT */
2943 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2950 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
2951 #ifdef SSI_DEBUG_LEVEL1
2953 #endif /* SSI_DEBUG_LEVEL1 */
2954 /* cm_mem_c_001.main_15 : Additions */
2955 #ifdef SS_HISTOGRAM_SUPPORT
2957 #endif /* SS_HISTOGRAM_SUPPORT */
2960 regCb = (CmMmRegCb *)regionCb;
2963 #if (ERRCLASS & ERRCLS_INT_PAR)
2965 /* error check on parameters */
2966 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2971 /* Check if the memory block is from the memory region */
2972 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2973 ((CmMmRegCb *)regCb)->regInfo.size)
2977 /* cm_mem_c_001.main_20 Addition */
2978 if (ptr < regCb->regInfo.start)
2986 * Check if the memory block was allocated from the bucket pool.
2988 if(ptr < regCb->regInfo.start)
2990 Buffer *tmpBuffer = NULLP;
2991 tmpBuffer->b_cont = NULLP;
2994 if (ptr < (regCb->regInfo.start + regCb->bktSize))
2996 /* The memory block was allocated from the bucket pool */
2998 /* Get the map to the mapping table */
2999 idx = ((size - 1) >> regCb->bktQnPwr);
3001 #if (ERRCLASS & ERRCLS_DEBUG)
3002 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3004 /* Some fatal error in the map table initialization. */
3009 /* Enqueue the memory block and return it to the user */
3010 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3013 * Check if the size is not greater than the size available
3014 * in the bucket. If so, then the buffer must have been allocated
3015 * from next bucket. We don't need to check the validity of the
3016 * next bucket, otherwise buffer must have been allocated from heap
3019 if (size > bkt->size)
3021 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3024 /* Acquire the bucket lock */
3025 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3027 (Void) WTLock(&(bkt->bktLock));
3029 (Void) SLock(&(bkt->bktLock));
3032 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3033 #ifdef SSI_DEBUG_LEVEL1
3034 /* increment the dealloc attempt counter at bucket level */
3035 bkt->numDeallocAttempts++;
3037 /* Check the memFlags to see whether this block was allocated */
3038 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3040 /* validate the block to be freed for trampling */
3041 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3043 /* Handle error case of Memory trampling */
3045 /* display an error message here */
3046 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3048 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3049 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3051 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3052 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3054 SDisplay(0, dbgPrntBuf);
3057 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3058 * as the memory blk is already invalidated in cmMmBktSanityChk
3060 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3064 /* Release the lock */
3065 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3067 (Void) WTUnlock(&(bkt->bktLock));
3069 (Void) SUnlock(&(bkt->bktLock));
3077 * this is the case where in the entire bucket has been made unusable
3080 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3082 (Void) WTUnlock(&(bkt->bktLock));
3084 (Void) SUnlock(&(bkt->bktLock));
3087 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3088 return (RTRAMPLINGNOK);
3092 /* reset the size */
3093 ptrHdr->requestedSize = 0;
3094 /* check if the block to be freed is already having the state as FREE */
3095 if (CMM_IS_FREE(ptrHdr->memFlags))
3097 /* Handle double deallocation error case */
3099 /* display an error message here */
3100 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3102 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3103 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3105 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3106 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3108 SDisplay(0, dbgPrntBuf);
3111 /* Release the lock */
3112 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3114 (Void) WTUnlock(&(bkt->bktLock));
3116 (Void) SUnlock(&(bkt->bktLock));
3119 /* handle RDBLFREE in SFree/SPutSBuf */
3122 if (CMM_IS_STATIC(ptrHdr->memFlags))
3124 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3125 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3126 /* deduct it from the static memory count */
3127 bkt->staticMemUsed -= bkt->size;
3129 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3131 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3132 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3133 /* deduct it from the dynamic memory count */
3134 bkt->dynamicMemUsed -= bkt->size;
3138 /* This is a case similar to trampled memory */
3140 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3142 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3144 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3146 SDisplay(0, dbgPrntBuf);
3148 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3150 /* do not add to the free list */
3153 /* Release the lock */
3154 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3156 (Void) WTUnlock(&(bkt->bktLock));
3158 (Void) SUnlock(&(bkt->bktLock));
3165 * this is the case where in the entire bucket has been made unusable
3168 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3170 (Void) WTUnlock(&(bkt->bktLock));
3172 (Void) SUnlock(&(bkt->bktLock));
3175 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3176 return (RTRAMPLINGNOK);
3180 /* Return the block to memory */
3181 ptrHdr->nextBlk = bkt->nextBlk;
3182 bkt->nextBlk = ptrHdr;
3185 *((CmMmEntry **)ptr) = bkt->next;
3186 bkt->next = (CmMmEntry *)ptr;
3187 #endif /* SSI_DEBUG_LEVEL1 */
3190 * Decrement the statistics variable of number of memory block
3198 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3200 g_overused[bktIdx] = 0;
3201 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3204 /* cm_mem_c_001.main_15 : Additions */
3205 #ifdef SS_HISTOGRAM_SUPPORT
3206 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3207 * information into the hash list */
3210 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3212 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3216 #endif /* SS_HISTOGRAM_SUPPORT */
3218 #ifdef SS_MEM_LEAK_STS
3219 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3220 cmRlsAllocBlk((PTR)ptr);
3221 #endif /* SS_MEM_LEAK_STS */
3223 /* Release the lock */
3224 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3226 (Void) WTUnlock(&(bkt->bktLock));
3228 (Void) SUnlock(&(bkt->bktLock));
3234 /* The memory block was allocated from the heap pool */
3235 /* cm_mem_c_001.main_15 : Additions */
3236 #ifdef SS_HISTOGRAM_SUPPORT
3237 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3239 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3240 #endif /* SS_HISTOGRAM_SUPPORT */
3241 #else /* use pure is on */
3242 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3243 #ifdef SS_4GMX_LCORE
3244 (Void)MxHeapFree(SsiHeap, ptr);
3250 #endif /* USE_PURE */
3253 } /* end of cmFree */
3260 * Desc: alloc without lock
3263 * Ret: ROK - successful
3264 * RFAILED - unsuccessful.
3270 /*cm_mem_c_001.main_21-added new function*/
3271 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3272 #ifdef T2K_MEM_LEAK_DBG
3273 static S16 cmAllocWL
3283 static S16 cmAllocWL
3294 CmMmBkt *bkt = NULLP;
3297 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3300 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3302 regCb = (CmMmRegCb *)regionCb;
3304 #ifdef SS_MEM_WL_DEBUG
3305 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3311 #if (ERRCLASS & ERRCLS_INT_PAR)
3313 /* error check on parameters */
3314 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3320 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3325 * Check if the requested size is less than or equal to the maximum block
3326 * size in the bucket.
3328 #ifdef MSPD_T2K_TRACK_BUG
3331 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3332 if ( *size <= regCb->bktMaxBlkSize)
3334 /* Get the map to the mapping table */
3335 idx = ((*size - 1) >> regCb->bktQnPwr);
3337 /* Dequeue the memory block and return it to the user */
3338 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3342 * Check if the size request is not greater than the size available
3345 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3346 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3348 /* Try to go to the next bucket if available */
3349 bkt->next = *((CmMmEntry **)(bkt->next));
3352 * Increment the statistics variable of number of memory block
3356 if (bkt->numAlloc > bkt->maxAlloc)
3358 bkt->maxAlloc = bkt->numAlloc;
3361 #ifdef MSPD_T2K_TRACK_BUG
3370 /* Update the size parameter */
3378 /* Memory not available in the bucket pool */
3379 if (regCb->heapFlag && (*size < regCb->heapSize))
3381 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3383 * The heap memory block is available. Allocate the memory block from
3386 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3387 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3390 /* No memory available */
3392 #else /* use pure is on */
3393 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3394 #ifdef SS_4GMX_LCORE
3395 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3396 memset(ptr, 0, *size);
3398 /* *ptr = (Data*) malloc(*size); */
3400 *ptr = (Data *)malloc(*size);
3402 if ( (*ptr) == NULLP)
3404 /* avail_size -= *size; */
3406 #endif /* USE_PURE */
3408 } /* end of cmAllocWL */
3415 * Desc: free without lock
3418 * Ret: ROK - successful
3419 * RFAILED - unsuccessful.
3426 #ifdef T2K_MEM_LEAK_DBG
3446 CmMmBkt *bkt = NULLP;
3449 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3452 regCb = (CmMmRegCb *)regionCb;
3454 #ifdef SS_MEM_WL_DEBUG
3455 if(tmpRegTidMap[regCb->region] != (pthread_self()))
3462 #if (ERRCLASS & ERRCLS_INT_PAR)
3464 /* error check on parameters */
3465 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3470 /* Check if the memory block is from the memory region */
3471 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3472 ((CmMmRegCb *)regCb)->regInfo.size)
3480 * Check if the memory block was allocated from the bucket pool.
3482 #ifdef MSPD_T2K_TRACK_BUG
3486 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3488 /* The memory block was allocated from the bucket pool */
3490 /* Get the map to the mapping table */
3491 idx = ((size - 1) >> regCb->bktQnPwr);
3493 #if (ERRCLASS & ERRCLS_DEBUG)
3494 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3496 /* Some fatal error in the map table initialization. */
3501 /* Enqueue the memory block and return it to the user */
3502 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3504 #ifdef MSPD_T2K_TRACK_BUG
3506 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3513 * Check if the size is not greater than the size available
3514 * in the bucket. If so, then the buffer must have been allocated
3515 * from next bucket. We don't need to check the validity of the
3516 * next bucket, otherwise buffer must have been allocated from heap
3519 if (size > bkt->size)
3521 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3524 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3525 *((CmMmEntry **)ptr) = bkt->next;
3526 bkt->next = (CmMmEntry *)ptr;
3529 * Decrement the statistics variable of number of memory block
3537 /* The memory block was allocated from the heap pool */
3538 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3539 #else /* use pure is on */
3540 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3541 #ifdef SS_4GMX_LCORE
3542 (Void)MxHeapFree(SsiHeap, ptr);
3544 /* (Void)free(ptr); */
3546 /* avail_size += size; */
3550 #endif /* USE_PURE */
3553 } /* end of cmFreeWL */
3560 * Desc: Control request function.
3563 * Ret: ROK - successful
3564 * RFAILED - unsuccessful.
3566 * Notes: The current semantics of the control function is defined for two
3567 * types of events: virtual address to physical address translation
3568 * and memory resource check.
3570 * The physical address translation is valid only for the memory
3571 * region physically contiguous and non pagable.
3589 regCb = (CmMmRegCb *)regionCb;
3591 #if (ERRCLASS & ERRCLS_INT_PAR)
3593 /* error check on parameters */
3594 if ((regCb == NULLP) || (memCtl == NULLP))
3607 #if (ERRCLASS & ERRCLS_INT_PAR)
3608 if ((memCtl->u.vtop.vaddr == NULLP) ||
3609 (memCtl->u.vtop.paddr == NULLP))
3615 /* Check if the virtual to physical address translation is valid */
3616 if (regCb->chFlag & CMM_REG_PHY_VALID)
3618 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3619 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3626 case SS_MEM_CHK_RES:
3629 #if (ERRCLASS & ERRCLS_INT_PAR)
3630 if (!(memCtl->u.chkres.size) ||
3631 (memCtl->u.chkres.status == NULLP))
3637 /* Check if the Bucket pool is configured */
3642 uint32_t avlSize, totSize;
3644 * The bucket pool is configured. The status value returned
3645 * does reflect on the memory availabilty in the bucket pool.
3646 * The value does not consider the available memory in the
3649 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3650 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3651 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3652 avlSize += regCb->heapCb.avlSize;
3653 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3654 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
3658 /* Bucket pool not configured */
3661 * Find the percentage memory available in the heap pool. The value
3662 * does not consider the fragmentation of the heap pool.
3664 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3665 (regCb->heapSize/10));
3669 #else /* use pure is on */
3670 *(memCtl->u.chkres.status) = ((avail_size) /
3671 (regCb->regInfo.size/10));
3673 #endif /* USE_PURE */
3679 /* No other event is supported currently */
3684 /* shouldn't reach here */
3686 } /* end of cmCtl */
3693 * Desc: Initialize the heap pool.
3696 * Ret: ROK - successful
3697 * RFAILED - unsuccessful.
3699 * Notes: This function is called by the cmMmRegInit.
3704 static Void cmMmHeapInit
3711 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3712 #ifdef SSI_DEBUG_LEVEL1
3714 #endif /* SSI_DEBUG_LEVEL1 */
3716 /* Initialize the heap control block */
3717 heapCb->vStart = memAddr;
3718 heapCb->vEnd = memAddr + size;
3719 heapCb->avlSize = size;
3720 heapCb->minSize = CMM_MINBUFSIZE;
3722 heapCb->next = (CmHEntry *)memAddr;
3723 heapCb->next->next = NULLP;
3724 /* cm_mem_c_001.main_12 - addition for header initialization */
3725 #ifdef SSI_DEBUG_LEVEL1
3726 heapCb->next->size = size - sizeof(CmHEntry);
3727 heapCb->next->requestedSize = 0;
3728 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3730 heapCb->next->trSignature[idx] = 0xAB;
3732 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3733 heapCb->staticHeapMemUsed = 0;
3734 heapCb->dynamicHeapMemUsed = 0;
3735 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3736 sizeof(heapCb->next->memFlags) +
3737 sizeof(heapCb->next->requestedSize);
3738 heapCb->numAllocAttempts = 0;
3739 heapCb->numDeallocAttempts = 0;
3740 heapCb->trampleCount = 0;
3742 heapCb->next->size = size;
3743 #endif /* SSI_DEBUG_LEVEL1 */
3745 #if (ERRCLASS & ERRCLS_DEBUG)
3746 heapCb->numFragBlk = 0;
3748 heapCb->numFailure = 0;
3751 heapCb->heapAllocCnt = 0;
3752 /* cm_mem_c_001.main_15 : Additions */
3753 #ifdef SS_HISTOGRAM_SUPPORT
3754 /* Initialise the memory histogram hash list */
3755 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3756 #endif /* SS_HISTOGRAM_SUPPORT */
3759 } /* end of cmMmHeapInit */
3767 * Desc: Allocates the memory block from the heap pool.
3770 * Ret: ROK - successful
3771 * RFAILED - unsuccessful.
3773 * Notes: This function is called by the cmAlloc. cmAlloc calls this
3774 * function when there is no memory block available in the bucket
3775 * and the heap pool is configured.
3782 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
3783 /* cm_mem_c_001.main_15 : Additions */
3784 #ifdef SS_HISTOGRAM_SUPPORT
3785 #ifdef SSI_DEBUG_LEVEL1
3786 static S16 cmHeapAlloc
3798 static S16 cmHeapAlloc
3808 #endif /* SSI_DEBUG_LEVEL1 */
3810 #ifdef SSI_DEBUG_LEVEL1
3811 static S16 cmHeapAlloc
3819 static S16 cmHeapAlloc
3825 #endif /* SSI_DEBUG_LEVEL1 */
3826 /* cm_mem_c_001.main_15 : Additions */
3827 #endif /* SS_HISTOGRAM_SUPPORT */
3829 CmHEntry *prvHBlk; /* Previous heap block */
3830 CmHEntry *curHBlk; /* Current heap block */
3832 /* cm_mem_c_001.main_15 : Additions */
3833 #ifdef SS_MEM_LEAK_STS
3835 #endif /* SS_MEM_LEAK_STS */
3836 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3837 #ifdef SSI_DEBUG_LEVEL1
3838 CmHEntry *alocHeapBlk;
3842 #endif /* SSI_DEBUG_LEVEL1 */
3843 /* cm_mem_c_001.main_15 : Additions */
3844 #ifdef SS_HISTOGRAM_SUPPORT
3846 #endif /* SS_HISTOGRAM_SUPPORT */
3848 /* cm_mem_c_001.main_15 : Additions */
3849 /* Acquire the heap lock */
3850 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3852 (Void) WTLock (&(heapCb->heapLock));
3854 (Void) SLock (&(heapCb->heapLock));
3857 #ifdef SS_MEM_LEAK_STS
3859 #endif /* SS_MEM_LEAK_STS */
3860 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
3861 #ifdef SSI_DEBUG_LEVEL1
3862 heapCb->numAllocAttempts++;
3863 requestedSize = *size;
3864 #endif /* SSI_DEBUG_LEVEL1 */
3866 /* Roundup the requested size */
3867 *size = CMM_DATALIGN(*size, (heapCb->minSize));
3869 /* Check if the available total size is adequate. */
3870 if ((*size) >= heapCb->avlSize)
3872 /* cm_mem_c_001.main_15 : Additions */
3874 (Void) WTUnlock (&(heapCb->heapLock));
3876 (Void) SUnlock (&(heapCb->heapLock));
3882 /* cm_mem_c_001.main_12 - addition for aligning the header size */
3883 #ifdef SSI_DEBUG_LEVEL1
3884 hdr = PTRALIGN(sizeof(CmHEntry));
3885 #endif /* SSI_DEBUG_LEVEL1 */
3888 * Search through the heap block list in the heap pool of size
3889 * greater than or equal to the requested size.
3892 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
3893 #ifdef SSI_DEBUG_LEVEL1
3894 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
3896 prvHBlk = (CmHEntry *)&(heapCb->next);
3897 #endif /* SSI_DEBUG_LEVEL1 */
3898 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
3899 prvHBlk = prvHBlk->next)
3902 * Since the size of the block is always multiple of CMM_MINBUFSIZE
3903 * and the requested size is rounded to the size multiple of
3904 * CMM_MINBUFSIZE, the difference between the size of the heap block
3905 * and the size to allocate will be either zero or multiple of
3908 if ((*size) <= curHBlk->size)
3910 /* cm_mem_c_001.main_12 - addition for block size calculation */
3911 #ifdef SSI_DEBUG_LEVEL1
3912 tmpSize = curHBlk->size - (*size);
3914 tmpSize = tmpSize - hdr;
3917 if ((tmpSize = (curHBlk->size - (*size))))
3918 #endif /* SSI_DEBUG_LEVEL1 */
3920 /* Heap block of bigger size */
3921 /* cm_mem_c_001.main_12 - addition for allocating memory */
3922 #ifdef SSI_DEBUG_LEVEL1
3923 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
3924 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
3926 * No need to look for memory trampling as this is a new block altogether
3927 * Update the header only for this case as it is new block formed
3929 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3931 alocHeapBlk->trSignature[idx] = 0xAB;
3933 alocHeapBlk->size = *size;
3935 *ptr = (Data *)curHBlk + tmpSize;
3936 #endif /* SSI_DEBUG_LEVEL1 */
3937 curHBlk->size = tmpSize;
3941 /* Heap block is same size of the requested size */
3942 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
3943 #ifdef SSI_DEBUG_LEVEL1
3944 /* look for memory trampling as this is a pure block*/
3947 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
3949 /* detected a trampled memory block in this bucket */
3951 /* display an error message here */
3952 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3954 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
3956 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
3958 SDisplay(0, dbgPrntBuf);
3961 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
3963 /* Release the lock */
3964 /* cm_mem_c_001.main_13: Replaced SUnlock with
3967 (Void) WTUnlock (&(heapCb->heapLock));
3969 (Void) SUnlock (&(heapCb->heapLock));
3971 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
3972 return (RTRAMPLINGNOK);
3976 /* Release the lock */
3977 /* cm_mem_c_001.main_13: Replaced SUnlock with
3980 (Void) WTUnlock (&(heapCb->heapLock));
3982 (Void) SUnlock (&(heapCb->heapLock));
3989 *ptr = (Data *)curHBlk + hdr;
3990 alocHeapBlk = curHBlk;
3991 *size = curHBlk->size;
3993 *ptr = (Data *)curHBlk;
3994 #endif /* SSI_DEBUG_LEVEL1 */
3995 prvHBlk->next = curHBlk->next;
3998 /* cm_mem_c_001.main_12 - addition for header updation */
3999 #ifdef SSI_DEBUG_LEVEL1
4000 /* update the header fields */
4001 alocHeapBlk->requestedSize = requestedSize;
4002 alocHeapBlk->memFlags = 0;
4003 if (memType == CMM_STATIC_MEM_FLAG)
4005 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4006 heapCb->staticHeapMemUsed += (*size + hdr);
4010 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4011 heapCb->dynamicHeapMemUsed += (*size + hdr);
4013 heapCb->avlSize -= ((*size) + hdr);
4015 heapCb->avlSize -= (*size);
4016 #endif /* SSI_DEBUG_LEVEL1 */
4022 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4023 *size, num_times, *ptr);
4024 SDisplay(0, prntBuf);
4028 /* cm_mem_c_001.main_15 : Additions */
4029 #ifdef SS_MEM_LEAK_STS
4030 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4031 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4032 #endif /* SS_MEM_LEAK_STS */
4033 /* Release the lock */
4034 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4036 (Void) WTUnlock (&(heapCb->heapLock));
4038 (Void) SUnlock (&(heapCb->heapLock));
4041 #ifdef SS_HISTOGRAM_SUPPORT
4042 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4043 * information into the hash list */
4046 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4048 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4053 #endif /* SS_HISTOGRAM_SUPPORT */
4059 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4065 /* Release the lock */
4066 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4068 (Void) WTUnlock (&(heapCb->heapLock));
4070 (Void) SUnlock (&(heapCb->heapLock));
4075 } /* end of cmHeapAlloc */
4082 * Desc: Return the memory block from the heap pool.
4085 * Ret: ROK - successful
4086 * RFAILED - unsuccessful.
4088 * Notes: This function returns the memory block to the heap pool. This
4089 * function is called by cmFree. The function does not check the
4090 * validity of the memory block. The caller must be sure that the
4091 * block was previously allocated and belongs to the heap pool. The
4092 * function maintain the sorting order of the memory block on the
4093 * starting address of the block. This function also do compaction
4094 * if the neighbouring blocks are already in the heap.
4101 /* cm_mem_c_001.main_15 : Additions */
4102 #ifdef SS_HISTOGRAM_SUPPORT
4103 static S16 cmHeapFree
4114 static S16 cmHeapFree
4120 /* cm_mem_c_001.main_15 : Additions */
4121 #endif /* SS_HISTOGRAM_SUPPORT */
4124 CmHEntry *curHBlk; /* Current heap block */
4125 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4126 #ifdef SSI_DEBUG_LEVEL1
4128 #endif /* SSI_DEBUG_LEVEL1 */
4129 /* cm_mem_c_001.main_15 : Additions */
4130 #ifdef SS_HISTOGRAM_SUPPORT
4131 Size allocSize = size;
4133 #endif /* SS_HISTOGRAM_SUPPORT */
4136 /* Roundup the requested size */
4137 size = CMM_DATALIGN(size, (heapCb->minSize));
4138 /* cm_mem_c_001.main_15: Additions */
4139 #ifdef SS_HISTOGRAM_SUPPORT
4141 #endif /* SS_HISTOGRAM_SUPPORT */
4143 /* Acquire the heap lock */
4144 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4146 (Void) WTLock (&(heapCb->heapLock));
4148 (Void) SLock (&(heapCb->heapLock));
4151 /* increase the avlSize */
4152 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4153 #ifdef SSI_DEBUG_LEVEL1
4154 hdr = PTRALIGN(sizeof(CmHEntry));
4155 heapCb->avlSize += (size + hdr);
4156 heapCb->numDeallocAttempts++;
4158 heapCb->avlSize += size;
4159 #endif /* SSI_DEBUG_LEVEL1 */
4161 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4162 #ifdef SSI_DEBUG_LEVEL1
4163 p = (CmHEntry *)(ptr - hdr);
4165 p = (CmHEntry *)ptr;
4166 /* cm_mem_c_001.main_15 : Additions */
4167 #ifdef SS_MEM_LEAK_STS
4168 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4169 cmRlsAllocBlk((PTR)ptr);
4170 #endif /* SS_MEM_LEAK_STS */
4171 #endif /* SSI_DEBUG_LEVEL1 */
4174 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4175 #ifdef SSI_DEBUG_LEVEL1
4176 /* look for memory trampling */
4177 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4179 /* detected a trampled memory block in heap */
4181 /* display an error message here */
4182 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4184 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4186 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4188 SDisplay(0, dbgPrntBuf);
4191 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4193 /* Release the lock */
4194 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4196 (Void) WTUnlock (&(heapCb->heapLock));
4198 (Void) SUnlock (&(heapCb->heapLock));
4200 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4201 return (RTRAMPLINGNOK);
4205 /* do not add to the free heap */
4206 heapCb->avlSize -= (size + hdr);
4207 /* Release the heap lock */
4208 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4210 (Void) WTUnlock (&(heapCb->heapLock));
4212 (Void) SUnlock (&(heapCb->heapLock));
4219 /* look for any double free */
4220 if (CMM_IS_FREE(p->memFlags))
4223 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4225 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4227 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4229 SDisplay(0, dbgPrntBuf);
4232 heapCb->avlSize -= (size + hdr);
4233 /* cm_mem_c_001.main_15 : Additions */
4235 (Void) WTUnlock (&(heapCb->heapLock));
4237 (Void) SUnlock (&(heapCb->heapLock));
4242 #endif /* SSI_DEBUG_LEVEL1 */
4244 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4247 * The block will be inserted to maintain the sorted order on the
4248 * starting address of the block.
4252 if (!(curHBlk->next) ||
4253 (p < (curHBlk->next)))
4255 /* Heap block should be inserted here */
4258 * Check if the block to be returned can be merged with the
4261 /* cm_mem_c_001.main_12 - addition for header consideration */
4262 #ifdef SSI_DEBUG_LEVEL1
4263 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4265 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4266 #endif /* SSI_DEBUG_LEVEL1 */
4268 /* Merge the block */
4269 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4270 #ifdef SSI_DEBUG_LEVEL1
4271 /* update the flags */
4272 if (CMM_IS_STATIC(p->memFlags))
4273 heapCb->staticHeapMemUsed -= (size + hdr);
4274 else if (CMM_IS_DYNAMIC(p->memFlags))
4275 heapCb->dynamicHeapMemUsed -= (size + hdr);
4276 size = (curHBlk->size += (size + hdr));
4278 size = (curHBlk->size += size);
4279 #endif /*SSI_DEBUG_LEVEL1*/
4284 /* cm_mem_c_001.main_12 - addition for double-free check */
4285 #ifdef SSI_DEBUG_LEVEL1
4286 /* Check for double deallocation in heap */
4287 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4289 /* Release the lock */
4290 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4292 (Void) WTUnlock (&(heapCb->heapLock));
4294 (Void) SUnlock (&(heapCb->heapLock));
4297 /* This block is already freed in the heap */
4300 /* update the flags as it is a new node */
4301 if (CMM_IS_STATIC(p->memFlags))
4303 heapCb->staticHeapMemUsed -= (size + hdr);
4304 CMM_RESET_STATIC_FLAG(p->memFlags);
4306 else if (CMM_IS_DYNAMIC(p->memFlags))
4308 heapCb->dynamicHeapMemUsed -= (size + hdr);
4309 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4311 CMM_SET_FREE_FLAG(p->memFlags);
4312 p->requestedSize = 0;
4313 #endif /*SSI_DEBUG_LEVEL1*/
4314 /* insert the block */
4315 p->next = curHBlk->next;
4320 /* Try to merge with the next block in the chain */
4321 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4322 #ifdef SSI_DEBUG_LEVEL1
4323 if (((Data *)p + hdr + size) == (Data *)(p->next))
4325 if (((Data *)p + size) == (Data *)(p->next))
4326 #endif /*SSI_DEBUG_LEVEL1*/
4328 /* p->next can not be NULL */
4329 /* cm_mem_c_001.main_12 - addition for header consideration */
4330 #ifdef SSI_DEBUG_LEVEL1
4331 p->size += (p->next->size + hdr);
4333 p->size += p->next->size;
4334 #endif /*SSI_DEBUG_LEVEL1*/
4335 p->next = p->next->next;
4338 /* Release the lock */
4339 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4341 (Void) WTUnlock (&(heapCb->heapLock));
4343 (Void) SUnlock (&(heapCb->heapLock));
4345 /* cm_mem_c_001.main_15 : Additions */
4346 #ifdef SS_HISTOGRAM_SUPPORT
4347 /* If If Tapa task (entId)is registerd for histogram then insert
4348 Memrory Freed information into the hash list */
4351 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4352 fileName, entId) != ROK)
4354 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4358 #endif /* SS_HISTOGRAM_SUPPORT */
4362 else if (p < curHBlk)
4365 * Check if the block to be returned can be merged with the
4368 /* cm_mem_c_001.main_12 - addition for header consideration */
4369 #ifdef SSI_DEBUG_LEVEL1
4370 if (((Data *)p + hdr + size) == (Data *)curHBlk)
4372 if (((Data *)p + size) == (Data *)curHBlk)
4373 #endif /* SSI_DEBUG_LEVEL1 */
4375 /* Merge the block */
4376 /* cm_mem_c_001.main_12 - addition for header consideration */
4377 #ifdef SSI_DEBUG_LEVEL1
4378 p->size = size + (curHBlk->size + hdr);
4380 p->size = size + curHBlk->size;
4381 #endif /* SSI_DEBUG_LEVEL1 */
4382 p->next = curHBlk->next;
4386 /* insert the block */
4390 /* cm_mem_c_001.main_12 - addition for header updation */
4391 #ifdef SSI_DEBUG_LEVEL1
4392 /* update the flags in both cases as they are new start nodes*/
4393 if (CMM_IS_STATIC(p->memFlags))
4395 heapCb->staticHeapMemUsed -= (size + hdr);
4396 CMM_RESET_STATIC_FLAG(p->memFlags);
4398 else if (CMM_IS_DYNAMIC(p->memFlags))
4400 heapCb->dynamicHeapMemUsed -= (size + hdr);
4401 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4403 CMM_SET_FREE_FLAG(p->memFlags);
4404 p->requestedSize = 0;
4405 #endif /* SSI_DEBUG_LEVEL1 */
4409 /* Release the lock */
4410 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4412 (Void) WTUnlock (&(heapCb->heapLock));
4414 (Void) SUnlock (&(heapCb->heapLock));
4416 /* cm_mem_c_001.main_15 : Additions */
4417 #ifdef SS_HISTOGRAM_SUPPORT
4418 /* If If Tapa task (entId)is registerd for histogram then insert
4419 Memrory Freed information into the hash list */
4422 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4423 fileName, entId) != ROK)
4425 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4429 #endif /* SS_HISTOGRAM_SUPPORT */
4435 if (heapCb->next == NULLP)
4437 /* Heap block is empty. Insert the block in the head. */
4442 /* cm_mem_c_001.main_12 - addition for header updation */
4443 #ifdef SSI_DEBUG_LEVEL1
4444 if (CMM_IS_STATIC(p->memFlags))
4446 heapCb->staticHeapMemUsed -= (size + hdr);
4447 CMM_RESET_STATIC_FLAG(p->memFlags);
4449 else if (CMM_IS_DYNAMIC(p->memFlags))
4451 heapCb->dynamicHeapMemUsed -= (size + hdr);
4452 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4454 CMM_SET_FREE_FLAG(p->memFlags);
4455 p->requestedSize = 0;
4456 #endif /* SSI_DEBUG_LEVEL1 */
4458 /* Release the heap lock */
4459 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4461 (Void) WTUnlock (&(heapCb->heapLock));
4463 (Void) SUnlock (&(heapCb->heapLock));
4465 /* cm_mem_c_001.main_15 : Additions */
4466 #ifdef SS_HISTOGRAM_SUPPORT
4467 /* If If Tapa task (entId)is registerd for histogram then insert
4468 Memrory Freed information into the hash list */
4471 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4472 fileName, entId) != ROK)
4474 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4478 #endif /* SS_HISTOGRAM_SUPPORT */
4482 /* Release the lock */
4483 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4485 (Void) WTUnlock (&(heapCb->heapLock));
4487 (Void) SUnlock (&(heapCb->heapLock));
4491 } /* end of cmHeapFree */
4492 /* cm_mem_c_001.main_15 : Additions */
4494 #ifdef SS_MEM_LEAK_STS
4497 * Fun: cmInitMemLeakMdl
4499 * Desc: Initializes the memory leak detection module
4504 * Notes: This function initializes the memory leak detection module.
4510 Void cmInitMemLeakMdl(Void)
4516 memLkCb.memLkMdlInit = FALSE;
4517 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4519 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4521 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4522 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4523 500, 0, FALSE, CM_HASH_KEYTYPE_UINT32_MOD, 0, 0);
4524 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4527 if(memLkCb.fileLkLog == NULLP)
4529 memLkCb.fileLkLog = (FILE *) stdout;
4531 memLkCb.memLkMdlInit = TRUE;
4534 } /* cmInitMemLeakMdl */
4535 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4538 * Fun: cmDeinitMemLeakMdl
4540 * Desc: De-initializes the memory leak detection module
4545 * Notes: This function de-initializes the memory leak detection module.
4551 Void cmDeinitMemLeakMdl (Void)
4557 memLkCb.memLkMdlInit = FALSE;
4558 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4560 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4562 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4563 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4564 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4571 * Fun: cmMemOpenMemLkFile
4573 * Desc: Initializes the memory leak detection module
4578 * Notes: This function initializes the memory leak detection module.
4584 Void cmMemOpenMemLkFile(S8 *arg)
4586 memLkCb.fileLkLog = NULLP;
4587 memLkCb.fileLkLog = fopen(arg, "w");
4595 * Desc: Initializes the memory leak detection module
4600 * Notes: This function initializes the memory leak detection module.
4606 Void SLogLkInfo (Void)
4609 MemAllocInfo *oldMemInfo;
4610 MemAllocInfo *newMemInfo;
4616 if( memLkCb.memLkMdlInit == FALSE)
4620 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4621 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4623 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4625 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4627 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4633 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4634 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4635 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4637 sprintf(prntBuf, "[LBIS]\n");
4638 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4639 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4641 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4643 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
4645 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4646 sprintf(prntBuf, "Module Name: %s\n",
4647 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
4648 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4649 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
4650 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4651 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
4652 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4653 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
4654 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4655 sprintf(prntBuf,"Memory Allocation Path:\n");
4656 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4657 funcNm = (S8 **)newMemInfo->backTrace;
4658 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
4660 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
4661 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4663 sprintf(prntBuf, "[LBIE]\n\n");
4664 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4665 fflush(memLkCb.fileLkLog);
4666 oldMemInfo = newMemInfo;
4669 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4672 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
4673 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4681 * Desc: Initializes the memory leak detection module
4686 * Notes: This function initializes the memory leak detection module.
4692 Void SFlushLkInfo (Void)
4694 MemAllocInfo *newMemInfo;
4698 #ifdef SS_MEM_LEAK_SOL
4700 #endif /* SS_MEM_LEAK_SOL */
4702 if( memLkCb.memLkMdlInit == FALSE)
4707 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4709 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4711 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4716 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4717 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4718 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
4720 funcNm = (S8 **)newMemInfo->backTrace;
4721 #ifdef SS_MEM_LEAK_SOL
4722 for(i = 0; i < newMemInfo->bTrcSz; i++)
4724 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4725 #ifdef SS_4GMX_LCORE
4726 MxHeapFree(SsiHeap, funcNm[i]);
4730 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4732 #endif /* SS_MEM_LEAK_SOl */
4733 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4734 #ifdef SS_4GMX_LCORE
4735 MxHeapFree(SsiHeap, funcNm);
4736 MxHeapFree(SsiHeap, newMemInfo);
4742 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4750 * Fun: cmStorAllocBlk
4752 * Desc: Initializes the memory leak detection module
4757 * Notes: This function initializes the memory leak detection module.
4771 #ifndef SS_MEM_LEAK_SOL
4772 Ptr trace[CM_MAX_STACK_TRACE];
4773 #endif /* SS_MEM_LEAK_SOL */
4776 MemAllocInfo *allocInfo;
4779 if( memLkCb.memLkMdlInit == FALSE)
4784 #ifdef SS_MEM_LEAK_SOL
4785 /* I need to do this for solaris, because it does not implement
4786 * backtrace. Here backtrace is my function. See below for the
4787 * implementation. */
4788 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4789 #ifdef SS_4GMX_LCORE
4790 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4791 memset(funcNm, 0, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4793 funcNm = (S8 **)calloc(1, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4795 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4796 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
4797 #else /* SS_MEM_LEAK_SOL */
4798 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4799 funcNm = backtrace_symbols(trace, traceSize);
4800 #endif /* SS_MEM_LEAK_SOL */
4802 moduleId = cmMemGetModuleId(funcNm, traceSize);
4804 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4805 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4806 #ifdef SS_4GMX_LCORE
4807 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
4808 memset(allocInfo, 0, sizeof(MemAllocInfo));
4810 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
4812 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
4813 allocInfo->memAddr = addr;
4814 allocInfo->reqSz = reqSz;
4815 allocInfo->allocSz = allocSz;
4816 allocInfo->bktIdx = bktIdx;
4817 allocInfo->backTrace = (PTR) funcNm;
4818 allocInfo->moduleId = moduleId;
4819 allocInfo->bTrcSz = traceSize;
4821 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
4822 (PTR)allocInfo, (uint8_t *)&(allocInfo->memAddr),
4823 sizeof(allocInfo->memAddr));
4824 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
4826 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4828 } /* cmStorAllocBlk */
4832 * Fun: cmMemGetModuleId
4834 * Desc: Initializes the memory leak detection module
4839 * Notes: This function initializes the memory leak detection module.
4845 uint8_t cmMemGetModuleId
4858 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
4860 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
4861 for(idx = 0; idx < traceSize; idx++)
4865 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
4867 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
4872 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4874 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4875 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
4876 memUsrMdlStr[mdlFunStrIdx].fPStr,
4880 return (mdlFunStrIdx);
4885 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4887 retVal = strcmp((const S8 *)"DEFAULT",
4888 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4891 return (mdlFunStrIdx);
4898 } /* cmMemGetModuleId */
4902 * Fun: cmMemGetStrMtchIdx
4904 * Desc: Initializes the memory leak detection module
4909 * Notes: This function initializes the memory leak detection module.
4915 S16 cmMemGetStrMtchIdx
4931 len = strlen((const S8 *)str);
4933 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
4934 cmpStr[len + 1] = '\0';
4937 for(;strtIdx < endIdx && !found; strtIdx++)
4940 tempLen = strlen((const S8 *)strLst[strtIdx]);
4944 while(*(strLst[strtIdx] + idx + len) != '\0')
4946 retVal = strncmp((const S8 *)cmpStr,
4947 ((const S8 *)strLst[strtIdx] + idx), len);
4963 } /* cmMemGetStrMtchIdx */
4967 * Fun: cmRlsAllocBlk
4969 * Desc: Initializes the memory leak detection module
4974 * Notes: This function initializes the memory leak detection module.
4985 Ptr trace[CM_MAX_STACK_TRACE];
4991 MemAllocInfo *memAllocInfo;
4993 if( memLkCb.memLkMdlInit == FALSE)
4999 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5001 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5002 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5003 (uint8_t *)&addr, sizeof(uint32_t), 0,
5004 (PTR *)&memAllocInfo);
5007 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5009 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5010 funcNm = (S8 **) memAllocInfo->backTrace;
5011 #ifdef SS_MEM_LEAK_SOL
5012 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5014 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5015 #ifdef SS_4GMX_LCORE
5016 MxHeapFree(SsiHeap, funcNm[i]);
5021 #endif /* SS_MEM_LEAK_SOL */
5022 #ifdef SS_MEM_LEAK_FREE_TRACE
5026 sprintf( prntBuf, "\n==============================\n");
5028 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5030 sprintf( prntBuf, "Address: [%x]\n", addr);
5032 sprintf( prntBuf, "Address: [%lx]\n", addr);
5035 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5036 funcNm = backtrace_symbols(trace, traceSize);
5037 sprintf( prntBuf, "[bt] Execution path:\n");
5039 for (i=0; i < traceSize; ++i)
5041 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5044 sprintf( prntBuf, "\n==============================\n");
5047 #endif /* SS_MEM_LEAK_FREE_TRACE */
5048 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5049 #ifdef SS_4GMX_LCORE
5050 MxHeapFree(SsiHeap, funcNm);
5051 MxHeapFree(SsiHeap, memAllocInfo);
5058 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5061 #ifndef SS_MEM_LEAK_SOL
5062 if(idx == CM_MEM_USR_MDL)
5065 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5067 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5069 sprintf( prntBuf, "Address: [%u]\n", addr);
5071 sprintf( prntBuf, "Address: [%lu]\n", addr);
5074 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5075 funcNm = backtrace_symbols(trace, traceSize);
5076 sprintf( prntBuf,"[bt] Execution path:\n");
5078 for (i=0; i < traceSize; ++i)
5080 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5083 printf("\n==============================\n");
5084 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5085 #ifdef SS_4GMX_LCORE
5086 MxHeapFree(SsiHeap, funcNm);
5091 #endif /* SS_MEM_LEAK_SOL */
5093 /*cm_mem_c_001.main_25 : */
5095 } /* cmRlsAllocBlk */
5098 #ifdef SS_MEM_LEAK_SOL
5101 * Fun: cmAddrToSymStr
5103 * Desc: Initializes the memory leak detection module
5108 * Notes: This function initializes the memory leak detection module.
5126 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5128 return (snprintf(buffer, size, "[0x%p]", pc));
5131 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5132 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5134 return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5137 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5141 return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5143 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5146 } /* cmAddrToSymStr */
5150 * Fun: cmLeakCallBack
5152 * Desc: Initializes the memory leak detection module
5157 * Notes: This function initializes the memory leak detection module.
5172 Backtrace_t *bt = (Backtrace_t *)arg;
5173 if (bt->bt_actcount >= bt->bt_maxcount)
5175 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5176 #ifdef SS_4GMX_LCORE
5177 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
5178 memset(buffer, 0, 510);
5180 buffer = (S8 *)calloc(1, 510);
5182 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
5183 (void) cmAddrToSymStr((void *)pc, buffer, 505);
5184 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5187 } /* cmLeakCallBack */
5193 * Desc: Initializes the memory leak detection module
5198 * Notes: This function initializes the memory leak detection module.
5214 bt.bt_buffer = buffer;
5215 bt.bt_maxcount = count;
5218 if (getcontext(&u) < 0)
5220 (Void) walkcontext(&u, cmLeakCallBack, &bt);
5221 return (bt.bt_actcount);
5225 #endif /* SS_MEM_LEAK_SOL */
5227 #endif /* SS_MEM_LEAK_STS */
5228 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5229 * These include sanity check functions for bucket and heap,
5230 * for printing several memory related statistics
5232 #ifdef SSI_DEBUG_LEVEL1
5235 * Fun: cmMmBktSanityChk
5237 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
5238 * This API gets called when trampling is detected in a memory block.
5240 * Ret: RTRAMPLINGNOK - Trampling, serious error
5241 * RTRAMPLINGOK - Trampling, but OK to proceed
5243 * Notes: This function performs the memory block sanity in a bucket. This
5244 * function is called by cmAlloc and cmFree as part of error handling mechanism.
5245 * Performs sanity check for the whole bucket by traversing each
5246 * of the memory blocks using the pointer bktStartPtr.
5247 * Keeps track of number of tramplings happened. If the count
5248 * exceeds the threshold decided, then invalidates this bucket.
5253 static S16 cmMmBktSanityChk(CmMmBkt *bkt)
5259 bkt->trampleCount = 0;
5261 /* scan the entire memory list of the bucket */
5262 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5263 blkCnt < (bkt->numBlks); blkCnt++)
5265 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5267 bkt->trampleCount++;
5268 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5270 /* Take action to invalidate the entire bucket */
5271 return (RTRAMPLINGNOK);
5274 /* reach next memory block in this bucket manually */
5275 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5279 /* display an error message here */
5280 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5281 SDisplay(0, dbgPrntBuf);
5284 return (RTRAMPLINGOK);
5289 * Fun: cmMmHeapSanityChk
5291 * Desc: Performs the sanity check for the memory blocks in the memory heap.
5292 * This API gets called when trampling is detected in heap(Alloc/Free).
5294 * Ret: RTRAMPLINGNOK - Trampling, serious error
5295 * RTRAMPLINGOK - Trampling, but OK to proceed
5297 * Notes: This function performs the memory block sanity in the heap. This
5298 * function is called by cmHeapAlloc and cmHeapFree as part of error
5299 * handling mechanism. Keeps track of number of tramplings happened.
5300 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5301 * count is less than threshold, then return RTRAMPLINGOK.
5306 static S16 cmMmHeapSanityChk(CmMmHeapCb *heapCb)
5309 /* increment the trample count */
5310 heapCb->trampleCount++;
5312 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5314 return (RTRAMPLINGNOK);
5317 return (RTRAMPLINGOK);
5322 * Fun: cmMmRegIsBlkSane
5324 * Desc: Performs the sanity check for the memory block by checking its header.
5326 * Ret: ROK - If no trampling is detected in the block
5327 * RFAILED - If trampling is detected in the block
5329 * Notes: This function performs the memory block sanity in a block.
5334 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr)
5339 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5341 if (blkPtr->trSignature[sigCnt] != 0xAB)
5354 * Desc: Computes the hash list index (bin number) for a specified
5355 * key of type (x % 101).
5357 * return (idx % hash_table_size);
5359 * Ret: ROK - successful, *idx contains computed index
5366 static S16 cmMmHashFunc
5368 CmMmHashListCp *hashListCp,
5374 *idx = (uint16_t)(key % hashListCp->numOfbins);
5378 } /* end of cmMmHashFunc () */
5382 * Fun: cmMmHashListInit
5384 * Desc: Initializes a hash list. Parameters are:
5386 * hashListCp control point for hash list
5387 * nmbBins number of bins in the hash list. Storage will
5388 * be allocated for them from the indicated memory
5391 * pool for allocating storage for bins.
5393 * Ret: ROK - initialization successful
5394 * RFAILED - initialization failed, lack of memory
5401 static S16 cmMmHashListInit
5403 CmMmHashListCp *hashListCp, /* hash list to initialize */
5404 uint16_t nmbBins, /* number of hash list bins */
5405 Region region, /* memory region to allocate bins */
5406 Pool pool /* memory pool to allocate bins */
5410 CmMmHashListEnt *hl;
5413 /* initialize control point fields */
5414 hashListCp->hashList = NULLP;
5415 hashListCp->numOfbins = 0;
5416 hashListCp->numOfEntries = 0;
5418 /* allocate memory for bins */
5421 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
5422 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5425 /* initialize bin pointers */
5426 hl = hashListCp->hashList;
5427 for(i = 0; i < nmbBins; i++)
5429 hl[i].size = hl[i].numAttempts = 0;
5432 /* initialize bin size */
5433 hashListCp->numOfbins = nmbBins;
5441 * Fun: cmMmHashListDeinit
5443 * Desc: Deinitializes a hash list. Deallocates memory for bins
5444 * and resets header fields. Parameters are:
5446 * hashListCp control point for hash list
5448 * pool for allocating storage for bins.
5450 * Ret: ROK - successful
5451 * RFAILED - failure, invalid parameters
5458 static S16 cmMmHashListDeinit
5460 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
5461 Region region, /* memory region to allocate bins */
5462 Pool pool /* memory pool to allocate bins */
5466 /* deallocate memory for bins */
5467 if (hashListCp->numOfbins)
5468 (Void) SPutSBuf(region, pool,
5469 (Data *) hashListCp->hashList,
5470 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5472 /* deinitialize control point fields */
5473 hashListCp->hashList = NULLP;
5474 hashListCp->numOfbins = 0;
5475 hashListCp->numOfEntries = 0;
5478 } /* end of cmMmHashListDeinit */
5482 * Fun: cmMmHashListInsert
5484 * Desc: Inserts a new entry in the hash list. Parameters are:
5486 * hashListCp control point for hash list
5487 * key pointer to key string in the new entry
5489 * Ret: ROK - insertion successful
5490 * RFAILED - insertion failed (incorrect parameter values)
5497 static S16 cmMmHashListInsert
5499 CmMmHashListCp *hashListCp, /* hash list to add to */
5500 uint32_t key /* pointer to key */
5503 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
5504 uint16_t idx; /* index for insertion into hash list */
5508 /* check if hashListCp is initialised yet */
5509 if ( hashListCp->numOfbins == 0)
5512 /* compute index for insertion */
5513 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5516 hashListEnt = hashListCp->hashList;
5518 if (hashListEnt[idx].numAttempts == 0)
5520 /* new entry, insert here */
5521 hashListEnt[idx].size = key;
5522 hashListEnt[idx].numAttempts++;
5523 /* increment count of entries in hash list */
5524 hashListCp->numOfEntries++;
5528 /* this hash is occupied, re-hash it using linear probing */
5529 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5531 if (hashListEnt[i].size == key)
5533 hashListEnt[i].numAttempts++;
5537 if (hashListEnt[i].numAttempts == 0)
5539 hashListEnt[i].size = key;
5540 hashListEnt[i].numAttempts++;
5541 /* increment count of entries in hash list */
5542 hashListCp->numOfEntries++;
5547 if (i == CMM_STAT_HASH_TBL_LEN)
5549 /* there is no free slot for this key */
5555 } /* end of cmMmHashListInsert */
5557 #endif /* SSI_DEBUG_LEVEL1 */
5558 /* cm_mem_c_001.main_15 : Additions */
5559 #ifdef SS_HISTOGRAM_SUPPORT
5562 * Fun: cmHstGrmHashListInit
5564 * Desc: Initializes a hash list. Parameters are:
5566 * hashListCp control point for hash list
5567 * Ret: ROK - initialization successful
5568 * RFAILED - initialization failed, lack of memory
5575 static S16 cmHstGrmHashListInit
5577 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5580 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5582 /* display an error message here */
5583 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5585 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5587 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5589 SDisplay(0, dbgPrntBuf);
5591 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5597 * Fun: cmHstGrmHashListDeInit
5599 * Desc: De-initializes a hash list. Parameters are:
5601 * hashListCp control point for hash list
5602 * Ret: ROK - initialization successful
5603 * RFAILED - initialization failed, lack of memory
5610 static S16 cmHstGrmHashListDeInit
5612 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5615 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5617 /* display an error message here */
5618 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5620 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5622 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5624 SDisplay(0, dbgPrntBuf);
5626 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5632 * Fun: cmHstGrmFreeInsert
5634 * Desc: Inserts a Freed information in into the hash list. Parameters are:
5636 * bkt : pointer to bucket for which memory is freed.
5637 * line : Line where memory is freed.
5638 * file : file where memory is freed.
5639 * entId : Tapa task which releases the memory.
5641 * Ret: ROK - insertion successful
5642 * RFAILED - insertion failed (incorrect parameter values)
5649 static S16 cmHstGrmFreeInsert
5651 CmHstGrmHashListCp* hashListCp, /* hash list cp */
5652 uint32_t blkSz, /* size of the block freed */
5653 uint32_t line, /* Line number */
5654 uint8_t *fileName, /* file name */
5655 uint8_t entId /* Tapa task which free the memory */
5658 uint32_t binIdx = 0; /* Bin index to insert the entry into the hash list */
5659 uint32_t key = 0; /* Key to fine the bin index */
5660 uint32_t ret = 0; /* Return value */
5661 CmMemEntries *entry = NULLP; /* Entry which contains the information */
5665 /* check for the total number of entries in the hash list. *
5666 * If there is no place for new entry return failure */
5667 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5669 /* After comuting the hash bind and key, check the entity already *
5670 existing or not. if we found the entry then update the information */
5671 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5674 entry->freedBytes += blkSz;
5675 entry->bucketFreeReq++;
5679 /* If hash list is full then print the error tna continue */
5680 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5682 printf("No place in the hash list. Increase the value of macro CMM_HIST_MAX_MEM_BIN and CMM_HIST_MAX_MEM_ENTRY_PER_BIN \n");
5686 /* Take the address of next free entry in the hash bin */
5687 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5689 /* Increase the number of time frees called */
5690 entry->bucketFreeReq++;
5691 entry->freedBytes += blkSz;
5693 /* Fill the information into the entry structure */
5694 cmHstGrmFillEntry(entry, key, line, fileName, entId);
5695 /* Increase the total numbet of entries in the bin */
5696 hashListCp->hashList[binIdx].numOfEntries++;
5698 /* Increase the total number of entries in the hash list */
5699 hashListCp->totalNumEntries++;
5702 } /* end of cmHstGrmFreeInsert */
5707 * Fun: ret = cmHstGrmAllocInsert
5709 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
5711 * hashListCp control point for hash list
5712 * key pointer to key string in the new entry
5714 * Ret: ROK - insertion successful
5715 * RFAILED - insertion failed (incorrect parameter values)
5722 static S16 cmHstGrmAllocInsert
5724 CmHstGrmHashListCp *hashListCp,
5732 uint32_t binIdx = 0;
5735 CmMemEntries *entry = NULLP;
5738 /* check for the total number of entries in the hash list. *
5739 * If there is no place for new entry return failure */
5740 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5742 /* After comuting the hash bind and key, check the entity already *
5743 existing or not. if we found the entry then update the information */
5744 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5748 entry->allocBytes += blkSz;
5749 entry->bucketAllocReq++;
5750 entry->wastedBytes += (blkSz - *reqSz);
5754 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5756 printf("No place in the hash list. Increase the value of macro CMM_HIST_MAX_MEM_BIN and CMM_HIST_MAX_MEM_ENTRY_PER_BIN\n");
5760 /* Take the address of next free entry in the hash bin */
5761 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5763 /* Clauculae the wasted bytes */
5764 /* Here wasted byte is differnce between the byte user
5765 * has requested and the byte the ssi allocated */
5766 entry->wastedBytes += (blkSz - *reqSz);
5767 entry->bucketAllocReq++;
5768 entry->allocBytes += blkSz;
5770 /* Fill the information into the entry structure */
5771 cmHstGrmFillEntry(entry, key, line, fileName, entId);
5772 /* Increase the total numbet of entries in the bin */
5773 hashListCp->hashList[binIdx].numOfEntries++;
5775 /* Increase the total number of entries in the hash list */
5776 hashListCp->totalNumEntries++;
5779 } /* end of cmHstGrmAllocInsert */
5784 * Fun: cmHstGrmGetHashIdxAndKey
5786 * Desc: Finds an entry in the hash list. Parameters are:
5788 * hashListCp control point for hash list
5789 * key pointer to key string in the new entry
5791 * Ret: ROK - insertion successful
5792 * RFAILED - insertion failed (incorrect parameter values)
5799 static S16 cmHstGrmGetHashIdxAndKey
5810 /* Calculate the key using file name and line number */
5811 for(i = 0 ; fileName[i] != '\0'; i++)
5813 *key += fileName[i];
5816 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
5818 } /* end of cmHstGrmFillEntry */
5822 * Fun: cmHstGrmFillEntry
5824 * Desc: Insert the entry into the hash list.
5826 * entry : Infornation which will be inserted into the hash list
5827 * key : Which will be used ti find the entry.
5828 * line : Line number
5829 * fileName : File name
5830 * entId : Tapa task Id
5832 * Ret: ROK - insertion successful
5833 * RFAILED - insertion failed (incorrect parameter values)
5840 static S16 cmHstGrmFillEntry
5842 CmMemEntries *entry,
5853 entry->entId = entId;
5854 for(idx = 0; fileName[idx] != '\0'; idx++)
5856 entry->fileName[idx] = fileName[idx];
5858 entry->fileName[idx] = '\0';
5860 } /* end of cmHstGrmFillEntry */
5864 * Fun: cmHstGrmFindEntry
5866 * Desc: Finds an entry in the hash list. Parameters are:
5868 * hashListCp control point for hash list
5869 * key pointer to key string in the new entry
5871 * Ret: ROK - insertion successful
5872 * RFAILED - insertion failed (incorrect parameter values)
5879 static S16 cmHstGrmFindEntry
5881 CmHstGrmHashListCp *hashListCp,
5884 CmMemEntries **entry
5888 uint32_t numEnt = 0;
5889 uint32_t numBin = 0;
5890 CmHstGrmHashListEnt *tmpBin = NULLP;
5893 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
5895 /* find for the entry in the bin */
5896 tmpBin = &(hashListCp->hashList[*binIdx]);
5897 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
5899 /* If key supplied is matched with the stored key then
5900 * return that entity */
5901 if(tmpBin->entries[numEnt].key == key)
5903 *entry = &(tmpBin->entries[numEnt]);
5905 }/* End of if (tmpBin->entries[numEnt].key) */
5906 }/* end of for (numEnt = 0) */
5908 /* Here we are checking for any room left in the bin. If the room *
5909 exists its mean that there is no entry with the Key. so return *
5911 If there is no room in the bin, then check the other bins to find *
5913 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
5915 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
5918 }/* End of if (binIdx) */
5922 }/* End of else (binIdx) */
5923 } /* End of if (numEnt) */
5926 printf ("Unable to find the entry in hash list\n");
5928 }/* End of else (numEnt) */
5929 }/* end of for (numBin = 0) */
5931 printf("Unable to find the entry in the hash list\n");
5933 } /* end of cmHstGrmFindEntry */
5935 #endif /* SS_HISTOGRAM_SUPPORT */
5936 #ifdef T2K_MEM_LEAK_DBG
5937 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
5938 uint32_t getT2kMemLeakIndex(uint32_t address)
5940 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
5943 static uint32_t t2kMemAllocTick;
5944 static uint32_t smallTick;
5946 void InsertToT2kMemLeakInfo(uint32_t address, uint32_t size, uint32_t lineNo, char* fileName)
5948 uint32_t idx = getT2kMemLeakIndex(address);
5950 if(((uint32_t)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
5952 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
5953 "line is %ld \n", address, size, fileName, lineNo);
5956 if(gMemLeakInfo[idx].address == 0)
5958 gMemLeakInfo[idx].address = address;
5959 gMemLeakInfo[idx].size = size;
5960 gMemLeakInfo[idx].lineNo = lineNo;
5961 gMemLeakInfo[idx].fileName = fileName;
5962 gMemLeakInfo[idx].age = t2kMemAllocTick;
5963 gMemLeakInfo[idx].prevRemLineNo = 0;
5964 gMemLeakInfo[idx].prevRemFileName = '\0';
5966 if(smallTick++ == 4096)
5969 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
5974 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
5975 "line is %ld \n",address, idx, fileName, lineNo);
5976 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
5977 "Age:%ld, differnce in Age:%ld",
5978 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
5979 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
5980 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
5985 void RemoveFromT2kMemLeakInfo(uint32_t address, char *file, uint32_t line)
5987 uint32_t idx = getT2kMemLeakIndex(address);
5989 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
5991 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
5997 if(gMemLeakInfo[idx].address == address)
5999 gMemLeakInfo[idx].address = 0;
6000 gMemLeakInfo[idx].age = 0;
6001 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6002 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
6004 gMemLeakInfo[idx].lastDelLineNum = line;
6005 gMemLeakInfo[idx].lastDelFileName = file;
6006 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6010 printf("Something is wrong, trying to remove %lx idx = %ld from"
6011 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
6012 gMemLeakInfo[idx].address);
6015 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6016 gMemLeakInfo[idx].lastDelLineNum);
6018 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6020 printf("Previous File:%s, Previous Line:%ld\n",
6021 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6026 void DumpT2kMemLeakInfoToFile()
6030 FILE *fp = fopen("memLeakInfo.txt","wb");
6034 printf("Could not open file for dumping mem leak info\n");
6038 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6040 if(gMemLeakInfo[i].address != 0)
6042 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6043 if(onlyFileName == NULL)
6045 onlyFileName = gMemLeakInfo[i].fileName;
6048 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
6049 gMemLeakInfo[i].size,
6050 gMemLeakInfo[i].age,
6051 gMemLeakInfo[i].lineNo,
6056 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6062 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6064 /* For Updating SOC Specific Memory Information */
6065 S16 UpdateSocMemInfo
6074 void *iccHdl = NULLP;
6075 uint32_t poolFreeCnt[4];
6076 uint32_t poolUsedCnt[4];
6077 uint32_t poolSize[4];
6078 uint32_t poolTotAvail[4];
6080 idxReg = mInfo->numRegions;
6081 mInfo->numRegions = mInfo->numRegions + 1;
6082 /* Calling Soc specific API to get shared memory status */
6083 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6084 iccHdl = ssGetIccHdl(areaIndex);
6086 /* Populating global memory information */
6087 mInfo->regInfo[idxReg].numPools = numPool;
6088 mInfo->regInfo[idxReg].regionId = areaIndex;
6089 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6091 /* Calling INTEL API's to Get Free MEM BLOCKS */
6092 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6093 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6094 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6095 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6097 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6098 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6099 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6100 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6102 poolSize[0] = ICC_POOL_ZERO_SIZE;
6103 poolSize[1] = ICC_POOL_ONE_SIZE;
6104 poolSize[2] = ICC_POOL_TWO_SIZE;
6105 poolSize[3] = ICC_POOL_THREE_SIZE;
6107 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6108 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6109 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6110 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6112 for(idxPool=0; idxPool<numPool;idxPool++)
6114 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6115 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
6116 poolTotAvail[idxPool];
6117 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6118 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
6119 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6121 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
6122 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6131 * Fun: isL2MemUsageBelowLowerThreshold
6133 * Desc: Checks for the Lower threshold of ICC memory.
6135 * region region for obtaining the ICC handle
6137 * Ret: TRUE - Threshold has reached
6138 * FALSE - Threshold has not reached
6145 uint32_t isL2MemUsageBelowLowerThreshold(
6149 void * iccHdl = ssGetIccHdl(region);
6151 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6152 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6154 /* We are below the threshold if free count in BOTH of the pools
6155 * is above the ICC_MEM_LOWER_THRESHOLD % */
6156 if(((poolZeroFreeCnt * 100) >
6157 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6158 ((poolOneFreeCnt * 100) >
6159 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6170 * Fun: isMemUsageBelowLowerThreshold
6172 * Desc: Checks for the Lower threshold of ICC memory.
6174 * region region for obtaining the ICC handle
6176 * Ret: TRUE - Threshold has reached
6177 * FALSE - Threshold has not reached
6184 uint32_t isMemUsageBelowLowerThreshold(
6188 void * iccHdl = ssGetIccHdl(region);
6190 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6191 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6192 uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6193 uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6195 /* We are below the threshold if free count in BOTH of the pools
6196 * is above the ICC_MEM_LOWER_THRESHOLD % */
6197 if(((poolZeroFreeCnt * 100) >
6198 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6199 ((poolOneFreeCnt * 100) >
6200 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6201 ((poolTwoFreeCnt * 100) >
6202 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6203 ((poolThreeFreeCnt * 100) >
6204 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6214 * Fun: isMemUsageAboveUpperThreshold
6216 * Desc: Checks for the Upper threshold of ICC memory.
6218 * region region for obtaining the ICC handle
6220 * Ret: TRUE - Threshold has reached
6221 * FALSE - Threshold has not reached
6228 static uint32_t isMemUsageAboveUpperThreshold(
6232 void * iccHdl = ssGetIccHdl(region);
6234 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6235 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6236 uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6237 uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6239 /* We are above the threshold if free count in either of the pools
6240 * is below the ICC_MEM_UPPER_THRESHOLD % */
6241 if(((poolZeroFreeCnt * 100) <
6242 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6243 ((poolOneFreeCnt * 100) <
6244 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6245 ((poolTwoFreeCnt * 100) <
6246 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6247 ((poolThreeFreeCnt * 100) <
6248 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6256 /* ccpu00142274- Function to check if we have reached the
6257 * Threshold for dropping UL packets at the RLC. This function
6258 * measures the free count of the ICC memory and based on the
6259 * volume of packets it sets an alarm to drop packets.
6260 * In DL, the PDCP packets are dropped at Admission Control, but
6261 * at UL we need to check if its an AM(Data only and
6262 * not Status PDU) or UM packet and free the PDU
6263 * Note: With the current design, we have PDCP DL and RLC UL
6264 * running in the same thread and the below function will be
6265 * accessed in tandem. But if PDCP DL and RLC UL are made to run
6266 * in different threads then there might be a race condition.
6267 * Please revisit this function in such a case.
6271 * Fun: isMemThreshReached
6273 * Desc: Checks whether the system has reached the
6274 * designated threshold of ICC memory.
6276 * region region for obtaining the ICC handle
6278 * Ret: ROK - Threshold has not reached
6279 * RFAILED - Threshold has reached
6286 uint32_t isMemThreshReached(
6292 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6297 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6299 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6300 memoryCheckCounter = 0;
6306 #endif /* SS_LOCKLESS_MEMORY */
6307 /**********************************************************************
6309 **********************************************************************/