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 *******************************************************************************/
19 /********************************************************************20**
21 Name: Common Memory Manager
25 Desc: C source code for the Commom Memory Manager module.
29 Sid: cm_mem.c@@/main/28 - Fri Aug 26 13:52:41 2011
33 *********************************************************************21*/
36 /************************************************************************
38 The following functions are provided in this file.
40 cmMmRegInit Memory Region Initialization.
41 cmMmRegDeInit Memory Region Deinitialization.
43 ************************************************************************/
46 /* header include files (.h) */
47 #include "envopt.h" /* environment options */
48 #include "envdep.h" /* environment dependent */
49 #include "envind.h" /* environment independent */
51 #include "gen.h" /* general */
52 #include "ssi.h" /* system services */
53 #include "cm_mem.h" /* Common memory manager cm_mem_c_001.main_15 */
54 #ifdef SS_MEM_LEAK_STS
58 #ifdef SS_MEM_LEAK_SOL
61 #include <sys/machelf.h>
62 #else /* SS_MEM_LEAK_SOL */
64 #endif /* SS_MEM_LEAK_SOL */
65 #include <sys/types.h>
67 #endif /* SS_MEM_LEAK_STS */
69 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
70 #include "cm_hash.h" /* common hash functions */
72 #ifdef SS_MULTICORE_SUPPORT /* cm_mem_c_001.main_14 */
73 #include "ss_dep.h" /* implementation-specific */
74 #include "ss_queue.h" /* queues */
75 #include "ss_task.h" /* tasking */
77 #ifdef SS_MULTICORE_SUPPORT
78 #include "ss_dep.h" /* implementation-specific */
79 #include "ss_queue.h" /* queues */
80 #include "ss_task.h" /* tasking */
83 /* header/extern include files (.x) */
84 #include "gen.x" /* general */
85 #include "ssi.x" /* system services */
86 #ifdef SS_MULTICORE_SUPPORT
87 #include "ss_dep.x" /* implementation-specific */
88 #include "ss_queue.x" /* queues */
89 #include "ss_task.x" /* system services */
91 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
92 #include "cm_hash.x" /* common hash functions */
94 #include "cm_mem.x" /* Common memory manager */
95 /* cm_mem_c_001.main_28 : Fix for compilation warning */
96 #include "cm_lib.x" /* common library functions */
97 /* cm_mem_c_001.main_15: Addition */
98 #ifdef SS_MEM_LEAK_STS
99 #include "cm_hash.x" /* common hash functions */
100 #endif /* SS_MEM_LEAK_STS */
104 #endif /* USE_PURE */
105 #ifdef SS_MULTICORE_SUPPORT
106 #include "ss_dep.x" /* implementation-specific */
107 #include "ss_queue.x" /* queues */
108 #include "ss_task.x" /* system services */
113 #endif /* USE_PURE */
115 #ifdef SS_LIGHT_MEM_LEAK_STS
117 uint32_t queueIndxAllocCnt =0;
118 uint32_t queueIndxFreeCnt =0;
119 uint32_t allocQueueFullCnt =0;
120 uint32_t allocQueueEmptyCnt =0;
129 /* forward references */
130 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
131 /* cm_mem_c_001.main_15: Addition */
132 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler*/
137 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
138 uint32_t memFreeCount=0;
139 uint32_t cmFreeCaller[4]={0};
140 uint32_t cmAllocCaller[4]={0};
141 Data *startPtr256=NULLP;
142 Data *startPtr128=NULLP;
143 uint32_t cmMemInfo128[100000][2]={0, 0};
144 uint32_t cmMemInfo256[100000][2]={0, 0};
145 Data *startPtr512=NULLP;
146 Data *startPtr768=NULLP;
147 Data *startPtr1664=NULLP;
148 Data *startPtr4800=NULLP;
149 Data *startPtr9920=NULLP;
152 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
153 //extern CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
155 #ifdef SS_HISTOGRAM_SUPPORT
156 #ifdef SSI_DEBUG_LEVEL1
157 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,
158 uint32_t memType, uint32_t line, uint8_t *fileName, uint8_t entId, Bool hstReg));
159 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size, uint32_t memType, uint32_t line, uint8_t *fileName, uint8_t entId, Bool hstReg));
160 /*cm_mem_c_001.main_20-added new functionto allocate memory from new region*/
162 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size,
163 uint32_t line, uint8_t *fileName, uint8_t entId, Bool hstReg));
164 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,
165 uint32_t line, uint8_t *fileName, uint8_t entId, Bool hstReg));
166 #endif /* SSI_DEBUG_LEVEL1 */
168 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size, uint32_t line,
169 uint8_t *fileName, uint8_t entId, Bool hstReg));
171 static S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size,
172 uint32_t line, uint8_t *fileName, uint8_t entId, Bool hstReg));
173 #else /* no histogram support */
174 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
175 #ifdef SSI_DEBUG_LEVEL1
176 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size, uint32_t memType));
179 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
181 #endif /* SSI_DEBUG_LEVEL1 */
183 static S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
185 /* cm_mem_c_001.main_15 :Additions */
186 #ifdef SS_LIGHT_MEM_LEAK_STS
187 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, uint32_t memType, uint32_t lineNo,uint8_t *funcName ));
188 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size, uint32_t lineNo, uint8_t* funcName));
189 #else /*SS_LIGHT_MEM_LEAK_STS */
190 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
191 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, uint32_t memType));
193 #ifdef T2K_MEM_LEAK_DBG
194 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, char* file, uint32_t line));
196 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
198 #endif /* SSI_DEBUG_LEVEL1 */
199 #ifdef T2K_MEM_LEAK_DBG
200 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size, char* file, uint32_t line));
202 static S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size));
204 #endif /* SS_HISTOGRAM_SUPPORT */
205 #endif /*SS_LIGHT_MEM_LEAK_STS*/
206 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
208 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
209 static S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
212 static S16 cmCtl ARGS((Void *regionCb, Event event, SMemCtl *memCtl));
214 static Void cmMmHeapInit ARGS((Data *memAddr, CmMmHeapCb *heapCb, Size size));
215 static Void cmMmBktInit ARGS((Data **memAddr, CmMmRegCb *regCb,
216 CmMmRegCfg *cfg, uint16_t bktIdx, uint16_t *lstMapIdx));
218 /* cm_mem_c_001.main_12 - addition of protoypes for sanity check and hash list functions */
219 #ifdef SSI_DEBUG_LEVEL1
220 static S16 cmMmBktSanityChk ARGS((CmMmBkt *bkt));
221 static S16 cmMmHeapSanityChk ARGS((CmMmHeapCb *heapCb));
222 static S16 cmMmHashFunc ARGS((CmMmHashListCp *hashListCp, uint32_t key, uint16_t *idx ));
223 static S16 cmMmHashListInit ARGS((CmMmHashListCp *hashListCp, uint16_t nmbBins,
224 Region region, Pool pool));
225 static S16 cmMmHashListDeinit ARGS((CmMmHashListCp *hashListCp, Region region, Pool pool));
226 static S16 cmMmHashListInsert ARGS((CmMmHashListCp *hashListCp, uint32_t key));
227 #endif /* SSI_DEBUG_LEVEL1 */
228 /* cm_mem_c_001.main_15 : Addtions */
229 #ifdef SS_HISTOGRAM_SUPPORT
230 static S16 cmHstGrmAllocInsert ARGS((CmHstGrmHashListCp *hashListCp, uint32_t blkSz, uint32_t *reqSz, uint32_t line, uint8_t *fileName, uint8_t entId));
231 static S16 cmHstGrmFreeInsert ARGS((CmHstGrmHashListCp* hashListCp, uint32_t blkSz, uint32_t line, uint8_t *fileName, uint8_t entId));
232 static S16 cmHstGrmHashListInit ARGS((CmHstGrmHashListCp *hashListCp));
233 static S16 cmHstGrmHashListDeInit ARGS((CmHstGrmHashListCp *hashListCp));
234 static S16 cmHstGrmGetHashIdxAndKey ARGS((uint8_t *fileName, uint32_t line, uint32_t *binIdx, uint32_t *key));
235 static S16 cmHstGrmFindEntry ARGS((CmHstGrmHashListCp *hashListCp, uint32_t key, uint32_t *binIdx, CmMemEntries **entry));
236 static S16 cmHstGrmFillEntry ARGS((CmMemEntries *entry, uint32_t key, uint32_t line, uint8_t *fileName, uint8_t entId));
237 #endif /* SS_HISTOGRAM_SUPPORT */
239 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler */
244 /* public variable declarations */
247 #endif /* USE_PURE */
248 /* cm_mem_c_001.main_15:Additions */
249 #ifdef SS_MEM_LEAK_STS
250 MemUsrMdlStr memUsrMdlStr[]=
252 MEMRAW2STR(DEFAULT, STACK),
253 MEMRAW2STR(tc, PDCP_LAYER),
254 MEMRAW2STR(Tc, PDCP_LAYER),
255 MEMRAW2STR(mg, GCP_LAYER),
256 MEMRAW2STR(Mg, GCP_LAYER),
261 #endif /* SS_MEM_LEAK_STS */
262 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
268 #ifdef T2K_MEM_LEAK_DBG
270 uint8_t minBktSzBitMask; /* minimum allocation size in Log(x)base 2, where X is minimum bucket size in region */
271 uint16_t minBktSzMins1; /* X-1 */
273 static RegMinBktSzInfo regMinBktSzInfo[SS_MAX_REGS] = {{8,0xFF},{7,0x7F},{7,0x7F},{7,0x7F}};
274 RegionMemLeakInfo regMemLeakInfo;
276 uint32_t getT2kMemLeakIndex(uint64_t address, Region region)
278 return ((address - regMemLeakInfo.regStartAddr[region]) >> regMinBktSzInfo[region].minBktSzBitMask);
281 static uint32_t t2kMemAllocTick;
282 static uint32_t smallTick;
284 void InsertToT2kMemLeakInfo(uint64_t address, uint32_t size, uint32_t lineNo, char* fileName, Region region)
287 T2kMeamLeakInfo *leakInfo;
293 uint32_t index1 = getT2kMemLeakIndex(address,region);
295 if(((uint64_t)(address - regMemLeakInfo.regStartAddr[region]) & regMinBktSzInfo[region].minBktSzMins1) !=0)
297 printf("address in InsertToT2kMemLeakInfo is %ld size = %d file is %s line is %d \n", address, size, fileName, lineNo);
300 leakInfo = (((T2kMeamLeakInfo*)(regMemLeakInfo.gMemLeakInfo[region])) + index1);
301 if(leakInfo->address == 0)
303 leakInfo->address = address;
304 leakInfo->size = size;
305 leakInfo->lineNo = lineNo;
306 leakInfo->fileName = fileName;
307 leakInfo->age = t2kMemAllocTick;
308 leakInfo->prevRemLineNo = 0;
309 leakInfo->prevRemFileName = '\0';
311 //printf("InsertToT2kMemLeakInfo the adress from List Address = %x, index1 = %d from File=%s, line=%d \n",address,index1,fileName,lineNo);
312 if(smallTick++ == 4096)
315 leakInfo->age = (++t2kMemAllocTick);
320 printf("Something is wrong, trying to insert %ld index1 = %d file is %s line is %d \n",address, index1, fileName, lineNo);
321 printf("Address present :%ld, from File:%s, Line:%d, Size:%d, Age:%d",
322 leakInfo->address, leakInfo->fileName,
323 leakInfo->lineNo, leakInfo->size,
329 void RemoveFromT2kMemLeakInfo(uint64_t address, char *file, uint32_t line,Region region)
331 T2kMeamLeakInfo *leakInfo;
338 uint32_t index1 = getT2kMemLeakIndex(address, region);
340 if(index1 >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
342 printf("index1 out of range = %d address is %ld file = %s line = %d. We are going to crash!!!\n",
348 leakInfo = (((T2kMeamLeakInfo*)(regMemLeakInfo.gMemLeakInfo[region])) + index1);
349 if(leakInfo->address == address)
352 leakInfo->address = 0;
354 leakInfo->prevRemLineNo = leakInfo->lineNo;
355 leakInfo->prevRemFileName = leakInfo->fileName;
356 leakInfo->lastDelLineNum = line;
357 leakInfo->lastDelFileName = file;
361 printf("Something is wrong, trying to remove %ld index1 = %d from File=%s, line=%d address present is %ld region%d \n",address, index1, file,line,leakInfo->address,region);
363 printf("\n Last Del file %s line %d\n",leakInfo->lastDelFileName,
364 leakInfo->lastDelLineNum);
366 if(leakInfo->prevRemFileName != NULLP)
368 printf("Previous File:%s, Previous Line:%d\n",
369 leakInfo->prevRemFileName, leakInfo->prevRemLineNo);
374 void DumpT2kMemLeakInfoToFile()
377 T2kMeamLeakInfo *leakInfo;
379 FILE *fp = fopen("memLeakInfo_reg.txt","wb");
383 printf("Could not open file for dumping mem leak info\n");
386 for(reg=0; reg <regMemLeakInfo.numActvRegions; reg++)
388 fprintf(fp, "REGION %d LEAKS START\n",reg);
391 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
393 leakInfo = (((T2kMeamLeakInfo*)(regMemLeakInfo.gMemLeakInfo[reg])) + i);
394 if(leakInfo->address != 0)
396 char* onlyFileName = rindex(leakInfo->fileName,'/');
397 if(onlyFileName == NULL)
399 onlyFileName = leakInfo->fileName;
402 fprintf(fp, "%ld s=%d a=%d l=%d f=%s\n",leakInfo->address,
409 fprintf(fp, "REGION %d LEAKS END\n",reg);
411 fprintf(fp,"Current t2kMemAllocTick = %d\n",t2kMemAllocTick);
415 #endif /* T2K_MEM_LEAK_DBG */
417 /* cm_mem_c_008.104 - Addition for memory calculator tool */
419 static Txt prntBuf[200]; /* print buffer */
420 static uint8_t tryHeap=0;
423 /* cm_mem_c_001.main_12 - addition for ssi enhancements prints */
424 /* cm_mem_c_001.main_20 Additions */
425 #if (defined(SSI_DEBUG_LEVEL1) || defined(SS_HISTOGRAM_SUPPORT) || \
426 defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
428 static Txt dbgPrntBuf[200]; /* print buffer */
430 #endif /*SSI_DEBUG_LEVEL1 || SS_HISTOGRAM_SUPPORT */
432 uint32_t num_times = 0;
433 #ifdef SSI_MEM_CORR_PREVENTION
434 uint32_t cmDblFreeAttempts = 0;
436 /* private variable declarations */
443 * Desc: Configure the memory region for allocation. The function
444 * registers the memory region with System Service by calling
448 * Ret: ROK - successful,
449 * RFAILED - unsuccessful.
451 * Notes: The memory owner calls this function to initialize the memory
452 * manager with the information of the memory region. Before
453 * calling this function, the memory owner should allocate memory
454 * for the memory region. The memory owner should also provide the
455 * memory for the control block needed by the memory manager. The
456 * memory owner should allocate the memory for the region control
457 * block as cachable memory. This may increase the average
458 * throughput in allocation and deallocation as the region control
459 * block is mostly accessed by the CMM.
464 S16 cmMmRegInit(Region region,CmMmRegCb *regCb,CmMmRegCfg *cfg)
470 #if (ERRCLASS & ERRCLS_INT_PAR)
473 Txt errMsg[256] = {'\0'};
475 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
481 #if (ERRCLASS & ERRCLS_INT_PAR)
483 /* error check on parameters */
484 if ((regCb == NULLP) || (cfg == NULLP))
489 /* Error check on the configuration fields */
490 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
491 (cfg->numBkts > CMM_MAX_BKT_ENT))
495 /* Check if the quantum size is power of 2 */
496 if ((cfg->numBkts) &&
497 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
499 /* cm_mem_c_001.main_20 Addition */
500 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
506 * Check if the size of the memory region is enough, whether bucket sizes
507 * are multiples of quantumn size, and also whether two consecutive buckets
508 * falls within same quanta.
510 lstQnSize = cfg->bktQnSize;
513 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
515 /* check if bucket size is mutiple of quantum size */
516 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
518 /* cm_mem_c_001.main_20 Addition */
519 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
521 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
522 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
524 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
525 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
531 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
534 * Two consecutive buckets are not separated by quantum size.
536 /* cm_mem_c_001.main_20 Addition */
537 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
541 /* cm_mem_c_001.main_20 Addition */
542 if (((cfg->bktCfg[bktIdx].size) /\
543 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
545 /* Error check whether the size of the mapping table is sufficient */
546 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
548 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
549 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
551 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
552 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
559 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
560 cfg->bktCfg[bktIdx].numBlks);
562 if (regCb->bktSize > cfg->size)
564 /* Size of the memory region is less than the required size */
566 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
571 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
576 /* Initialize the region control block */
577 regCb->region = region;
578 regCb->regInfo.regCb = regCb;
579 regCb->regInfo.start = cfg->vAddr;
580 regCb->regInfo.size = cfg->size;
583 avail_size = cfg->size;
584 #endif /* USE_PURE */
586 if ( cfg->chFlag & CMM_REG_OUTBOARD)
588 /* Out_of_board memory */
589 regCb->regInfo.flags = CMM_REG_OUTBOARD;
593 regCb->regInfo.flags = 0;
597 /* Initialize the memory manager function handlers */
598 /*cm_mem_c_001.main_21-registering new alloc function for new region*/
600 if(region == SS_WL_REGION)
602 regCb->regInfo.alloc = cmAllocWL;
603 regCb->regInfo.free = cmFreeWL;
608 /* Initialize the memory manager function handlers */
609 regCb->regInfo.alloc = cmAlloc;
610 regCb->regInfo.free = cmFree;
612 regCb->regInfo.ctl = cmCtl;
614 /* Initialize the physical address */
615 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
617 regCb->pAddr = cfg->pAddr;
620 /* Initial address of the memory region block */
621 memAddr = cfg->vAddr;
623 /* Initialize the fields related to the bucket pool */
624 regCb->bktMaxBlkSize = 0;
627 if (cfg->numBkts > 0 && cfg->numBkts < CMM_MAX_BKT_ENT)
629 /* Last bucket has the maximum size */
630 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
632 /* Get the power of the bktQnSize */
634 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
639 /* Initilaize the bktIndex of the map entries to FF */
640 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
642 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
646 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
648 /* Allocate the lock for the bucket pool */
649 /* cm_mem_c_001.main_13 : Replaced SInitLock with WTInitLock for NT */
651 if (WTInitLock (&(regCb->bktTbl[bktIdx].bktLock), cfg->lType) != ROK)
653 if (SInitLock (&(regCb->bktTbl[bktIdx].bktLock), cfg->lType) != ROK)
656 /* Free the initialzed lock for the earlier buckets. */
659 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
660 WTDestroyLock for NT */
661 /* cm_mem_c_001.main_24 fix for memory corruption*/
664 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
666 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
673 cmMmBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
676 /* Used while freeing the bktLock in cmMmRegDeInit */
677 regCb->numBkts = cfg->numBkts;
681 * Initialize the heap pool if size the memory region region is more
682 * than the size of the bucket pool
685 regCb->heapFlag = FALSE;
687 /* Align the memory address */
688 memAddr = (Data *)(PTRALIGN(memAddr));
690 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
693 * Round the heap size so that the heap size is multiple
696 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
700 /* Allocate the lock for the heap pool */
701 /* cm_mem_c_001.main_13 : Replaced SInitLock with WTInitLock for NT */
703 if (WTInitLock (®Cb->heapCb.heapLock, cfg->lType) != ROK)
705 if (SInitLock (®Cb->heapCb.heapLock, cfg->lType) != ROK)
708 bktIdx = cfg->numBkts;/* ccpu00125353: warning fix */
711 /* Free the initialzed locks of the buckets */
714 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
715 WTDestroyLock for NT */
716 /* cm_mem_c_001.main_24 fix for memory corruption*/
719 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
721 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
729 regCb->heapFlag = TRUE;
730 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
733 /* Call SRegRegion to register the memory region with SSI */
734 if (SRegRegion(region, ®Cb->regInfo) != ROK)
739 /* cm_mem_c_001.main_12 - addition for initializing the hash table */
740 #ifdef SSI_DEBUG_LEVEL1
741 /* Initialize the region level hash table for debug info storage */
742 if (cmMmHashListInit(®Cb->hashListCp, CMM_STAT_HASH_TBL_LEN, region, 0) != ROK)
746 #endif /* SSI_DEBUG_LEVEL1 */
747 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
748 /* Initialize the hast list to maintain the SSI memory information for Broadcom */
749 offset = (uint16_t)((PTR)(&ptrHdr.ent) - (PTR) &ptrHdr);
750 printf("###########offset is %d region %d\n", offset, region);
751 if(cmHashListInit(®Cb->brdcmSsiLstCp, 1000, offset, FALSE,
752 CM_HASH_KEYTYPE_UINT32_MOD, region, 0) != ROK)
756 #endif /* SSI_DEBUG_LEVEL1 */
759 } /* end of cmMmRegInit*/
767 * Desc: Deinitialize the memory region. The function call SDeregRegion
768 * to deregister the memory region with System Service.
771 * Ret: ROK - successful
772 * RFAILED - unsuccessful.
774 * Notes: The memory owner calls this function to deinitialize the region.
775 * The memory manager does not return the memory to the system.
776 * Before calling this function, the memory owner must be sure that
777 * no layer is using any memory block from this region. On
778 * successful return from the function, any request to the memory
779 * manager to allocate/deallocate memory will fail. The memory owner
780 * can reuse the memory for other region or return the memory to the
781 * system memory pool.
788 S16 cmMmRegDeInit(CmMmRegCb *regCb)
793 #if (ERRCLASS & ERRCLS_INT_PAR)
795 /* error check on parameters */
803 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
804 #ifdef SSI_DEBUG_LEVEL1
805 /* Deinitialize the hash table used for debug info storage at region level */
806 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
810 #endif /* SSI_DEBUG_LEVEL1 */
811 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
812 /* Deinitialize the hash table used for broadcom ssi instrumentation */
813 if (cmHashListDeinit(®Cb->brdcmSsiLstCp) != ROK)
819 /* Call SDeregRegion first to deregister the memory region with SSI */
820 (Void) SDeregRegion (regCb->region);
824 /* Bucket pool is configured */
826 /* Free the initialzed locks of the buckets */
827 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
829 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
830 WTDestroyLock for NT */
831 /* cm_mem_c_001.main_24 fix for memory corruption*/
834 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
836 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
838 /* cm_mem_c_001.main_15:Additions */
839 #ifdef SS_HISTOGRAM_SUPPORT
840 /* De-initialise the memory histogram hash list */
841 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
842 #endif /* SS_HISTOGRAM_SUPPORT */
848 /* Heap pool is configured */
850 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
851 WTDestroyLock for NT */
853 WTDestroyLock(®Cb->heapCb.heapLock);
855 SDestroyLock(®Cb->heapCb.heapLock);
861 } /* end of cmMmRegDeInit */
863 #ifdef CM_MEM_OVERUSED
864 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
866 int g_overused[5] = {0};
869 #ifdef CM_MEM_PRINT_DEFINED
870 volatile int gSubIndex = 0;
871 int regAllocBktSts[10][2][6]={{0}};
872 int regFreeBktSts[10][2][6]={{0}};
879 * Desc: Allocate a memory block for the memory region.
882 * Ret: ROK - successful
883 * RFAILED - unsuccessful.
886 * The function allocates a memory block of size atleast equal to
887 * the requested size. The size parameter will be updated with the
888 * actual size of the memory block allocated for the request. The
889 * CMM tries to allocate the memory block form the bucket pool. If
890 * there is no memory in the bucket the CMM allocates the memory
891 * block form the heap pool. This function is always called by the
892 * System Service module.
894 * The caller of the function should try to use the out value of
895 * the size while returning the memory block to the region. However
896 * the current design of the memory manager does not enforce to pass
897 * the actual size of the memory block. (Due to the SGetSBuf
898 * semantics the layer will not able to pass the correct size of the
899 * memory block while calling SPutSBuf).
905 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
907 /* cm_mem_c_001.main_15 : Additions */
908 #ifdef SS_HISTOGRAM_SUPPORT
909 #ifdef SSI_DEBUG_LEVEL1
934 #endif /* SSI_DEBUG_LEVEL1 */
936 #ifdef SS_LIGHT_MEM_LEAK_STS
947 #else /*SS_LIGHT_MEM_LEAK_STS */
948 #ifdef SSI_DEBUG_LEVEL1
958 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
968 #ifdef T2K_MEM_LEAK_DBG
987 #endif /* BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1 */
988 #endif /* SSI_DEBUG_LEVEL1 */
989 #endif /*SS_LIGHT_MEM_LEAK_STS */
990 /* cm_mem_c_001.main_15: Additions */
991 #endif /* SS_HISTOGRAM_SUPPORT */
994 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
1000 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
1004 /* cm_mem_c_001.main_15 : Additions */
1005 #if (defined(SS_MEM_LEAK_STS) || defined( BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
1007 #endif /* SS_MEM_LEAK_STS */
1008 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
1009 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
1010 CmMmBlkHdr *alocBlk;
1011 #endif /* SSI_DEBUG_LEVEL1 */
1012 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
1015 /* cm_mem_c_001.main_15 : Additions */
1016 #ifdef SS_HISTOGRAM_SUPPORT
1018 #endif /* SS_HISTOGRAM_SUPPORT */
1019 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
1020 uint16_t memIndex=0;
1033 /* cm_mem_c_001.main_15 : Additions */
1034 #if (defined(SS_MEM_LEAK_STS) || defined( BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
1036 #endif /* SS_MEM_LEAK_STS */
1038 regCb = (CmMmRegCb *)regionCb;
1040 #if (ERRCLASS & ERRCLS_INT_PAR)
1042 /* error check on parameters */
1043 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
1049 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
1050 #ifdef SSI_DEBUG_LEVEL1
1051 #if (ERRCLASS & ERRCLS_INT_PAR)
1052 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
1056 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
1057 #endif /* SSI_DEBUG_LEVEL1 */
1064 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
1065 #ifdef SSI_DEBUG_LEVEL1
1066 /* Update the hash list */
1067 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
1069 /* display that, this entry could not be made in the hash list */
1071 /* display an error message here */
1072 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1074 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
1075 *size, regCb->region);
1077 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
1078 *size, regCb->region);
1080 SDisplay(0, dbgPrntBuf);
1083 #endif /* SSI_DEBUG_LEVEL1 */
1086 * Check if the requested size is less than or equal to the maximum block
1087 * size in the bucket.
1089 if ( *size <= regCb->bktMaxBlkSize)
1091 /* Get the map to the mapping table */
1092 idx = ((*size - 1) >> regCb->bktQnPwr);
1094 #if (ERRCLASS & ERRCLS_DEBUG)
1095 if (regCb->mapTbl[idx].bktIdx == 0xFF)
1097 /* Some fatal error in the map table initialization. */
1102 /* Dequeue the memory block and return it to the user */
1103 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
1106 /* While loop is introduced to use the "break statement inside */
1110 * Check if the size request is not greater than the size available
1113 if (*size > bkt->size)
1115 /* Try to go to the next bucket if available */
1116 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
1117 (regCb->mapTbl[++idx].bktIdx != 0xFF))
1119 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
1123 /* This is the last bucket, try to allocate from heap */
1128 /* Acquire the bucket lock */
1129 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
1131 (Void) WTLock(&(bkt->bktLock));
1133 (Void) SLock(&(bkt->bktLock));
1135 #ifdef XEON_SPECIFIC_CHANGES
1136 CM_MEM_ALLOC_STS(regCb->region, idx);
1139 #if (ERRCLASS & ERRCLS_DEBUG)
1140 regCb->mapTbl[idx].numReq++;
1141 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
1143 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
1144 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
1145 /* increment the allocation attempt counter at bucket level */
1146 bkt->numAllocAttempts++;
1148 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
1149 the allocation is always from (bkt->nextBlk) */
1152 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1153 if(cmMmRegIsBlkSane(bkt->nextBlk, bkt->size) != ROK)
1155 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
1158 /* detected a trampled memory block in this bucket */
1160 /* display an error message here */
1161 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1163 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
1164 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
1166 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
1167 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
1169 SDisplay(0, dbgPrntBuf);
1172 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1173 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
1175 /* Release the lock */
1176 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1178 (Void) WTUnlock(&(bkt->bktLock));
1180 (Void) SUnlock(&(bkt->bktLock));
1182 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
1183 return (RTRAMPLINGNOK);
1188 /* Release the lock */
1189 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1191 (Void) WTUnlock(&(bkt->bktLock));
1193 (Void) SUnlock(&(bkt->bktLock));
1195 /* return RFAILED */
1200 *ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr)); /* ccpu00125353: warning fix */
1201 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
1202 ptrHdr = (CmMmBlkHdr *)bkt->nextBlk;
1204 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1205 /* Initialize the elements with 0xAB */
1206 memset(*ptr, 0xAB, *size);
1208 // printf("Pointer allocated %8p size %d\n", *ptr, *size);
1209 /* Store this pointer in hash list */
1210 if ((bkt->nextBlk) && *ptr)
1211 #elif SS_LIGHT_MEM_LEAK_STS
1212 *ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr)); /* ccpu00125353: warning fix */
1213 if ((bkt->nextBlk) && *ptr)
1215 *ptr = bkt->next;/* ccpu00125353: warning fix */
1217 #endif /* SSI_DEBUG_LEVEL1 */
1219 /* cm_mem_c_001.main_12 - addition for header */
1220 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
1221 /* point to next block header */
1222 alocBlk = bkt->nextBlk;
1223 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
1225 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
1226 if(bkt->size == 128)
1228 memIndex = (*ptr - startPtr128) / 128;
1230 if(bkt->size == 256)
1232 memIndex = (*ptr - startPtr256) / 256;
1235 if (*((uint32_t *)(*ptr + 4)) != 0xDEADDEAD && *((uint32_t *)(*ptr + 80)) != 0xDEADDEAD && *((uint32_t *)(*ptr + 24)) != 0xDEADDEAD)
1238 if(bkt->size == 256)
1243 #endif /* MS_MBUF_CORRUPTION */
1244 #ifdef SSI_MEM_CORR_PREVENTION
1245 *(((uint32_t *)(*ptr)) + 2) = 0;
1248 #ifdef T2K_MEM_LEAK_DBG
1251 /* Lock before the transaction-start */
1252 pthread_mutex_lock(&(regMemLeakInfo.memLock[regCb->region]));
1253 InsertToT2kMemLeakInfo( (uint64_t)*ptr,*size,line,file,regCb->region);
1254 /* UnLock after the transaction */
1255 pthread_mutex_unlock(&(regMemLeakInfo.memLock[regCb->region]));
1257 #endif /* T2K_MEM_LEAK_DBG */
1259 bkt->next = *((CmMmEntry **)(bkt->next));
1260 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
1261 *nextptr = bkt->next;
1262 if (*((uint32_t *)(*nextptr + 4)) != 0xDEADDEAD && *((uint32_t *)(*nextptr + 80)) != 0xDEADDEAD && *((uint32_t *)(*nextptr + 24)) != 0xDEADDEAD)
1264 if(bkt->size == 128)
1265 *prevptr = startPtr128 + ((memIndex-1)*128);
1266 if(bkt->size == 256)
1267 *prevptr = startPtr256 + ((memIndex-1)*256);
1268 if(bkt->size == 128)
1269 memIndex = (*nextptr - startPtr128) / 128;
1270 if(bkt->size == 256)
1271 memIndex = (*nextptr - startPtr256) / 256;
1275 if(bkt->size == 128)
1277 memIndex = (*ptr - startPtr128) / 128;
1278 cmMemInfo128[memIndex][0] = cmAllocCaller[MxGetCpuID()];
1280 if(bkt->size == 256)
1282 memIndex = (*ptr - startPtr256) / 256;
1283 cmMemInfo256[memIndex][0] = cmAllocCaller[MxGetCpuID()];
1285 cmAllocCaller[MxGetCpuID()] = NULLP;
1286 *((uint32_t *)(*ptr + 4)) = 0x00000000;
1287 *((uint32_t *)(*ptr + 124)) = 0;
1288 *((uint32_t *)(*ptr + 24)) = 0x00000000;
1289 *((uint32_t *)(*ptr + 44)) = 0x00000000;
1290 *((uint32_t *)(*ptr + 80)) = 0x00000000;
1291 *((uint32_t *)(*ptr + 116)) = 0x00000000;
1293 #endif /* SSI_DEBUG_LEVEL1 */
1295 /* cache_coherency_changes */
1300 * Increment the statistics variable of number of memory block
1304 if (bkt->numAlloc > bkt->maxAlloc)
1306 bkt->maxAlloc = bkt->numAlloc;
1308 #ifdef CM_MEM_OVERUSED
1310 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
1312 g_overused[bktIdx] = 1;
1313 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
1317 /* cm_mem_c_001.main_12 - addition for header manipulation */
1318 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
1319 /* update the size for which this memory block has been allocated */
1320 alocBlk->requestedSize = *size;
1321 /* update the memory block header */
1322 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
1323 if (memType == CMM_STATIC_MEM_FLAG)
1325 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
1326 /* add it to the static memory allocated */
1327 bkt->staticMemUsed += bkt->size;
1331 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
1332 /* add it to the dynamic memory allocated */
1333 bkt->dynamicMemUsed += bkt->size;
1335 #elif SS_LIGHT_MEM_LEAK_STS
1336 alocBlk->requestedSize = *size;
1337 alocBlk->lineNo = lineNo;
1338 alocBlk->currFuncName = funcName;
1339 if(gmemLkCb.isStarted == TRUE)
1341 alocBlk->allocQueueIndx = cmStorAllocBlk(alocBlk);
1343 #endif /* SSI_DEBUG_LEVEL1 */
1345 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
1349 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1352 "[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++);
1355 "[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++);
1357 SDisplay(0, prntBuf);
1365 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
1366 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
1367 SDisplay(0, prntBuf);
1369 #endif /* MEMCAL_DEBUG */
1370 /* cm_mem_c_001.main_15 : Additions */
1371 #ifdef SS_HISTOGRAM_SUPPORT
1372 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
1373 * information into the hash list */
1376 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
1378 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
1383 #endif /* SS_HISTOGRAM_SUPPORT */
1385 /* Update the size parameter */
1387 #ifdef SS_MEM_LEAK_STS
1388 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
1389 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
1390 regCb->mapTbl[idx].bktIdx);
1391 #elif BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
1392 cmStorAllocBlk(ptrHdr, (Size)reqSz, (Size) *size,
1393 regCb->mapTbl[idx].bktIdx, regCb);
1394 #endif /* SS_MEM_LEAK_STS */
1396 /* cm_mem_c_008.104 - Addition for memory calculator tool */
1398 /* Release the lock */
1399 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1401 (Void) WTUnlock(&(bkt->bktLock));
1403 (Void) SUnlock(&(bkt->bktLock));
1412 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1415 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
1418 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
1420 SDisplay(0, prntBuf);
1424 #if (ERRCLASS & ERRCLS_DEBUG)
1425 regCb->mapTbl[idx].numFailure++;
1426 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
1428 /* Release the lock */
1429 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1431 (Void) WTUnlock(&(bkt->bktLock));
1433 (Void) SUnlock(&(bkt->bktLock));
1442 regCb->heapCb.heapAllocCnt++;
1444 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1447 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
1448 regCb->heapCb.heapAllocCnt);
1451 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
1452 regCb->heapCb.heapAllocCnt);
1454 SDisplay(0, prntBuf);
1459 /* Memory not available in the bucket pool */
1460 if (regCb->heapFlag && (*size < regCb->heapSize))
1463 if (flags) tryHeap = 1;
1466 * The heap memory block is available. Allocate the memory block from
1469 /* cm_mem_c_001.main_15: Additions */
1470 #ifdef SS_HISTOGRAM_SUPPORT
1471 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
1472 #ifdef SSI_DEBUG_LEVEL1
1473 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
1475 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
1476 #endif /* SSI_DEBUG_LEVEL1 */
1478 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
1479 #ifdef SSI_DEBUG_LEVEL1
1480 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
1482 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
1483 #endif /* SSI_DEBUG_LEVEL1 */
1484 #endif /* SS_HISTOGRAM_SUPPORT */
1487 /* No memory available */
1489 #else /* use pure is on */
1490 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
1491 #ifdef SS_4GMX_LCORE
1492 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
1493 memset(ptr, 0, *size);
1495 *ptr = (Data*) malloc(*size);
1497 if ( (*ptr) == NULLP)
1499 avail_size -= *size;
1501 #endif /* USE_PURE */
1503 } /* end of cmAlloc */
1510 * Desc: Return the memory block for the memory region.
1513 * Ret: ROK - successful
1514 * RFAILED - unsuccessful.
1516 * Notes: The user calls this function to return the previously allocated
1517 * memory block to the memory region. The memory manager does not
1518 * check the validity of the state of the memory block(like whether
1519 * it was allocated earlier). The caller must be sure that, the
1520 * address specified in the parameter 'ptr' is valid and was
1521 * allocated previously from same region.
1528 /* cm_mem_c_001.main_15 : Additions */
1529 #ifdef SS_LIGHT_MEM_LEAK_STS
1538 #else /*SS_LIGHT_MEM_LEAK_STS */
1539 #ifdef SS_HISTOGRAM_SUPPORT
1552 #ifdef T2K_MEM_LEAK_DBG
1561 #else /* T2K_MEM_LEAK_DBG */
1569 /* cm_mem_c_001.main_15 : Additions */
1570 #endif /* SS_HISTOGRAM_SUPPORT */
1571 #endif /*SS_LIGHT_MEM_LEAK_STS */
1574 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
1580 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
1581 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
1583 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1584 CmMmBlkHdr *lastHdr;
1586 #endif /* SSI_DEBUG_LEVEL1 */
1587 /* cm_mem_c_001.main_15 : Additions */
1588 #ifdef SS_HISTOGRAM_SUPPORT
1590 #endif /* SS_HISTOGRAM_SUPPORT */
1591 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption*/
1592 uint16_t memIndex=0;
1596 regCb = (CmMmRegCb *)regionCb;
1599 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1600 /* Check if the memory block is from the memory region */
1601 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
1602 ((CmMmRegCb *)regCb)->regInfo.size)
1607 #if (ERRCLASS & ERRCLS_INT_PAR)
1609 /* error check on parameters */
1610 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
1615 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1616 /* Check if the memory block is from the memory region */
1617 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
1618 ((CmMmRegCb *)regCb)->regInfo.size)
1623 /* cm_mem_c_001.main_20 Addition */
1624 if (ptr < regCb->regInfo.start)
1632 * Check if the memory block was allocated from the bucket pool.
1635 if (ptr < (regCb->regInfo.start + regCb->bktSize))
1637 #ifdef T2K_MEM_LEAK_DBG
1639 pthread_mutex_lock(&(regMemLeakInfo.memLock[regCb->region]));
1640 RemoveFromT2kMemLeakInfo((uint64_t)ptr , file,line,regCb->region);
1641 pthread_mutex_unlock(&(regMemLeakInfo.memLock[regCb->region]));
1644 /* The memory block was allocated from the bucket pool */
1646 /* Get the map to the mapping table */
1647 idx = ((size - 1) >> regCb->bktQnPwr);
1649 #if (ERRCLASS & ERRCLS_DEBUG)
1650 if (regCb->mapTbl[idx].bktIdx == 0xFF)
1652 /* Some fatal error in the map table initialization. */
1657 /* Enqueue the memory block and return it to the user */
1658 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
1661 * Check if the size is not greater than the size available
1662 * in the bucket. If so, then the buffer must have been allocated
1663 * from next bucket. We don't need to check the validity of the
1664 * next bucket, otherwise buffer must have been allocated from heap
1667 if (size > bkt->size)
1669 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
1672 /* Acquire the bucket lock */
1673 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
1675 (Void) WTLock(&(bkt->bktLock));
1677 (Void) SLock(&(bkt->bktLock));
1679 #ifdef XEON_SPECIFIC_CHANGES
1680 CM_MEM_FREE_STS(regCb->region, idx);
1682 /* cache_coherency_changes */
1687 /* cm_mem_c_001.main_12 - addition for sanity check and free */
1688 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
1689 /* increment the dealloc attempt counter at bucket level */
1690 bkt->numDeallocAttempts++;
1692 /* Check the memFlags to see whether this block was allocated */
1693 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
1694 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
1695 cmRlsAllocBlk(ptrHdr, regCb);
1697 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1698 /* Check for ptr size */
1699 if(((ptrHdr->requestedSize - size) % size) != 0)
1702 sprintf(dbgPrntBuf, "Passed size (%d) does not match with allocated \
1703 size(%d) %8p, Bucket Id:%03d\n",
1704 size, ptrHdr->requestedSize, ptr, regCb->mapTbl[idx].bktIdx);
1706 printf("Passed size (%d) does not match with allocated \
1707 size(%d) %8p, Bucket Id:%03d\n",
1708 size, ptrHdr->requestedSize, ptr, regCb->mapTbl[idx].bktIdx);
1711 /* Validate the tail part to see if there is any over run */
1712 // printf("Pointer free request %8p, size %d\n", ptr, size);
1715 /* validate the block to be freed for trampling */
1716 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1717 if(cmMmRegIsBlkSane(ptrHdr, bkt->size) != ROK)
1719 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
1722 /* Handle error case of Memory trampling */
1724 /* display an error message here */
1725 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1727 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
1728 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
1730 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
1731 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
1733 SDisplay(0, dbgPrntBuf);
1737 * if sanity check returns RTRAMPLINGOK then there is nothing to do
1738 * as the memory blk is already invalidated in cmMmBktSanityChk
1740 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1741 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
1745 /* Release the lock */
1746 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1748 (Void) WTUnlock(&(bkt->bktLock));
1750 (Void) SUnlock(&(bkt->bktLock));
1759 * this is the case where in the entire bucket has been made unusable
1762 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1764 (Void) WTUnlock(&(bkt->bktLock));
1766 (Void) SUnlock(&(bkt->bktLock));
1769 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
1770 return (RTRAMPLINGNOK);
1772 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1773 printf("Memory signature is invalid\n");
1778 /* reset the size */
1779 ptrHdr->requestedSize = 0;
1780 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1781 /* Initialize the elements with 0xAB */
1782 memset(ptr, 0xAB, size);
1784 /* check if the block to be freed is already having the state as FREE */
1785 if (CMM_IS_FREE(ptrHdr->memFlags))
1787 /* Handle double deallocation error case */
1789 /* display an error message here */
1790 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1792 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
1793 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
1795 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
1796 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
1798 SDisplay(0, dbgPrntBuf);
1801 /* Release the lock */
1802 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1804 (Void) WTUnlock(&(bkt->bktLock));
1806 (Void) SUnlock(&(bkt->bktLock));
1808 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1809 printf("Attempt to double deallocate memory at: %8p, Bucket Id:%03d,\
1810 size %u bytes \n", ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
1813 /* handle RDBLFREE in SFree/SPutSBuf */
1816 if (CMM_IS_STATIC(ptrHdr->memFlags))
1818 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
1819 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
1820 /* deduct it from the static memory count */
1821 bkt->staticMemUsed -= bkt->size;
1823 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
1825 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
1826 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
1827 /* deduct it from the dynamic memory count */
1828 bkt->dynamicMemUsed -= bkt->size;
1832 /* This is a case similar to trampled memory */
1834 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
1836 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
1838 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
1840 SDisplay(0, dbgPrntBuf);
1842 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1843 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
1845 /* do not add to the free list */
1848 /* Release the lock */
1849 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1851 (Void) WTUnlock(&(bkt->bktLock));
1853 (Void) SUnlock(&(bkt->bktLock));
1861 * this is the case where in the entire bucket has been made unusable
1864 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
1866 (Void) WTUnlock(&(bkt->bktLock));
1868 (Void) SUnlock(&(bkt->bktLock));
1871 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
1872 return (RTRAMPLINGNOK);
1875 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1876 /* Return the block to memory */
1877 ptrHdr->nextBlk = bkt->nextBlk;
1878 bkt->nextBlk = ptrHdr;
1880 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
1881 /* Move the ptr to end of the bucket */
1882 lastHdr = (CmMmBlkHdr *)bkt->lastBlk;
1883 lastHdr->nextBlk = ptrHdr;
1884 bkt->lastBlk = ptrHdr;
1885 ptrHdr->nextBlk = NULLP;
1887 #elif SS_LIGHT_MEM_LEAK_STS
1888 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
1889 ptrHdr->lineNo = lineNo;
1890 ptrHdr->currFuncName = funcName;
1891 if(gmemLkCb.isStarted == TRUE)
1893 cmRlsAllocBlk(ptrHdr->allocQueueIndx);
1895 ptrHdr->nextBlk = bkt->nextBlk;
1896 bkt->nextBlk = ptrHdr;
1899 #ifndef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
1900 #ifdef SSI_MEM_CORR_PREVENTION
1901 if (*(((uint32_t *)(ptr)) + 2) == 0xdeaddead)
1903 /* Do not free an already freed block to avoid corruption */
1904 cmDblFreeAttempts++;
1909 *((CmMmEntry **)bkt->last) = ptr;
1910 bkt->last = (CmMmEntry *)ptr;
1911 *((CmMmEntry **)ptr) = NULLP;
1912 *(((uint32_t *)(ptr)) + 2) = 0xdeaddead;
1915 *((CmMmEntry **)ptr) = bkt->next;
1916 bkt->next = (CmMmEntry *)ptr;
1919 if(memFreeCount >= 125000)
1921 if(bkt->size == 128)
1923 Data *crashPtr=NULLP;
1924 if(((ptr - startPtr128) % 128) != 0)
1928 memIndex = (ptr - startPtr128) / 128;
1930 if(bkt->size == 256)
1932 Data *crashPtr=NULLP;
1933 if(((ptr - startPtr256) % 256) != 0)
1937 memIndex = (ptr - startPtr256) / 256;
1939 if(bkt->size == 512)
1941 Data *crashPtr=NULLP;
1942 if(((ptr - startPtr512) % 512) != 0)
1947 if(bkt->size == 768)
1949 Data *crashPtr=NULLP;
1950 if(((ptr - startPtr768) % 768) != 0)
1955 if(bkt->size == 1664)
1957 Data *crashPtr=NULLP;
1958 if(((ptr - startPtr1664) % 1664) != 0)
1963 if(bkt->size == 4800)
1965 Data *crashPtr=NULLP;
1966 if(((ptr - startPtr4800) % 4800) != 0)
1971 if(bkt->size == 9920)
1973 Data *crashPtr=NULLP;
1974 if(((ptr - startPtr9920) % 9920) != 0)
1979 if (*((uint32_t *)(ptr + 4)) != 0xDEADDEAD)
1981 *(uint32_t *)(ptr + 4) = 0xDEADDEAD;
1985 Data *crashPtr=NULLP;
1988 if (*((uint32_t *)(ptr + 24)) != 0xDEADDEAD)
1990 *(uint32_t *)(ptr + 24) = 0xDEADDEAD;
1994 Data *crashPtr=NULLP;
1997 if (*((uint32_t *)(ptr + 44)) != 0xDEADDEAD)
1999 *(uint32_t *)(ptr + 44) = 0xDEADDEAD;
2003 Data *crashPtr=NULLP;
2006 if (*((uint32_t *)(ptr + 80)) != 0xDEADDEAD)
2008 *(uint32_t *)(ptr + 80) = 0xDEADDEAD;
2012 Data *crashPtr=NULLP;
2014 /* Cause a crash to identify the caller */
2016 *(uint32_t *)(ptr + 124) = memFreeCount++;
2017 (*(uint32_t *)(ptr + 116)) = cmFreeCaller[MxGetCpuID()];
2018 if(bkt->size == 128)
2020 memIndex = (ptr - startPtr128) / 128;
2021 cmMemInfo128[memIndex][1] = cmFreeCaller[MxGetCpuID()];
2023 if(bkt->size == 256)
2025 memIndex = (ptr - startPtr256) / 256;
2026 cmMemInfo256[memIndex][1] = cmFreeCaller[MxGetCpuID()];
2028 cmFreeCaller[MxGetCpuID()] = NULLP;
2031 Reverted: Removed functionality to move freed buffer to end of free List in bucket.
2032 This is impacting throughput.
2035 *((CmMmEntry **)bkt->last) = ptr;
2036 bkt->last = (CmMmEntry *)ptr;
2037 *((CmMmEntry **)ptr) = NULLP;
2039 *((CmMmEntry **)ptr) = bkt->next;
2040 bkt->next = (CmMmEntry *)ptr;
2043 #endif /* SSI_DEBUG_LEVEL1 */
2045 /* cache_coherency_changes */
2050 * Decrement the statistics variable of number of memory block
2054 /* cm_mem_c_001.main_15 : Additions */
2055 #ifdef SS_HISTOGRAM_SUPPORT
2056 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
2057 * information into the hash list */
2060 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
2062 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2066 #endif /* SS_HISTOGRAM_SUPPORT */
2068 #ifdef SS_MEM_LEAK_STS
2069 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2070 cmRlsAllocBlk((PTR)ptr);
2071 #endif /* SS_MEM_LEAK_STS */
2072 /* Release the lock */
2073 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2075 (Void) WTUnlock(&(bkt->bktLock));
2077 (Void) SUnlock(&(bkt->bktLock));
2083 /* The memory block was allocated from the heap pool */
2084 /* cm_mem_c_001.main_15 : Additions */
2085 #ifdef SS_HISTOGRAM_SUPPORT
2086 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2088 return (cmHeapFree (&(regCb->heapCb), ptr, size));
2089 #endif /* SS_HISTOGRAM_SUPPORT */
2090 #else /* use pure is on */
2091 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2092 #ifdef SS_4GMX_LCORE
2093 (Void)MxHeapFree(SsiHeap, ptr);
2099 #endif /* USE_PURE */
2102 } /* end of cmFree */
2108 * Desc: Allocate a memory block for the memory region(No Lock).
2111 * Ret: ROK - successful
2112 * RFAILED - unsuccessful.
2115 * The function allocates a memory block of size atleast equal to
2116 * the requested size. The size parameter will be updated with the
2117 * actual size of the memory block allocated for the request. The
2118 * CMM tries to allocate the memory block form the bucket pool. If
2119 * there is no memory in the bucket the CMM allocates the memory
2120 * block form the heap pool. This function is always called by the
2121 * System Service module.
2123 * The caller of the function should try to use the out value of
2124 * the size while returning the memory block to the region. However
2125 * the current design of the memory manager does not enforce to pass
2126 * the actual size of the memory block. (Due to the SGetSBuf
2127 * semantics the layer will not able to pass the correct size of the
2128 * memory block while calling SPutSBuf).
2134 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2136 /* cm_mem_c_001.main_15 : Additions */
2137 #ifdef SS_HISTOGRAM_SUPPORT
2138 #ifdef SSI_DEBUG_LEVEL1
2163 #endif /* SSI_DEBUG_LEVEL1 */
2166 #ifdef SS_LIGHT_MEM_LEAK_STS
2177 #else /*SS_LIGHT_MEM_LEAK_STS */
2178 #ifdef SSI_DEBUG_LEVEL1
2188 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2205 #endif /* BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1 */
2206 #endif /* SSI_DEBUG_LEVEL1 */
2207 /* cm_mem_c_001.main_15: Additions */
2208 #endif /*SS_LIGHT_MEM_LEAK_STS */
2209 #endif /* SS_HISTOGRAM_SUPPORT */
2212 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2218 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2222 /* cm_mem_c_001.main_15 : Additions */
2223 #if (defined(SS_MEM_LEAK_STS) || defined( BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
2225 #endif /* SS_MEM_LEAK_STS */
2226 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2227 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
2228 CmMmBlkHdr *alocBlk;
2229 #endif /* SSI_DEBUG_LEVEL1 */
2230 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
2233 /* cm_mem_c_001.main_15 : Additions */
2234 #ifdef SS_HISTOGRAM_SUPPORT
2236 #endif /* SS_HISTOGRAM_SUPPORT */
2242 /* cm_mem_c_001.main_15 : Additions */
2243 #ifdef SS_MEM_LEAK_STS
2245 #endif /* SS_MEM_LEAK_STS */
2247 regCb = (CmMmRegCb *)regionCb;
2249 #if (ERRCLASS & ERRCLS_INT_PAR)
2251 /* error check on parameters */
2252 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2258 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2259 #ifdef SSI_DEBUG_LEVEL1
2260 #if (ERRCLASS & ERRCLS_INT_PAR)
2261 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2265 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2266 #endif /* SSI_DEBUG_LEVEL1 */
2273 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2274 #ifdef SSI_DEBUG_LEVEL1
2275 /* Update the hash list */
2276 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2278 /* display that, this entry could not be made in the hash list */
2280 /* display an error message here */
2282 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u \
2283 in hash table of region %d \n",
2284 *size, regCb->region);
2286 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu \
2287 in hash table of region %d \n",
2288 *size, regCb->region);
2290 SDisplay(0, dbgPrntBuf);
2293 #endif /* SSI_DEBUG_LEVEL1 */
2296 * Check if the requested size is less than or equal to the maximum block
2297 * size in the bucket.
2299 if ( *size <= regCb->bktMaxBlkSize)
2301 /* Get the map to the mapping table */
2302 idx = ((*size - 1) >> regCb->bktQnPwr);
2304 #if (ERRCLASS & ERRCLS_DEBUG)
2305 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2307 /* Some fatal error in the map table initialization. */
2312 /* Dequeue the memory block and return it to the user */
2313 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
2316 /* While loop is introduced to use the "break statement inside */
2320 * Check if the size request is not greater than the size available
2323 if (*size > bkt->size)
2325 /* Try to go to the next bucket if available */
2326 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2327 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2329 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
2333 /* This is the last bucket, try to allocate from heap */
2338 #if (ERRCLASS & ERRCLS_DEBUG)
2339 regCb->mapTbl[idx].numReq++;
2340 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2342 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2343 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
2344 /* increment the allocation attempt counter at bucket level */
2345 bkt->numAllocAttempts++;
2347 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2348 the allocation is always from (bkt->nextBlk) */
2351 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2352 if(cmMmRegIsBlkSane(bkt->nextBlk, bkt->size) != ROK)
2354 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2357 /* detected a trampled memory block in this bucket */
2359 /* display an error message here */
2360 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2362 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, \
2364 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2366 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, \
2368 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2370 SDisplay(0, dbgPrntBuf);
2374 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2375 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2377 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2378 return (RTRAMPLINGNOK);
2382 /* return RFAILED */
2388 *ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr));
2389 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
2390 ptrHdr = (CmMmBlkHdr *)bkt->nextBlk;
2392 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2393 /* Initialize the elements with 0xAB */
2394 memset(*ptr, 0xAB, *size);
2396 if ((bkt->nextBlk) && *ptr)
2397 #elif SS_LIGHT_MEM_LEAK_STS
2398 *ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr)); /* ccpu00125353: warning fix */
2399 if ((bkt->nextBlk) && *ptr)
2401 *ptr = bkt->next;/* ccpu00125353: warning fix */
2403 #endif /* SSI_DEBUG_LEVEL1 */
2405 /* cm_mem_c_001.main_12 - addition for header */
2406 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
2407 /* point to next block header */
2408 alocBlk = bkt->nextBlk;
2409 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2411 #ifdef SSI_MEM_CORR_PREVENTION
2412 *(((uint32_t *)(*ptr)) + 2) = 0;
2414 bkt->next = *((CmMmEntry **)(bkt->next));
2415 #endif /* SSI_DEBUG_LEVEL1 */
2417 /* cache_coherency_changes */
2422 * Increment the statistics variable of number of memory block
2426 if (bkt->numAlloc > bkt->maxAlloc)
2428 bkt->maxAlloc = bkt->numAlloc;
2430 #ifdef CM_MEM_OVERUSED
2432 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2434 g_overused[bktIdx] = 1;
2438 /* cm_mem_c_001.main_12 - addition for header manipulation */
2439 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
2440 /* update the size for which this memory block has been allocated */
2441 alocBlk->requestedSize = *size;
2442 /* update the memory block header */
2443 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2444 if (memType == CMM_STATIC_MEM_FLAG)
2446 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2447 /* add it to the static memory allocated */
2448 bkt->staticMemUsed += bkt->size;
2452 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2453 /* add it to the dynamic memory allocated */
2454 bkt->dynamicMemUsed += bkt->size;
2456 #elif SS_LIGHT_MEM_LEAK_STS
2457 alocBlk->requestedSize = *size;
2458 alocBlk->lineNo = lineNo;
2459 alocBlk->currFuncName = funcName;
2460 if(gmemLkCb.isStarted == TRUE)
2462 alocBlk->allocQueueIndx = cmStorAllocBlk(alocBlk);
2464 #endif /* SSI_DEBUG_LEVEL1 */
2466 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2472 "[MEM_CAL_CNTA] %u bytes request not fitted in bkt %d \
2473 [size %u bytes] %u times\n",
2474 *size, regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktNoFitCnt++);
2477 "[MEM_CAL_CNTA] %lu bytes request not fitted in bkt %d \
2478 [size %lu bytes] %lu times\n",
2479 *size, regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktNoFitCnt++);
2481 SDisplay(0, prntBuf);
2489 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2490 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2491 SDisplay(0, prntBuf);
2493 #endif /* MEMCAL_DEBUG */
2494 /* cm_mem_c_001.main_15 : Additions */
2495 #ifdef SS_HISTOGRAM_SUPPORT
2498 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp),
2499 bkt->size, size, line, fileName, entId) != ROK)
2501 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2506 #endif /* SS_HISTOGRAM_SUPPORT */
2508 /* Update the size parameter */
2510 #ifdef SS_MEM_LEAK_STS
2511 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2512 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2513 regCb->mapTbl[idx].bktIdx);
2514 #elif BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
2515 cmStorAllocBlk(ptrHdr, (Size) reqSz, (Size) *size,
2516 regCb->mapTbl[idx].bktIdx, regCb);
2517 #endif /* SS_MEM_LEAK_STS */
2519 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2529 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], \
2530 %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2533 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], \
2534 %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2536 SDisplay(0, prntBuf);
2540 #if (ERRCLASS & ERRCLS_DEBUG)
2541 regCb->mapTbl[idx].numFailure++;
2542 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2551 regCb->heapCb.heapAllocCnt++;
2555 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n \
2556 Number of blocks allocated from heap = %u\n",*size,
2557 regCb->heapCb.heapAllocCnt);
2560 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n \
2561 Number of blocks allocated from heap = %lu\n",*size,
2562 regCb->heapCb.heapAllocCnt);
2564 SDisplay(0, prntBuf);
2569 /* Memory not available in the bucket pool */
2570 if (regCb->heapFlag && (*size < regCb->heapSize))
2573 if (flags) tryHeap = 1;
2576 * The heap memory block is available. Allocate the memory block from
2579 /* cm_mem_c_001.main_15: Additions */
2580 #ifdef SS_HISTOGRAM_SUPPORT
2581 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2582 #ifdef SSI_DEBUG_LEVEL1
2583 return (cmHeapAlloc(&(regCb->heapCb), ptr, size,
2584 memType, line, fileName, entId, hstReg));
2586 return (cmHeapAlloc(&(regCb->heapCb), ptr, size,
2587 line, fileName, entId, hstReg));
2588 #endif /* SSI_DEBUG_LEVEL1 */
2590 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2591 #ifdef SSI_DEBUG_LEVEL1
2592 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2594 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2595 #endif /* SSI_DEBUG_LEVEL1 */
2596 #endif /* SS_HISTOGRAM_SUPPORT */
2599 /* No memory available */
2601 #else /* use pure is on */
2602 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2603 #ifdef SS_4GMX_LCORE
2604 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2605 memset(ptr, 0, *size);
2607 *ptr = (Data*) malloc(*size);
2609 if ( (*ptr) == NULLP)
2611 avail_size -= *size;
2613 #endif /* USE_PURE */
2615 } /* end of cmAllocNL */
2622 * Desc: Return the memory block for the memory region(No Lock).
2625 * Ret: ROK - successful
2626 * RFAILED - unsuccessful.
2628 * Notes: The user calls this function to return the previously allocated
2629 * memory block to the memory region. The memory manager does not
2630 * check the validity of the state of the memory block(like whether
2631 * it was allocated earlier). The caller must be sure that, the
2632 * address specified in the parameter 'ptr' is valid and was
2633 * allocated previously from same region.
2640 /* cm_mem_c_001.main_15 : Additions */
2641 #ifdef SS_LIGHT_MEM_LEAK_STS
2650 #else /*SS_LIGHT_MEM_LEAK_STS */
2652 #ifdef SS_HISTOGRAM_SUPPORT
2671 /* cm_mem_c_001.main_15 : Additions */
2672 #endif /* SS_HISTOGRAM_SUPPORT */
2673 #endif /*SS_LIGHT_MEM_LEAK_STS */
2681 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
2682 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
2684 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2685 CmMmBlkHdr *lastHdr;
2686 #endif /* BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1 */
2687 #endif /* SSI_DEBUG_LEVEL1 */
2688 /* cm_mem_c_001.main_15 : Additions */
2689 #ifdef SS_HISTOGRAM_SUPPORT
2691 #endif /* SS_HISTOGRAM_SUPPORT */
2694 regCb = (CmMmRegCb *)regionCb;
2697 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2698 /* Check if the memory block is from the memory region */
2699 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2700 ((CmMmRegCb *)regCb)->regInfo.size)
2705 #if (ERRCLASS & ERRCLS_INT_PAR)
2707 /* error check on parameters */
2708 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2712 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2713 /* Check if the memory block is from the memory region */
2714 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2715 ((CmMmRegCb *)regCb)->regInfo.size)
2720 /* cm_mem_c_001.main_20 Addition */
2721 if (ptr < regCb->regInfo.start)
2729 * Check if the memory block was allocated from the bucket pool.
2732 if (ptr < (regCb->regInfo.start + regCb->bktSize))
2734 /* The memory block was allocated from the bucket pool */
2736 /* Get the map to the mapping table */
2737 idx = ((size - 1) >> regCb->bktQnPwr);
2739 #if (ERRCLASS & ERRCLS_DEBUG)
2740 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2742 /* Some fatal error in the map table initialization. */
2747 /* Enqueue the memory block and return it to the user */
2748 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
2751 * Check if the size is not greater than the size available
2752 * in the bucket. If so, then the buffer must have been allocated
2753 * from next bucket. We don't need to check the validity of the
2754 * next bucket, otherwise buffer must have been allocated from heap
2757 if (size > bkt->size)
2759 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
2762 /* cache_coherency_changes */
2767 /* cm_mem_c_001.main_12 - addition for sanity check and free */
2768 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
2769 /* increment the dealloc attempt counter at bucket level */
2770 bkt->numDeallocAttempts++;
2772 /* Check the memFlags to see whether this block was allocated */
2773 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
2774 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
2775 cmRlsAllocBlk(ptrHdr, regCb);
2777 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2778 /* Check for ptr size */
2779 if(((ptrHdr->requestedSize - size) % size) != 0)
2782 sprintf(dbgPrntBuf, "Passed size (%d) does not match with allocated size(%d):%8p, Bucket Id:%03d\n",
2783 size, ptrHdr->requestedSize, ptr, regCb->mapTbl[idx].bktIdx);
2785 printf("Passed size (%d) does not match with allocated size(%d):%8p, Bucket Id:%03d\n",
2786 size, ptrHdr->requestedSize, ptr, regCb->mapTbl[idx].bktIdx);
2791 /* validate the block to be freed for trampling */
2792 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2793 if(cmMmRegIsBlkSane(ptrHdr, bkt->size) != ROK)
2795 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
2798 /* Handle error case of Memory trampling */
2800 /* display an error message here */
2802 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2803 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
2805 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2806 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
2808 SDisplay(0, dbgPrntBuf);
2812 * if sanity check returns RTRAMPLINGOK then there is nothing to do
2813 * as the memory blk is already invalidated in cmMmBktSanityChk
2815 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2816 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
2824 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
2825 return (RTRAMPLINGNOK);
2828 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2829 printf("Memory signature is invalid\n");
2833 /* reset the size */
2834 ptrHdr->requestedSize = 0;
2835 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2836 /* Initialize the elements with 0XAB */
2837 memset(ptr, 0xAB, size);
2839 /* check if the block to be freed is already having the state as FREE */
2840 if (CMM_IS_FREE(ptrHdr->memFlags))
2842 /* Handle double deallocation error case */
2844 /* display an error message here */
2845 /*cm_mem_c_001.main_23 Fix for specifier mismatch
2846 * warnings in 64BIT compilation*/
2848 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p,"
2849 "Bucket Id:%03d, size %u bytes \n",
2850 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
2852 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p,"
2853 "Bucket Id:%03d, size %lu bytes \n",
2854 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
2856 SDisplay(0, dbgPrntBuf);
2858 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2859 printf("Attempt to double deallocate memory at: %8p, Bucket Id:%03d,\
2860 size %u bytes \n", ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
2864 /* handle RDBLFREE in SFree/SPutSBuf */
2867 if (CMM_IS_STATIC(ptrHdr->memFlags))
2869 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
2870 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
2871 /* deduct it from the static memory count */
2872 bkt->staticMemUsed -= bkt->size;
2874 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
2876 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
2877 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
2878 /* deduct it from the dynamic memory count */
2879 bkt->dynamicMemUsed -= bkt->size;
2883 /* This is a case similar to trampled memory */
2885 /*cm_mem_c_001.main_23 Fix for specifier
2886 * mismatch warnings in 64BIT compilation*/
2888 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
2890 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
2892 SDisplay(0, dbgPrntBuf);
2894 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2895 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
2897 /* do not add to the free list */
2903 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
2904 return (RTRAMPLINGNOK);
2908 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2909 /* Return the block to memory */
2910 ptrHdr->nextBlk = bkt->nextBlk;
2911 bkt->nextBlk = ptrHdr;
2913 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
2914 /* Move the ptr to end of the bucket */
2915 lastHdr = (CmMmBlkHdr *)bkt->lastBlk;
2916 lastHdr->nextBlk = ptrHdr;
2917 bkt->lastBlk = ptrHdr;
2918 ptrHdr->nextBlk = NULLP;
2920 #elif SS_LIGHT_MEM_LEAK_STS
2921 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
2922 ptrHdr->lineNo = lineNo;
2923 ptrHdr->currFuncName = funcName;
2924 if(gmemLkCb.isStarted == TRUE)
2926 cmRlsAllocBlk(ptrHdr->allocQueueIndx);
2928 ptrHdr->nextBlk = bkt->nextBlk;
2929 bkt->nextBlk = ptrHdr;
2932 #ifdef SSI_MEM_CORR_PREVENTION
2933 if (*(((uint32_t *)(ptr)) + 2) == 0xdeaddead)
2935 /* Do not free an already freed block to avoid corruption */
2936 cmDblFreeAttempts++;
2941 *((CmMmEntry **)bkt->last) = ptr;
2942 bkt->last = (CmMmEntry *)ptr;
2943 *((CmMmEntry **)ptr) = NULLP;
2944 *(((uint32_t *)(ptr)) + 2) = 0xdeaddead;
2947 *((CmMmEntry **)ptr) = bkt->next;
2948 bkt->next = (CmMmEntry *)ptr;
2950 #endif /* SSI_DEBUG_LEVEL1 */
2952 /* cache_coherency_changes */
2957 * Decrement the statistics variable of number of memory block
2961 /* cm_mem_c_001.main_15 : Additions */
2962 #ifdef SS_HISTOGRAM_SUPPORT
2963 /* If Tapa task (entId)is registerd for histogram then insert Memrory Freed
2964 * information into the hash list */
2967 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size,
2968 line, fileName, entId) != ROK)
2970 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2974 #endif /* SS_HISTOGRAM_SUPPORT */
2976 #ifdef SS_MEM_LEAK_STS
2977 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2978 cmRlsAllocBlk((PTR)ptr);
2979 #endif /* SS_MEM_LEAK_STS */
2984 /* The memory block was allocated from the heap pool */
2985 /* cm_mem_c_001.main_15 : Additions */
2986 #ifdef SS_HISTOGRAM_SUPPORT
2987 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2989 return (cmHeapFree (&(regCb->heapCb), ptr, size));
2990 #endif /* SS_HISTOGRAM_SUPPORT */
2991 #else /* use pure is on */
2992 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2993 #ifdef SS_4GMX_LCORE
2994 (Void)MxHeapFree(SsiHeap, ptr);
3000 #endif /* USE_PURE */
3001 } /* end of cmFreeNL */
3008 * Desc: alloc without lock
3011 * Ret: ROK - successful
3012 * RFAILED - unsuccessful.
3018 /*cm_mem_c_001.main_21-added new function*/
3019 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3021 static S16 cmAllocWL
3032 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3035 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3037 regCb = (CmMmRegCb *)regionCb;
3039 #if (ERRCLASS & ERRCLS_INT_PAR)
3041 /* error check on parameters */
3042 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3048 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3053 * Check if the requested size is less than or equal to the maximum block
3054 * size in the bucket.
3056 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3057 if ( *size <= regCb->bktMaxBlkSize)
3059 /* Get the map to the mapping table */
3060 idx = ((*size - 1) >> regCb->bktQnPwr);
3062 /* Dequeue the memory block and return it to the user */
3063 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3067 * Check if the size request is not greater than the size available
3070 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3071 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3073 /* Try to go to the next bucket if available */
3074 bkt->next = *((CmMmEntry **)(bkt->next));
3077 * Increment the statistics variable of number of memory block
3082 /* Update the size parameter */
3090 /* Memory not available in the bucket pool */
3091 if (regCb->heapFlag && (*size < regCb->heapSize))
3093 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3095 * The heap memory block is available. Allocate the memory block from
3098 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3099 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3102 /* No memory available */
3104 #else /* use pure is on */
3105 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3106 #ifdef SS_4GMX_LCORE
3107 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3108 memset(ptr, 0, *size);
3110 *ptr = (Data*) malloc(*size);
3112 if ( (*ptr) == NULLP)
3114 avail_size -= *size;
3116 #endif /* USE_PURE */
3118 } /* end of cmAllocWL */
3125 * Desc: free without lock
3128 * Ret: ROK - successful
3129 * RFAILED - unsuccessful.
3136 static S16 cmFreeWL(Void *regionCb,Data *ptr, Size size)
3141 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3144 regCb = (CmMmRegCb *)regionCb;
3147 #if (ERRCLASS & ERRCLS_INT_PAR)
3149 /* error check on parameters */
3150 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3155 /* Check if the memory block is from the memory region */
3156 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3157 ((CmMmRegCb *)regCb)->regInfo.size)
3165 * Check if the memory block was allocated from the bucket pool.
3168 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3170 /* The memory block was allocated from the bucket pool */
3172 /* Get the map to the mapping table */
3173 idx = ((size - 1) >> regCb->bktQnPwr);
3175 #if (ERRCLASS & ERRCLS_DEBUG)
3176 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3178 /* Some fatal error in the map table initialization. */
3183 /* Enqueue the memory block and return it to the user */
3184 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3187 * Check if the size is not greater than the size available
3188 * in the bucket. If so, then the buffer must have been allocated
3189 * from next bucket. We don't need to check the validity of the
3190 * next bucket, otherwise buffer must have been allocated from heap
3193 if (size > bkt->size)
3195 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3198 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3199 *((CmMmEntry **)ptr) = bkt->next;
3200 bkt->next = (CmMmEntry *)ptr;
3203 * Decrement the statistics variable of number of memory block
3211 /* The memory block was allocated from the heap pool */
3212 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3213 #else /* use pure is on */
3214 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3215 #ifdef SS_4GMX_LCORE
3216 (Void)MxHeapFree(SsiHeap, ptr);
3222 #endif /* USE_PURE */
3225 } /* end of cmFreeWL */
3233 * Desc: Control request function.
3236 * Ret: ROK - successful
3237 * RFAILED - unsuccessful.
3239 * Notes: The current semantics of the control function is defined for two
3240 * types of events: virtual address to physical address translation
3241 * and memory resource check.
3243 * The physical address translation is valid only for the memory
3244 * region physically contiguous and non pagable.
3252 static S16 cmCtl(Void *regionCb,Event event, SMemCtl *memCtl)
3257 regCb = (CmMmRegCb *)regionCb;
3259 #if (ERRCLASS & ERRCLS_INT_PAR)
3261 /* error check on parameters */
3262 if ((regCb == NULLP) || (memCtl == NULLP))
3275 #if (ERRCLASS & ERRCLS_INT_PAR)
3276 if ((memCtl->u.vtop.vaddr == NULLP) ||
3277 (memCtl->u.vtop.paddr == NULLP))
3283 /* Check if the virtual to physical address translation is valid */
3284 if (regCb->chFlag & CMM_REG_PHY_VALID)
3286 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3287 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3294 case SS_MEM_CHK_RES:
3297 #if (ERRCLASS & ERRCLS_INT_PAR)
3298 if (!(memCtl->u.chkres.size) ||
3299 (memCtl->u.chkres.status == NULLP))
3305 /* Check if the Bucket pool is configured */
3310 uint32_t avlSize, totSize;
3312 * The bucket pool is configured. The status value returned
3313 * does reflect on the memory availabilty in the bucket pool.
3314 * The value does not consider the available memory in the
3317 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3318 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3319 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3320 avlSize += regCb->heapCb.avlSize;
3321 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3322 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
3326 /* Bucket pool not configured */
3329 * Find the percentage memory available in the heap pool. The value
3330 * does not consider the fragmentation of the heap pool.
3332 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3333 (regCb->heapSize/10));
3337 #else /* use pure is on */
3338 *(memCtl->u.chkres.status) = ((avail_size) /
3339 (regCb->regInfo.size/10));
3341 #endif /* USE_PURE */
3347 /* No other event is supported currently */
3352 /* shouldn't reach here */
3354 } /* end of cmCtl */
3361 * Desc: Initialize the bucket and the map table.
3364 * Ret: ROK - successful,
3365 * RFAILED - unsuccessful.
3367 * Notes: This function is called by the cmMmRegInit.
3372 static Void cmMmBktInit
3385 /* cm_mem_c_001.main_12 - addition for temporary variables */
3386 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
3387 CmMmBlkHdr **nextBlk;
3388 #ifdef SS_LIGHT_MEM_LEAK_STS
3389 CmMmBlkHdr *lastBlk;
3390 #endif /*SS_LIGHT_MEM_LEAK_STS */
3392 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
3394 CmMmBlkTail *blkTail;
3398 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3401 #endif /* SSI_DEBUG_LEVEL1 */
3405 size = cfg->bktCfg[bktIdx].size;
3406 numBlks = cfg->bktCfg[bktIdx].numBlks;
3408 /* cm_mem_c_001.main_12 - addition for header initialization */
3409 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
3410 /* Reset the next block pointer */
3411 regCb->bktTbl[bktIdx].nextBlk = NULLP;
3412 #if (defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
3413 regCb->bktTbl[bktIdx].lastBlk = NULLP;
3415 /* Initialize the link list of the memory block */
3416 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
3418 for (cnt = 0; cnt < numBlks; cnt++)
3420 *nextBlk = (CmMmBlkHdr *)*memAddr;
3421 #ifdef SS_LIGHT_MEM_LEAK_STS
3422 lastBlk = (CmMmBlkHdr *)*memAddr;
3423 #endif /*SS_LIGHT_MEM_LEAK_STS */
3425 /* initialize the memory block header */
3426 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
3428 (*nextBlk)->trSignature[sigCnt] = 0xAB;
3430 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
3431 /* Initialize memory block tail */
3432 blkTail = (CmMmBlkTail *)(*memAddr + sizeof(CmMmBlkHdr) + size);
3433 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
3435 blkTail->trSignature[sigCnt] = 0xFE;
3438 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
3439 (*nextBlk)->requestedSize = 0;
3440 #ifdef SS_LIGHT_MEM_LEAK_STS
3441 (*nextBlk)->timeStamp = 0X7777;
3442 (*nextBlk)->lineNo = 0;
3443 (*nextBlk)->allocQueueIndx = 1;
3444 (*nextBlk)->currFuncName = NULL;
3445 #endif /*SS_LIGHT_MEM_LEAK_STS */
3447 #if defined(SSI_DEBUG_LEVEL1) || defined(SS_LIGHT_MEM_LEAK_STS)
3448 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
3449 #elif BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
3450 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + sizeof(CmMmBlkTail) + size));
3452 nextBlk = &((*nextBlk)->nextBlk);
3456 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
3457 tmpMemAddr = (Data *)((*memAddr) - ((sizeof(CmMmBlkHdr)) + sizeof(uint32_t) + size));
3458 regCb->bktTbl[bktIdx].lastBlk = (CmMmBlkHdr *)tmpMemAddr;
3462 /* Reset the next pointer */
3463 regCb->bktTbl[bktIdx].next = NULLP;
3464 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3465 regCb->bktTbl[bktIdx].last = NULLP;
3468 /* Initialize the link list of the memory block */
3469 next = &(regCb->bktTbl[bktIdx].next);
3470 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3471 last = &(regCb->bktTbl[bktIdx].last);
3472 if(regCb->region == 0)
3476 startPtr128 = *memAddr;
3477 regMemSize = regCb->regInfo.size;
3478 uart_printf("size of all pool=%u\n", regMemSize);
3479 uart_printf("startPtr128=%x\n", startPtr128);
3483 startPtr256 = *memAddr;
3484 uart_printf("startPtr256=%x\n", startPtr256);
3488 startPtr512 = *memAddr;
3489 uart_printf("startPtr512=%x\n", startPtr512);
3493 startPtr768 = *memAddr;
3494 uart_printf("startPtr768=%x\n", startPtr768);
3498 startPtr1664 = *memAddr;
3499 uart_printf("startPtr1664=%x\n", startPtr1664);
3503 startPtr4800 = *memAddr;
3504 uart_printf("startPtr4800=%x\n", startPtr4800);
3508 startPtr9920 = *memAddr;
3509 uart_printf("startPtr9920=%x\n", startPtr9920);
3513 for (cnt = 0; cnt < numBlks; cnt++)
3516 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3517 (*(uint32_t *)(*next + 4)) = 0xdeaddead;
3518 (*(uint32_t *)(*next + 124)) = 0;
3519 (*(uint32_t *)(*next + 116)) = 0xdeaddead;
3520 (*(uint32_t *)(*next + 24)) = 0xdeaddead;
3521 (*(uint32_t *)(*next + 44)) = 0xdeaddead;
3522 (*(uint32_t *)(*next + 80)) = 0xdeaddead;
3524 #ifdef SSI_MEM_CORR_PREVENTION
3525 *(((uint32_t *)(*next)) + 2) = 0xdeaddead;
3527 next = (CmMmEntry **)(*memAddr);
3528 *memAddr = (*memAddr) + size;
3531 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3532 *last = (CmMmEntry *)next;
3534 #ifdef SSI_MEM_CORR_PREVENTION
3535 regCb->bktTbl[bktIdx].last = (CmMmEntry *)next;
3538 #endif /* SSI_DEBUG_LEVEL1 */
3540 /* Initialize the Map entry */
3541 idx = size / cfg->bktQnSize;
3544 * Check if the size is multiple of quantum size. If not we need to initialize
3545 * one more map table entry.
3547 if(size % cfg->bktQnSize)
3552 while ( *lstMapIdx < idx)
3554 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
3556 #if (ERRCLASS & ERRCLS_DEBUG)
3557 regCb->mapTbl[*lstMapIdx].numReq = 0;
3558 regCb->mapTbl[*lstMapIdx].numFailure = 0;
3564 /* Initialize the bucket structure */
3565 regCb->bktTbl[bktIdx].size = size;
3566 regCb->bktTbl[bktIdx].numBlks = numBlks;
3567 regCb->bktTbl[bktIdx].numAlloc = 0;
3569 /* Update the total bucket size */
3570 /* cm_mem_c_001.main_12 - addition for considering the header size */
3571 #if (defined(SSI_DEBUG_LEVEL1) || defined (SS_LIGHT_MEM_LEAK_STS))
3572 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
3573 /* Addition for considering the header size and tail */
3574 #elif BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
3575 regCb->bktSize += ((size + sizeof(CmMmBlkHdr) + sizeof(uint32_t)) * numBlks);
3577 regCb->bktSize += (size * numBlks);
3578 #endif /* SSI_DEBUG_LEVEL1 */
3580 regCb->bktTbl[bktIdx].bktFailCnt = 0;
3581 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
3583 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
3584 #if (defined(SSI_DEBUG_LEVEL1) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1))
3585 /* Initialize other required pointers */
3586 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
3587 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
3588 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
3589 regCb->bktTbl[bktIdx].staticMemUsed = 0;
3590 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
3591 regCb->bktTbl[bktIdx].trampleCount = 0;
3592 #endif /*SSI_DEBUG_LEVEL1*/
3593 /* cm_mem_c_001.main_15 : Additions */
3594 #ifdef SS_HISTOGRAM_SUPPORT
3595 /* Initialise the memory histogram hash list */
3596 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
3597 #endif /* SS_HISTOGRAM_SUPPORT */
3600 } /* end of cmMmBktInit */
3607 * Desc: Initialize the heap pool.
3610 * Ret: ROK - successful
3611 * RFAILED - unsuccessful.
3613 * Notes: This function is called by the cmMmRegInit.
3618 static Void cmMmHeapInit(Data *memAddr,CmMmHeapCb *heapCb,Size size)
3620 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3621 #ifdef SSI_DEBUG_LEVEL1
3623 #endif /* SSI_DEBUG_LEVEL1 */
3625 /* Initialize the heap control block */
3626 heapCb->vStart = memAddr;
3627 heapCb->vEnd = memAddr + size;
3628 heapCb->avlSize = size;
3629 heapCb->minSize = CMM_MINBUFSIZE;
3631 heapCb->next = (CmHEntry *)memAddr;
3632 heapCb->next->next = NULLP;
3633 /* cm_mem_c_001.main_12 - addition for header initialization */
3634 #ifdef SSI_DEBUG_LEVEL1
3635 heapCb->next->size = size - sizeof(CmHEntry);
3636 heapCb->next->requestedSize = 0;
3637 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3639 heapCb->next->trSignature[idx] = 0xAB;
3641 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3642 heapCb->staticHeapMemUsed = 0;
3643 heapCb->dynamicHeapMemUsed = 0;
3644 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3645 sizeof(heapCb->next->memFlags) +
3646 sizeof(heapCb->next->requestedSize);
3647 heapCb->numAllocAttempts = 0;
3648 heapCb->numDeallocAttempts = 0;
3649 heapCb->trampleCount = 0;
3651 heapCb->next->size = size;
3652 #endif /* SSI_DEBUG_LEVEL1 */
3654 #if (ERRCLASS & ERRCLS_DEBUG)
3655 heapCb->numFragBlk = 0;
3657 heapCb->numFailure = 0;
3660 heapCb->heapAllocCnt = 0;
3661 /* cm_mem_c_001.main_15 : Additions */
3662 #ifdef SS_HISTOGRAM_SUPPORT
3663 /* Initialise the memory histogram hash list */
3664 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3665 #endif /* SS_HISTOGRAM_SUPPORT */
3668 } /* end of cmMmHeapInit */
3675 * Desc: Allocates the memory block from the heap pool.
3678 * Ret: ROK - successful
3679 * RFAILED - unsuccessful.
3681 * Notes: This function is called by the cmAlloc. cmAlloc calls this
3682 * function when there is no memory block available in the bucket
3683 * and the heap pool is configured.
3690 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
3691 /* cm_mem_c_001.main_15 : Additions */
3692 #ifdef SS_4GMX_LCORE
3693 uint8_t ysCellConfigDone;
3695 #ifdef SS_HISTOGRAM_SUPPORT
3696 #ifdef SSI_DEBUG_LEVEL1
3697 static S16 cmHeapAlloc
3709 static S16 cmHeapAlloc
3719 #endif /* SSI_DEBUG_LEVEL1 */
3721 #ifdef SSI_DEBUG_LEVEL1
3722 static S16 cmHeapAlloc
3730 static S16 cmHeapAlloc
3736 #endif /* SSI_DEBUG_LEVEL1 */
3737 /* cm_mem_c_001.main_15 : Additions */
3738 #endif /* SS_HISTOGRAM_SUPPORT */
3740 CmHEntry *prvHBlk; /* Previous heap block */
3741 CmHEntry *curHBlk; /* Current heap block */
3743 /* cm_mem_c_001.main_15 : Additions */
3744 #ifdef SS_MEM_LEAK_STS
3746 #endif /* SS_MEM_LEAK_STS */
3747 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3748 #ifdef SSI_DEBUG_LEVEL1
3749 CmHEntry *alocHeapBlk;
3753 #endif /* SSI_DEBUG_LEVEL1 */
3754 /* cm_mem_c_001.main_15 : Additions */
3755 #ifdef SS_HISTOGRAM_SUPPORT
3757 #endif /* SS_HISTOGRAM_SUPPORT */
3759 /* cm_mem_c_001.main_15 : Additions */
3760 /* Acquire the heap lock */
3761 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3762 #ifdef SS_4GMX_LCORE
3763 if(1 == ysCellConfigDone)
3765 #ifdef SSI_DEBUG_LEVEL1
3766 /* display a message here */
3767 sprintf(dbgPrntBuf,"Allocating from heap size=%u\n", *size);
3768 SDisplay(0, dbgPrntBuf);
3769 #endif /* SSI_DEBUG_LEVEL1 */
3773 (Void) WTLock (&(heapCb->heapLock));
3775 (Void) SLock (&(heapCb->heapLock));
3778 #ifdef SS_MEM_LEAK_STS
3780 #endif /* SS_MEM_LEAK_STS */
3781 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
3782 #ifdef SSI_DEBUG_LEVEL1
3783 heapCb->numAllocAttempts++;
3784 requestedSize = *size;
3785 #endif /* SSI_DEBUG_LEVEL1 */
3787 /* Roundup the requested size */
3788 *size = CMM_DATALIGN(*size, (heapCb->minSize));
3790 /* Check if the available total size is adequate. */
3791 if ((*size) >= heapCb->avlSize)
3793 /* cm_mem_c_001.main_15 : Additions */
3795 (Void) WTUnlock (&(heapCb->heapLock));
3797 (Void) SUnlock (&(heapCb->heapLock));
3803 /* cm_mem_c_001.main_12 - addition for aligning the header size */
3804 #ifdef SSI_DEBUG_LEVEL1
3805 hdr = PTRALIGN(sizeof(CmHEntry));
3806 #endif /* SSI_DEBUG_LEVEL1 */
3809 * Search through the heap block list in the heap pool of size
3810 * greater than or equal to the requested size.
3813 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
3814 #ifdef SSI_DEBUG_LEVEL1
3815 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
3817 prvHBlk = (CmHEntry *)&(heapCb->next);
3818 #endif /* SSI_DEBUG_LEVEL1 */
3819 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
3820 prvHBlk = prvHBlk->next)
3823 * Since the size of the block is always multiple of CMM_MINBUFSIZE
3824 * and the requested size is rounded to the size multiple of
3825 * CMM_MINBUFSIZE, the difference between the size of the heap block
3826 * and the size to allocate will be either zero or multiple of
3829 if ((*size) <= curHBlk->size)
3831 /* cm_mem_c_001.main_12 - addition for block size calculation */
3832 #ifdef SSI_DEBUG_LEVEL1
3833 tmpSize = curHBlk->size - (*size);
3835 tmpSize = tmpSize - hdr;
3838 /* cm_mem_c_001.main_28 : compilation warning fix */
3839 tmpSize = (curHBlk->size - (*size));
3841 #endif /* SSI_DEBUG_LEVEL1 */
3843 /* Heap block of bigger size */
3844 /* cm_mem_c_001.main_12 - addition for allocating memory */
3845 #ifdef SSI_DEBUG_LEVEL1
3846 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
3847 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
3849 * No need to look for memory trampling as this is a new block altogether
3850 * Update the header only for this case as it is new block formed
3852 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3854 alocHeapBlk->trSignature[idx] = 0xAB;
3856 alocHeapBlk->size = *size;
3858 *ptr = (Data *)curHBlk + tmpSize;
3859 #endif /* SSI_DEBUG_LEVEL1 */
3860 curHBlk->size = tmpSize;
3864 /* Heap block is same size of the requested size */
3865 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
3866 #ifdef SSI_DEBUG_LEVEL1
3867 /* look for memory trampling as this is a pure block*/
3870 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
3872 /* detected a trampled memory block in this bucket */
3874 /* display an error message here */
3875 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3877 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
3879 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
3881 SDisplay(0, dbgPrntBuf);
3884 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
3886 /* Release the lock */
3887 /* cm_mem_c_001.main_13: Replaced SUnlock with
3890 (Void) WTUnlock (&(heapCb->heapLock));
3892 (Void) SUnlock (&(heapCb->heapLock));
3894 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
3895 return (RTRAMPLINGNOK);
3899 /* Release the lock */
3900 /* cm_mem_c_001.main_13: Replaced SUnlock with
3903 (Void) WTUnlock (&(heapCb->heapLock));
3905 (Void) SUnlock (&(heapCb->heapLock));
3912 *ptr = (Data *)curHBlk + hdr;
3913 alocHeapBlk = curHBlk;
3914 *size = curHBlk->size;
3916 *ptr = (Data *)curHBlk;
3917 #endif /* SSI_DEBUG_LEVEL1 */
3918 prvHBlk->next = curHBlk->next;
3921 /* cm_mem_c_001.main_12 - addition for header updation */
3922 #ifdef SSI_DEBUG_LEVEL1
3923 /* update the header fields */
3924 alocHeapBlk->requestedSize = requestedSize;
3925 alocHeapBlk->memFlags = 0;
3926 if (memType == CMM_STATIC_MEM_FLAG)
3928 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
3929 heapCb->staticHeapMemUsed += (*size + hdr);
3933 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
3934 heapCb->dynamicHeapMemUsed += (*size + hdr);
3936 heapCb->avlSize -= ((*size) + hdr);
3938 heapCb->avlSize -= (*size);
3939 #endif /* SSI_DEBUG_LEVEL1 */
3945 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
3946 *size, num_times, *ptr);
3947 SDisplay(0, prntBuf);
3951 /* cm_mem_c_001.main_15 : Additions */
3952 #ifdef SS_MEM_LEAK_STS
3953 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3954 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
3955 #endif /* SS_MEM_LEAK_STS */
3956 /* Release the lock */
3957 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
3959 (Void) WTUnlock (&(heapCb->heapLock));
3961 (Void) SUnlock (&(heapCb->heapLock));
3964 #ifdef SS_HISTOGRAM_SUPPORT
3965 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
3966 * information into the hash list */
3969 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
3971 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3976 #endif /* SS_HISTOGRAM_SUPPORT */
3982 /* cm_mem_c_008.104 - Addition for memory calculator tool */
3988 /* Release the lock */
3989 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3991 (Void) WTUnlock (&(heapCb->heapLock));
3993 (Void) SUnlock (&(heapCb->heapLock));
3998 } /* end of cmHeapAlloc */
4005 * Desc: Return the memory block from the heap pool.
4008 * Ret: ROK - successful
4009 * RFAILED - unsuccessful.
4011 * Notes: This function returns the memory block to the heap pool. This
4012 * function is called by cmFree. The function does not check the
4013 * validity of the memory block. The caller must be sure that the
4014 * block was previously allocated and belongs to the heap pool. The
4015 * function maintain the sorting order of the memory block on the
4016 * starting address of the block. This function also do compaction
4017 * if the neighbouring blocks are already in the heap.
4024 /* cm_mem_c_001.main_15 : Additions */
4025 #ifdef SS_HISTOGRAM_SUPPORT
4026 static S16 cmHeapFree
4037 static S16 cmHeapFree
4043 /* cm_mem_c_001.main_15 : Additions */
4044 #endif /* SS_HISTOGRAM_SUPPORT */
4047 CmHEntry *curHBlk; /* Current heap block */
4048 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4049 #ifdef SSI_DEBUG_LEVEL1
4051 #endif /* SSI_DEBUG_LEVEL1 */
4052 /* cm_mem_c_001.main_15 : Additions */
4053 #ifdef SS_HISTOGRAM_SUPPORT
4054 Size allocSize = size;
4056 #endif /* SS_HISTOGRAM_SUPPORT */
4059 /* Roundup the requested size */
4060 size = CMM_DATALIGN(size, (heapCb->minSize));
4061 /* cm_mem_c_001.main_15: Additions */
4062 #ifdef SS_HISTOGRAM_SUPPORT
4064 #endif /* SS_HISTOGRAM_SUPPORT */
4066 /* Acquire the heap lock */
4067 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4069 (Void) WTLock (&(heapCb->heapLock));
4071 (Void) SLock (&(heapCb->heapLock));
4074 /* increase the avlSize */
4075 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4076 #ifdef SSI_DEBUG_LEVEL1
4077 hdr = PTRALIGN(sizeof(CmHEntry));
4078 heapCb->avlSize += (size + hdr);
4079 heapCb->numDeallocAttempts++;
4081 heapCb->avlSize += size;
4082 #endif /* SSI_DEBUG_LEVEL1 */
4084 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4085 #ifdef SSI_DEBUG_LEVEL1
4086 p = (CmHEntry *)(ptr - hdr);
4088 p = (CmHEntry *)ptr;
4089 /* cm_mem_c_001.main_15 : Additions */
4090 #ifdef SS_MEM_LEAK_STS
4091 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4092 cmRlsAllocBlk((PTR)ptr);
4093 #endif /* SS_MEM_LEAK_STS */
4094 #endif /* SSI_DEBUG_LEVEL1 */
4097 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4098 #ifdef SSI_DEBUG_LEVEL1
4099 /* look for memory trampling */
4100 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4102 /* detected a trampled memory block in heap */
4104 /* display an error message here */
4105 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4107 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4109 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4111 SDisplay(0, dbgPrntBuf);
4114 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4116 /* Release the lock */
4117 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4119 (Void) WTUnlock (&(heapCb->heapLock));
4121 (Void) SUnlock (&(heapCb->heapLock));
4123 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4124 return (RTRAMPLINGNOK);
4128 /* do not add to the free heap */
4129 heapCb->avlSize -= (size + hdr);
4130 /* Release the heap lock */
4131 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4133 (Void) WTUnlock (&(heapCb->heapLock));
4135 (Void) SUnlock (&(heapCb->heapLock));
4142 /* look for any double free */
4143 if (CMM_IS_FREE(p->memFlags))
4146 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4148 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4150 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4152 SDisplay(0, dbgPrntBuf);
4155 heapCb->avlSize -= (size + hdr);
4156 /* cm_mem_c_001.main_15 : Additions */
4158 (Void) WTUnlock (&(heapCb->heapLock));
4160 (Void) SUnlock (&(heapCb->heapLock));
4165 #endif /* SSI_DEBUG_LEVEL1 */
4167 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4170 * The block will be inserted to maintain the sorted order on the
4171 * starting address of the block.
4175 if (!(curHBlk->next) ||
4176 (p < (curHBlk->next)))
4178 /* Heap block should be inserted here */
4181 * Check if the block to be returned can be merged with the
4184 /* cm_mem_c_001.main_12 - addition for header consideration */
4185 #ifdef SSI_DEBUG_LEVEL1
4186 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4188 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4189 #endif /* SSI_DEBUG_LEVEL1 */
4191 /* Merge the block */
4192 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4193 #ifdef SSI_DEBUG_LEVEL1
4194 /* update the flags */
4195 if (CMM_IS_STATIC(p->memFlags))
4196 heapCb->staticHeapMemUsed -= (size + hdr);
4197 else if (CMM_IS_DYNAMIC(p->memFlags))
4198 heapCb->dynamicHeapMemUsed -= (size + hdr);
4199 size = (curHBlk->size += (size + hdr));
4201 size = (curHBlk->size += size);
4202 #endif /*SSI_DEBUG_LEVEL1*/
4207 /* cm_mem_c_001.main_12 - addition for double-free check */
4208 #ifdef SSI_DEBUG_LEVEL1
4209 /* Check for double deallocation in heap */
4210 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4212 /* Release the lock */
4213 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4215 (Void) WTUnlock (&(heapCb->heapLock));
4217 (Void) SUnlock (&(heapCb->heapLock));
4220 /* This block is already freed in the heap */
4223 /* update the flags as it is a new node */
4224 if (CMM_IS_STATIC(p->memFlags))
4226 heapCb->staticHeapMemUsed -= (size + hdr);
4227 CMM_RESET_STATIC_FLAG(p->memFlags);
4229 else if (CMM_IS_DYNAMIC(p->memFlags))
4231 heapCb->dynamicHeapMemUsed -= (size + hdr);
4232 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4234 CMM_SET_FREE_FLAG(p->memFlags);
4235 p->requestedSize = 0;
4236 #endif /*SSI_DEBUG_LEVEL1*/
4237 /* insert the block */
4238 p->next = curHBlk->next;
4243 /* Try to merge with the next block in the chain */
4244 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4245 #ifdef SSI_DEBUG_LEVEL1
4246 if (((Data *)p + hdr + size) == (Data *)(p->next) && (p->next))
4248 if (((Data *)p + size) == (Data *)(p->next) && (p->next))
4249 #endif /*SSI_DEBUG_LEVEL1*/
4251 /* p->next can not be NULL */
4252 /* cm_mem_c_001.main_12 - addition for header consideration */
4253 #ifdef SSI_DEBUG_LEVEL1
4254 p->size += (p->next->size + hdr);
4256 p->size += p->next->size;
4257 #endif /*SSI_DEBUG_LEVEL1*/
4258 p->next = p->next->next;
4261 /* Release the lock */
4262 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4264 (Void) WTUnlock (&(heapCb->heapLock));
4266 (Void) SUnlock (&(heapCb->heapLock));
4268 /* cm_mem_c_001.main_15 : Additions */
4269 #ifdef SS_HISTOGRAM_SUPPORT
4270 /* If If Tapa task (entId)is registerd for histogram then insert
4271 Memrory Freed information into the hash list */
4274 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4275 fileName, entId) != ROK)
4277 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4281 #endif /* SS_HISTOGRAM_SUPPORT */
4285 else if (p < curHBlk)
4288 * Check if the block to be returned can be merged with the
4291 /* cm_mem_c_001.main_12 - addition for header consideration */
4292 #ifdef SSI_DEBUG_LEVEL1
4293 if (((Data *)p + hdr + size) == (Data *)curHBlk)
4295 if (((Data *)p + size) == (Data *)curHBlk)
4296 #endif /* SSI_DEBUG_LEVEL1 */
4298 /* Merge the block */
4299 /* cm_mem_c_001.main_12 - addition for header consideration */
4300 #ifdef SSI_DEBUG_LEVEL1
4301 p->size = size + (curHBlk->size + hdr);
4303 p->size = size + curHBlk->size;
4304 #endif /* SSI_DEBUG_LEVEL1 */
4305 p->next = curHBlk->next;
4309 /* insert the block */
4313 /* cm_mem_c_001.main_12 - addition for header updation */
4314 #ifdef SSI_DEBUG_LEVEL1
4315 /* update the flags in both cases as they are new start nodes*/
4316 if (CMM_IS_STATIC(p->memFlags))
4318 heapCb->staticHeapMemUsed -= (size + hdr);
4319 CMM_RESET_STATIC_FLAG(p->memFlags);
4321 else if (CMM_IS_DYNAMIC(p->memFlags))
4323 heapCb->dynamicHeapMemUsed -= (size + hdr);
4324 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4326 CMM_SET_FREE_FLAG(p->memFlags);
4327 p->requestedSize = 0;
4328 #endif /* SSI_DEBUG_LEVEL1 */
4332 /* Release the lock */
4333 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4335 (Void) WTUnlock (&(heapCb->heapLock));
4337 (Void) SUnlock (&(heapCb->heapLock));
4339 /* cm_mem_c_001.main_15 : Additions */
4340 #ifdef SS_HISTOGRAM_SUPPORT
4341 /* If If Tapa task (entId)is registerd for histogram then insert
4342 Memrory Freed information into the hash list */
4345 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4346 fileName, entId) != ROK)
4348 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4352 #endif /* SS_HISTOGRAM_SUPPORT */
4358 if (heapCb->next == NULLP)
4360 /* Heap block is empty. Insert the block in the head. */
4365 /* cm_mem_c_001.main_12 - addition for header updation */
4366 #ifdef SSI_DEBUG_LEVEL1
4367 if (CMM_IS_STATIC(p->memFlags))
4369 heapCb->staticHeapMemUsed -= (size + hdr);
4370 CMM_RESET_STATIC_FLAG(p->memFlags);
4372 else if (CMM_IS_DYNAMIC(p->memFlags))
4374 heapCb->dynamicHeapMemUsed -= (size + hdr);
4375 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4377 CMM_SET_FREE_FLAG(p->memFlags);
4378 p->requestedSize = 0;
4379 #endif /* SSI_DEBUG_LEVEL1 */
4381 /* Release the heap lock */
4382 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4384 (Void) WTUnlock (&(heapCb->heapLock));
4386 (Void) SUnlock (&(heapCb->heapLock));
4388 /* cm_mem_c_001.main_15 : Additions */
4389 #ifdef SS_HISTOGRAM_SUPPORT
4390 /* If If Tapa task (entId)is registerd for histogram then insert
4391 Memrory Freed information into the hash list */
4394 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4395 fileName, entId) != ROK)
4397 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4401 #endif /* SS_HISTOGRAM_SUPPORT */
4405 /* Release the lock */
4406 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4408 (Void) WTUnlock (&(heapCb->heapLock));
4410 (Void) SUnlock (&(heapCb->heapLock));
4414 } /* end of cmHeapFree */
4416 #ifdef SS_LIGHT_MEM_LEAK_STS
4417 uint32_t cmGetFreeIndx(Void)
4420 if(gmemLkCb.head == gmemLkCb.tail)
4422 allocQueueEmptyCnt++;
4423 return (CM_MAX_ALLOC_ENTERIES);
4427 uint32_t allocQIndx = gmemLkCb.queue[gmemLkCb.head];
4428 gmemLkCb.head = (gmemLkCb.head +1) % CM_MAX_ALLOC_ENTERIES;
4429 return (allocQIndx);
4433 uint32_t cmPutFreeIndx(uint32_t allocQIndx)
4435 uint32_t tmpTail = (gmemLkCb.tail+1)% CM_MAX_ALLOC_ENTERIES;
4436 if(tmpTail == gmemLkCb.head)
4438 allocQueueFullCnt++;
4443 gmemLkCb.queue[gmemLkCb.tail] = allocQIndx;
4444 gmemLkCb.tail = tmpTail;
4450 * Fun: cmInitMemLeakMdl
4452 * Desc: Initializes the memory leak detection module
4457 * Notes: This function initializes the memory leak detection module.
4463 Void cmInitMemLeak (Void)
4468 gmemLkCb.isStarted = FALSE;
4471 SInitLock(&gmemLkCb.memLock, 1);
4472 for(indx = 0; indx < CM_MAX_ALLOC_ENTERIES; indx++)
4474 gmemLkCb.allocInfo[indx].used = FALSE;
4475 cmPutFreeIndx(indx);
4479 } /* cmInitMemLeak */
4482 * Fun: cmDeinitMemLeak
4484 * Desc: De-initializes the memory leak detection
4489 * Notes: This function de-initializes the memory leak detection module.
4495 Void cmDeinitMemLeak(Void)
4500 for(indx = 0; indx < CM_MAX_ALLOC_ENTERIES; indx++)
4502 gmemLkCb.allocInfo[indx].used = FALSE;
4504 SDestroyLock(&gmemLkCb.memLock);
4505 gmemLkCb.isStarted = FALSE;
4512 * Fun: cmStorAllocBlk
4514 * Desc: Initializes the memory leak detection module
4519 * Notes: This function initializes the memory leak detection module.
4525 uint32_t cmStorAllocBlk(Void *addr)
4527 uint32_t allocQIndx;
4529 (Void) SLock(&gmemLkCb.memLock);
4530 allocQIndx = cmGetFreeIndx();
4531 if(allocQIndx < CM_MAX_ALLOC_ENTERIES)
4533 queueIndxAllocCnt++;
4534 gmemLkCb.allocInfo[allocQIndx].memAddr = addr;
4535 gmemLkCb.allocInfo[allocQIndx].used = TRUE;
4537 (Void) SUnlock(&(gmemLkCb.memLock));
4539 return (allocQIndx);
4540 } /* cmStorAllocBlk */
4545 * Fun: cmRlsAllocBlk
4547 * Desc: Initializes the memory leak detection module
4552 * Notes: This function initializes the memory leak detection module.
4558 Void cmRlsAllocBlk(uint32_t allocQIndx)
4561 if(allocQIndx < CM_MAX_ALLOC_ENTERIES)
4563 if(gmemLkCb.allocInfo[allocQIndx].used == TRUE)
4565 (Void) SLock(&gmemLkCb.memLock);
4566 gmemLkCb.allocInfo[allocQIndx].used = FALSE;
4567 cmPutFreeIndx(allocQIndx);
4569 (Void) SUnlock(&(gmemLkCb.memLock));
4573 } /* cmRlsAllocBlk */
4577 * Fun: cmStartStopLeakLog
4586 Void cmStartStopLeakLog(Void)
4588 if (FALSE == gmemLkCb.isStarted)
4590 printf("!!leak capturing started\n");
4591 gmemLkCb.isStarted = TRUE;
4595 gmemLkCb.isStarted = FALSE;
4596 printf("!!leak capturing stopped\n");
4604 * Fun: cmPrintLeakLog
4606 * Desc: Prints leak log
4615 Void cmPrintLeakLog(Void)
4620 static uint32_t leakCount =0;
4623 printf("---- START OF LEAK LOG ----");
4624 SLock(&gmemLkCb.memLock);
4625 printf("---- Lock Acquired ----");
4626 for(indx = 0; indx < CM_MAX_ALLOC_ENTERIES; indx++)
4628 if(gmemLkCb.allocInfo[indx].used == TRUE)
4631 aBkt =(CmMmBlkHdr *)gmemLkCb.allocInfo[indx].memAddr;
4632 printf("LeakCnt(%ld)Addr(0x%p)RqSz(%ld)",
4633 leakCount,gmemLkCb.allocInfo[indx].memAddr, aBkt->requestedSize);
4634 printf("LineNo(%ld)funcName(%s)\n",
4635 aBkt->lineNo, aBkt->currFuncName);
4636 gmemLkCb.allocInfo[indx].used = FALSE;
4637 cmPutFreeIndx(indx);
4639 //if(leakCount % 10 == 0)
4642 printf("---- END OF LEAK LOG ----");
4643 SUnlock(&gmemLkCb.memLock);
4644 printf("---- Lock Released ----");
4651 #if (defined(SS_MEM_LEAK_STS) || defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2))
4654 * Fun: cmRlsAllocBlk
4656 * Desc: Initializes the memory leak detection module
4661 * Notes: This function initializes the memory leak detection module.
4667 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4684 Ptr trace[CM_MAX_STACK_TRACE];
4690 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4691 MemAllocInfo *memAllocInfo;
4695 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4697 retVal = cmHashListFind(®Cb->brdcmSsiLstCp,(uint8_t *)&ptrHdr,
4698 (uint16_t)sizeof(uint64_t), 0, (PTR *)&ptrHdr);
4700 retVal = cmHashListFind(®Cb->brdcmSsiLstCp,(uint8_t *)&ptrHdr,
4701 (uint16_t)sizeof(uint32_t), 0, (PTR *)&ptrHdr);
4705 cmHashListDelete(®Cb->brdcmSsiLstCp, (PTR)ptrHdr);
4708 if( memLkCb.memLkMdlInit == FALSE)
4712 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
4714 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
4716 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
4717 (uint8_t *)&addr, sizeof(uint64_t), 0,
4718 (PTR *)&memAllocInfo);
4720 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
4721 (uint8_t *)&addr, sizeof(uint32_t), 0,
4722 (PTR *)&memAllocInfo);
4726 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
4728 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
4729 funcNm = (S8 **) memAllocInfo->backTrace;
4730 #ifdef SS_MEM_LEAK_SOL
4731 for(i = 0; i < memAllocInfo->bTrcSz; i++)
4733 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4734 #ifdef SS_4GMX_LCORE
4735 MxHeapFree(SsiHeap, funcNm[i]);
4740 #endif /* SS_MEM_LEAK_SOL */
4741 #ifdef SS_MEM_LEAK_FREE_TRACE
4745 sprintf( prntBuf, "\n==============================\n");
4747 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4749 sprintf( prntBuf, "Address: [%x]\n", addr);
4751 sprintf( prntBuf, "Address: [%lx]\n", addr);
4754 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4755 funcNm = backtrace_symbols(trace, traceSize);
4756 sprintf( prntBuf, "[bt] Execution path:\n");
4758 for (i=0; i < traceSize; ++i)
4760 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
4763 sprintf( prntBuf, "\n==============================\n");
4766 #endif /* SS_MEM_LEAK_FREE_TRACE */
4767 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4768 #ifdef SS_4GMX_LCORE
4769 MxHeapFree(SsiHeap, funcNm);
4770 MxHeapFree(SsiHeap, memAllocInfo);
4777 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
4780 #ifndef SS_MEM_LEAK_SOL
4781 if(idx == CM_MEM_USR_MDL)
4784 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
4786 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4788 sprintf( prntBuf, "Address: [%u]\n", addr);
4790 sprintf( prntBuf, "Address: [%lu]\n", addr);
4793 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4794 funcNm = backtrace_symbols(trace, traceSize);
4795 sprintf( prntBuf,"[bt] Execution path:\n");
4797 for (i=0; i < traceSize; ++i)
4799 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
4802 printf("\n==============================\n");
4803 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4804 #ifdef SS_4GMX_LCORE
4805 MxHeapFree(SsiHeap, funcNm);
4810 #endif /* SS_MEM_LEAK_SOL */
4811 #endif/* BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1 */
4812 /*cm_mem_c_001.main_25 : */
4814 } /* cmRlsAllocBlk */
4819 * Fun: cmStorAllocBlk
4821 * Desc: Initializes the memory leak detection module
4826 * Notes: This function initializes the memory leak detection module.
4832 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4853 #endif /* BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1 */
4855 #ifndef SS_MEM_LEAK_SOL
4856 void *trace[CM_MAX_STACK_TRACE];
4857 #endif /* SS_MEM_LEAK_SOL */
4858 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4861 MemAllocInfo *allocInfo;
4867 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4868 if( memLkCb.memLkMdlInit == FALSE)
4873 #ifdef SS_MEM_LEAK_SOL
4874 /* I need to do this for solaris, because it does not implement
4875 * backtrace. Here backtrace is my function. See below for the
4876 * implementation. */
4877 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4878 #ifdef SS_4GMX_LCORE
4879 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4880 memset(funcNm, 0, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4882 funcNm = (S8 **)calloc(1, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4884 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4885 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
4886 #else /* SS_MEM_LEAK_SOL */
4887 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4888 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4889 funcNm = backtrace_symbols(trace, traceSize);
4891 #endif /* SS_MEM_LEAK_SOL */
4893 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4894 moduleId = cmMemGetModuleId(funcNm, traceSize);
4895 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4898 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4899 #ifndef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4900 #ifdef SS_4GMX_LCORE
4901 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
4902 memset(allocInfo, 0, sizeof(MemAllocInfo));
4904 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
4907 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
4908 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4909 /* check if hashListCp is initialised yet */
4910 if ( regCb->brdcmSsiLstCp.nmbBins == 0)
4914 ptrHdr->reqSz = reqSz;
4915 ptrHdr->allocSz = allocSz;
4916 ptrHdr->bktIdx = bktIdx;
4917 cmHashListInsert(®Cb->brdcmSsiLstCp, (PTR)ptrHdr,
4918 (uint8_t *)&(ptrHdr), sizeof(PTR));
4920 allocInfo->memAddr = addr;
4921 allocInfo->reqSz = reqSz;
4922 allocInfo->allocSz = allocSz;
4923 allocInfo->bktIdx = bktIdx;
4924 allocInfo->backTrace = (PTR) funcNm;
4925 allocInfo->moduleId = moduleId;
4926 allocInfo->bTrcSz = traceSize;
4927 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
4928 (PTR)allocInfo, (uint8_t *)&(allocInfo->memAddr),
4929 sizeof(allocInfo->memAddr));
4930 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
4932 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4935 } /* cmStorAllocBlk */
4940 } /* cmStorAllocBlk */
4946 * Desc: Initializes the memory leak detection module
4951 * Notes: This function initializes the memory leak detection module.
4957 Void SLogLkInfo (Void)
4959 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL2
4964 CmMmBlkHdr *newBlkHdr;
4965 CmMmBlkHdr *oldBlkHdr;
4966 CmMmRegCb *tmpRegCb;
4969 fp = fopen("meLeakLog.txt", "w");
4972 memLk.fileLkLog = (FILE *)stdout;
4976 memLk.fileLkLog = fp;
4978 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4979 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
4980 for(regionIdx = 0; regionIdx < SS_MAX_REGS; regionIdx++)
4982 // tmpRegCb = mtCMMRegCb[regionIdx];
4983 while(cmHashListGetNext(&tmpRegCb->brdcmSsiLstCp,
4984 (PTR)oldBlkHdr, (PTR *)&newBlkHdr) == ROK)
4986 sprintf(prntBuf, "[LBIS]\n");
4987 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
4989 sprintf(prntBuf, "Address: 0x%u\n", newBlkHdr);
4991 sprintf(prntBuf, "Address: 0x%lu\n", newBlkHdr);
4993 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
4994 sprintf(prntBuf, "Requested Size: %d\n", (S16)newBlkHdr->reqSz);
4995 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
4996 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newBlkHdr->allocSz);
4997 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
4998 sprintf(prntBuf, "Bucket Idx: %d\n", newBlkHdr->bktIdx);
4999 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
5000 sprintf(prntBuf,"Memory Allocation Path:\n");
5001 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
5002 //funcNm = (S8 **)newBlkHdr->backTrace;
5003 for(idx = 0; idx < BRDCM_MEM_LEAK_BTRACE; idx ++)
5005 // sprintf(prntBuf,"==> %p\n", newBlkHdr->backTrace[idx]);
5006 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
5008 sprintf(prntBuf, "[LBIE]\n\n");
5009 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
5010 fflush(memLk.fileLkLog);
5011 oldBlkHdr = newBlkHdr;
5015 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
5016 fwrite(prntBuf, strlen(prntBuf), 1, memLk.fileLkLog);
5019 MemAllocInfo *oldMemInfo;
5020 MemAllocInfo *newMemInfo;
5026 if( memLkCb.memLkMdlInit == FALSE)
5030 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
5031 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5033 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5035 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5037 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5043 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5044 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5045 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
5047 sprintf(prntBuf, "[LBIS]\n");
5048 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5049 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5051 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
5053 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
5055 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5056 sprintf(prntBuf, "Module Name: %s\n",
5057 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
5058 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5059 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
5060 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5061 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
5062 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5063 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
5064 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5065 sprintf(prntBuf,"Memory Allocation Path:\n");
5066 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5067 funcNm = (S8 **)newMemInfo->backTrace;
5068 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
5070 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
5071 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5073 sprintf(prntBuf, "[LBIE]\n\n");
5074 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5075 fflush(memLkCb.fileLkLog);
5076 oldMemInfo = newMemInfo;
5079 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5082 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
5083 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5090 /* cm_mem_c_001.main_15 : Additions */
5091 #ifdef SS_MEM_LEAK_STS
5094 * Fun: cmInitMemLeakMdl
5096 * Desc: Initializes the memory leak detection module
5101 * Notes: This function initializes the memory leak detection module.
5107 Void cmInitMemLeakMdl (Void)
5113 memLkCb.memLkMdlInit = FALSE;
5114 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5116 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5118 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
5119 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5120 500, 0, FALSE, CM_HASH_KEYTYPE_UINT32_MOD, 0, 0);
5121 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5124 if(memLkCb.fileLkLog == NULLP)
5126 memLkCb.fileLkLog = (FILE *) stdout;
5128 memLkCb.memLkMdlInit = TRUE;
5131 } /* cmInitMemLeakMdl */
5132 /* cm_mem_c_002.main_21 Added for shutdown procedure */
5135 * Fun: cmDeinitMemLeakMdl
5137 * Desc: De-initializes the memory leak detection module
5142 * Notes: This function de-initializes the memory leak detection module.
5148 Void cmDeinitMemLeakMdl (Void)
5154 memLkCb.memLkMdlInit = FALSE;
5155 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5157 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5159 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5160 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
5161 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5168 * Fun: cmMemOpenMemLkFile
5170 * Desc: Initializes the memory leak detection module
5175 * Notes: This function initializes the memory leak detection module.
5181 Void cmMemOpenMemLkFile(S8 *arg)
5183 memLkCb.fileLkLog = NULLP;
5184 memLkCb.fileLkLog = fopen(arg, "w");
5191 * Desc: Initializes the memory leak detection module
5196 * Notes: This function initializes the memory leak detection module.
5202 Void SFlushLkInfo (Void)
5204 MemAllocInfo *newMemInfo;
5208 #ifdef SS_MEM_LEAK_SOL
5210 #endif /* SS_MEM_LEAK_SOL */
5212 if( memLkCb.memLkMdlInit == FALSE)
5217 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5219 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5221 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5226 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5227 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5228 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
5230 funcNm = (S8 **)newMemInfo->backTrace;
5231 #ifdef SS_MEM_LEAK_SOL
5232 for(i = 0; i < newMemInfo->bTrcSz; i++)
5234 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5235 #ifdef SS_4GMX_LCORE
5236 MxHeapFree(SsiHeap, funcNm[i]);
5240 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
5242 #endif /* SS_MEM_LEAK_SOl */
5243 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5244 #ifdef SS_4GMX_LCORE
5245 MxHeapFree(SsiHeap, funcNm);
5246 MxHeapFree(SsiHeap, newMemInfo);
5252 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5259 * Fun: cmMemGetModuleId
5261 * Desc: Initializes the memory leak detection module
5266 * Notes: This function initializes the memory leak detection module.
5272 uint8_t cmMemGetModuleId(S8 **funNm,S32 traceSize)
5281 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
5283 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5284 for(idx = 0; idx < traceSize; idx++)
5288 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
5290 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
5295 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5297 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5298 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
5299 memUsrMdlStr[mdlFunStrIdx].fPStr,
5303 return (mdlFunStrIdx);
5308 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5310 retVal = strcmp((const S8 *)"DEFAULT",
5311 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5314 return (mdlFunStrIdx);
5321 } /* cmMemGetModuleId */
5325 * Fun: cmMemGetStrMtchIdx
5327 * Desc: Initializes the memory leak detection module
5332 * Notes: This function initializes the memory leak detection module.
5338 S16 cmMemGetStrMtchIdx
5354 len = strlen((const S8 *)str);
5356 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
5357 cmpStr[len + 1] = '\0';
5360 for(;strtIdx < endIdx && !found; strtIdx++)
5363 tempLen = strlen((const S8 *)strLst[strtIdx]);
5367 while(*(strLst[strtIdx] + idx + len) != '\0')
5369 retVal = strncmp((const S8 *)cmpStr,
5370 ((const S8 *)strLst[strtIdx] + idx), len);
5386 } /* cmMemGetStrMtchIdx */
5387 #ifdef SS_MEM_LEAK_SOL
5390 * Fun: cmAddrToSymStr
5392 * Desc: Initializes the memory leak detection module
5397 * Notes: This function initializes the memory leak detection module.
5403 S32 cmAddrToSymStr(Void *pc, S8 *buffer, S32 size)
5410 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5412 return (snprintf(buffer, size, "[0x%p]", pc));
5415 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5416 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5418 return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5421 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5425 return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5427 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5430 } /* cmAddrToSymStr */
5434 * Fun: cmLeakCallBack
5436 * Desc: Initializes the memory leak detection module
5441 * Notes: This function initializes the memory leak detection module.
5447 S32 cmLeakCallBack(uintptr_t pc,S32 sigNo, Void *arg)
5451 Backtrace_t *bt = (Backtrace_t *)arg;
5452 if (bt->bt_actcount >= bt->bt_maxcount)
5454 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5455 #ifdef SS_4GMX_LCORE
5456 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
5457 memset(buffer, 0, 510);
5459 buffer = (S8 *)calloc(1, 510);
5461 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
5462 (void) cmAddrToSymStr((void *)pc, buffer, 505);
5463 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5466 } /* cmLeakCallBack */
5467 #endif /* SS_MEM_LEAK_SOL */
5469 #endif /* SS_MEM_LEAK_STS */
5470 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5471 * These include sanity check functions for bucket and heap,
5472 * for printing several memory related statistics
5474 #if (defined(BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1) || defined(SSI_DEBUG_LEVEL1))
5477 * Fun: cmMmRegIsBlkSane
5479 * Desc: Performs the sanity check for the memory block by checking its header.
5481 * Ret: ROK - If no trampling is detected in the block
5482 * RFAILED - If trampling is detected in the block
5484 * Notes: This function performs the memory block sanity in a block.
5489 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
5490 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr,Size size)
5492 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr)
5496 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
5497 CmMmBlkTail *tailPtr;
5500 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5502 if (blkPtr->trSignature[sigCnt] != 0xAB)
5507 #ifdef BRDCM_SSI_MEM_LEAK_DEBUG_LEVEL1
5508 tailPtr = (CmMmBlkTail *)((Data *)blkPtr + (sizeof(CmMmBlkHdr) + size));
5509 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5511 if (tailPtr->trSignature[sigCnt] != 0xFE)
5520 #ifdef SSI_DEBUG_LEVEL1
5523 * Fun: cmMmBktSanityChk
5525 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
5526 * This API gets called when trampling is detected in a memory block.
5528 * Ret: RTRAMPLINGNOK - Trampling, serious error
5529 * RTRAMPLINGOK - Trampling, but OK to proceed
5531 * Notes: This function performs the memory block sanity in a bucket. This
5532 * function is called by cmAlloc and cmFree as part of error handling mechanism.
5533 * Performs sanity check for the whole bucket by traversing each
5534 * of the memory blocks using the pointer bktStartPtr.
5535 * Keeps track of number of tramplings happened. If the count
5536 * exceeds the threshold decided, then invalidates this bucket.
5541 static S16 cmMmBktSanityChk(CmMmBkt *bkt)
5546 bkt->trampleCount = 0;
5548 /* scan the entire memory list of the bucket */
5549 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5550 blkCnt < (bkt->numBlks); blkCnt++)
5552 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5554 bkt->trampleCount++;
5555 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5557 /* Take action to invalidate the entire bucket */
5558 return (RTRAMPLINGNOK);
5561 /* reach next memory block in this bucket manually */
5562 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5566 /* display an error message here */
5567 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5568 SDisplay(0, dbgPrntBuf);
5571 return (RTRAMPLINGOK);
5576 * Fun: cmMmHeapSanityChk
5578 * Desc: Performs the sanity check for the memory blocks in the memory heap.
5579 * This API gets called when trampling is detected in heap(Alloc/Free).
5581 * Ret: RTRAMPLINGNOK - Trampling, serious error
5582 * RTRAMPLINGOK - Trampling, but OK to proceed
5584 * Notes: This function performs the memory block sanity in the heap. This
5585 * function is called by cmHeapAlloc and cmHeapFree as part of error
5586 * handling mechanism. Keeps track of number of tramplings happened.
5587 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5588 * count is less than threshold, then return RTRAMPLINGOK.
5593 static S16 cmMmHeapSanityChk(CmMmHeapCb *heapCb)
5596 /* increment the trample count */
5597 heapCb->trampleCount++;
5599 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5601 return (RTRAMPLINGNOK);
5604 return (RTRAMPLINGOK);
5610 * Desc: Computes the hash list index (bin number) for a specified
5611 * key of type (x % 101).
5613 * return (idx % hash_table_size);
5615 * Ret: ROK - successful, *idx contains computed index
5622 static S16 cmMmHashFunc(CmMmHashListCp *hashListCp,uint32_t key,uint16_t *idx)
5625 *idx = (uint16_t)(key % hashListCp->numOfbins);
5629 } /* end of cmMmHashFunc () */
5633 * Fun: cmMmHashListInit
5635 * Desc: Initializes a hash list. Parameters are:
5637 * hashListCp control point for hash list
5638 * nmbBins number of bins in the hash list. Storage will
5639 * be allocated for them from the indicated memory
5642 * pool for allocating storage for bins.
5644 * Ret: ROK - initialization successful
5645 * RFAILED - initialization failed, lack of memory
5652 static S16 cmMmHashListInit
5654 CmMmHashListCp *hashListCp, /* hash list to initialize */
5655 uint16_t nmbBins, /* number of hash list bins */
5656 Region region, /* memory region to allocate bins */
5657 Pool pool /* memory pool to allocate bins */
5661 CmMmHashListEnt *hl;
5664 /* initialize control point fields */
5665 hashListCp->hashList = NULLP;
5666 hashListCp->numOfbins = 0;
5667 hashListCp->numOfEntries = 0;
5669 /* allocate memory for bins */
5672 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
5673 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5676 /* initialize bin pointers */
5677 hl = hashListCp->hashList;
5678 for(i = 0; i < nmbBins; i++)
5680 hl[i].size = hl[i].numAttempts = 0;
5683 /* initialize bin size */
5684 hashListCp->numOfbins = nmbBins;
5692 * Fun: cmMmHashListDeinit
5694 * Desc: Deinitializes a hash list. Deallocates memory for bins
5695 * and resets header fields. Parameters are:
5697 * hashListCp control point for hash list
5699 * pool for allocating storage for bins.
5701 * Ret: ROK - successful
5702 * RFAILED - failure, invalid parameters
5709 static S16 cmMmHashListDeinit
5711 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
5712 Region region, /* memory region to allocate bins */
5713 Pool pool /* memory pool to allocate bins */
5717 /* deallocate memory for bins */
5718 if (hashListCp->numOfbins)
5719 (Void) SPutSBuf(region, pool,
5720 (Data *) hashListCp->hashList,
5721 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5723 /* deinitialize control point fields */
5724 hashListCp->hashList = NULLP;
5725 hashListCp->numOfbins = 0;
5726 hashListCp->numOfEntries = 0;
5729 } /* end of cmMmHashListDeinit */
5733 * Fun: cmMmHashListInsert
5735 * Desc: Inserts a new entry in the hash list. Parameters are:
5737 * hashListCp control point for hash list
5738 * key pointer to key string in the new entry
5740 * Ret: ROK - insertion successful
5741 * RFAILED - insertion failed (incorrect parameter values)
5748 static S16 cmMmHashListInsert
5750 CmMmHashListCp *hashListCp, /* hash list to add to */
5751 uint32_t key /* pointer to key */
5754 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
5755 uint16_t idx; /* index for insertion into hash list */
5759 /* check if hashListCp is initialised yet */
5760 if ( hashListCp->numOfbins == 0)
5763 /* compute index for insertion */
5764 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5767 hashListEnt = hashListCp->hashList;
5769 if (hashListEnt[idx].numAttempts == 0)
5771 /* new entry, insert here */
5772 hashListEnt[idx].size = key;
5773 hashListEnt[idx].numAttempts++;
5774 /* increment count of entries in hash list */
5775 hashListCp->numOfEntries++;
5779 /* this hash is occupied, re-hash it using linear probing */
5780 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5782 if (hashListEnt[i].size == key)
5784 hashListEnt[i].numAttempts++;
5788 if (hashListEnt[i].numAttempts == 0)
5790 hashListEnt[i].size = key;
5791 hashListEnt[i].numAttempts++;
5792 /* increment count of entries in hash list */
5793 hashListCp->numOfEntries++;
5798 if (i == CMM_STAT_HASH_TBL_LEN)
5800 /* there is no free slot for this key */
5806 } /* end of cmMmHashListInsert */
5808 #endif /* SSI_DEBUG_LEVEL1 */
5809 /* cm_mem_c_001.main_15 : Additions */
5810 #ifdef SS_HISTOGRAM_SUPPORT
5813 * Fun: cmHstGrmHashListInit
5815 * Desc: Initializes a hash list. Parameters are:
5817 * hashListCp control point for hash list
5818 * Ret: ROK - initialization successful
5819 * RFAILED - initialization failed, lack of memory
5826 static S16 cmHstGrmHashListInit
5828 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5831 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5833 /* display an error message here */
5834 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5836 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5838 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5840 SDisplay(0, dbgPrntBuf);
5842 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5848 * Fun: cmHstGrmHashListDeInit
5850 * Desc: De-initializes a hash list. Parameters are:
5852 * hashListCp control point for hash list
5853 * Ret: ROK - initialization successful
5854 * RFAILED - initialization failed, lack of memory
5861 static S16 cmHstGrmHashListDeInit
5863 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
5866 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5868 /* display an error message here */
5869 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
5871 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5873 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5875 SDisplay(0, dbgPrntBuf);
5877 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5883 * Fun: cmHstGrmFreeInsert
5885 * Desc: Inserts a Freed information in into the hash list. Parameters are:
5887 * bkt : pointer to bucket for which memory is freed.
5888 * line : Line where memory is freed.
5889 * file : file where memory is freed.
5890 * entId : Tapa task which releases the memory.
5892 * Ret: ROK - insertion successful
5893 * RFAILED - insertion failed (incorrect parameter values)
5900 static S16 cmHstGrmFreeInsert
5902 CmHstGrmHashListCp* hashListCp, /* hash list cp */
5903 uint32_t blkSz, /* size of the block freed */
5904 uint32_t line, /* Line number */
5905 uint8_t *fileName, /* file name */
5906 uint8_t entId /* Tapa task which free the memory */
5909 uint32_t binIdx = 0; /* Bin index to insert the entry into the hash list */
5910 uint32_t key = 0; /* Key to fine the bin index */
5911 uint32_t ret = 0; /* Return value */
5912 CmMemEntries *entry = NULLP; /* Entry which contains the information */
5916 /* check for the total number of entries in the hash list. *
5917 * If there is no place for new entry return failure */
5918 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5920 /* After comuting the hash bind and key, check the entity already *
5921 existing or not. if we found the entry then update the information */
5922 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5925 entry->freedBytes += blkSz;
5926 entry->bucketFreeReq++;
5930 /* If hash list is full then print the error tna continue */
5931 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5933 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");
5937 /* Take the address of next free entry in the hash bin */
5938 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5940 /* Increase the number of time frees called */
5941 entry->bucketFreeReq++;
5942 entry->freedBytes += blkSz;
5944 /* Fill the information into the entry structure */
5945 cmHstGrmFillEntry(entry, key, line, fileName, entId);
5946 /* Increase the total numbet of entries in the bin */
5947 hashListCp->hashList[binIdx].numOfEntries++;
5949 /* Increase the total number of entries in the hash list */
5950 hashListCp->totalNumEntries++;
5953 } /* end of cmHstGrmFreeInsert */
5958 * Fun: ret = cmHstGrmAllocInsert
5960 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
5962 * hashListCp control point for hash list
5963 * key pointer to key string in the new entry
5965 * Ret: ROK - insertion successful
5966 * RFAILED - insertion failed (incorrect parameter values)
5973 static S16 cmHstGrmAllocInsert
5975 CmHstGrmHashListCp *hashListCp,
5983 uint32_t binIdx = 0;
5986 CmMemEntries *entry = NULLP;
5989 /* check for the total number of entries in the hash list. *
5990 * If there is no place for new entry return failure */
5991 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5993 /* After comuting the hash bind and key, check the entity already *
5994 existing or not. if we found the entry then update the information */
5995 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5999 entry->allocBytes += blkSz;
6000 entry->bucketAllocReq++;
6001 entry->wastedBytes += (blkSz - *reqSz);
6005 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6007 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");
6011 /* Take the address of next free entry in the hash bin */
6012 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6014 /* Clauculae the wasted bytes */
6015 /* Here wasted byte is differnce between the byte user
6016 * has requested and the byte the ssi allocated */
6017 entry->wastedBytes += (blkSz - *reqSz);
6018 entry->bucketAllocReq++;
6019 entry->allocBytes += blkSz;
6021 /* Fill the information into the entry structure */
6022 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6023 /* Increase the total numbet of entries in the bin */
6024 hashListCp->hashList[binIdx].numOfEntries++;
6026 /* Increase the total number of entries in the hash list */
6027 hashListCp->totalNumEntries++;
6030 } /* end of cmHstGrmAllocInsert */
6035 * Fun: cmHstGrmGetHashIdxAndKey
6037 * Desc: Finds an entry in the hash list. Parameters are:
6039 * hashListCp control point for hash list
6040 * key pointer to key string in the new entry
6042 * Ret: ROK - insertion successful
6043 * RFAILED - insertion failed (incorrect parameter values)
6050 static S16 cmHstGrmGetHashIdxAndKey
6061 /* Calculate the key using file name and line number */
6062 for(i = 0 ; fileName[i] != '\0'; i++)
6064 *key += fileName[i];
6067 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
6069 } /* end of cmHstGrmFillEntry */
6073 * Fun: cmHstGrmFillEntry
6075 * Desc: Insert the entry into the hash list.
6077 * entry : Infornation which will be inserted into the hash list
6078 * key : Which will be used ti find the entry.
6079 * line : Line number
6080 * fileName : File name
6081 * entId : Tapa task Id
6083 * Ret: ROK - insertion successful
6084 * RFAILED - insertion failed (incorrect parameter values)
6091 static S16 cmHstGrmFillEntry
6093 CmMemEntries *entry,
6104 entry->entId = entId;
6105 for(idx = 0; fileName[idx] != '\0'; idx++)
6107 entry->fileName[idx] = fileName[idx];
6109 entry->fileName[idx] = '\0';
6111 } /* end of cmHstGrmFillEntry */
6115 * Fun: cmHstGrmFindEntry
6117 * Desc: Finds an entry in the hash list. Parameters are:
6119 * hashListCp control point for hash list
6120 * key pointer to key string in the new entry
6122 * Ret: ROK - insertion successful
6123 * RFAILED - insertion failed (incorrect parameter values)
6130 static S16 cmHstGrmFindEntry
6132 CmHstGrmHashListCp *hashListCp,
6135 CmMemEntries **entry
6139 uint32_t numEnt = 0;
6140 uint32_t numBin = 0;
6141 CmHstGrmHashListEnt *tmpBin = NULLP;
6143 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
6145 /* find for the entry in the bin */
6146 tmpBin = &(hashListCp->hashList[*binIdx]);
6147 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
6149 /* If key supplied is matched with the stored key then
6150 * return that entity */
6151 if(tmpBin->entries[numEnt].key == key)
6153 *entry = &(tmpBin->entries[numEnt]);
6155 }/* End of if (tmpBin->entries[numEnt].key) */
6156 }/* end of for (numEnt = 0) */
6158 /* Here we are checking for any room left in the bin. If the room *
6159 exists its mean that there is no entry with the Key. so return *
6161 If there is no room in the bin, then check the other bins to find *
6163 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
6165 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
6168 }/* End of if (binIdx) */
6172 }/* End of else (binIdx) */
6173 } /* End of if (numEnt) */
6176 printf ("Unable to find the entry in hash list\n");
6178 }/* End of else (numEnt) */
6179 }/* end of for (numBin = 0) */
6181 printf("Unable to find the entry in the hash list\n");
6183 } /* end of cmHstGrmFindEntry */
6185 #endif /* SS_HISTOGRAM_SUPPORT */
6187 /**********************************************************************
6189 **********************************************************************/