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 extern uint8_t stopBtInfo = FALSE;
225 extern Buffer *mtTskBuffer1;
226 extern 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 extern pthread_t tmpRegTidMap[20];
338 extern Bool g_usettitmr;
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 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,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 SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,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 */
1826 if((SLock(&dynAllocFreeLock)) != ROK)
1828 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1832 ret = cmDynAlloc (regionCb, size,flags,ptr);
1834 if((SUnlock(&dynAllocFreeLock)) != ROK)
1836 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1841 } /* end of cmDynAlloc */
1847 * Desc: Allocate a memory block for use by dynamic buffers
1850 * Ret: ROK - successful
1851 * RFAILED - unsuccessful.
1858 /* cm_mem_c_001.main_15 : Additions */
1860 static S16 cmDynAlloc
1862 Void *regionCb, /* Pointer to a region */
1863 Size *size, /* size needs to be allocated */
1864 uint32_t flags, /* Flags used */
1865 Data **ptr /* Reference to pointer for which need to be allocate */
1868 CmMmDynRegCb *regCb;
1871 regCb = (CmMmDynRegCb *)regionCb;
1873 #ifdef SS_MEM_WL_DEBUG
1874 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
1880 #if (ERRCLASS & ERRCLS_INT_PAR)
1882 /* error check on parameters */
1885 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory region pointer is null");
1891 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory block pointer is null");
1897 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory size pointer null");
1903 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory block size is 0");
1911 * Check if the requested size is less than or equal to the maximum block
1912 * size in the bucket.
1915 #ifdef SS_MEM_WL_DEBUG
1916 if ( (*size + 4) <= regCb->bktMaxBlkSize)
1918 if ( (*size) <= regCb->bktMaxBlkSize)
1922 CmMmBlkSetElement *dynMemElem;
1926 /* Get the map to the mapping table */
1927 #ifdef SS_MEM_WL_DEBUG
1928 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
1930 idx = (((*size) - 1) >> regCb->bktQnPwr);
1933 #if (ERRCLASS & ERRCLS_DEBUG)
1934 if (regCb->mapTbl[idx].bktIdx == 0xFF)
1936 DU_LOG("\nERROR --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
1937 /* Some fatal error in the map table initialization. */
1943 DU_LOG("\nERROR --> CM: cmDynAlloc(): idx value is greater than 512");
1946 /* Dequeue the memory block and return it to the user */
1947 bktIdx = regCb->mapTbl[idx].bktIdx;
1948 bkt = &(regCb->bktTbl[bktIdx]);
1949 #ifdef SS_MEM_WL_DEBUG
1950 if(bkt->size < (*size+4))
1952 if(bkt->size < (*size))
1956 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
1959 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
1961 /* Check if the bucket index, if its not valid, return failure */
1962 if(dynMemElem == NULLP)
1965 DU_LOG("\nERROR --> CM: cmDynAlloc(): Failed to get the buffer of size %ld\n", *size);
1967 printf("\nERROR --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
1972 #ifdef SS_MEM_WL_DEBUG
1973 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
1979 /* Get the bucket node from the index returned and allocate the memory */
1980 *ptr = dynMemElem->nextBktPtr;
1983 DU_LOG("\nERROR --> CM: cmDynAlloc(): nextBktPtr is null");
1986 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
1987 dynMemElem->numFreeBlks--;
1989 #ifdef SS_MEM_WL_DEBUG
1990 prvAllocPtr[regCb->region] = *ptr;
1992 **ptr = (uint8_t) bktIdx;
1996 *ptr += sizeof (uint32_t);
1998 if ((bktIdx == 0) && (!stopBtInfo))
2002 btInfo = &allocBtInfo[regCb->region];
2003 btIdx = btInfo->btInfoIdx;
2004 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2006 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2008 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2011 btIdx &= (NUM_FREE_BUFFERS - 1);
2013 btInfo->btInfo[btIdx].ptr = (PTR)0;
2014 btInfo->btInfo[btIdx].btSize = 0;
2015 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2016 btInfo->btInfoIdx = btIdx;
2023 /* If the size is not matching, return failure to caller */
2025 DU_LOG("\nERROR --> CM : cmDynAlloc(): Failed to get the buffer of size %ld\n", *size);
2027 DU_LOG("\nERROR --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
2031 #else /* use pure is on */
2033 #ifdef SS_4GMX_LCORE
2034 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2035 memset(ptr, 0, *size);
2037 /* *ptr = (Data*) malloc(*size); */
2039 *ptr = (Data *)malloc(*size);
2041 if ( (*ptr) == NULLP)
2043 DU_LOG("\nERROR --> CM : cmDynAlloc(): Data ptr is null");
2046 /* avail_size -= *size; */
2048 #endif /* USE_PURE */
2050 } /* end of cmDynAlloc */
2051 #endif /* SS_USE_ICC_MEMORY */
2054 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2056 int g_overused[5] = {0};
2063 * Desc: Allocate a memory block for the memory region.
2066 * Ret: ROK - successful
2067 * RFAILED - unsuccessful.
2070 * The function allocates a memory block of size atleast equal to
2071 * the requested size. The size parameter will be updated with the
2072 * actual size of the memory block allocated for the request. The
2073 * CMM tries to allocate the memory block form the bucket pool. If
2074 * there is no memory in the bucket the CMM allocates the memory
2075 * block form the heap pool. This function is always called by the
2076 * System Service module.
2078 * The caller of the function should try to use the out value of
2079 * the size while returning the memory block to the region. However
2080 * the current design of the memory manager does not enforce to pass
2081 * the actual size of the memory block. (Due to the SGetSBuf
2082 * semantics the layer will not able to pass the correct size of the
2083 * memory block while calling SPutSBuf).
2089 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2091 /* cm_mem_c_001.main_15 : Additions */
2092 #ifdef T2K_MEM_LEAK_DBG
2103 #ifdef SS_HISTOGRAM_SUPPORT
2104 #ifdef SSI_DEBUG_LEVEL1
2129 #endif /* SSI_DEBUG_LEVEL1 */
2133 #ifdef SSI_DEBUG_LEVEL1
2152 #endif /* SSI_DEBUG_LEVEL1 */
2153 /* cm_mem_c_001.main_15: Additions */
2154 #endif /* SS_HISTOGRAM_SUPPORT */
2157 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2164 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2168 /* cm_mem_c_001.main_15 : Additions */
2169 #ifdef SS_MEM_LEAK_STS
2171 #endif /* SS_MEM_LEAK_STS */
2172 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2173 #ifdef SSI_DEBUG_LEVEL1
2174 CmMmBlkHdr *alocBlk;
2175 #endif /* SSI_DEBUG_LEVEL1 */
2176 /* cm_mem_c_001.main_15 : Additions */
2177 #ifdef SS_HISTOGRAM_SUPPORT
2179 #endif /* SS_HISTOGRAM_SUPPORT */
2185 /* cm_mem_c_001.main_15 : Additions */
2186 #ifdef SS_MEM_LEAK_STS
2188 #endif /* SS_MEM_LEAK_STS */
2190 regCb = (CmMmRegCb *)regionCb;
2192 #if (ERRCLASS & ERRCLS_INT_PAR)
2194 /* error check on parameters */
2197 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory region pointer is null");
2203 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory block pointer is null");
2209 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory size pointer null");
2215 DU_LOG("\nERROR --> CM: cmDynAlloc(): Received memory block size is 0");
2220 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2221 #ifdef SSI_DEBUG_LEVEL1
2222 #if (ERRCLASS & ERRCLS_INT_PAR)
2223 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2225 DU_LOG("\nERROR --> CM : cmAlloc(): memType[%d] is invalid",memType);
2228 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2229 #endif /* SSI_DEBUG_LEVEL1 */
2236 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2237 #ifdef SSI_DEBUG_LEVEL1
2238 /* Update the hash list */
2239 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2241 /* display that, this entry could not be made in the hash list */
2243 /* display an error message here */
2244 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2246 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2247 *size, regCb->region);
2249 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2250 *size, regCb->region);
2252 SDisplay(0, dbgPrntBuf);
2255 #endif /* SSI_DEBUG_LEVEL1 */
2258 * Check if the requested size is less than or equal to the maximum block
2259 * size in the bucket.
2261 if ( *size <= regCb->bktMaxBlkSize)
2263 /* Get the map to the mapping table */
2264 idx = ((*size - 1) >> regCb->bktQnPwr);
2266 #if (ERRCLASS & ERRCLS_DEBUG)
2267 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2269 /* Some fatal error in the map table initialization. */
2270 DU_LOG("\nERROR --> CM : cmAlloc(): bktIdx is invalid");
2275 /* Dequeue the memory block and return it to the user */
2276 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2279 /* While loop is introduced to use the "break statement inside */
2283 * Check if the size request is not greater than the size available
2286 if (*size > bkt->size)
2288 /* Try to go to the next bucket if available */
2289 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2290 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2292 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2296 /* This is the last bucket, try to allocate from heap */
2301 /* Acquire the bucket lock */
2302 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2304 (Void) WTLock(&(bkt->bktLock));
2306 (Void) SLock(&(bkt->bktLock));
2309 #if (ERRCLASS & ERRCLS_DEBUG)
2310 regCb->mapTbl[idx].numReq++;
2311 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2313 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2314 #ifdef SSI_DEBUG_LEVEL1
2315 /* increment the allocation attempt counter at bucket level */
2316 bkt->numAllocAttempts++;
2318 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2319 the allocation is always from (bkt->nextBlk) */
2322 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2324 /* detected a trampled memory block in this bucket */
2326 /* display an error message here */
2327 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2329 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2330 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2332 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2333 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2335 SDisplay(0, dbgPrntBuf);
2338 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2340 /* Release the lock */
2341 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2343 (Void) WTUnlock(&(bkt->bktLock));
2345 (Void) SUnlock(&(bkt->bktLock));
2347 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2348 return (RTRAMPLINGNOK);
2352 /* Release the lock */
2353 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2355 (Void) WTUnlock(&(bkt->bktLock));
2357 (Void) SUnlock(&(bkt->bktLock));
2359 DU_LOG("\nERROR --> CM : cmAlloc(): Sanity check returns failure");
2360 /* return RFAILED */
2366 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2368 if ((*ptr = bkt->next))
2369 #endif /* SSI_DEBUG_LEVEL1 */
2371 /* cm_mem_c_001.main_12 - addition for header */
2372 #ifdef SSI_DEBUG_LEVEL1
2373 /* point to next block header */
2374 alocBlk = bkt->nextBlk;
2375 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2377 bkt->next = *((CmMmEntry **)(bkt->next));
2378 #endif /* SSI_DEBUG_LEVEL1 */
2381 * Increment the statistics variable of number of memory block
2385 if (bkt->numAlloc > bkt->maxAlloc)
2387 bkt->maxAlloc = bkt->numAlloc;
2390 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2392 g_overused[bktIdx] = 1;
2393 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2397 /* cm_mem_c_001.main_12 - addition for header manipulation */
2398 #ifdef SSI_DEBUG_LEVEL1
2399 /* update the size for which this memory block has been allocated */
2400 alocBlk->requestedSize = *size;
2401 /* update the memory block header */
2402 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2403 if (memType == CMM_STATIC_MEM_FLAG)
2405 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2406 /* add it to the static memory allocated */
2407 bkt->staticMemUsed += bkt->size;
2411 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2412 /* add it to the dynamic memory allocated */
2413 bkt->dynamicMemUsed += bkt->size;
2415 #endif /* SSI_DEBUG_LEVEL1 */
2417 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2421 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2424 "[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++);
2427 "[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++);
2429 SDisplay(0, prntBuf);
2437 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2438 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2439 SDisplay(0, prntBuf);
2441 #endif /* MEMCAL_DEBUG */
2442 /* cm_mem_c_001.main_15 : Additions */
2443 #ifdef SS_HISTOGRAM_SUPPORT
2444 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2445 * information into the hash list */
2448 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2450 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2455 #endif /* SS_HISTOGRAM_SUPPORT */
2457 /* Update the size parameter */
2459 #ifdef SS_MEM_LEAK_STS
2460 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2461 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2462 regCb->mapTbl[idx].bktIdx);
2463 #endif /* SS_MEM_LEAK_STS */
2465 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2467 /* Release the lock */
2468 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2470 (Void) WTUnlock(&(bkt->bktLock));
2472 (Void) SUnlock(&(bkt->bktLock));
2481 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2484 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2487 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2489 SDisplay(0, prntBuf);
2493 #if (ERRCLASS & ERRCLS_DEBUG)
2494 regCb->mapTbl[idx].numFailure++;
2495 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2497 /* Release the lock */
2498 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2500 (Void) WTUnlock(&(bkt->bktLock));
2502 (Void) SUnlock(&(bkt->bktLock));
2511 regCb->heapCb.heapAllocCnt++;
2513 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2516 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2517 regCb->heapCb.heapAllocCnt);
2520 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2521 regCb->heapCb.heapAllocCnt);
2523 SDisplay(0, prntBuf);
2528 /* Memory not available in the bucket pool */
2529 if (regCb->heapFlag && (*size < regCb->heapSize))
2532 if (flags) tryHeap = 1;
2535 * The heap memory block is available. Allocate the memory block from
2538 /* cm_mem_c_001.main_15: Additions */
2539 #ifdef SS_HISTOGRAM_SUPPORT
2540 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2541 #ifdef SSI_DEBUG_LEVEL1
2542 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2544 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2545 #endif /* SSI_DEBUG_LEVEL1 */
2547 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2548 #ifdef SSI_DEBUG_LEVEL1
2549 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2551 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2552 #endif /* SSI_DEBUG_LEVEL1 */
2553 #endif /* SS_HISTOGRAM_SUPPORT */
2556 /* No memory available */
2557 DU_LOG("\nERROR --> CM : cmAlloc(): No memory available in heap");
2559 #else /* use pure is on */
2560 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2561 #ifdef SS_4GMX_LCORE
2562 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2563 memset(ptr, 0, *size);
2565 *ptr = (Data*) malloc(*size);
2567 if ( (*ptr) == NULLP)
2569 DU_LOG("\nERROR --> CM : cmAlloc(): ptr is null");
2572 avail_size -= *size;
2574 #endif /* USE_PURE */
2576 } /* end of cmAlloc */
2578 #ifdef SS_MEM_WL_DEBUG
2581 * Fun: cmInitDoubleFreeList
2583 * Desc: Initialize the hashlist used for detecting double free
2585 * Ret: ROK - successful
2586 * RFAILED - unsuccessful.
2594 S16 cmInitDoubleFreeList(void)
2597 CmMemDoubleFree memNode;
2599 offset = (uint16_t)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2601 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2602 CM_HASH_KEYTYPE_UINT32_MOD, 0, 0)) != ROK);
2606 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2611 #ifdef SS_MEM_WL_DEBUG
2616 * Desc: Return the Dynamic memory block for the memory region.
2619 * Ret: ROK - successful
2620 * RFAILED - unsuccessful.
2628 static S16 cmInitBtInfo()
2630 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2631 if (regBtInfo == NULLP)
2635 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2636 if(allocBtInfo == NULLP)
2643 #endif /* SS_MEM_WL_DEBUG */
2646 * Fun: cmAnalyseBtInfo
2648 * Desc: Return the Dynamic memory block for the memory region.
2651 * Ret: ROK - successful
2652 * RFAILED - unsuccessful.
2660 Void cmAnalyseBtInfo
2662 PTR ptr, /* Memory block needs to be freed */
2671 /* for(regIdx = 0; regIdx < 8; regIdx++)
2674 btInfo = &allocBtInfo[idx];
2675 btIdx = btInfo->btInfoIdx;
2677 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
2679 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
2680 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
2681 if(btInfo->btInfo[btIdx].btSize != 0)
2685 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2686 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);
2687 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2689 printf("%s\n", strings[i]);
2691 printf("*******************************************************\n");
2699 btIdx = NUM_FREE_BUFFERS - 1;
2708 #ifndef SS_USE_ICC_MEMORY
2711 * Fun: cmDynFreeWithLock
2713 * Desc: Return the Dynamic memory block for the memory region.
2716 * Ret: ROK - successful
2717 * RFAILED - unsuccessful.
2725 static S16 cmDynFreeWithLock
2727 Void *regionCb, /* Pointer to region cb */
2728 Data *ptr, /* Memory block needs to be freed */
2729 Size size /* Size of the block */
2734 if((SLock(&dynAllocFreeLock)) != ROK)
2736 printf("dynAllocWithLock: Failed to get the DYN lock\n");
2740 ret = cmDynFree(regionCb, ptr,size);
2742 if((SUnlock(&dynAllocFreeLock)) != ROK)
2744 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2750 } /* end of cmDynFree */
2756 * Desc: Return the Dynamic memory block for the memory region.
2759 * Ret: ROK - successful
2760 * RFAILED - unsuccessful.
2768 static S16 cmDynFree
2770 Void *regionCb, /* Pointer to region cb */
2771 Data *ptr, /* Memory block needs to be freed */
2772 Size size /* Size of the block */
2775 CmMmDynRegCb *regCb;
2779 CmMmDynBktCb *bkt = NULLP;
2780 CmMmBlkSetElement *dynMemElem;
2782 #ifdef SS_MEM_WL_DEBUG
2788 regCb = (CmMmDynRegCb *)regionCb;
2789 #ifdef SS_MEM_WL_DEBUG
2790 if((tmpRegTidMap[regCb->region] != (pthread_self())))
2797 #if (ERRCLASS & ERRCLS_INT_PAR)
2798 /* error check on parameters */
2799 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2801 DU_LOG("\nERROR --> CM : cmDynFree(): Received memory region[%p] or size[%p] or block[%p] is invalid",regCb,size,ptr);
2805 /* Check if the memory block is from the memory region */
2806 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2807 ((CmMmRegCb *)regCb)->regInfo.size)
2809 DU_LOG("\nERROR --> CM : cmDynFree(): Memory block[%p] not from region[%d]", ptr, ((CmMmRegCb *)regCb)->region);
2812 /* cm_mem_c_001.main_20 Addition */
2813 if (ptr < regCb->regInfo.start)
2815 DU_LOG("\nERROR --> CM : cmDynFree(): Memory block[%p] not from region[%d]", ptr, ((CmMmRegCb *)regCb)->region);
2821 #ifdef SS_MEM_WL_DEBUG
2822 ptr -= sizeof (uint32_t);
2825 /* The memory block was allocated from the bucket pool */
2827 /* Get the map to the mapping table */
2828 idx = ((size - 1) >> regCb->bktQnPwr);
2830 #if (ERRCLASS & ERRCLS_DEBUG)
2831 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2833 DU_LOG("\nERROR --> CM : cmDynFree(): bktIdx is not valid");
2834 /* Some fatal error in the map table initialization. */
2839 /* Enqueue the memory block and return it to the user */
2840 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2843 * Check if the size is not greater than the size available
2844 * in the bucket. If so, then the buffer must have been allocated
2845 * from next bucket. We don't need to check the validity of the
2846 * next bucket, otherwise buffer must have been allocated from heap
2849 #ifdef SS_MEM_WL_DEBUG
2850 if (size > bkt->size)
2852 DU_LOG("Size = %d bucket size = %d\n", size, bkt->size);
2854 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
2856 if(size > bkt->size)
2858 DU_LOG("2nd time Size = %d bucket size = %d\n", size, bkt->size);
2860 uint8_t *tmpptr = NULLP;
2861 printf("Bucket Size wrong \n");
2866 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
2868 /* Check if the bucket index, if its not valid, return failure */
2869 if(dynMemElem == NULLP)
2871 DU_LOG("\nERROR --> CM : cmDynFree(): dynMemElem is null");
2875 #ifdef SS_MEM_WL_DEBUG
2876 tmpBktIdx = (uint8_t)*ptr;
2877 tmpVal = (uint8_t)*(ptr+1);
2879 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
2881 uint8_t *tmpptr = NULLP;
2882 printf("bktIdx wrong \n");
2886 if ((bktIdx == 0) && (!stopBtInfo))
2890 btInfo = ®BtInfo[regCb->region];
2891 btIdx = btInfo->btInfoIdx;
2892 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
2894 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2896 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2899 btIdx &= (NUM_FREE_BUFFERS - 1);
2901 btInfo->btInfo[btIdx].ptr = (PTR)0;
2902 btInfo->btInfo[btIdx].btSize = 0;
2903 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2904 btInfo->btInfoIdx = btIdx;
2907 if(prvAllocPtr[regCb->region] == ptr)
2909 prvAllocPtr[regCb->region] = NULLP;
2912 memset(ptr, (regCb->region+1), bkt->size);
2914 /* Get the bucket node from the index returned and allocate the memory */
2915 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
2916 dynMemElem->nextBktPtr = ptr;
2917 dynMemElem->numFreeBlks++;
2921 #else /* use pure is on */
2922 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2923 #ifdef SS_4GMX_LCORE
2924 (Void)MxHeapFree(SsiHeap, ptr);
2926 /* (Void)free(ptr); */
2928 /* avail_size += size; */
2932 #endif /* USE_PURE */
2935 } /* end of cmDynFree */
2936 #endif /* SS_USE_ICC_MEMORY */
2944 * Desc: Return the memory block for the memory region.
2947 * Ret: ROK - successful
2948 * RFAILED - unsuccessful.
2950 * Notes: The user calls this function to return the previously allocated
2951 * memory block to the memory region. The memory manager does not
2952 * check the validity of the state of the memory block(like whether
2953 * it was allocated earlier). The caller must be sure that, the
2954 * address specified in the parameter 'ptr' is valid and was
2955 * allocated previously from same region.
2962 /* cm_mem_c_001.main_15 : Additions */
2963 #ifdef T2K_MEM_LEAK_DBG
2973 #ifdef SS_HISTOGRAM_SUPPORT
2992 /* cm_mem_c_001.main_15 : Additions */
2993 #endif /* SS_HISTOGRAM_SUPPORT */
2996 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
3003 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3004 #ifdef SSI_DEBUG_LEVEL1
3006 #endif /* SSI_DEBUG_LEVEL1 */
3007 /* cm_mem_c_001.main_15 : Additions */
3008 #ifdef SS_HISTOGRAM_SUPPORT
3010 #endif /* SS_HISTOGRAM_SUPPORT */
3013 regCb = (CmMmRegCb *)regionCb;
3016 #if (ERRCLASS & ERRCLS_INT_PAR)
3018 /* error check on parameters */
3019 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3021 DU_LOG("\nERROR --> CM : cmFree(): Received memory region[%p] or size[%p] or block[%p] is invalid",regCb,size,ptr);
3025 /* Check if the memory block is from the memory region */
3026 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3027 ((CmMmRegCb *)regCb)->regInfo.size)
3029 DU_LOG("\nERROR --> CM : cmFree(): Memory block[%p] not from region[%d]",ptr,regCb.region);
3032 /* cm_mem_c_001.main_20 Addition */
3033 if (ptr < regCb->regInfo.start)
3035 DU_LOG("\nERROR --> CM : cmFree(): Memory block[%p] not from region[%d]",ptr,regCb.region);
3042 * Check if the memory block was allocated from the bucket pool.
3044 if(ptr < regCb->regInfo.start)
3046 Buffer *tmpBuffer = NULLP;
3047 tmpBuffer->b_cont = NULLP;
3050 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3052 /* The memory block was allocated from the bucket pool */
3054 /* Get the map to the mapping table */
3055 idx = ((size - 1) >> regCb->bktQnPwr);
3057 #if (ERRCLASS & ERRCLS_DEBUG)
3058 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3060 /* Some fatal error in the map table initialization. */
3061 DU_LOG("\nERROR --> CM : cmFree(): Invalid bktIdx");
3066 /* Enqueue the memory block and return it to the user */
3067 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3070 * Check if the size is not greater than the size available
3071 * in the bucket. If so, then the buffer must have been allocated
3072 * from next bucket. We don't need to check the validity of the
3073 * next bucket, otherwise buffer must have been allocated from heap
3076 if (size > bkt->size)
3078 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3081 /* Acquire the bucket lock */
3082 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3084 (Void) WTLock(&(bkt->bktLock));
3086 (Void) SLock(&(bkt->bktLock));
3089 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3090 #ifdef SSI_DEBUG_LEVEL1
3091 /* increment the dealloc attempt counter at bucket level */
3092 bkt->numDeallocAttempts++;
3094 /* Check the memFlags to see whether this block was allocated */
3095 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3097 /* validate the block to be freed for trampling */
3098 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3100 /* Handle error case of Memory trampling */
3102 /* display an error message here */
3103 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3105 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3106 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3108 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3109 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3111 SDisplay(0, dbgPrntBuf);
3114 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3115 * as the memory blk is already invalidated in cmMmBktSanityChk
3117 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3121 /* Release the lock */
3122 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3124 (Void) WTUnlock(&(bkt->bktLock));
3126 (Void) SUnlock(&(bkt->bktLock));
3134 * this is the case where in the entire bucket has been made unusable
3137 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3139 (Void) WTUnlock(&(bkt->bktLock));
3141 (Void) SUnlock(&(bkt->bktLock));
3144 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3145 DU_LOG("\nERROR --> CM : cmFree(): Sanity check returns failure");
3146 return (RTRAMPLINGNOK);
3150 /* reset the size */
3151 ptrHdr->requestedSize = 0;
3152 /* check if the block to be freed is already having the state as FREE */
3153 if (CMM_IS_FREE(ptrHdr->memFlags))
3155 /* Handle double deallocation error case */
3157 /* display an error message here */
3158 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3160 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3161 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3163 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3164 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3166 SDisplay(0, dbgPrntBuf);
3169 /* Release the lock */
3170 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3172 (Void) WTUnlock(&(bkt->bktLock));
3174 (Void) SUnlock(&(bkt->bktLock));
3177 /* handle RDBLFREE in SFree/SPutSBuf */
3178 DU_LOG("\nERROR --> CM : cmFree(): Memory block is already freed");
3181 if (CMM_IS_STATIC(ptrHdr->memFlags))
3183 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3184 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3185 /* deduct it from the static memory count */
3186 bkt->staticMemUsed -= bkt->size;
3188 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3190 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3191 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3192 /* deduct it from the dynamic memory count */
3193 bkt->dynamicMemUsed -= bkt->size;
3197 /* This is a case similar to trampled memory */
3199 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3201 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3203 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3205 SDisplay(0, dbgPrntBuf);
3207 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3209 /* do not add to the free list */
3212 /* Release the lock */
3213 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3215 (Void) WTUnlock(&(bkt->bktLock));
3217 (Void) SUnlock(&(bkt->bktLock));
3224 * this is the case where in the entire bucket has been made unusable
3227 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3229 (Void) WTUnlock(&(bkt->bktLock));
3231 (Void) SUnlock(&(bkt->bktLock));
3234 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3235 DU_LOG("\nERROR --> CM : cmFree(): Sanity check returns failure");
3236 return (RTRAMPLINGNOK);
3240 /* Return the block to memory */
3241 ptrHdr->nextBlk = bkt->nextBlk;
3242 bkt->nextBlk = ptrHdr;
3245 *((CmMmEntry **)ptr) = bkt->next;
3246 bkt->next = (CmMmEntry *)ptr;
3247 #endif /* SSI_DEBUG_LEVEL1 */
3250 * Decrement the statistics variable of number of memory block
3258 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3260 g_overused[bktIdx] = 0;
3261 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3264 /* cm_mem_c_001.main_15 : Additions */
3265 #ifdef SS_HISTOGRAM_SUPPORT
3266 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3267 * information into the hash list */
3270 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3272 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3276 #endif /* SS_HISTOGRAM_SUPPORT */
3278 #ifdef SS_MEM_LEAK_STS
3279 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3280 cmRlsAllocBlk((PTR)ptr);
3281 #endif /* SS_MEM_LEAK_STS */
3283 /* Release the lock */
3284 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3286 (Void) WTUnlock(&(bkt->bktLock));
3288 (Void) SUnlock(&(bkt->bktLock));
3294 /* The memory block was allocated from the heap pool */
3295 /* cm_mem_c_001.main_15 : Additions */
3296 #ifdef SS_HISTOGRAM_SUPPORT
3297 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3299 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3300 #endif /* SS_HISTOGRAM_SUPPORT */
3301 #else /* use pure is on */
3302 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3303 #ifdef SS_4GMX_LCORE
3304 (Void)MxHeapFree(SsiHeap, ptr);
3310 #endif /* USE_PURE */
3313 } /* end of cmFree */
3320 * Desc: alloc without lock
3323 * Ret: ROK - successful
3324 * RFAILED - unsuccessful.
3330 /*cm_mem_c_001.main_21-added new function*/
3331 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3332 #ifdef T2K_MEM_LEAK_DBG
3333 static S16 cmAllocWL
3343 static S16 cmAllocWL
3354 CmMmBkt *bkt = NULLP;
3357 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3360 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3362 regCb = (CmMmRegCb *)regionCb;
3364 #ifdef SS_MEM_WL_DEBUG
3365 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3371 #if (ERRCLASS & ERRCLS_INT_PAR)
3373 /* error check on parameters */
3374 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3380 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3385 * Check if the requested size is less than or equal to the maximum block
3386 * size in the bucket.
3388 #ifdef MSPD_T2K_TRACK_BUG
3391 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3392 if ( *size <= regCb->bktMaxBlkSize)
3394 /* Get the map to the mapping table */
3395 idx = ((*size - 1) >> regCb->bktQnPwr);
3397 /* Dequeue the memory block and return it to the user */
3398 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3402 * Check if the size request is not greater than the size available
3405 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3406 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3408 /* Try to go to the next bucket if available */
3409 bkt->next = *((CmMmEntry **)(bkt->next));
3412 * Increment the statistics variable of number of memory block
3416 if (bkt->numAlloc > bkt->maxAlloc)
3418 bkt->maxAlloc = bkt->numAlloc;
3421 #ifdef MSPD_T2K_TRACK_BUG
3430 /* Update the size parameter */
3438 /* Memory not available in the bucket pool */
3439 if (regCb->heapFlag && (*size < regCb->heapSize))
3441 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3443 * The heap memory block is available. Allocate the memory block from
3446 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3447 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3450 /* No memory available */
3452 #else /* use pure is on */
3453 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3454 #ifdef SS_4GMX_LCORE
3455 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3456 memset(ptr, 0, *size);
3458 /* *ptr = (Data*) malloc(*size); */
3460 *ptr = (Data *)malloc(*size);
3462 if ( (*ptr) == NULLP)
3464 /* avail_size -= *size; */
3466 #endif /* USE_PURE */
3468 } /* end of cmAllocWL */
3475 * Desc: free without lock
3478 * Ret: ROK - successful
3479 * RFAILED - unsuccessful.
3486 #ifdef T2K_MEM_LEAK_DBG
3506 CmMmBkt *bkt = NULLP;
3509 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3512 regCb = (CmMmRegCb *)regionCb;
3514 #ifdef SS_MEM_WL_DEBUG
3515 if(tmpRegTidMap[regCb->region] != (pthread_self()))
3522 #if (ERRCLASS & ERRCLS_INT_PAR)
3524 /* error check on parameters */
3525 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3530 /* Check if the memory block is from the memory region */
3531 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3532 ((CmMmRegCb *)regCb)->regInfo.size)
3540 * Check if the memory block was allocated from the bucket pool.
3542 #ifdef MSPD_T2K_TRACK_BUG
3546 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3548 /* The memory block was allocated from the bucket pool */
3550 /* Get the map to the mapping table */
3551 idx = ((size - 1) >> regCb->bktQnPwr);
3553 #if (ERRCLASS & ERRCLS_DEBUG)
3554 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3556 /* Some fatal error in the map table initialization. */
3561 /* Enqueue the memory block and return it to the user */
3562 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3564 #ifdef MSPD_T2K_TRACK_BUG
3566 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3573 * Check if the size is not greater than the size available
3574 * in the bucket. If so, then the buffer must have been allocated
3575 * from next bucket. We don't need to check the validity of the
3576 * next bucket, otherwise buffer must have been allocated from heap
3579 if (size > bkt->size)
3581 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3584 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3585 *((CmMmEntry **)ptr) = bkt->next;
3586 bkt->next = (CmMmEntry *)ptr;
3589 * Decrement the statistics variable of number of memory block
3597 /* The memory block was allocated from the heap pool */
3598 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3599 #else /* use pure is on */
3600 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3601 #ifdef SS_4GMX_LCORE
3602 (Void)MxHeapFree(SsiHeap, ptr);
3604 /* (Void)free(ptr); */
3606 /* avail_size += size; */
3610 #endif /* USE_PURE */
3613 } /* end of cmFreeWL */
3620 * Desc: Control request function.
3623 * Ret: ROK - successful
3624 * RFAILED - unsuccessful.
3626 * Notes: The current semantics of the control function is defined for two
3627 * types of events: virtual address to physical address translation
3628 * and memory resource check.
3630 * The physical address translation is valid only for the memory
3631 * region physically contiguous and non pagable.
3649 regCb = (CmMmRegCb *)regionCb;
3651 #if (ERRCLASS & ERRCLS_INT_PAR)
3653 /* error check on parameters */
3654 if ((regCb == NULLP) || (memCtl == NULLP))
3667 #if (ERRCLASS & ERRCLS_INT_PAR)
3668 if ((memCtl->u.vtop.vaddr == NULLP) ||
3669 (memCtl->u.vtop.paddr == NULLP))
3675 /* Check if the virtual to physical address translation is valid */
3676 if (regCb->chFlag & CMM_REG_PHY_VALID)
3678 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3679 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3686 case SS_MEM_CHK_RES:
3689 #if (ERRCLASS & ERRCLS_INT_PAR)
3690 if (!(memCtl->u.chkres.size) ||
3691 (memCtl->u.chkres.status == NULLP))
3697 /* Check if the Bucket pool is configured */
3702 uint32_t avlSize, totSize;
3704 * The bucket pool is configured. The status value returned
3705 * does reflect on the memory availabilty in the bucket pool.
3706 * The value does not consider the available memory in the
3709 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3710 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3711 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3712 avlSize += regCb->heapCb.avlSize;
3713 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3714 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
3718 /* Bucket pool not configured */
3721 * Find the percentage memory available in the heap pool. The value
3722 * does not consider the fragmentation of the heap pool.
3724 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3725 (regCb->heapSize/10));
3729 #else /* use pure is on */
3730 *(memCtl->u.chkres.status) = ((avail_size) /
3731 (regCb->regInfo.size/10));
3733 #endif /* USE_PURE */
3739 /* No other event is supported currently */
3744 /* shouldn't reach here */
3746 } /* end of cmCtl */
3753 * Desc: Initialize the heap pool.
3756 * Ret: ROK - successful
3757 * RFAILED - unsuccessful.
3759 * Notes: This function is called by the cmMmRegInit.
3764 static Void cmMmHeapInit
3771 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3772 #ifdef SSI_DEBUG_LEVEL1
3774 #endif /* SSI_DEBUG_LEVEL1 */
3776 /* Initialize the heap control block */
3777 heapCb->vStart = memAddr;
3778 heapCb->vEnd = memAddr + size;
3779 heapCb->avlSize = size;
3780 heapCb->minSize = CMM_MINBUFSIZE;
3782 heapCb->next = (CmHEntry *)memAddr;
3783 heapCb->next->next = NULLP;
3784 /* cm_mem_c_001.main_12 - addition for header initialization */
3785 #ifdef SSI_DEBUG_LEVEL1
3786 heapCb->next->size = size - sizeof(CmHEntry);
3787 heapCb->next->requestedSize = 0;
3788 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3790 heapCb->next->trSignature[idx] = 0xAB;
3792 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3793 heapCb->staticHeapMemUsed = 0;
3794 heapCb->dynamicHeapMemUsed = 0;
3795 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3796 sizeof(heapCb->next->memFlags) +
3797 sizeof(heapCb->next->requestedSize);
3798 heapCb->numAllocAttempts = 0;
3799 heapCb->numDeallocAttempts = 0;
3800 heapCb->trampleCount = 0;
3802 heapCb->next->size = size;
3803 #endif /* SSI_DEBUG_LEVEL1 */
3805 #if (ERRCLASS & ERRCLS_DEBUG)
3806 heapCb->numFragBlk = 0;
3808 heapCb->numFailure = 0;
3811 heapCb->heapAllocCnt = 0;
3812 /* cm_mem_c_001.main_15 : Additions */
3813 #ifdef SS_HISTOGRAM_SUPPORT
3814 /* Initialise the memory histogram hash list */
3815 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3816 #endif /* SS_HISTOGRAM_SUPPORT */
3819 } /* end of cmMmHeapInit */
3827 * Desc: Allocates the memory block from the heap pool.
3830 * Ret: ROK - successful
3831 * RFAILED - unsuccessful.
3833 * Notes: This function is called by the cmAlloc. cmAlloc calls this
3834 * function when there is no memory block available in the bucket
3835 * and the heap pool is configured.
3842 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
3843 /* cm_mem_c_001.main_15 : Additions */
3844 #ifdef SS_HISTOGRAM_SUPPORT
3845 #ifdef SSI_DEBUG_LEVEL1
3846 static S16 cmHeapAlloc
3858 static S16 cmHeapAlloc
3868 #endif /* SSI_DEBUG_LEVEL1 */
3870 #ifdef SSI_DEBUG_LEVEL1
3871 static S16 cmHeapAlloc
3879 static S16 cmHeapAlloc
3885 #endif /* SSI_DEBUG_LEVEL1 */
3886 /* cm_mem_c_001.main_15 : Additions */
3887 #endif /* SS_HISTOGRAM_SUPPORT */
3889 CmHEntry *prvHBlk; /* Previous heap block */
3890 CmHEntry *curHBlk; /* Current heap block */
3892 /* cm_mem_c_001.main_15 : Additions */
3893 #ifdef SS_MEM_LEAK_STS
3895 #endif /* SS_MEM_LEAK_STS */
3896 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3897 #ifdef SSI_DEBUG_LEVEL1
3898 CmHEntry *alocHeapBlk;
3902 #endif /* SSI_DEBUG_LEVEL1 */
3903 /* cm_mem_c_001.main_15 : Additions */
3904 #ifdef SS_HISTOGRAM_SUPPORT
3906 #endif /* SS_HISTOGRAM_SUPPORT */
3908 /* cm_mem_c_001.main_15 : Additions */
3909 /* Acquire the heap lock */
3910 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3912 (Void) WTLock (&(heapCb->heapLock));
3914 (Void) SLock (&(heapCb->heapLock));
3917 #ifdef SS_MEM_LEAK_STS
3919 #endif /* SS_MEM_LEAK_STS */
3920 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
3921 #ifdef SSI_DEBUG_LEVEL1
3922 heapCb->numAllocAttempts++;
3923 requestedSize = *size;
3924 #endif /* SSI_DEBUG_LEVEL1 */
3926 /* Roundup the requested size */
3927 *size = CMM_DATALIGN(*size, (heapCb->minSize));
3929 /* Check if the available total size is adequate. */
3930 if ((*size) >= heapCb->avlSize)
3932 /* cm_mem_c_001.main_15 : Additions */
3934 (Void) WTUnlock (&(heapCb->heapLock));
3936 (Void) SUnlock (&(heapCb->heapLock));
3942 /* cm_mem_c_001.main_12 - addition for aligning the header size */
3943 #ifdef SSI_DEBUG_LEVEL1
3944 hdr = PTRALIGN(sizeof(CmHEntry));
3945 #endif /* SSI_DEBUG_LEVEL1 */
3948 * Search through the heap block list in the heap pool of size
3949 * greater than or equal to the requested size.
3952 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
3953 #ifdef SSI_DEBUG_LEVEL1
3954 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
3956 prvHBlk = (CmHEntry *)&(heapCb->next);
3957 #endif /* SSI_DEBUG_LEVEL1 */
3958 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
3959 prvHBlk = prvHBlk->next)
3962 * Since the size of the block is always multiple of CMM_MINBUFSIZE
3963 * and the requested size is rounded to the size multiple of
3964 * CMM_MINBUFSIZE, the difference between the size of the heap block
3965 * and the size to allocate will be either zero or multiple of
3968 if ((*size) <= curHBlk->size)
3970 /* cm_mem_c_001.main_12 - addition for block size calculation */
3971 #ifdef SSI_DEBUG_LEVEL1
3972 tmpSize = curHBlk->size - (*size);
3974 tmpSize = tmpSize - hdr;
3977 if ((tmpSize = (curHBlk->size - (*size))))
3978 #endif /* SSI_DEBUG_LEVEL1 */
3980 /* Heap block of bigger size */
3981 /* cm_mem_c_001.main_12 - addition for allocating memory */
3982 #ifdef SSI_DEBUG_LEVEL1
3983 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
3984 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
3986 * No need to look for memory trampling as this is a new block altogether
3987 * Update the header only for this case as it is new block formed
3989 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3991 alocHeapBlk->trSignature[idx] = 0xAB;
3993 alocHeapBlk->size = *size;
3995 *ptr = (Data *)curHBlk + tmpSize;
3996 #endif /* SSI_DEBUG_LEVEL1 */
3997 curHBlk->size = tmpSize;
4001 /* Heap block is same size of the requested size */
4002 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4003 #ifdef SSI_DEBUG_LEVEL1
4004 /* look for memory trampling as this is a pure block*/
4007 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4009 /* detected a trampled memory block in this bucket */
4011 /* display an error message here */
4012 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4014 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4016 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4018 SDisplay(0, dbgPrntBuf);
4021 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4023 /* Release the lock */
4024 /* cm_mem_c_001.main_13: Replaced SUnlock with
4027 (Void) WTUnlock (&(heapCb->heapLock));
4029 (Void) SUnlock (&(heapCb->heapLock));
4031 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4032 return (RTRAMPLINGNOK);
4036 /* Release the lock */
4037 /* cm_mem_c_001.main_13: Replaced SUnlock with
4040 (Void) WTUnlock (&(heapCb->heapLock));
4042 (Void) SUnlock (&(heapCb->heapLock));
4049 *ptr = (Data *)curHBlk + hdr;
4050 alocHeapBlk = curHBlk;
4051 *size = curHBlk->size;
4053 *ptr = (Data *)curHBlk;
4054 #endif /* SSI_DEBUG_LEVEL1 */
4055 prvHBlk->next = curHBlk->next;
4058 /* cm_mem_c_001.main_12 - addition for header updation */
4059 #ifdef SSI_DEBUG_LEVEL1
4060 /* update the header fields */
4061 alocHeapBlk->requestedSize = requestedSize;
4062 alocHeapBlk->memFlags = 0;
4063 if (memType == CMM_STATIC_MEM_FLAG)
4065 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4066 heapCb->staticHeapMemUsed += (*size + hdr);
4070 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4071 heapCb->dynamicHeapMemUsed += (*size + hdr);
4073 heapCb->avlSize -= ((*size) + hdr);
4075 heapCb->avlSize -= (*size);
4076 #endif /* SSI_DEBUG_LEVEL1 */
4082 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4083 *size, num_times, *ptr);
4084 SDisplay(0, prntBuf);
4088 /* cm_mem_c_001.main_15 : Additions */
4089 #ifdef SS_MEM_LEAK_STS
4090 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4091 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4092 #endif /* SS_MEM_LEAK_STS */
4093 /* Release the lock */
4094 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4096 (Void) WTUnlock (&(heapCb->heapLock));
4098 (Void) SUnlock (&(heapCb->heapLock));
4101 #ifdef SS_HISTOGRAM_SUPPORT
4102 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4103 * information into the hash list */
4106 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4108 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4113 #endif /* SS_HISTOGRAM_SUPPORT */
4119 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4125 /* Release the lock */
4126 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4128 (Void) WTUnlock (&(heapCb->heapLock));
4130 (Void) SUnlock (&(heapCb->heapLock));
4135 } /* end of cmHeapAlloc */
4142 * Desc: Return the memory block from the heap pool.
4145 * Ret: ROK - successful
4146 * RFAILED - unsuccessful.
4148 * Notes: This function returns the memory block to the heap pool. This
4149 * function is called by cmFree. The function does not check the
4150 * validity of the memory block. The caller must be sure that the
4151 * block was previously allocated and belongs to the heap pool. The
4152 * function maintain the sorting order of the memory block on the
4153 * starting address of the block. This function also do compaction
4154 * if the neighbouring blocks are already in the heap.
4161 /* cm_mem_c_001.main_15 : Additions */
4162 #ifdef SS_HISTOGRAM_SUPPORT
4163 static S16 cmHeapFree
4174 static S16 cmHeapFree
4180 /* cm_mem_c_001.main_15 : Additions */
4181 #endif /* SS_HISTOGRAM_SUPPORT */
4184 CmHEntry *curHBlk; /* Current heap block */
4185 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4186 #ifdef SSI_DEBUG_LEVEL1
4188 #endif /* SSI_DEBUG_LEVEL1 */
4189 /* cm_mem_c_001.main_15 : Additions */
4190 #ifdef SS_HISTOGRAM_SUPPORT
4191 Size allocSize = size;
4193 #endif /* SS_HISTOGRAM_SUPPORT */
4196 /* Roundup the requested size */
4197 size = CMM_DATALIGN(size, (heapCb->minSize));
4198 /* cm_mem_c_001.main_15: Additions */
4199 #ifdef SS_HISTOGRAM_SUPPORT
4201 #endif /* SS_HISTOGRAM_SUPPORT */
4203 /* Acquire the heap lock */
4204 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4206 (Void) WTLock (&(heapCb->heapLock));
4208 (Void) SLock (&(heapCb->heapLock));
4211 /* increase the avlSize */
4212 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4213 #ifdef SSI_DEBUG_LEVEL1
4214 hdr = PTRALIGN(sizeof(CmHEntry));
4215 heapCb->avlSize += (size + hdr);
4216 heapCb->numDeallocAttempts++;
4218 heapCb->avlSize += size;
4219 #endif /* SSI_DEBUG_LEVEL1 */
4221 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4222 #ifdef SSI_DEBUG_LEVEL1
4223 p = (CmHEntry *)(ptr - hdr);
4225 p = (CmHEntry *)ptr;
4226 /* cm_mem_c_001.main_15 : Additions */
4227 #ifdef SS_MEM_LEAK_STS
4228 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4229 cmRlsAllocBlk((PTR)ptr);
4230 #endif /* SS_MEM_LEAK_STS */
4231 #endif /* SSI_DEBUG_LEVEL1 */
4234 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4235 #ifdef SSI_DEBUG_LEVEL1
4236 /* look for memory trampling */
4237 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4239 /* detected a trampled memory block in heap */
4241 /* display an error message here */
4242 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4244 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4246 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4248 SDisplay(0, dbgPrntBuf);
4251 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4253 /* Release the lock */
4254 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4256 (Void) WTUnlock (&(heapCb->heapLock));
4258 (Void) SUnlock (&(heapCb->heapLock));
4260 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4261 return (RTRAMPLINGNOK);
4265 /* do not add to the free heap */
4266 heapCb->avlSize -= (size + hdr);
4267 /* Release the heap lock */
4268 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4270 (Void) WTUnlock (&(heapCb->heapLock));
4272 (Void) SUnlock (&(heapCb->heapLock));
4279 /* look for any double free */
4280 if (CMM_IS_FREE(p->memFlags))
4283 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4285 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4287 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4289 SDisplay(0, dbgPrntBuf);
4292 heapCb->avlSize -= (size + hdr);
4293 /* cm_mem_c_001.main_15 : Additions */
4295 (Void) WTUnlock (&(heapCb->heapLock));
4297 (Void) SUnlock (&(heapCb->heapLock));
4302 #endif /* SSI_DEBUG_LEVEL1 */
4304 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4307 * The block will be inserted to maintain the sorted order on the
4308 * starting address of the block.
4312 if (!(curHBlk->next) ||
4313 (p < (curHBlk->next)))
4315 /* Heap block should be inserted here */
4318 * Check if the block to be returned can be merged with the
4321 /* cm_mem_c_001.main_12 - addition for header consideration */
4322 #ifdef SSI_DEBUG_LEVEL1
4323 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4325 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4326 #endif /* SSI_DEBUG_LEVEL1 */
4328 /* Merge the block */
4329 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4330 #ifdef SSI_DEBUG_LEVEL1
4331 /* update the flags */
4332 if (CMM_IS_STATIC(p->memFlags))
4333 heapCb->staticHeapMemUsed -= (size + hdr);
4334 else if (CMM_IS_DYNAMIC(p->memFlags))
4335 heapCb->dynamicHeapMemUsed -= (size + hdr);
4336 size = (curHBlk->size += (size + hdr));
4338 size = (curHBlk->size += size);
4339 #endif /*SSI_DEBUG_LEVEL1*/
4344 /* cm_mem_c_001.main_12 - addition for double-free check */
4345 #ifdef SSI_DEBUG_LEVEL1
4346 /* Check for double deallocation in heap */
4347 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4349 /* Release the lock */
4350 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4352 (Void) WTUnlock (&(heapCb->heapLock));
4354 (Void) SUnlock (&(heapCb->heapLock));
4357 /* This block is already freed in the heap */
4360 /* update the flags as it is a new node */
4361 if (CMM_IS_STATIC(p->memFlags))
4363 heapCb->staticHeapMemUsed -= (size + hdr);
4364 CMM_RESET_STATIC_FLAG(p->memFlags);
4366 else if (CMM_IS_DYNAMIC(p->memFlags))
4368 heapCb->dynamicHeapMemUsed -= (size + hdr);
4369 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4371 CMM_SET_FREE_FLAG(p->memFlags);
4372 p->requestedSize = 0;
4373 #endif /*SSI_DEBUG_LEVEL1*/
4374 /* insert the block */
4375 p->next = curHBlk->next;
4380 /* Try to merge with the next block in the chain */
4381 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4382 #ifdef SSI_DEBUG_LEVEL1
4383 if (((Data *)p + hdr + size) == (Data *)(p->next))
4385 if (((Data *)p + size) == (Data *)(p->next))
4386 #endif /*SSI_DEBUG_LEVEL1*/
4388 /* p->next can not be NULL */
4389 /* cm_mem_c_001.main_12 - addition for header consideration */
4390 #ifdef SSI_DEBUG_LEVEL1
4391 p->size += (p->next->size + hdr);
4393 p->size += p->next->size;
4394 #endif /*SSI_DEBUG_LEVEL1*/
4395 p->next = p->next->next;
4398 /* Release the lock */
4399 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4401 (Void) WTUnlock (&(heapCb->heapLock));
4403 (Void) SUnlock (&(heapCb->heapLock));
4405 /* cm_mem_c_001.main_15 : Additions */
4406 #ifdef SS_HISTOGRAM_SUPPORT
4407 /* If If Tapa task (entId)is registerd for histogram then insert
4408 Memrory Freed information into the hash list */
4411 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4412 fileName, entId) != ROK)
4414 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4418 #endif /* SS_HISTOGRAM_SUPPORT */
4422 else if (p < curHBlk)
4425 * Check if the block to be returned can be merged with the
4428 /* cm_mem_c_001.main_12 - addition for header consideration */
4429 #ifdef SSI_DEBUG_LEVEL1
4430 if (((Data *)p + hdr + size) == (Data *)curHBlk)
4432 if (((Data *)p + size) == (Data *)curHBlk)
4433 #endif /* SSI_DEBUG_LEVEL1 */
4435 /* Merge the block */
4436 /* cm_mem_c_001.main_12 - addition for header consideration */
4437 #ifdef SSI_DEBUG_LEVEL1
4438 p->size = size + (curHBlk->size + hdr);
4440 p->size = size + curHBlk->size;
4441 #endif /* SSI_DEBUG_LEVEL1 */
4442 p->next = curHBlk->next;
4446 /* insert the block */
4450 /* cm_mem_c_001.main_12 - addition for header updation */
4451 #ifdef SSI_DEBUG_LEVEL1
4452 /* update the flags in both cases as they are new start nodes*/
4453 if (CMM_IS_STATIC(p->memFlags))
4455 heapCb->staticHeapMemUsed -= (size + hdr);
4456 CMM_RESET_STATIC_FLAG(p->memFlags);
4458 else if (CMM_IS_DYNAMIC(p->memFlags))
4460 heapCb->dynamicHeapMemUsed -= (size + hdr);
4461 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4463 CMM_SET_FREE_FLAG(p->memFlags);
4464 p->requestedSize = 0;
4465 #endif /* SSI_DEBUG_LEVEL1 */
4469 /* Release the lock */
4470 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4472 (Void) WTUnlock (&(heapCb->heapLock));
4474 (Void) SUnlock (&(heapCb->heapLock));
4476 /* cm_mem_c_001.main_15 : Additions */
4477 #ifdef SS_HISTOGRAM_SUPPORT
4478 /* If If Tapa task (entId)is registerd for histogram then insert
4479 Memrory Freed information into the hash list */
4482 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4483 fileName, entId) != ROK)
4485 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4489 #endif /* SS_HISTOGRAM_SUPPORT */
4495 if (heapCb->next == NULLP)
4497 /* Heap block is empty. Insert the block in the head. */
4502 /* cm_mem_c_001.main_12 - addition for header updation */
4503 #ifdef SSI_DEBUG_LEVEL1
4504 if (CMM_IS_STATIC(p->memFlags))
4506 heapCb->staticHeapMemUsed -= (size + hdr);
4507 CMM_RESET_STATIC_FLAG(p->memFlags);
4509 else if (CMM_IS_DYNAMIC(p->memFlags))
4511 heapCb->dynamicHeapMemUsed -= (size + hdr);
4512 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4514 CMM_SET_FREE_FLAG(p->memFlags);
4515 p->requestedSize = 0;
4516 #endif /* SSI_DEBUG_LEVEL1 */
4518 /* Release the heap lock */
4519 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4521 (Void) WTUnlock (&(heapCb->heapLock));
4523 (Void) SUnlock (&(heapCb->heapLock));
4525 /* cm_mem_c_001.main_15 : Additions */
4526 #ifdef SS_HISTOGRAM_SUPPORT
4527 /* If If Tapa task (entId)is registerd for histogram then insert
4528 Memrory Freed information into the hash list */
4531 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4532 fileName, entId) != ROK)
4534 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4538 #endif /* SS_HISTOGRAM_SUPPORT */
4542 /* Release the lock */
4543 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4545 (Void) WTUnlock (&(heapCb->heapLock));
4547 (Void) SUnlock (&(heapCb->heapLock));
4551 } /* end of cmHeapFree */
4552 /* cm_mem_c_001.main_15 : Additions */
4554 #ifdef SS_MEM_LEAK_STS
4557 * Fun: cmInitMemLeakMdl
4559 * Desc: Initializes the memory leak detection module
4564 * Notes: This function initializes the memory leak detection module.
4570 Void cmInitMemLeakMdl(Void)
4576 memLkCb.memLkMdlInit = FALSE;
4577 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4579 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4581 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4582 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4583 500, 0, FALSE, CM_HASH_KEYTYPE_UINT32_MOD, 0, 0);
4584 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4587 if(memLkCb.fileLkLog == NULLP)
4589 memLkCb.fileLkLog = (FILE *) stdout;
4591 memLkCb.memLkMdlInit = TRUE;
4594 } /* cmInitMemLeakMdl */
4595 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4598 * Fun: cmDeinitMemLeakMdl
4600 * Desc: De-initializes the memory leak detection module
4605 * Notes: This function de-initializes the memory leak detection module.
4611 Void cmDeinitMemLeakMdl (Void)
4617 memLkCb.memLkMdlInit = FALSE;
4618 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4620 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4622 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4623 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4624 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4631 * Fun: cmMemOpenMemLkFile
4633 * Desc: Initializes the memory leak detection module
4638 * Notes: This function initializes the memory leak detection module.
4644 Void cmMemOpenMemLkFile(S8 *arg)
4646 memLkCb.fileLkLog = NULLP;
4647 memLkCb.fileLkLog = fopen(arg, "w");
4655 * Desc: Initializes the memory leak detection module
4660 * Notes: This function initializes the memory leak detection module.
4666 Void SLogLkInfo (Void)
4669 MemAllocInfo *oldMemInfo;
4670 MemAllocInfo *newMemInfo;
4676 if( memLkCb.memLkMdlInit == FALSE)
4680 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4681 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4683 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4685 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4687 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4693 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4694 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4695 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4697 sprintf(prntBuf, "[LBIS]\n");
4698 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4699 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4701 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4703 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
4705 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4706 sprintf(prntBuf, "Module Name: %s\n",
4707 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
4708 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4709 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
4710 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4711 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
4712 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4713 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
4714 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4715 sprintf(prntBuf,"Memory Allocation Path:\n");
4716 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4717 funcNm = (S8 **)newMemInfo->backTrace;
4718 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
4720 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
4721 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4723 sprintf(prntBuf, "[LBIE]\n\n");
4724 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4725 fflush(memLkCb.fileLkLog);
4726 oldMemInfo = newMemInfo;
4729 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4732 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
4733 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4741 * Desc: Initializes the memory leak detection module
4746 * Notes: This function initializes the memory leak detection module.
4752 Void SFlushLkInfo (Void)
4754 MemAllocInfo *newMemInfo;
4758 #ifdef SS_MEM_LEAK_SOL
4760 #endif /* SS_MEM_LEAK_SOL */
4762 if( memLkCb.memLkMdlInit == FALSE)
4767 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4769 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4771 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4776 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4777 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4778 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
4780 funcNm = (S8 **)newMemInfo->backTrace;
4781 #ifdef SS_MEM_LEAK_SOL
4782 for(i = 0; i < newMemInfo->bTrcSz; i++)
4784 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4785 #ifdef SS_4GMX_LCORE
4786 MxHeapFree(SsiHeap, funcNm[i]);
4790 /* SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4792 #endif /* SS_MEM_LEAK_SOl */
4793 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4794 #ifdef SS_4GMX_LCORE
4795 MxHeapFree(SsiHeap, funcNm);
4796 MxHeapFree(SsiHeap, newMemInfo);
4802 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4810 * Fun: cmStorAllocBlk
4812 * Desc: Initializes the memory leak detection module
4817 * Notes: This function initializes the memory leak detection module.
4831 #ifndef SS_MEM_LEAK_SOL
4832 Ptr trace[CM_MAX_STACK_TRACE];
4833 #endif /* SS_MEM_LEAK_SOL */
4836 MemAllocInfo *allocInfo;
4839 if( memLkCb.memLkMdlInit == FALSE)
4844 #ifdef SS_MEM_LEAK_SOL
4845 /* I need to do this for solaris, because it does not implement
4846 * backtrace. Here backtrace is my function. See below for the
4847 * implementation. */
4848 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4849 #ifdef SS_4GMX_LCORE
4850 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4851 memset(funcNm, 0, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4853 funcNm = (S8 **)calloc(1, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4855 /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &funcNm, sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4856 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
4857 #else /* SS_MEM_LEAK_SOL */
4858 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4859 funcNm = backtrace_symbols(trace, traceSize);
4860 #endif /* SS_MEM_LEAK_SOL */
4862 moduleId = cmMemGetModuleId(funcNm, traceSize);
4864 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4865 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4866 #ifdef SS_4GMX_LCORE
4867 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
4868 memset(allocInfo, 0, sizeof(MemAllocInfo));
4870 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
4872 /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
4873 allocInfo->memAddr = addr;
4874 allocInfo->reqSz = reqSz;
4875 allocInfo->allocSz = allocSz;
4876 allocInfo->bktIdx = bktIdx;
4877 allocInfo->backTrace = (PTR) funcNm;
4878 allocInfo->moduleId = moduleId;
4879 allocInfo->bTrcSz = traceSize;
4881 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
4882 (PTR)allocInfo, (uint8_t *)&(allocInfo->memAddr),
4883 sizeof(allocInfo->memAddr));
4884 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
4886 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4888 } /* cmStorAllocBlk */
4892 * Fun: cmMemGetModuleId
4894 * Desc: Initializes the memory leak detection module
4899 * Notes: This function initializes the memory leak detection module.
4905 uint8_t cmMemGetModuleId
4918 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
4920 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
4921 for(idx = 0; idx < traceSize; idx++)
4925 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
4927 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
4932 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4934 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4935 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
4936 memUsrMdlStr[mdlFunStrIdx].fPStr,
4940 return (mdlFunStrIdx);
4945 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4947 retVal = strcmp((const S8 *)"DEFAULT",
4948 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4951 return (mdlFunStrIdx);
4958 } /* cmMemGetModuleId */
4962 * Fun: cmMemGetStrMtchIdx
4964 * Desc: Initializes the memory leak detection module
4969 * Notes: This function initializes the memory leak detection module.
4975 S16 cmMemGetStrMtchIdx
4991 len = strlen((const S8 *)str);
4993 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
4994 cmpStr[len + 1] = '\0';
4997 for(;strtIdx < endIdx && !found; strtIdx++)
5000 tempLen = strlen((const S8 *)strLst[strtIdx]);
5004 while(*(strLst[strtIdx] + idx + len) != '\0')
5006 retVal = strncmp((const S8 *)cmpStr,
5007 ((const S8 *)strLst[strtIdx] + idx), len);
5023 } /* cmMemGetStrMtchIdx */
5027 * Fun: cmRlsAllocBlk
5029 * Desc: Initializes the memory leak detection module
5034 * Notes: This function initializes the memory leak detection module.
5045 Ptr trace[CM_MAX_STACK_TRACE];
5051 MemAllocInfo *memAllocInfo;
5053 if( memLkCb.memLkMdlInit == FALSE)
5059 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5061 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5062 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5063 (uint8_t *)&addr, sizeof(uint32_t), 0,
5064 (PTR *)&memAllocInfo);
5067 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5069 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5070 funcNm = (S8 **) memAllocInfo->backTrace;
5071 #ifdef SS_MEM_LEAK_SOL
5072 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5074 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5075 #ifdef SS_4GMX_LCORE
5076 MxHeapFree(SsiHeap, funcNm[i]);
5081 #endif /* SS_MEM_LEAK_SOL */
5082 #ifdef SS_MEM_LEAK_FREE_TRACE
5086 sprintf( prntBuf, "\n==============================\n");
5088 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5090 sprintf( prntBuf, "Address: [%x]\n", addr);
5092 sprintf( prntBuf, "Address: [%lx]\n", addr);
5095 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5096 funcNm = backtrace_symbols(trace, traceSize);
5097 sprintf( prntBuf, "[bt] Execution path:\n");
5099 for (i=0; i < traceSize; ++i)
5101 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5104 sprintf( prntBuf, "\n==============================\n");
5107 #endif /* SS_MEM_LEAK_FREE_TRACE */
5108 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5109 #ifdef SS_4GMX_LCORE
5110 MxHeapFree(SsiHeap, funcNm);
5111 MxHeapFree(SsiHeap, memAllocInfo);
5118 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5121 #ifndef SS_MEM_LEAK_SOL
5122 if(idx == CM_MEM_USR_MDL)
5125 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5127 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5129 sprintf( prntBuf, "Address: [%u]\n", addr);
5131 sprintf( prntBuf, "Address: [%lu]\n", addr);
5134 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5135 funcNm = backtrace_symbols(trace, traceSize);
5136 sprintf( prntBuf,"[bt] Execution path:\n");
5138 for (i=0; i < traceSize; ++i)
5140 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5143 printf("\n==============================\n");
5144 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5145 #ifdef SS_4GMX_LCORE
5146 MxHeapFree(SsiHeap, funcNm);
5151 #endif /* SS_MEM_LEAK_SOL */
5153 /*cm_mem_c_001.main_25 : */
5155 } /* cmRlsAllocBlk */
5158 #ifdef SS_MEM_LEAK_SOL
5161 * Fun: cmAddrToSymStr
5163 * Desc: Initializes the memory leak detection module
5168 * Notes: This function initializes the memory leak detection module.
5186 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5188 return (snprintf(buffer, size, "[0x%p]", pc));
5191 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5192 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5194 return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5197 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5201 return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5203 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5206 } /* cmAddrToSymStr */
5210 * Fun: cmLeakCallBack
5212 * Desc: Initializes the memory leak detection module
5217 * Notes: This function initializes the memory leak detection module.
5232 Backtrace_t *bt = (Backtrace_t *)arg;
5233 if (bt->bt_actcount >= bt->bt_maxcount)
5235 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5236 #ifdef SS_4GMX_LCORE
5237 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
5238 memset(buffer, 0, 510);
5240 buffer = (S8 *)calloc(1, 510);
5242 /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &buffer, 510); */
5243 (void) cmAddrToSymStr((void *)pc, buffer, 505);
5244 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5247 } /* cmLeakCallBack */
5253 * Desc: Initializes the memory leak detection module
5258 * Notes: This function initializes the memory leak detection module.
5274 bt.bt_buffer = buffer;
5275 bt.bt_maxcount = count;
5278 if (getcontext(&u) < 0)
5280 (Void) walkcontext(&u, cmLeakCallBack, &bt);
5281 return (bt.bt_actcount);
5285 #endif /* SS_MEM_LEAK_SOL */
5287 #endif /* SS_MEM_LEAK_STS */
5288 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5289 * These include sanity check functions for bucket and heap,
5290 * for printing several memory related statistics
5292 #ifdef SSI_DEBUG_LEVEL1
5295 * Fun: cmMmBktSanityChk
5297 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
5298 * This API gets called when trampling is detected in a memory block.
5300 * Ret: RTRAMPLINGNOK - Trampling, serious error
5301 * RTRAMPLINGOK - Trampling, but OK to proceed
5303 * Notes: This function performs the memory block sanity in a bucket. This
5304 * function is called by cmAlloc and cmFree as part of error handling mechanism.
5305 * Performs sanity check for the whole bucket by traversing each
5306 * of the memory blocks using the pointer bktStartPtr.
5307 * Keeps track of number of tramplings happened. If the count
5308 * exceeds the threshold decided, then invalidates this bucket.
5313 static S16 cmMmBktSanityChk(CmMmBkt *bkt)
5319 bkt->trampleCount = 0;
5321 /* scan the entire memory list of the bucket */
5322 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5323 blkCnt < (bkt->numBlks); blkCnt++)
5325 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5327 bkt->trampleCount++;
5328 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5330 /* Take action to invalidate the entire bucket */
5331 return (RTRAMPLINGNOK);
5334 /* reach next memory block in this bucket manually */
5335 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5339 /* display an error message here */
5340 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5341 SDisplay(0, dbgPrntBuf);
5344 return (RTRAMPLINGOK);
5349 * Fun: cmMmHeapSanityChk
5351 * Desc: Performs the sanity check for the memory blocks in the memory heap.
5352 * This API gets called when trampling is detected in heap(Alloc/Free).
5354 * Ret: RTRAMPLINGNOK - Trampling, serious error
5355 * RTRAMPLINGOK - Trampling, but OK to proceed
5357 * Notes: This function performs the memory block sanity in the heap. This
5358 * function is called by cmHeapAlloc and cmHeapFree as part of error
5359 * handling mechanism. Keeps track of number of tramplings happened.
5360 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5361 * count is less than threshold, then return RTRAMPLINGOK.
5366 static S16 cmMmHeapSanityChk(CmMmHeapCb *heapCb)
5369 /* increment the trample count */
5370 heapCb->trampleCount++;
5372 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5374 return (RTRAMPLINGNOK);
5377 return (RTRAMPLINGOK);
5382 * Fun: cmMmRegIsBlkSane
5384 * Desc: Performs the sanity check for the memory block by checking its header.
5386 * Ret: ROK - If no trampling is detected in the block
5387 * RFAILED - If trampling is detected in the block
5389 * Notes: This function performs the memory block sanity in a block.
5394 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr)
5399 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5401 if (blkPtr->trSignature[sigCnt] != 0xAB)
5414 * Desc: Computes the hash list index (bin number) for a specified
5415 * key of type (x % 101).
5417 * return (idx % hash_table_size);
5419 * Ret: ROK - successful, *idx contains computed index
5426 static S16 cmMmHashFunc
5428 CmMmHashListCp *hashListCp,
5434 *idx = (uint16_t)(key % hashListCp->numOfbins);
5438 } /* end of cmMmHashFunc () */
5442 * Fun: cmMmHashListInit
5444 * Desc: Initializes a hash list. Parameters are:
5446 * hashListCp control point for hash list
5447 * nmbBins number of bins in the hash list. Storage will
5448 * be allocated for them from the indicated memory
5451 * pool for allocating storage for bins.
5453 * Ret: ROK - initialization successful
5454 * RFAILED - initialization failed, lack of memory
5461 static S16 cmMmHashListInit
5463 CmMmHashListCp *hashListCp, /* hash list to initialize */
5464 uint16_t nmbBins, /* number of hash list bins */
5465 Region region, /* memory region to allocate bins */
5466 Pool pool /* memory pool to allocate bins */
5470 CmMmHashListEnt *hl;
5473 /* initialize control point fields */
5474 hashListCp->hashList = NULLP;
5475 hashListCp->numOfbins = 0;
5476 hashListCp->numOfEntries = 0;
5478 /* allocate memory for bins */
5481 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool, (Data **) &hashListCp->hashList,
5482 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5485 /* initialize bin pointers */
5486 hl = hashListCp->hashList;
5487 for(i = 0; i < nmbBins; i++)
5489 hl[i].size = hl[i].numAttempts = 0;
5492 /* initialize bin size */
5493 hashListCp->numOfbins = nmbBins;
5501 * Fun: cmMmHashListDeinit
5503 * Desc: Deinitializes a hash list. Deallocates memory for bins
5504 * and resets header fields. Parameters are:
5506 * hashListCp control point for hash list
5508 * pool for allocating storage for bins.
5510 * Ret: ROK - successful
5511 * RFAILED - failure, invalid parameters
5518 static S16 cmMmHashListDeinit
5520 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
5521 Region region, /* memory region to allocate bins */
5522 Pool pool /* memory pool to allocate bins */
5526 /* deallocate memory for bins */
5527 if (hashListCp->numOfbins)
5528 (Void) SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool,
5529 (Data *) hashListCp->hashList,
5530 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5532 /* deinitialize control point fields */
5533 hashListCp->hashList = NULLP;
5534 hashListCp->numOfbins = 0;
5535 hashListCp->numOfEntries = 0;
5538 } /* end of cmMmHashListDeinit */
5542 * Fun: cmMmHashListInsert
5544 * Desc: Inserts a new entry in the hash list. Parameters are:
5546 * hashListCp control point for hash list
5547 * key pointer to key string in the new entry
5549 * Ret: ROK - insertion successful
5550 * RFAILED - insertion failed (incorrect parameter values)
5557 static S16 cmMmHashListInsert
5559 CmMmHashListCp *hashListCp, /* hash list to add to */
5560 uint32_t key /* pointer to key */
5563 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
5564 uint16_t idx; /* index for insertion into hash list */
5568 /* check if hashListCp is initialised yet */
5569 if ( hashListCp->numOfbins == 0)
5572 /* compute index for insertion */
5573 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5576 hashListEnt = hashListCp->hashList;
5578 if (hashListEnt[idx].numAttempts == 0)
5580 /* new entry, insert here */
5581 hashListEnt[idx].size = key;
5582 hashListEnt[idx].numAttempts++;
5583 /* increment count of entries in hash list */
5584 hashListCp->numOfEntries++;
5588 /* this hash is occupied, re-hash it using linear probing */
5589 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5591 if (hashListEnt[i].size == key)
5593 hashListEnt[i].numAttempts++;
5597 if (hashListEnt[i].numAttempts == 0)
5599 hashListEnt[i].size = key;
5600 hashListEnt[i].numAttempts++;
5601 /* increment count of entries in hash list */
5602 hashListCp->numOfEntries++;
5607 if (i == CMM_STAT_HASH_TBL_LEN)
5609 /* there is no free slot for this key */
5615 } /* end of cmMmHashListInsert */
5617 #endif /* SSI_DEBUG_LEVEL1 */
5618 /* cm_mem_c_001.main_15 : Additions */
5619 #ifdef SS_HISTOGRAM_SUPPORT
5622 * Fun: cmHstGrmHashListInit
5624 * Desc: Initializes a hash list. Parameters are:
5626 * hashListCp control point for hash list
5627 * Ret: ROK - initialization successful
5628 * RFAILED - initialization failed, lack of memory
5635 static S16 cmHstGrmHashListInit
5637 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5640 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5642 /* display an error message here */
5643 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5645 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5647 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5649 SDisplay(0, dbgPrntBuf);
5651 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5657 * Fun: cmHstGrmHashListDeInit
5659 * Desc: De-initializes a hash list. Parameters are:
5661 * hashListCp control point for hash list
5662 * Ret: ROK - initialization successful
5663 * RFAILED - initialization failed, lack of memory
5670 static S16 cmHstGrmHashListDeInit
5672 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5675 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5677 /* display an error message here */
5678 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5680 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5682 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5684 SDisplay(0, dbgPrntBuf);
5686 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5692 * Fun: cmHstGrmFreeInsert
5694 * Desc: Inserts a Freed information in into the hash list. Parameters are:
5696 * bkt : pointer to bucket for which memory is freed.
5697 * line : Line where memory is freed.
5698 * file : file where memory is freed.
5699 * entId : Tapa task which releases the memory.
5701 * Ret: ROK - insertion successful
5702 * RFAILED - insertion failed (incorrect parameter values)
5709 static S16 cmHstGrmFreeInsert
5711 CmHstGrmHashListCp* hashListCp, /* hash list cp */
5712 uint32_t blkSz, /* size of the block freed */
5713 uint32_t line, /* Line number */
5714 uint8_t *fileName, /* file name */
5715 uint8_t entId /* Tapa task which free the memory */
5718 uint32_t binIdx = 0; /* Bin index to insert the entry into the hash list */
5719 uint32_t key = 0; /* Key to fine the bin index */
5720 uint32_t ret = 0; /* Return value */
5721 CmMemEntries *entry = NULLP; /* Entry which contains the information */
5725 /* check for the total number of entries in the hash list. *
5726 * If there is no place for new entry return failure */
5727 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5729 /* After comuting the hash bind and key, check the entity already *
5730 existing or not. if we found the entry then update the information */
5731 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5734 entry->freedBytes += blkSz;
5735 entry->bucketFreeReq++;
5739 /* If hash list is full then print the error tna continue */
5740 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5742 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");
5746 /* Take the address of next free entry in the hash bin */
5747 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5749 /* Increase the number of time frees called */
5750 entry->bucketFreeReq++;
5751 entry->freedBytes += blkSz;
5753 /* Fill the information into the entry structure */
5754 cmHstGrmFillEntry(entry, key, line, fileName, entId);
5755 /* Increase the total numbet of entries in the bin */
5756 hashListCp->hashList[binIdx].numOfEntries++;
5758 /* Increase the total number of entries in the hash list */
5759 hashListCp->totalNumEntries++;
5762 } /* end of cmHstGrmFreeInsert */
5767 * Fun: ret = cmHstGrmAllocInsert
5769 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
5771 * hashListCp control point for hash list
5772 * key pointer to key string in the new entry
5774 * Ret: ROK - insertion successful
5775 * RFAILED - insertion failed (incorrect parameter values)
5782 static S16 cmHstGrmAllocInsert
5784 CmHstGrmHashListCp *hashListCp,
5792 uint32_t binIdx = 0;
5795 CmMemEntries *entry = NULLP;
5798 /* check for the total number of entries in the hash list. *
5799 * If there is no place for new entry return failure */
5800 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5802 /* After comuting the hash bind and key, check the entity already *
5803 existing or not. if we found the entry then update the information */
5804 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5808 entry->allocBytes += blkSz;
5809 entry->bucketAllocReq++;
5810 entry->wastedBytes += (blkSz - *reqSz);
5814 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5816 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");
5820 /* Take the address of next free entry in the hash bin */
5821 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5823 /* Clauculae the wasted bytes */
5824 /* Here wasted byte is differnce between the byte user
5825 * has requested and the byte the ssi allocated */
5826 entry->wastedBytes += (blkSz - *reqSz);
5827 entry->bucketAllocReq++;
5828 entry->allocBytes += blkSz;
5830 /* Fill the information into the entry structure */
5831 cmHstGrmFillEntry(entry, key, line, fileName, entId);
5832 /* Increase the total numbet of entries in the bin */
5833 hashListCp->hashList[binIdx].numOfEntries++;
5835 /* Increase the total number of entries in the hash list */
5836 hashListCp->totalNumEntries++;
5839 } /* end of cmHstGrmAllocInsert */
5844 * Fun: cmHstGrmGetHashIdxAndKey
5846 * Desc: Finds an entry in the hash list. Parameters are:
5848 * hashListCp control point for hash list
5849 * key pointer to key string in the new entry
5851 * Ret: ROK - insertion successful
5852 * RFAILED - insertion failed (incorrect parameter values)
5859 static S16 cmHstGrmGetHashIdxAndKey
5870 /* Calculate the key using file name and line number */
5871 for(i = 0 ; fileName[i] != '\0'; i++)
5873 *key += fileName[i];
5876 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
5878 } /* end of cmHstGrmFillEntry */
5882 * Fun: cmHstGrmFillEntry
5884 * Desc: Insert the entry into the hash list.
5886 * entry : Infornation which will be inserted into the hash list
5887 * key : Which will be used ti find the entry.
5888 * line : Line number
5889 * fileName : File name
5890 * entId : Tapa task Id
5892 * Ret: ROK - insertion successful
5893 * RFAILED - insertion failed (incorrect parameter values)
5900 static S16 cmHstGrmFillEntry
5902 CmMemEntries *entry,
5913 entry->entId = entId;
5914 for(idx = 0; fileName[idx] != '\0'; idx++)
5916 entry->fileName[idx] = fileName[idx];
5918 entry->fileName[idx] = '\0';
5920 } /* end of cmHstGrmFillEntry */
5924 * Fun: cmHstGrmFindEntry
5926 * Desc: Finds an entry in the hash list. Parameters are:
5928 * hashListCp control point for hash list
5929 * key pointer to key string in the new entry
5931 * Ret: ROK - insertion successful
5932 * RFAILED - insertion failed (incorrect parameter values)
5939 static S16 cmHstGrmFindEntry
5941 CmHstGrmHashListCp *hashListCp,
5944 CmMemEntries **entry
5948 uint32_t numEnt = 0;
5949 uint32_t numBin = 0;
5950 CmHstGrmHashListEnt *tmpBin = NULLP;
5953 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
5955 /* find for the entry in the bin */
5956 tmpBin = &(hashListCp->hashList[*binIdx]);
5957 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
5959 /* If key supplied is matched with the stored key then
5960 * return that entity */
5961 if(tmpBin->entries[numEnt].key == key)
5963 *entry = &(tmpBin->entries[numEnt]);
5965 }/* End of if (tmpBin->entries[numEnt].key) */
5966 }/* end of for (numEnt = 0) */
5968 /* Here we are checking for any room left in the bin. If the room *
5969 exists its mean that there is no entry with the Key. so return *
5971 If there is no room in the bin, then check the other bins to find *
5973 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
5975 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
5978 }/* End of if (binIdx) */
5982 }/* End of else (binIdx) */
5983 } /* End of if (numEnt) */
5986 printf ("Unable to find the entry in hash list\n");
5988 }/* End of else (numEnt) */
5989 }/* end of for (numBin = 0) */
5991 printf("Unable to find the entry in the hash list\n");
5993 } /* end of cmHstGrmFindEntry */
5995 #endif /* SS_HISTOGRAM_SUPPORT */
5996 #ifdef T2K_MEM_LEAK_DBG
5997 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
5998 uint32_t getT2kMemLeakIndex(uint32_t address)
6000 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6003 static uint32_t t2kMemAllocTick;
6004 static uint32_t smallTick;
6006 void InsertToT2kMemLeakInfo(uint32_t address, uint32_t size, uint32_t lineNo, char* fileName)
6008 uint32_t idx = getT2kMemLeakIndex(address);
6010 if(((uint32_t)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6012 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6013 "line is %ld \n", address, size, fileName, lineNo);
6016 if(gMemLeakInfo[idx].address == 0)
6018 gMemLeakInfo[idx].address = address;
6019 gMemLeakInfo[idx].size = size;
6020 gMemLeakInfo[idx].lineNo = lineNo;
6021 gMemLeakInfo[idx].fileName = fileName;
6022 gMemLeakInfo[idx].age = t2kMemAllocTick;
6023 gMemLeakInfo[idx].prevRemLineNo = 0;
6024 gMemLeakInfo[idx].prevRemFileName = '\0';
6026 if(smallTick++ == 4096)
6029 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
6034 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
6035 "line is %ld \n",address, idx, fileName, lineNo);
6036 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
6037 "Age:%ld, differnce in Age:%ld",
6038 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
6039 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
6040 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
6045 void RemoveFromT2kMemLeakInfo(uint32_t address, char *file, uint32_t line)
6047 uint32_t idx = getT2kMemLeakIndex(address);
6049 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
6051 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
6057 if(gMemLeakInfo[idx].address == address)
6059 gMemLeakInfo[idx].address = 0;
6060 gMemLeakInfo[idx].age = 0;
6061 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6062 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
6064 gMemLeakInfo[idx].lastDelLineNum = line;
6065 gMemLeakInfo[idx].lastDelFileName = file;
6066 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6070 printf("Something is wrong, trying to remove %lx idx = %ld from"
6071 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
6072 gMemLeakInfo[idx].address);
6075 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6076 gMemLeakInfo[idx].lastDelLineNum);
6078 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6080 printf("Previous File:%s, Previous Line:%ld\n",
6081 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6086 void DumpT2kMemLeakInfoToFile()
6090 FILE *fp = fopen("memLeakInfo.txt","wb");
6094 printf("Could not open file for dumping mem leak info\n");
6098 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6100 if(gMemLeakInfo[i].address != 0)
6102 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6103 if(onlyFileName == NULL)
6105 onlyFileName = gMemLeakInfo[i].fileName;
6108 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
6109 gMemLeakInfo[i].size,
6110 gMemLeakInfo[i].age,
6111 gMemLeakInfo[i].lineNo,
6116 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6122 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6124 /* For Updating SOC Specific Memory Information */
6125 S16 UpdateSocMemInfo
6134 void *iccHdl = NULLP;
6135 uint32_t poolFreeCnt[4];
6136 uint32_t poolUsedCnt[4];
6137 uint32_t poolSize[4];
6138 uint32_t poolTotAvail[4];
6140 idxReg = mInfo->numRegions;
6141 mInfo->numRegions = mInfo->numRegions + 1;
6142 /* Calling Soc specific API to get shared memory status */
6143 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6144 iccHdl = ssGetIccHdl(areaIndex);
6146 /* Populating global memory information */
6147 mInfo->regInfo[idxReg].numPools = numPool;
6148 mInfo->regInfo[idxReg].regionId = areaIndex;
6149 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6151 /* Calling INTEL API's to Get Free MEM BLOCKS */
6152 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6153 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6154 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6155 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6157 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6158 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6159 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6160 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6162 poolSize[0] = ICC_POOL_ZERO_SIZE;
6163 poolSize[1] = ICC_POOL_ONE_SIZE;
6164 poolSize[2] = ICC_POOL_TWO_SIZE;
6165 poolSize[3] = ICC_POOL_THREE_SIZE;
6167 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6168 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6169 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6170 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6172 for(idxPool=0; idxPool<numPool;idxPool++)
6174 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6175 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
6176 poolTotAvail[idxPool];
6177 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6178 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
6179 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6181 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
6182 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6191 * Fun: isL2MemUsageBelowLowerThreshold
6193 * Desc: Checks for the Lower threshold of ICC memory.
6195 * region region for obtaining the ICC handle
6197 * Ret: TRUE - Threshold has reached
6198 * FALSE - Threshold has not reached
6205 uint32_t isL2MemUsageBelowLowerThreshold(
6209 void * iccHdl = ssGetIccHdl(region);
6211 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6212 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6214 /* We are below the threshold if free count in BOTH of the pools
6215 * is above the ICC_MEM_LOWER_THRESHOLD % */
6216 if(((poolZeroFreeCnt * 100) >
6217 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6218 ((poolOneFreeCnt * 100) >
6219 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6230 * Fun: isMemUsageBelowLowerThreshold
6232 * Desc: Checks for the Lower threshold of ICC memory.
6234 * region region for obtaining the ICC handle
6236 * Ret: TRUE - Threshold has reached
6237 * FALSE - Threshold has not reached
6244 uint32_t isMemUsageBelowLowerThreshold(
6248 void * iccHdl = ssGetIccHdl(region);
6250 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6251 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6252 uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6253 uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6255 /* We are below the threshold if free count in BOTH of the pools
6256 * is above the ICC_MEM_LOWER_THRESHOLD % */
6257 if(((poolZeroFreeCnt * 100) >
6258 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6259 ((poolOneFreeCnt * 100) >
6260 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6261 ((poolTwoFreeCnt * 100) >
6262 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6263 ((poolThreeFreeCnt * 100) >
6264 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6274 * Fun: isMemUsageAboveUpperThreshold
6276 * Desc: Checks for the Upper threshold of ICC memory.
6278 * region region for obtaining the ICC handle
6280 * Ret: TRUE - Threshold has reached
6281 * FALSE - Threshold has not reached
6288 static uint32_t isMemUsageAboveUpperThreshold(
6292 void * iccHdl = ssGetIccHdl(region);
6294 uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6295 uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6296 uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6297 uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6299 /* We are above the threshold if free count in either of the pools
6300 * is below the ICC_MEM_UPPER_THRESHOLD % */
6301 if(((poolZeroFreeCnt * 100) <
6302 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6303 ((poolOneFreeCnt * 100) <
6304 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6305 ((poolTwoFreeCnt * 100) <
6306 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6307 ((poolThreeFreeCnt * 100) <
6308 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6316 /* ccpu00142274- Function to check if we have reached the
6317 * Threshold for dropping UL packets at the RLC. This function
6318 * measures the free count of the ICC memory and based on the
6319 * volume of packets it sets an alarm to drop packets.
6320 * In DL, the PDCP packets are dropped at Admission Control, but
6321 * at UL we need to check if its an AM(Data only and
6322 * not Status PDU) or UM packet and free the PDU
6323 * Note: With the current design, we have PDCP DL and RLC UL
6324 * running in the same thread and the below function will be
6325 * accessed in tandem. But if PDCP DL and RLC UL are made to run
6326 * in different threads then there might be a race condition.
6327 * Please revisit this function in such a case.
6331 * Fun: isMemThreshReached
6333 * Desc: Checks whether the system has reached the
6334 * designated threshold of ICC memory.
6336 * region region for obtaining the ICC handle
6338 * Ret: ROK - Threshold has not reached
6339 * RFAILED - Threshold has reached
6346 uint32_t isMemThreshReached(
6352 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6357 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6359 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6360 memoryCheckCounter = 0;
6366 #endif /* SS_LOCKLESS_MEMORY */
6367 /**********************************************************************
6369 **********************************************************************/