1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
20 /********************************************************************20**
22 Name: Common Memory Manager
26 Desc: C source code for the Commom Memory Manager module.
30 *********************************************************************21*/
33 /************************************************************************
35 The following functions are provided in this file.
37 cmMmRegInit Memory Region Initialization.
38 cmMmRegDeInit Memory Region Deinitialization.
40 ************************************************************************/
44 /* header include files (.h) */
45 #include "envopt.h" /* environment options */
46 #include "envdep.h" /* environment dependent */
47 #include "envind.h" /* environment independent */
49 #include "gen.h" /* general */
50 #include "ssi.h" /* system services */
51 #include "cm_mem.h" /* Common memory manager cm_mem_c_001.main_15 */
53 #ifdef SS_MEM_LEAK_STS
56 #ifdef SS_MEM_LEAK_SOL
59 #include <sys/machelf.h>
60 #else /* SS_MEM_LEAK_SOL */
62 #endif /* SS_MEM_LEAK_SOL */
63 #include <sys/types.h>
64 #endif /* SS_MEM_LEAK_STS */
67 #ifdef SS_MULTICORE_SUPPORT /* cm_mem_c_001.main_14 */
68 #include "ss_dep.h" /* implementation-specific */
69 #include "ss_queue.h" /* queues */
70 #include "ss_task.h" /* tasking */
72 #ifdef SS_MULTICORE_SUPPORT
73 #include "ss_dep.h" /* implementation-specific */
74 #include "ss_queue.h" /* queues */
75 #include "ss_task.h" /* tasking */
79 /* header/extern include files (.x) */
80 #include "gen.x" /* general */
81 #include "ssi.x" /* system services */
82 #ifdef SS_MULTICORE_SUPPORT
83 #include "ss_dep.x" /* implementation-specific */
84 #include "ss_queue.x" /* queues */
85 #include "ss_task.x" /* system services */
87 #include "cm_hash.x" /* common hash functions */
89 #include "cm_mem_wl.x" /* Common memory manager */
90 /* cm_mem_c_001.main_15: Addition */
91 #include "cm_lib.x" /* common library functions */
97 #ifdef SS_MULTICORE_SUPPORT
98 #include "ss_dep.x" /* implementation-specific */
99 #include "ss_queue.x" /* queues */
100 #include "ss_task.x" /* system services */
105 #endif /* USE_PURE */
107 #include <execinfo.h>
110 #include <sys/time.h>
112 #ifdef SS_USE_ICC_MEMORY
114 #endif /* SS_USE_ICC_MEMORY */
117 #include "mt_plat_t33.h"
118 extern S32 clusterMode;
125 /*ccpu00142274 - UL mem based flow control changes */
126 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
129 PRIVATE U32 memoryCheckCounter;
131 #define NUM_CALLS_TO_CHECK_MEM_AGAIN 80 /* Number of calls after which need to check mem */
133 #ifdef T2200_2GB_DDR_CHANGES
134 #define ICC_MEM_UPPER_THRESHOLD 20 /* Only 20% of the available memory blocks are free */
135 #define ICC_MEM_LOWER_THRESHOLD 10 /* Only 10% of the available memory blocks are free */
137 #define ICC_MEM_UPPER_THRESHOLD 10 /* Only 20% of the available memory blocks are free */
138 #define ICC_MEM_LOWER_THRESHOLD 8 /* Only 10% of the available memory blocks are free */
141 #define ICC_MEM_UPPER_THRESHOLD 9 /* Only 20% of the available memory blocks are free */
142 #define ICC_MEM_LOWER_THRESHOLD 12 /* Only 30% of the available memory blocks are free */
144 #define ICC_POOL_ZERO_SIZE 384
145 #define ICC_POOL_ONE_SIZE 1920
146 #define ICC_POOL_TWO_SIZE 3968
147 #ifdef T2200_2GB_DDR_CHANGES
148 #define ICC_POOL_THREE_SIZE 16256
150 #define ICC_POOL_THREE_SIZE 8064
153 #ifdef T2200_2GB_DDR_CHANGES
154 #define ICC_POOL_ZERO_TOTAL_BLKS 139809 /* this and the next should be dynamic*/
155 #define ICC_POOL_ONE_TOTAL_BLKS 209714
156 #define ICC_POOL_TWO_TOTAL_BLKS 27961
157 #define ICC_POOL_THREE_TOTAL_BLKS 27961
159 #define ICC_POOL_ZERO_TOTAL_BLKS 55106 /* this and the next should be dynamic*/
160 #define ICC_POOL_ONE_TOTAL_BLKS 68567
161 #define ICC_POOL_TWO_TOTAL_BLKS 13819
162 #define ICC_POOL_THREE_TOTAL_BLKS 10902
165 /* The below configuration used for icc_part_size=573M in boot args, if icc part
166 * size changes then need to change the below configuration values*/
168 #define ICC_POOL_ZERO_TOTAL_BLKS 78232
169 #define ICC_POOL_ONE_TOTAL_BLKS 117349
170 #define ICC_POOL_TWO_TOTAL_BLKS 15645
171 #define ICC_POOL_THREE_TOTAL_BLKS 15645
173 #define ICC_POOL_ZERO_TOTAL_BLKS 79437
174 #define ICC_POOL_ONE_TOTAL_BLKS 80009
175 #define ICC_POOL_TWO_TOTAL_BLKS 16864
176 #define ICC_POOL_THREE_TOTAL_BLKS 11970
185 /* forward references */
186 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
187 /* cm_mem_c_001.main_15: Addition */
188 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler*/
193 CmHashListCp memDoubleFree; /* Added to find the double free */
194 SLockId memDoubleFreeLock;
195 #define NUM_BT_TRACES 12
196 typedef struct cmMemFreeInfo
200 void *btArr[NUM_BT_TRACES];
201 struct timeval timeStamp;
205 #define NUM_FREE_BUFFERS 128
206 typedef struct cmBtInfo
209 CmMemFreeInfo btInfo[NUM_FREE_BUFFERS];
213 CmBtInfo *allocBtInfo;
215 typedef struct cmMemDoubleFree
217 CmHashListEnt tmpListEnt;
218 CmMemFreeInfo traceInfo;
223 PUBLIC U8 stopBtInfo = FALSE;
224 PUBLIC Buffer *palBuffer;
225 EXTERN Buffer *mtTskBuffer1;
226 EXTERN Buffer *mtTskBuffer2;
228 #ifdef SS_USE_ICC_MEMORY
229 PRIVATE pthread_mutex_t iccAllocFreeLock;
231 PRIVATE pthread_mutex_t dynAllocFreeLock;
232 #endif /* SS_USE_ICC_MEMORY */
234 #ifdef SS_MEM_WL_DEBUG
235 PRIVATE S16 cmInitBtInfo ARGS((void));
238 #ifdef SS_USE_ICC_MEMORY
239 #ifdef T2K_MEM_LEAK_DBG
240 PRIVATE S16 cmIccAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr, char*, U32));
241 PRIVATE S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
242 PRIVATE S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr, char*, U32));
243 PRIVATE S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
244 PUBLIC void InsertToT2kMemLeakInfo ARGS((U32 address, U32 size, U32 lineNo, char* fileName));
245 void RemoveFromT2kMemLeakInfo ARGS((U32 address, char *file, U32 line));
246 PRIVATE U32 getT2kMemLeakIndex ARGS((U32 address));
248 PRIVATE S16 cmIccAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
249 PRIVATE S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size));
250 PRIVATE S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
251 PRIVATE S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size));
253 #else /* SS_USE_ICC_MEMORY */
254 PRIVATE S16 cmDynAllocWithLock ARGS((Void *regionCb,Size *size,U32 flags,Data **ptr));
255 PRIVATE S16 cmDynFreeWithLock ARGS((Void *regionCb,Data *ptr, Size size));
256 PRIVATE S16 cmDynAlloc ARGS((Void *regionCb,Size *size,U32 flags,Data **ptr));
257 PRIVATE S16 cmDynFree ARGS((Void *regionCb,Data *ptr, Size size));
258 #endif /* SS_USE_ICC_MEMORY */
261 #ifdef T2K_MEM_LEAK_DBG
262 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
263 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
265 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
266 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
268 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
269 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
271 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
272 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size));
274 #ifdef T2K_MEM_LEAK_DBG
275 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
276 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
278 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
279 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
282 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
283 PRIVATE S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
285 PRIVATE S16 cmCtl ARGS((Void *regionCb, Event event, SMemCtl *memCtl));
286 PRIVATE Void cmMmHeapInit ARGS((Data *memAddr, CmMmHeapCb *heapCb, Size size));
288 #ifdef SS_HISTOGRAM_SUPPORT
289 #ifdef SSI_DEBUG_LEVEL1
290 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,
291 U32 memType, U32 line, U8 *fileName, U8 entId, Bool hstReg));
292 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size, U32 memType, U32 line, U8 *fileName, U8 entId, Bool hstReg));
293 /*cm_mem_c_001.main_20-added new functionto allocate memory from new region*/
295 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size,
296 U32 line, U8 *fileName, U8 entId, Bool hstReg));
297 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,
298 U32 line, U8 *fileName, U8 entId, Bool hstReg));
299 #endif /* SSI_DEBUG_LEVEL1 */
301 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size, U32 line,
302 U8 *fileName, U8 entId, Bool hstReg));
304 PRIVATE S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size,
305 U32 line, U8 *fileName, U8 entId, Bool hstReg));
306 #else /* no histogram support */
307 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
308 #ifdef SSI_DEBUG_LEVEL1
309 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size, U32 memType));
311 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
312 #endif /* SSI_DEBUG_LEVEL1 */
313 PRIVATE S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
314 /* cm_mem_c_001.main_15 :Additions */
315 #ifdef SSI_DEBUG_LEVEL1
316 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr, U32 memType));
318 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
319 #endif /* SSI_DEBUG_LEVEL1 */
320 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size));
321 #endif /* SS_HISTOGRAM_SUPPORT */
323 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
325 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
326 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
330 PRIVATE Void cmMmBktInit ARGS((Data **memAddr, CmMmRegCb *regCb,
331 CmMmRegCfg *cfg, U16 bktIdx, U16 *lstMapIdx));
333 /* cm_mem_c_001.main_12 - addition of protoypes for sanity check and hash list functions */
334 #ifdef SSI_DEBUG_LEVEL1
335 PRIVATE S16 cmMmBktSanityChk ARGS((CmMmBkt *bkt));
336 PRIVATE S16 cmMmHeapSanityChk ARGS((CmMmHeapCb *heapCb));
337 PRIVATE S16 cmMmHashFunc ARGS((CmMmHashListCp *hashListCp, U32 key, U16 *idx ));
338 PRIVATE S16 cmMmHashListInit ARGS((CmMmHashListCp *hashListCp, U16 nmbBins,
339 Region region, Pool pool));
340 PRIVATE S16 cmMmHashListDeinit ARGS((CmMmHashListCp *hashListCp, Region region, Pool pool));
341 PRIVATE S16 cmMmHashListInsert ARGS((CmMmHashListCp *hashListCp, U32 key));
342 #endif /* SSI_DEBUG_LEVEL1 */
343 /* cm_mem_c_001.main_15 : Addtions */
344 #ifdef SS_HISTOGRAM_SUPPORT
345 PRIVATE S16 cmHstGrmAllocInsert ARGS((CmHstGrmHashListCp *hashListCp, U32 blkSz, U32 *reqSz, U32 line, U8 *fileName, U8 entId));
346 PRIVATE S16 cmHstGrmFreeInsert ARGS((CmHstGrmHashListCp* hashListCp, U32 blkSz, U32 line, U8 *fileName, U8 entId));
347 PRIVATE S16 cmHstGrmHashListInit ARGS((CmHstGrmHashListCp *hashListCp));
348 PRIVATE S16 cmHstGrmHashListDeInit ARGS((CmHstGrmHashListCp *hashListCp));
349 PRIVATE S16 cmHstGrmGetHashIdxAndKey ARGS((U8 *fileName, U32 line, U32 *binIdx, U32 *key));
350 PRIVATE S16 cmHstGrmFindEntry ARGS((CmHstGrmHashListCp *hashListCp, U32 key, U32 *binIdx, CmMemEntries **entry));
351 PRIVATE S16 cmHstGrmFillEntry ARGS((CmMemEntries *entry, U32 key, U32 line, U8 *fileName, U8 entId));
352 #endif /* SS_HISTOGRAM_SUPPORT */
355 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler */
360 /* public variable declarations */
363 #endif /* USE_PURE */
364 /* cm_mem_c_001.main_15:Additions */
365 #ifdef SS_MEM_LEAK_STS
366 MemUsrMdlStr memUsrMdlStr[]=
368 MEMRAW2STR(DEFAULT, STACK),
369 MEMRAW2STR(tc, PDCP_LAYER),
370 MEMRAW2STR(Tc, PDCP_LAYER),
371 MEMRAW2STR(mg, GCP_LAYER),
372 MEMRAW2STR(Mg, GCP_LAYER),
377 #endif /* SS_MEM_LEAK_STS */
379 /* cm_mem_c_008.104 - Addition for memory calculator tool */
381 PRIVATE Txt prntBuf[200]; /* print buffer */
382 PRIVATE U8 tryHeap=0;
385 /* cm_mem_c_001.main_12 - addition for ssi enhancements prints */
386 /* cm_mem_c_001.main_20 Additions */
387 #if (defined(SSI_DEBUG_LEVEL1) || defined(SS_HISTOGRAM_SUPPORT))
389 PRIVATE Txt dbgPrntBuf[200]; /* print buffer */
391 #endif /*SSI_DEBUG_LEVEL1 || SS_HISTOGRAM_SUPPORT */
393 #ifdef T2K_MEM_LEAK_DBG
394 /* convert to decimal (0x(end_addr - start_addr)>>8)*2 */
395 #define T2K_MEM_LEAK_INFO_TABLE_SIZE 3670014 /* New Sercomm Board*/
396 //#define T2K_MEM_LEAK_INFO_TABLE_SIZE 3145726 /*Old Sercomm Board*/
397 /* 0x94200000 is the starting address allocated by ICC,
398 * whenever that changes pleasse change here */
399 //#define T2K_MEM_LEAK_START_ADDR 0x9d400000 /*Old Sercomm Board*/
400 #define T2K_MEM_LEAK_START_ADDR 0x9d200000 /*New Sercomm Board*/
404 EXTERN pthread_t tmpRegTidMap[20];
406 EXTERN pthread_t tmpMainTid;
408 extern Bool g_usettitmr;
409 PUBLIC void DumpLayersDebugInformation()
411 DumpSSIDemandQDebugInformation();
412 /* dump layers information only after we start receiving the TTIs */
416 if (clusterMode == RADIO_CLUSTER_MODE)
418 DumpRLCDlDebugInformation();
420 #ifndef UL_RLC_NET_CLUSTER
421 DumpRLCUlDebugInformation();
427 #ifdef UL_RLC_NET_CLUSTER
428 DumpRLCUlDebugInformation();
430 DumpPDCPDlDebugInformation();
431 DumpPDCPUlDebugInformation();
434 //DumpPDCPDlDebugInformation();
435 //DumpPDCPUlDebugInformation();
436 DumpRLCDlDebugInformation();
437 DumpRLCUlDebugInformation();
438 //printSchCellInfo();
443 /* private variable declarations */
446 * Fun: cmMmStatBktInit
448 * Desc: Initialize the bucket and the map table.
451 * Ret: ROK - successful,
452 * RFAILED - unsuccessful.
454 * Notes: This function is called by the cmMmRegInit.
460 PRIVATE Void cmMmStatBktInit
469 PRIVATE Void cmMmStatBktInit (memAddr, regCb, cfg, bktIdx, lstMapIdx)
481 /* cm_mem_c_001.main_12 - addition for temporary variables */
482 #ifdef SSI_DEBUG_LEVEL1
483 CmMmBlkHdr **nextBlk;
487 #endif /* SSI_DEBUG_LEVEL1 */
489 TRC2(cmMmStatBktInit);
492 size = cfg->bktCfg[bktIdx].size;
493 numBlks = cfg->bktCfg[bktIdx].numBlks;
495 /* cm_mem_c_001.main_12 - addition for header initialization */
496 #ifdef SSI_DEBUG_LEVEL1
497 /* Reset the next block pointer */
498 regCb->bktTbl[bktIdx].nextBlk = NULLP;
500 /* Initialize the link list of the memory block */
501 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
503 for (cnt = 0; cnt < numBlks; cnt++)
505 *nextBlk = (CmMmBlkHdr *)*memAddr;
507 /* initialize the memory block header */
508 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
510 (*nextBlk)->trSignature[sigCnt] = 0xAB;
513 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
514 (*nextBlk)->requestedSize = 0;
515 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
516 nextBlk = &((*nextBlk)->nextBlk);
522 /* Initialize the bucket linked list */
524 /* Reset the next pointer */
525 regCb->bktTbl[bktIdx].next = NULLP;
527 /* Initialize the link list of the memory block */
528 next = &(regCb->bktTbl[bktIdx].next);
529 for (cnt = 0; cnt < numBlks; cnt++)
532 next = (CmMmEntry **)(*memAddr);
533 *memAddr = (*memAddr) + size;
538 #endif /* SSI_DEBUG_LEVEL1 */
540 /* Initialize the Map entry */
541 idx = size / cfg->bktQnSize;
544 * Check if the size is multiple of quantum size. If not we need to initialize
545 * one more map table entry.
547 if(size % cfg->bktQnSize)
552 while ( *lstMapIdx < idx)
554 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
556 #if (ERRCLASS & ERRCLS_DEBUG)
557 regCb->mapTbl[*lstMapIdx].numReq = 0;
558 regCb->mapTbl[*lstMapIdx].numFailure = 0;
564 /* Initialize the bucket structure */
565 regCb->bktTbl[bktIdx].size = size;
566 regCb->bktTbl[bktIdx].numBlks = numBlks;
567 regCb->bktTbl[bktIdx].numAlloc = 0;
568 regCb->bktTbl[bktIdx].maxAlloc = 0;
570 /* Update the total bucket size */
571 /* cm_mem_c_001.main_12 - addition for considering the header size */
572 #ifdef SSI_DEBUG_LEVEL1
573 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
575 regCb->bktSize += (size * numBlks);
576 #endif /* SSI_DEBUG_LEVEL1 */
578 regCb->bktTbl[bktIdx].bktFailCnt = 0;
579 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
581 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
582 #ifdef SSI_DEBUG_LEVEL1
583 /* Initialize other required pointers */
584 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
585 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
586 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
587 regCb->bktTbl[bktIdx].staticMemUsed = 0;
588 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
589 regCb->bktTbl[bktIdx].trampleCount = 0;
590 #endif /*SSI_DEBUG_LEVEL1*/
591 /* cm_mem_c_001.main_15 : Additions */
592 #ifdef SS_HISTOGRAM_SUPPORT
593 /* Initialise the memory histogram hash list */
594 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
595 #endif /* SS_HISTOGRAM_SUPPORT */
598 } /* end of cmMmStatBktInit */
602 * Fun: cmMmStatRegInit
604 * Desc: Configure the memory region for allocation. The function
605 * registers the memory region with System Service by calling
609 * Ret: ROK - successful,
610 * RFAILED - unsuccessful.
612 * Notes: The memory owner calls this function to initialize the memory
613 * manager with the information of the memory region. Before
614 * calling this function, the memory owner should allocate memory
615 * for the memory region. The memory owner should also provide the
616 * memory for the control block needed by the memory manager. The
617 * memory owner should allocate the memory for the region control
618 * block as cachable memory. This may increase the average
619 * throughput in allocation and deallocation as the region control
620 * block is mostly accessed by the CMM.
626 PUBLIC S16 cmMmStatRegInit
633 PUBLIC S16 cmMmStatRegInit(region, regCb, cfg)
643 #if (ERRCLASS & ERRCLS_INT_PAR)
646 Txt errMsg[256] = {'\0'};
651 #if (ERRCLASS & ERRCLS_INT_PAR)
653 /* error check on parameters */
654 if ((regCb == NULLP) || (cfg == NULLP))
659 /* Error check on the configuration fields */
660 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
661 (cfg->numBkts > CMM_MAX_BKT_ENT))
665 /* Check if the quantum size is power of 2 */
666 if ((cfg->numBkts) &&
667 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
669 /* cm_mem_c_001.main_20 Addition */
670 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
676 * Check if the size of the memory region is enough, whether bucket sizes
677 * are multiples of quantumn size, and also whether two consecutive buckets
678 * falls within same quanta.
680 lstQnSize = cfg->bktQnSize;
683 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
685 /* check if bucket size is mutiple of quantum size */
686 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
688 /* cm_mem_c_001.main_20 Addition */
689 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
691 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
692 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
694 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
695 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
701 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
704 * Two consecutive buckets are not separated by quantum size.
706 /* cm_mem_c_001.main_20 Addition */
707 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
711 /* cm_mem_c_001.main_20 Addition */
712 if (((cfg->bktCfg[bktIdx].size) /\
713 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
715 /* Error check whether the size of the mapping table is sufficient */
716 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
718 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
719 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
721 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
722 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
729 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
730 cfg->bktCfg[bktIdx].numBlks);
732 if (regCb->bktSize > cfg->size)
734 /* Size of the memory region is less than the required size */
736 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
741 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
746 /* Initialize the region control block */
747 regCb->region = region;
748 regCb->regInfo.regCb = regCb;
749 regCb->regInfo.start = cfg->vAddr;
750 regCb->regInfo.size = cfg->size;
753 avail_size = cfg->size;
754 #endif /* USE_PURE */
756 if ( cfg->chFlag & CMM_REG_OUTBOARD)
758 /* Out_of_board memory */
759 regCb->regInfo.flags = CMM_REG_OUTBOARD;
763 regCb->regInfo.flags = 0;
768 if(region == SS_MAX_REGS - 1)
770 regCb->regInfo.alloc = cmAlloc;
771 regCb->regInfo.free = cmFree;
772 regCb->regInfo.ctl = cmCtl;
776 regCb->regInfo.alloc = cmAllocWL;
777 regCb->regInfo.free = cmFreeWL;
778 regCb->regInfo.ctl = cmCtl;
781 regCb->regInfo.alloc = cmAlloc;
782 regCb->regInfo.free = cmFree;
783 regCb->regInfo.ctl = cmCtl;
786 /* Initialize the physical address */
787 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
789 regCb->pAddr = cfg->pAddr;
792 /* Initial address of the memory region block */
793 memAddr = cfg->vAddr;
795 /* Initialize the fields related to the bucket pool */
796 regCb->bktMaxBlkSize = 0;
801 /* Last bucket has the maximum size */
802 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
804 /* Get the power of the bktQnSize */
806 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
811 /* Initilaize the bktIndex of the map entries to FF */
812 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
814 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
818 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
820 /* Allocate the lock for the bucket pool */
821 cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
824 /* Used while freeing the bktLock in cmMmRegDeInit */
825 regCb->numBkts = cfg->numBkts;
829 * Initialize the heap pool if size the memory region region is more
830 * than the size of the bucket pool
833 regCb->heapFlag = FALSE;
835 /* Align the memory address */
836 memAddr = (Data *)(PTRALIGN(memAddr));
838 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
841 * Round the heap size so that the heap size is multiple
844 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
848 /* Allocate the lock for the heap pool */
849 regCb->heapFlag = TRUE;
850 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
853 /* Call SRegRegion to register the memory region with SSI */
854 if (SRegRegion(region, ®Cb->regInfo) != ROK)
860 } /* end of cmMmRegInit*/
865 * Fun: ssPutDynBufSet
867 * Desc: Puts the set of dynamic buffers into the global region
870 * Ret: ROK - successful,
871 * RFAILED - unsuccessful.
879 PUBLIC S16 ssPutDynBufSet
882 CmMmBktLstCb *bktLstCb
885 PUBLIC S16 ssPutDynBufSet(bktIdx, bktLstCb)
887 CmMmBktLstCb *bktLstCb;
890 CmMmGlobRegCb *globReg;
893 TRC1(ssPutDynBufSet);
895 globReg = &osCp.globRegCb;
897 if(bktIdx > CMM_MAX_BKT_ENT)
902 bktCb = &(globReg->bktTbl[bktIdx]);
904 /* Lock the global region first */
905 SLock(&(globReg->regLock));
907 cmLListAdd2Tail(&(bktCb->listBktSet), bktLstCb);
909 SUnlock(&(globReg->regLock));
916 * Fun: ssGetDynBufSet
918 * Desc: Gets the set of dynamic buffers into the global region
921 * Ret: ROK - successful,
922 * RFAILED - unsuccessful.
930 PUBLIC S16 ssGetDynBufSet
933 CmMmBktLstCb **bktLstCb
936 PUBLIC S16 ssGetDynBufSet(bktIdx, bktLstCb)
938 CmMmBktLstCb **bktLstCb;
941 CmMmGlobRegCb *globReg;
945 TRC1(ssGetDynBufSet);
947 globReg = &osCp.globRegCb;
949 if(bktIdx > CMM_MAX_BKT_ENT)
955 bktCb = &(globReg->bktTbl[bktIdx]);
957 /* Lock the global region first */
958 SLock(&(globReg->regLock));
960 lstNode = cmLListFirst(&(bktCb->listBktSet));
964 SUnlock(&(globReg->regLock));
968 cmLListDelFrm(&(bktCb->listBktSet), lstNode);
969 SUnlock(&(globReg->regLock));
971 *bktLstCb = (CmMmBktLstCb *)lstNode->node;
980 * Fun: cmMmGlobRegInit
982 * Desc: Configure the memory region for allocation. The function
983 * registers the memory region with System Service by calling
987 * Ret: ROK - successful,
988 * RFAILED - unsuccessful.
996 PUBLIC S16 cmMmGlobRegInit
1001 PUBLIC S16 cmMmGlobRegInit(regCb)
1002 CmMmGlobRegCb *regCb;
1011 CmMmBlkSetElement *blkLstElem;
1014 #if (ERRCLASS & ERRCLS_INT_PAR)
1017 Txt errMsg[256] = {'\0'};
1020 TRC2(cmMmGlobRegInit);
1022 #ifdef SS_MEM_WL_DEBUG
1023 if (cmInitBtInfo() == RFAILED)
1028 for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
1030 /* Initial address of the memory region block */
1031 memAddr = ®Cb->bktTbl[bktIdx].startAddr;
1032 bucketSetSize = regCb->bktTbl[bktIdx].bucketSetSize;
1033 size = regCb->bktTbl[bktIdx].size;
1035 /* Initialize the bucket linked list */
1036 cmLListInit(®Cb->bktTbl[bktIdx].listValidBktSet);
1037 cmLListInit(®Cb->bktTbl[bktIdx].listFreeBktSet);
1038 SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
1040 /* Initialize the link list of the memory block */
1041 next = &(regCb->bktTbl[bktIdx].next);
1043 numBlks = regCb->bktTbl[bktIdx].numBlks;
1044 for (cnt = 1; cnt <= numBlks; cnt++)
1047 next = (CmMmEntry **)(*memAddr);
1048 *memAddr = (*memAddr) + size;
1050 /* Maintain the list Cb */
1051 if(!(cnt % bucketSetSize))
1053 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1054 blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
1055 blkLstElem->numFreeBlks = bucketSetSize;
1056 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1057 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
1058 next = &(regCb->bktTbl[bktIdx].next);
1065 } /* end of cmMmGlobRegInit*/
1067 #ifdef SS_USE_ICC_MEMORY
1070 * Fun: cmIccAllocWithLock
1072 * Desc: Allocate a memory block for use by dynamic buffers.
1073 * This handler uses the lock to avoid the two thread
1074 * trying to allocate the memory at same time. This
1075 * handler must be used only for non-data plane thread
1076 * it causes delay due to lock.
1079 * Ret: ROK - successful
1080 * RFAILED - unsuccessful.
1087 #ifdef T2K_MEM_LEAK_DBG
1089 PRIVATE S16 cmIccAllocWithLock
1091 Void *regionCb, /* Pointer to a region */
1092 Size *size, /* size needs to be allocated */
1093 U32 flags, /* Flags used */
1094 Data **ptr, /* Reference to pointer for which need to be allocate */
1101 PRIVATE S16 cmIccAllocWithLock
1103 Void *regionCb, /* Pointer to a region */
1104 Size *size, /* size needs to be allocated */
1105 U32 flags, /* Flags used */
1106 Data **ptr /* Reference to pointer for which need to be allocate */
1109 PRIVATE S16 cmIccAllocWithLock(regionCb, size, flags, ptr)
1110 Void *regionCb; /* Pointer to a region */
1111 Size *size; /* size needs to be allocated */
1112 U32 flags; /* Flags used */
1113 Data **ptr; /* Reference to pointer for which need to be allocate */
1117 CmMmDynRegCb *regCb;
1120 TRC2(cmIccAllocWithLock);
1122 regCb = (CmMmDynRegCb *)regionCb;
1124 if((SLock(&iccAllocFreeLock)) != ROK)
1126 printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
1130 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1132 if((SUnlock(&iccAllocFreeLock)) != ROK)
1134 printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
1138 if ((memPtr) == NULLP)
1141 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1142 printf("Exiting...\n");
1147 #ifdef T2K_MEM_LEAK_DBG
1148 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1150 printf("Address returned is %p size = %ld\n",memPtr,*size);
1153 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1159 } /* end of cmIccAllocWithLock */
1163 * Fun: cmIccFreeWithLock
1165 * Desc: Return the Dynamic memory block for the memory region.
1166 * This handler uses the lock to avoid the two thread
1167 * trying to free the memory at same time. This
1168 * handler must be used only for non-data plane thread
1169 * it causes delay due to lock.
1171 * Ret: ROK - successful
1172 * RFAILED - unsuccessful.
1180 #ifdef T2K_MEM_LEAK_DBG
1182 PRIVATE S16 cmIccFreeWithLock
1184 Void *regionCb, /* Pointer to region cb */
1185 Data *ptr, /* Memory block needs to be freed */
1186 Size size, /* Size of the block */
1193 PRIVATE S16 cmIccFreeWithLock
1195 Void *regionCb, /* Pointer to region cb */
1196 Data *ptr, /* Memory block needs to be freed */
1197 Size size /* Size of the block */
1200 PRIVATE S16 cmIccFreeWithLock(regionCb, ptr, size)
1201 Void *regionCb; /* Pointer to region cb */
1202 Data *ptr; /* Memory block needs to be freed */
1203 Size size; /* Size of the block */
1207 CmMmDynRegCb *regCb;
1209 TRC2(cmIccFreeWithLock);
1211 regCb = (CmMmDynRegCb *)regionCb;
1213 if((SLock(&iccAllocFreeLock)) != ROK)
1215 printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
1219 #ifdef T2K_MEM_LEAK_DBG
1220 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1223 TL_Free(regCb->iccHdl, ptr);
1225 if((SUnlock(&iccAllocFreeLock)) != ROK)
1227 printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1232 } /* end of cmIccFree */
1238 * Desc: Allocate a memory block for use by dynamic buffers
1241 * Ret: ROK - successful
1242 * RFAILED - unsuccessful.
1249 #ifdef T2K_MEM_LEAK_DBG
1251 PRIVATE S16 cmIccAlloc
1253 Void *regionCb, /* Pointer to a region */
1254 Size *size, /* size needs to be allocated */
1255 U32 flags, /* Flags used */
1256 Data **ptr, /* Reference to pointer for which need to be allocate */
1264 PRIVATE S16 cmIccAlloc
1266 Void *regionCb, /* Pointer to a region */
1267 Size *size, /* size needs to be allocated */
1268 U32 flags, /* Flags used */
1269 Data **ptr /* Reference to pointer for which need to be allocate */
1272 PRIVATE S16 cmIccAlloc(regionCb, size, flags, ptr)
1273 Void *regionCb; /* Pointer to a region */
1274 Size *size; /* size needs to be allocated */
1275 U32 flags; /* Flags used */
1276 Data **ptr; /* Reference to pointer for which need to be allocate */
1281 CmMmDynRegCb *regCb;
1286 regCb = (CmMmDynRegCb *)regionCb;
1288 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1290 if ((memPtr) == NULLP)
1293 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1294 printf("Exiting...\n");
1298 #ifdef T2K_MEM_LEAK_DBG
1299 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1301 printf("Address returned is %p size = %ld\n",memPtr,*size);
1304 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1307 *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1309 *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1314 } /* end of cmIccAlloc */
1320 * Desc: Return the Dynamic memory block for the memory region.
1323 * Ret: ROK - successful
1324 * RFAILED - unsuccessful.
1332 #ifdef T2K_MEM_LEAK_DBG
1333 PRIVATE S16 cmIccFree
1335 Void *regionCb, /* Pointer to region cb */
1336 Data *ptr, /* Memory block needs to be freed */
1337 Size size, /* Size of the block */
1343 PRIVATE S16 cmIccFree
1345 Void *regionCb, /* Pointer to region cb */
1346 Data *ptr, /* Memory block needs to be freed */
1347 Size size /* Size of the block */
1350 PRIVATE S16 cmIccFree(regionCb, ptr, size)
1351 Void *regionCb; /* Pointer to region cb */
1352 Data *ptr; /* Memory block needs to be freed */
1353 Size size; /* Size of the block */
1357 CmMmDynRegCb *regCb;
1360 regCb = (CmMmDynRegCb *)regionCb;
1363 // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1365 #ifdef T2K_MEM_LEAK_DBG
1366 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1370 TL_Free(regCb->iccHdl, ptr);
1372 /* memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1374 TL_Free(regCb->iccHdl, memPtr);
1376 /*TL_Free(regCb->iccHdl, ptr);*/
1380 printf("FREE -ICC Addr Before PA2VA %x After PA2VA %x\n", memPtr, ptr);
1385 } /* end of cmIccFree */
1389 * Fun: cmMmDynRegInit
1391 * Desc: Configure the memory region for allocation. The function
1392 * registers the memory region with System Service by calling
1396 * Ret: ROK - successful,
1397 * RFAILED - unsuccessful.
1399 * Notes: The memory owner calls this function to initialize the memory
1400 * manager with the information of the memory region. Before
1401 * calling this function, the memory owner should allocate memory
1402 * for the memory region. The memory owner should also provide the
1403 * memory for the control block needed by the memory manager. The
1404 * memory owner should allocate the memory for the region control
1405 * block as cachable memory. This may increase the average
1406 * throughput in allocation and deallocation as the region control
1407 * block is mostly accessed by the CMM.
1413 PUBLIC S16 cmMmDynRegInit
1418 PUBLIC S16 cmMmDynRegInit(regCb)
1419 CmMmDynRegCb *regCb;
1423 #ifdef T2200_2GB_DDR_CHANGES
1424 Txt regIccStr[10] = {'\0'};
1426 Txt regIccStr[64] = {'\0'};
1429 TRC2(cmMmDynRegInit);
1431 /* Register the region/memory with ICC and get the handler for same. The id is starting
1432 * from region+1 as the zero is used by PHY code */
1433 #ifdef T2200_2GB_DDR_CHANGES
1434 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1437 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1439 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1441 // snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1443 if(clusterMode == RADIO_CLUSTER_MODE)
1445 if(regCb->region == 3)
1446 {/* ICC packet receiver */
1447 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1450 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1451 //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1455 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1456 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1457 //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1460 #ifdef T2200_2GB_DDR_CHANGES
1461 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1463 sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1468 printf(" %s \n",regIccStr);
1469 regCb->iccHdl = TL_Open(regIccStr, 0);
1471 printf("\nICC Region is %d\n",regCb->region);
1473 /* Call SRegRegion to register the memory region with SSI */
1474 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1476 /* Register the lock region for SS_MAX_REGS - 1 region */
1477 if((SS_MAX_REGS - 1) == regCb->region)
1479 regInfo.alloc = cmIccAllocWithLock;
1480 regInfo.free = cmIccFreeWithLock;
1481 regInfo.regCb = regCb;
1482 if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1484 printf("Failed to initialize the lock region lock\n");
1489 regInfo.alloc = cmIccAlloc;
1490 regInfo.free = cmIccFree;
1491 regInfo.regCb = regCb;
1494 if (SRegDynRegion(regCb->region, ®Info) != ROK)
1500 } /* end of cmMmDynRegInit*/
1502 #else /* SS_USE_ICC_MEMORY */
1506 * Fun: cmMmDynRegInit
1508 * Desc: Configure the memory region for allocation. The function
1509 * registers the memory region with System Service by calling
1513 * Ret: ROK - successful,
1514 * RFAILED - unsuccessful.
1516 * Notes: The memory owner calls this function to initialize the memory
1517 * manager with the information of the memory region. Before
1518 * calling this function, the memory owner should allocate memory
1519 * for the memory region. The memory owner should also provide the
1520 * memory for the control block needed by the memory manager. The
1521 * memory owner should allocate the memory for the region control
1522 * block as cachable memory. This may increase the average
1523 * throughput in allocation and deallocation as the region control
1524 * block is mostly accessed by the CMM.
1530 PUBLIC S16 cmMmDynRegInit
1535 PUBLIC S16 cmMmDynRegInit(regCb)
1536 CmMmDynRegCb *regCb;
1543 CmMmBlkSetElement *blkLstElem;
1545 Size bktQnSize = MT_BKTQNSIZE;
1550 TRC2(cmMmDynRegInit);
1552 /* Initialize the region control block */
1553 region = regCb->region;
1554 numBkts = regCb->numBkts;
1556 /* Initilaize the bktIndex of the map entries to FF */
1557 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1559 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1564 for(cnt = 0; cnt < numBkts; cnt++)
1566 /* Initialize the Map entry */
1567 size = regCb->bktTbl[cnt].size;
1568 idx = size / bktQnSize;
1571 * Check if the size is multiple of quantum size. If not we need to initialize
1572 * one more map table entry.
1574 if(size % bktQnSize)
1579 while ( lstMapIdx < idx)
1581 regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1586 regCb->bktQnPwr = 0;
1588 while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1593 /* Initialize the bucket structure */
1595 regCb->bktTbl[bktIdx].numAlloc = 0;
1596 regCb->bktTbl[bktIdx].maxAlloc = 0;
1598 /* Update the total bucket size */
1599 regCb->bktSize += (regCb->bktTbl[bktIdx].size * regCb->bktTbl[bktIdx].numBkt);
1601 regCb->bktTbl[bktIdx].bktFailCnt = 0;
1602 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
1604 if(regCb->bktMaxBlkSize < regCb->bktTbl[bktIdx].size)
1606 regCb->bktMaxBlkSize = regCb->bktTbl[bktIdx].size;
1610 for(idx = 0; idx < numBkts; idx++)
1612 regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1614 for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1616 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1617 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1618 cmLListAdd2Tail((®Cb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1622 /* Call SRegRegion to register the memory region with SSI */
1623 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1625 if((SS_MAX_REGS - 1) == regCb->region)
1627 regInfo.alloc = cmDynAllocWithLock;
1628 regInfo.free = cmDynFreeWithLock;
1629 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1631 printf("Failed to initialize the lock region lock\n");
1638 static dynLockCreated;
1639 regInfo.alloc = cmDynAllocWithLock;
1640 regInfo.free = cmDynFreeWithLock;
1641 if ( dynLockCreated == 0)
1643 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1645 printf("Failed to initialize the lock region lock\n");
1652 regInfo.alloc = cmDynAlloc;
1653 regInfo.free = cmDynFree;
1657 regInfo.regCb = regCb;
1659 if (SRegDynRegion(region, ®Info) != ROK)
1665 } /* end of cmMmDynRegInit*/
1667 #endif /* SS_USE_ICC_MEMORY */
1672 * Fun: cmMmRegDeInit
1674 * Desc: Deinitialize the memory region. The function call SDeregRegion
1675 * to deregister the memory region with System Service.
1678 * Ret: ROK - successful
1679 * RFAILED - unsuccessful.
1681 * Notes: The memory owner calls this function to deinitialize the region.
1682 * The memory manager does not return the memory to the system.
1683 * Before calling this function, the memory owner must be sure that
1684 * no layer is using any memory block from this region. On
1685 * successful return from the function, any request to the memory
1686 * manager to allocate/deallocate memory will fail. The memory owner
1687 * can reuse the memory for other region or return the memory to the
1688 * system memory pool.
1696 PUBLIC S16 cmMmRegDeInit
1701 PUBLIC S16 cmMmRegDeInit(regCb)
1707 TRC2(cmMmRegDeInit);
1709 #if (ERRCLASS & ERRCLS_INT_PAR)
1711 /* error check on parameters */
1719 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1720 #ifdef SSI_DEBUG_LEVEL1
1721 /* Deinitialize the hash table used for debug info storage at region level */
1722 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
1726 #endif /* SSI_DEBUG_LEVEL1 */
1728 /* Call SDeregRegion first to deregister the memory region with SSI */
1729 (Void) SDeregRegion (regCb->region);
1733 /* Bucket pool is configured */
1735 /* Free the initialzed locks of the buckets */
1736 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1738 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1739 WTDestroyLock for NT */
1740 /* cm_mem_c_001.main_24 fix for memory corruption*/
1743 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1745 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1747 /* cm_mem_c_001.main_15:Additions */
1748 #ifdef SS_HISTOGRAM_SUPPORT
1749 /* De-initialise the memory histogram hash list */
1750 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1751 #endif /* SS_HISTOGRAM_SUPPORT */
1755 if (regCb->heapFlag)
1757 /* Heap pool is configured */
1759 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1760 WTDestroyLock for NT */
1762 WTDestroyLock(®Cb->heapCb.heapLock);
1764 SDestroyLock(®Cb->heapCb.heapLock);
1770 } /* end of cmMmRegDeInit */
1773 #ifndef SS_USE_ICC_MEMORY
1776 * Fun: cmGetMemBlkSetForAlloc
1778 * Desc: Retruns the pointer to the element which is used for
1779 * allocating the buffer. Also, it does the threshold check
1780 * and get the additional memory block set from the global
1784 * Ret: Pointer to memory block set - successful
1785 * NULL - unsuccessful.
1788 * Current implementation of the is function is made assuming that
1789 * there will maximum two set of nodes only.
1796 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1798 U8 bucketIndex, /* Index to the bucket list */
1799 CmMmDynBktCb *bkt /* Bucket list control block */
1802 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc(bucketIndex, bkt)
1803 U8 bucketIndex; /* Index to the bucket list */
1804 CmMmDynBktCb *bkt; /* Bucket list control block */
1807 CmMmBlkSetElement *memBlkSetElem;
1808 CmMmBlkSetElement *nextMemBlkSetElem;
1809 CmLList *memSetNode;
1810 CmLList *nextMemSetNode;
1812 /* Check if we are coming here for the first time, if yes get a new
1813 * block set from global region */
1814 if(bkt->crntMemBlkSetElem == NULLP)
1816 /* set the current index to initial one and get the bucket set from
1818 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1820 /* Check if the element exits or not */
1821 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1826 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1827 /* Get the new block set from the gloabl region and return the same */
1828 ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1829 RETVALUE(bkt->crntMemBlkSetElem);
1831 /* If this is not the first time, take the bucket list CB from the
1833 memBlkSetElem = bkt->crntMemBlkSetElem;
1834 /* If the current index doesnot have any free buckets, it check in
1835 * the next bucket node */
1836 if(memBlkSetElem->numFreeBlks == 0)
1838 /* Get the next element in the list and if it is not present, then
1839 * get the first node */
1840 memSetNode = cmLListNext(&bkt->memBlkSetElem);
1842 if(memSetNode == NULLP)
1844 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1846 memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1848 /* if next node also empty, return failure */
1849 if(memBlkSetElem->numFreeBlks == 0)
1853 /* store the new index in the current node which will be
1854 * used in the next time. */
1855 bkt->crntMemBlkSetElem = memBlkSetElem;
1859 if(memBlkSetElem->nextBktPtr == NULLP)
1861 ssGetDynMemBlkSet(bucketIndex, memBlkSetElem);
1864 /* If we have reached the threshold value, get the next set of buckets from
1865 * the global region and place it */
1866 if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1868 /* Get the next element for the threshold check. If next is not present,
1869 * get the first one. Here, we are not using the cmLList macros to get
1870 * to the next node or first node as those macros are working on the crnt
1871 * node and will change the crnt. As we dont want to change the crnt node
1872 * at this point, we are directly using the listCp prameter to get next
1874 nextMemSetNode = memBlkSetElem->memSetNode.next;
1876 if(nextMemSetNode == NULLP)
1878 nextMemSetNode = bkt->memBlkSetElem.first;
1881 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1883 if(nextMemBlkSetElem->numFreeBlks == 0)
1885 /* The last parameter is used wheather to block for the block set aquiring
1886 or not. Here, the logic is such that, when the current node number of
1887 free blocks becomes one and the next node has zero free blocks,
1888 we must get the block set from global region.
1889 For example, if acquire threashold is 20 and current node has only one
1890 free block and next node has zero free blocks we block to aquire lock
1891 and get the set from global region else, we try for lock, if we get
1892 the lock, the get the block set else it is get in next go
1894 ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1895 (memBlkSetElem->numFreeBlks - 1));
1899 /* On successful, return the bucket node to calling function */
1900 RETVALUE(memBlkSetElem);
1901 } /* cmGetMemBlkSetForAlloc */
1906 * Fun: cmGetMemBlkSetForFree
1908 * Desc: Retruns the pointer to the element which is used for
1909 * freeing the buffer. Also, it does the threshold check
1910 * and release the additional memory block set to the global
1914 * Ret: Pointer to memory block set - successful
1915 * NULL - unsuccessful.
1918 * Current implementation of the is function is made assuming that
1919 * there will maximum two set of nodes only.
1926 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree
1928 U8 bucketIndex, /* Index to the bucket list */
1929 CmMmDynBktCb *bkt /* Bucket list control block */
1932 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree(bucketIndex, bkt)
1933 U8 bucketIndex; /* Index to the bucket list */
1934 CmMmDynBktCb *bkt; /* Bucket list control block */
1937 CmMmBlkSetElement *memBlkSetElem;
1938 CmMmBlkSetElement *nextMemBlkSetElem;
1939 CmLList *memSetNode;
1940 CmLList *nextMemSetNode;
1942 /* Check if we are coming here for the first time, if yes get a new
1943 * block set from global region */
1944 if(bkt->crntMemBlkSetElem == NULLP)
1946 /* set the current index to initial one */
1947 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1949 /* Check if the element exits or not */
1950 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1954 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1955 RETVALUE(bkt->crntMemBlkSetElem);
1957 /* If this is not the first time, take the bucket list CB from the
1959 memBlkSetElem = bkt->crntMemBlkSetElem;
1960 /* If the current index doesnot have any free buckets, it check in
1961 * the next bucket node */
1962 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1964 /* Get the next element in the list and if it is not present, then
1965 * get the first node */
1966 nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1968 if(nextMemSetNode == NULLP)
1970 nextMemSetNode = cmLListFirst(&bkt->memBlkSetElem);
1972 memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1974 /* if next node also empty, return failure */
1975 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1979 /* store the new index in the current node which will be
1980 * used in the next time. */
1981 bkt->crntMemBlkSetElem = memBlkSetElem;
1984 /* If we have reached the threshold value and have additional block set,
1985 * release the additional block set back to global region */
1986 if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold)
1988 /* Get the next element for the threshold check. If next is not present,
1989 * get the first one. Here, we are not using the cmLList macros to get
1990 * to the next node or first node as those macros are working on the crnt
1991 * node and will change the crnt. As we dont want to change the crnt node
1992 * at this point, we are directly using the listCp prameter to get next
1994 nextMemSetNode = memBlkSetElem->memSetNode.next;
1995 if(nextMemSetNode == NULLP)
1997 nextMemSetNode = bkt->memBlkSetElem.first;
2000 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
2001 if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
2003 /* The last parameter is used wheather to block for the block set aquiring
2004 or not. Here, the logic is such that, when the current node number of
2005 free blocks becomes one less than the bucket set size and the next node
2006 is has full free blocks, we must free the block set back to global region
2007 For example, if bucket set size if 100 and release threashold is 80 and
2008 current node has number of free blocks 99 and next node has 100 free blocks
2009 we block to aquire lock and free it back to global region else, we try for
2010 lock, if we get the lock, the block set is freed else its freed in next go
2012 ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
2013 (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
2015 nextMemBlkSetElem->numFreeBlks = 0;
2016 nextMemBlkSetElem->nextBktPtr = NULLP;
2021 /* On successful, return the bucket node to calling function */
2022 RETVALUE(memBlkSetElem);
2024 #endif /* SS_USE_ICC_MEMORY */
2025 #endif /* USE_PURE */
2027 #ifdef SS_MEM_WL_DEBUG
2030 * Fun: cmRemoveAllocPtrFromList
2032 * Desc: Remove a node with Free PTR from hashlist. The memory
2033 * of the node is Freed to the same region
2036 * Ret: ROK - successful
2037 * RFAILED - unsuccessful.
2046 PRIVATE S16 cmRemoveAllocPtrFromList
2048 CmMmDynRegCb *regionCb, /* Pointer to a region */
2052 PRIVATE S16 cmRemoveAllocPtrFromList(regionCb, ptr)
2053 CmMmDynRegCb *regionCb; /* Pointer to a region */
2058 CmMemDoubleFree *memNode = NULLP;
2060 SLock(&memDoubleFreeLock);
2061 if((cmHashListFind(&(memDoubleFree), (U8*)&ptr,
2062 sizeof(U32), 0, (PTR *)&memNode)) != ROK)
2069 tmpBtSize = backtrace(tmpBtArr, 10);
2070 strings = backtrace_symbols(tmpBtArr, tmpBtSize);
2071 printf("**** Trying to free non allocated block BT is: \n");
2072 for(idx = 0; idx < tmpBtSize; idx++)
2074 printf("%s\n", strings[idx]);
2076 printf("*****************************************\n");
2077 printf("Analysis from Array storing BT for freeing and allocation\n");
2078 cmAnalyseBtInfo(ptr, regionCb->region);
2079 SUnlock(&memDoubleFreeLock);
2083 if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
2085 SUnlock(&memDoubleFreeLock);
2088 SUnlock(&memDoubleFreeLock);
2089 SPutSBuf(regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
2096 * Fun: cmInsertAllocPtrToList
2098 * Desc: Insert a node with allocated PTR into hashlist. The memory
2099 * for the node is allocated from the same region
2102 * Ret: ROK - successful
2103 * RFAILED - unsuccessful.
2112 PRIVATE S16 cmInsertAllocPtrToList
2114 CmMmDynRegCb *regionCb, /* Pointer to a region */
2118 PRIVATE S16 cmInsertAllocPtrToList(regionCb, ptr)
2119 CmMmDynRegCb *regionCb; /* Pointer to a region */
2124 CmMemDoubleFree *memNode;
2126 SGetSBuf(regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
2127 if(memNode == NULLP)
2132 memNode->memBlkPtr = ptr;
2133 SLock(&memDoubleFreeLock);
2134 if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (U8*)&memNode->memBlkPtr,
2135 sizeof(PTR))) != ROK)
2137 SUnlock(&memDoubleFreeLock);
2140 SUnlock(&memDoubleFreeLock);
2147 #ifndef SS_USE_ICC_MEMORY
2150 * Fun: cmDynAllocWithLock
2152 * Desc: Allocate a memory block for use by dynamic buffers
2155 * Ret: ROK - successful
2156 * RFAILED - unsuccessful.
2163 /* cm_mem_c_001.main_15 : Additions */
2166 PRIVATE S16 cmDynAllocWithLock
2168 Void *regionCb, /* Pointer to a region */
2169 Size *size, /* size needs to be allocated */
2170 U32 flags, /* Flags used */
2171 Data **ptr /* Reference to pointer for which need to be allocate */
2174 PRIVATE S16 cmDynAllocWithLock(regionCb, size, flags, ptr)
2175 Void *regionCb; /* Pointer to a region */
2176 Size *size; /* size needs to be allocated */
2177 U32 flags; /* Flags used */
2178 Data **ptr; /* Reference to pointer for which need to be allocate */
2185 if((SLock(&dynAllocFreeLock)) != ROK)
2187 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
2191 ret = cmDynAlloc (regionCb, size,flags,ptr);
2193 if((SUnlock(&dynAllocFreeLock)) != ROK)
2195 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
2200 } /* end of cmDynAlloc */
2206 * Desc: Allocate a memory block for use by dynamic buffers
2209 * Ret: ROK - successful
2210 * RFAILED - unsuccessful.
2217 /* cm_mem_c_001.main_15 : Additions */
2220 PRIVATE S16 cmDynAlloc
2222 Void *regionCb, /* Pointer to a region */
2223 Size *size, /* size needs to be allocated */
2224 U32 flags, /* Flags used */
2225 Data **ptr /* Reference to pointer for which need to be allocate */
2228 PRIVATE S16 cmDynAlloc(regionCb, size, flags, ptr)
2229 Void *regionCb; /* Pointer to a region */
2230 Size *size; /* size needs to be allocated */
2231 U32 flags; /* Flags used */
2232 Data **ptr; /* Reference to pointer for which need to be allocate */
2235 CmMmDynRegCb *regCb;
2239 regCb = (CmMmDynRegCb *)regionCb;
2241 #ifdef SS_MEM_WL_DEBUG
2242 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
2248 #if (ERRCLASS & ERRCLS_INT_PAR)
2250 /* error check on parameters */
2251 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2260 * Check if the requested size is less than or equal to the maximum block
2261 * size in the bucket.
2264 #ifdef SS_MEM_WL_DEBUG
2265 if ( (*size + 4) <= regCb->bktMaxBlkSize)
2267 if ( (*size) <= regCb->bktMaxBlkSize)
2271 CmMmBlkSetElement *dynMemElem;
2275 /* Get the map to the mapping table */
2276 #ifdef SS_MEM_WL_DEBUG
2277 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
2279 idx = (((*size) - 1) >> regCb->bktQnPwr);
2282 #if (ERRCLASS & ERRCLS_DEBUG)
2283 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2285 printf("Failed to get the buffer of size %d\n", *size);
2286 /* Some fatal error in the map table initialization. */
2294 /* Dequeue the memory block and return it to the user */
2295 bktIdx = regCb->mapTbl[idx].bktIdx;
2296 bkt = &(regCb->bktTbl[bktIdx]);
2297 #ifdef SS_MEM_WL_DEBUG
2298 if(bkt->size < (*size+4))
2300 if(bkt->size < (*size))
2304 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2307 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
2309 /* Check if the bucket index, if its not valid, return failure */
2310 if(dynMemElem == NULLP)
2313 printf("Failed to get the buffer of size %ld\n", *size);
2315 printf("Failed to get the buffer of size %d\n", *size);
2320 #ifdef SS_MEM_WL_DEBUG
2321 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
2327 /* Get the bucket node from the index returned and allocate the memory */
2328 *ptr = dynMemElem->nextBktPtr;
2333 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
2334 dynMemElem->numFreeBlks--;
2336 #ifdef SS_MEM_WL_DEBUG
2337 prvAllocPtr[regCb->region] = *ptr;
2339 if(regCb->region == 6)
2340 printf("cmDynAlloc: PTR = %x\n", *ptr);
2341 **ptr = (U32) ((bktIdx << 4) | 0x0f);
2344 **ptr = (U8) bktIdx;
2348 *ptr += sizeof (U32);
2350 if ((bktIdx == 0) && (!stopBtInfo))
2354 btInfo = &allocBtInfo[regCb->region];
2355 btIdx = btInfo->btInfoIdx;
2356 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2358 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2360 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2362 cmInsertAllocPtrToList(regCb, (PTR)*ptr);
2366 btIdx &= (NUM_FREE_BUFFERS - 1);
2368 btInfo->btInfo[btIdx].ptr = (PTR)0;
2369 btInfo->btInfo[btIdx].btSize = 0;
2370 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2371 btInfo->btInfoIdx = btIdx;
2378 /* If the size is not matching, return failure to caller */
2380 printf("Failed to get the buffer of size %ld\n", *size);
2382 printf("Failed to get the buffer of size %d\n", *size);
2386 #else /* use pure is on */
2388 #ifdef SS_4GMX_LCORE
2389 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2390 cmMemset((U8*)ptr, 0, *size);
2392 /* *ptr = (Data*) malloc(*size); */
2394 *ptr = (Data *)malloc(*size);
2396 if ( (*ptr) == NULLP)
2398 /* avail_size -= *size; */
2400 #endif /* USE_PURE */
2402 } /* end of cmDynAlloc */
2403 #endif /* SS_USE_ICC_MEMORY */
2406 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2408 int g_overused[5] = {0};
2415 * Desc: Allocate a memory block for the memory region.
2418 * Ret: ROK - successful
2419 * RFAILED - unsuccessful.
2422 * The function allocates a memory block of size atleast equal to
2423 * the requested size. The size parameter will be updated with the
2424 * actual size of the memory block allocated for the request. The
2425 * CMM tries to allocate the memory block form the bucket pool. If
2426 * there is no memory in the bucket the CMM allocates the memory
2427 * block form the heap pool. This function is always called by the
2428 * System Service module.
2430 * The caller of the function should try to use the out value of
2431 * the size while returning the memory block to the region. However
2432 * the current design of the memory manager does not enforce to pass
2433 * the actual size of the memory block. (Due to the SGetSBuf
2434 * semantics the layer will not able to pass the correct size of the
2435 * memory block while calling SPutSBuf).
2441 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2443 /* cm_mem_c_001.main_15 : Additions */
2444 #ifdef T2K_MEM_LEAK_DBG
2455 #ifdef SS_HISTOGRAM_SUPPORT
2456 #ifdef SSI_DEBUG_LEVEL1
2471 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType, line, fileName, entId, hstReg)
2496 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, line, fileName, entId, hstReg)
2506 #endif /* SSI_DEBUG_LEVEL1 */
2510 #ifdef SSI_DEBUG_LEVEL1
2521 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType)
2538 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr)
2546 #endif /* SSI_DEBUG_LEVEL1 */
2547 /* cm_mem_c_001.main_15: Additions */
2548 #endif /* SS_HISTOGRAM_SUPPORT */
2551 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2558 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2562 /* cm_mem_c_001.main_15 : Additions */
2563 #ifdef SS_MEM_LEAK_STS
2565 #endif /* SS_MEM_LEAK_STS */
2566 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2567 #ifdef SSI_DEBUG_LEVEL1
2568 CmMmBlkHdr *alocBlk;
2569 #endif /* SSI_DEBUG_LEVEL1 */
2570 /* cm_mem_c_001.main_15 : Additions */
2571 #ifdef SS_HISTOGRAM_SUPPORT
2573 #endif /* SS_HISTOGRAM_SUPPORT */
2580 /* cm_mem_c_001.main_15 : Additions */
2581 #ifdef SS_MEM_LEAK_STS
2583 #endif /* SS_MEM_LEAK_STS */
2585 regCb = (CmMmRegCb *)regionCb;
2587 #if (ERRCLASS & ERRCLS_INT_PAR)
2589 /* error check on parameters */
2590 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2596 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2597 #ifdef SSI_DEBUG_LEVEL1
2598 #if (ERRCLASS & ERRCLS_INT_PAR)
2599 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2603 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2604 #endif /* SSI_DEBUG_LEVEL1 */
2611 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2612 #ifdef SSI_DEBUG_LEVEL1
2613 /* Update the hash list */
2614 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2616 /* display that, this entry could not be made in the hash list */
2618 /* display an error message here */
2619 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2621 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2622 *size, regCb->region);
2624 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2625 *size, regCb->region);
2627 SDisplay(0, dbgPrntBuf);
2630 #endif /* SSI_DEBUG_LEVEL1 */
2633 * Check if the requested size is less than or equal to the maximum block
2634 * size in the bucket.
2636 if ( *size <= regCb->bktMaxBlkSize)
2638 /* Get the map to the mapping table */
2639 idx = ((*size - 1) >> regCb->bktQnPwr);
2641 #if (ERRCLASS & ERRCLS_DEBUG)
2642 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2644 /* Some fatal error in the map table initialization. */
2649 /* Dequeue the memory block and return it to the user */
2650 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2653 /* While loop is introduced to use the "break statement inside */
2657 * Check if the size request is not greater than the size available
2660 if (*size > bkt->size)
2662 /* Try to go to the next bucket if available */
2663 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2664 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2666 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2670 /* This is the last bucket, try to allocate from heap */
2675 /* Acquire the bucket lock */
2676 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2678 (Void) WTLock(&(bkt->bktLock));
2680 (Void) SLock(&(bkt->bktLock));
2683 #if (ERRCLASS & ERRCLS_DEBUG)
2684 regCb->mapTbl[idx].numReq++;
2685 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2687 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2688 #ifdef SSI_DEBUG_LEVEL1
2689 /* increment the allocation attempt counter at bucket level */
2690 bkt->numAllocAttempts++;
2692 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2693 the allocation is always from (bkt->nextBlk) */
2696 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2698 /* detected a trampled memory block in this bucket */
2700 /* display an error message here */
2701 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2703 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2704 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2706 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2707 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2709 SDisplay(0, dbgPrntBuf);
2712 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2714 /* Release the lock */
2715 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2717 (Void) WTUnlock(&(bkt->bktLock));
2719 (Void) SUnlock(&(bkt->bktLock));
2721 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2722 RETVALUE(RTRAMPLINGNOK);
2726 /* Release the lock */
2727 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2729 (Void) WTUnlock(&(bkt->bktLock));
2731 (Void) SUnlock(&(bkt->bktLock));
2733 /* return RFAILED */
2739 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2741 if ((*ptr = bkt->next))
2742 #endif /* SSI_DEBUG_LEVEL1 */
2744 /* cm_mem_c_001.main_12 - addition for header */
2745 #ifdef SSI_DEBUG_LEVEL1
2746 /* point to next block header */
2747 alocBlk = bkt->nextBlk;
2748 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2750 bkt->next = *((CmMmEntry **)(bkt->next));
2751 #endif /* SSI_DEBUG_LEVEL1 */
2754 * Increment the statistics variable of number of memory block
2758 if (bkt->numAlloc > bkt->maxAlloc)
2760 bkt->maxAlloc = bkt->numAlloc;
2763 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2765 g_overused[bktIdx] = 1;
2766 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2770 if(bkt->numAlloc < 100)
2771 printf("cmAlloc: Allocated PTR = %x size = %d\n", *ptr, *size);
2774 /* cm_mem_c_001.main_12 - addition for header manipulation */
2775 #ifdef SSI_DEBUG_LEVEL1
2776 /* update the size for which this memory block has been allocated */
2777 alocBlk->requestedSize = *size;
2778 /* update the memory block header */
2779 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2780 if (memType == CMM_STATIC_MEM_FLAG)
2782 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2783 /* add it to the static memory allocated */
2784 bkt->staticMemUsed += bkt->size;
2788 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2789 /* add it to the dynamic memory allocated */
2790 bkt->dynamicMemUsed += bkt->size;
2792 #endif /* SSI_DEBUG_LEVEL1 */
2794 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2798 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2801 "[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++);
2804 "[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++);
2806 SDisplay(0, prntBuf);
2814 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2815 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2816 SDisplay(0, prntBuf);
2818 #endif /* MEMCAL_DEBUG */
2819 /* cm_mem_c_001.main_15 : Additions */
2820 #ifdef SS_HISTOGRAM_SUPPORT
2821 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2822 * information into the hash list */
2825 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2827 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2832 #endif /* SS_HISTOGRAM_SUPPORT */
2834 /* Update the size parameter */
2836 #ifdef SS_MEM_LEAK_STS
2837 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2838 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2839 regCb->mapTbl[idx].bktIdx);
2840 #endif /* SS_MEM_LEAK_STS */
2842 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2844 /* Release the lock */
2845 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2847 (Void) WTUnlock(&(bkt->bktLock));
2849 (Void) SUnlock(&(bkt->bktLock));
2858 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2861 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2864 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2866 SDisplay(0, prntBuf);
2870 #if (ERRCLASS & ERRCLS_DEBUG)
2871 regCb->mapTbl[idx].numFailure++;
2872 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2874 /* Release the lock */
2875 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2877 (Void) WTUnlock(&(bkt->bktLock));
2879 (Void) SUnlock(&(bkt->bktLock));
2888 regCb->heapCb.heapAllocCnt++;
2890 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2893 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2894 regCb->heapCb.heapAllocCnt);
2897 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2898 regCb->heapCb.heapAllocCnt);
2900 SDisplay(0, prntBuf);
2905 /* Memory not available in the bucket pool */
2906 if (regCb->heapFlag && (*size < regCb->heapSize))
2909 if (flags) tryHeap = 1;
2912 * The heap memory block is available. Allocate the memory block from
2915 /* cm_mem_c_001.main_15: Additions */
2916 #ifdef SS_HISTOGRAM_SUPPORT
2917 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2918 #ifdef SSI_DEBUG_LEVEL1
2919 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2921 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2922 #endif /* SSI_DEBUG_LEVEL1 */
2924 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2925 #ifdef SSI_DEBUG_LEVEL1
2926 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2928 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size));
2929 #endif /* SSI_DEBUG_LEVEL1 */
2930 #endif /* SS_HISTOGRAM_SUPPORT */
2933 /* No memory available */
2935 #else /* use pure is on */
2936 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2937 #ifdef SS_4GMX_LCORE
2938 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2939 cmMemset((U8*)ptr, 0, *size);
2941 *ptr = (Data*) malloc(*size);
2943 if ( (*ptr) == NULLP)
2945 avail_size -= *size;
2947 #endif /* USE_PURE */
2949 } /* end of cmAlloc */
2951 #ifdef SS_MEM_WL_DEBUG
2954 * Fun: cmInitDoubleFreeList
2956 * Desc: Initialize the hashlist used for detecting double free
2958 * Ret: ROK - successful
2959 * RFAILED - unsuccessful.
2968 PUBLIC S16 cmInitDoubleFreeList
2973 PUBLIC S16 cmInitDoubleFreeList()
2977 CmMemDoubleFree memNode;
2979 TRC2(cmInitDoubleFreeList);
2981 offset = (U16)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2983 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2984 CM_HASH_KEYTYPE_U32MOD, 0, 0)) != ROK);
2988 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2993 #ifdef SS_MEM_WL_DEBUG
2998 * Desc: Return the Dynamic memory block for the memory region.
3001 * Ret: ROK - successful
3002 * RFAILED - unsuccessful.
3011 PRIVATE S16 cmInitBtInfo
3015 PRIVATE S16 cmInitBtInfo (Void)
3018 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
3019 if (regBtInfo == NULLP)
3023 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
3024 if(allocBtInfo == NULLP)
3031 #endif /* SS_MEM_WL_DEBUG */
3034 * Fun: cmAnalyseBtInfo
3036 * Desc: Return the Dynamic memory block for the memory region.
3039 * Ret: ROK - successful
3040 * RFAILED - unsuccessful.
3049 PUBLIC Void cmAnalyseBtInfo
3051 PTR ptr, /* Memory block needs to be freed */
3055 PUBLIC Void cmAnalyseBtInfo (ptr,idx)
3056 PTR ptr; /* Memory block needs to be freed */
3066 for(regIdx = 0; regIdx < 8; regIdx++)
3068 btInfo = & regBtInfo[regIdx];
3069 btIdx = btInfo->btInfoIdx;
3071 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
3074 if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
3075 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr)
3078 if(btInfo->btInfo[btIdx].btSize != 0)
3082 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
3083 printf("*** Last Free Region = %d PTR %x Timestamp sec = (%ld) usec = (%ld) ***\n", idx, ptr, btInfo->btInfo[btIdx].timeStamp.tv_sec, btInfo->btInfo[btIdx].timeStamp.tv_usec);
3084 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
3086 printf("%s\n", strings[i]);
3088 printf("*******************************************************\n");
3096 btIdx = NUM_FREE_BUFFERS - 1;
3103 /* for(regIdx = 0; regIdx < 8; regIdx++)
3106 btInfo = &allocBtInfo[idx];
3107 btIdx = btInfo->btInfoIdx;
3109 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
3111 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
3112 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
3113 if(btInfo->btInfo[btIdx].btSize != 0)
3117 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
3118 printf("*** Last Allocation Region = %d PTR %x Timestamp sec = (%ld) usec = (%ld) ***\n", idx, ptr, btInfo->btInfo[btIdx].timeStamp.tv_sec, btInfo->btInfo[btIdx].timeStamp.tv_usec);
3119 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
3121 printf("%s\n", strings[i]);
3123 printf("*******************************************************\n");
3131 btIdx = NUM_FREE_BUFFERS - 1;
3140 #ifndef SS_USE_ICC_MEMORY
3143 * Fun: cmDynFreeWithLock
3145 * Desc: Return the Dynamic memory block for the memory region.
3148 * Ret: ROK - successful
3149 * RFAILED - unsuccessful.
3158 PRIVATE S16 cmDynFreeWithLock
3160 Void *regionCb, /* Pointer to region cb */
3161 Data *ptr, /* Memory block needs to be freed */
3162 Size size /* Size of the block */
3165 PRIVATE S16 cmDynFreeWithLock(regionCb, ptr, size)
3166 Void *regionCb; /* Pointer to region cb */
3167 Data *ptr; /* Memory block needs to be freed */
3168 Size size; /* Size of the block */
3173 if((SLock(&dynAllocFreeLock)) != ROK)
3175 printf("dynAllocWithLock: Failed to get the DYN lock\n");
3179 ret = cmDynFree(regionCb, ptr,size);
3181 if((SUnlock(&dynAllocFreeLock)) != ROK)
3183 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
3189 } /* end of cmDynFree */
3195 * Desc: Return the Dynamic memory block for the memory region.
3198 * Ret: ROK - successful
3199 * RFAILED - unsuccessful.
3208 PRIVATE S16 cmDynFree
3210 Void *regionCb, /* Pointer to region cb */
3211 Data *ptr, /* Memory block needs to be freed */
3212 Size size /* Size of the block */
3215 PRIVATE S16 cmDynFree(regionCb, ptr, size)
3216 Void *regionCb; /* Pointer to region cb */
3217 Data *ptr; /* Memory block needs to be freed */
3218 Size size; /* Size of the block */
3221 CmMmDynRegCb *regCb;
3225 CmMmDynBktCb *bkt = NULLP;
3226 CmMmBlkSetElement *dynMemElem;
3228 #ifdef SS_MEM_WL_DEBUG
3235 regCb = (CmMmDynRegCb *)regionCb;
3236 #ifdef SS_MEM_WL_DEBUG
3237 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3244 #if (ERRCLASS & ERRCLS_INT_PAR)
3245 /* error check on parameters */
3246 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3251 /* Check if the memory block is from the memory region */
3252 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3253 ((CmMmRegCb *)regCb)->regInfo.size)
3257 /* cm_mem_c_001.main_20 Addition */
3258 if (ptr < regCb->regInfo.start)
3265 #ifdef SS_MEM_WL_DEBUG
3266 ptr -= sizeof (U32);
3269 /* The memory block was allocated from the bucket pool */
3271 /* Get the map to the mapping table */
3272 idx = ((size - 1) >> regCb->bktQnPwr);
3274 #if (ERRCLASS & ERRCLS_DEBUG)
3275 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3277 /* Some fatal error in the map table initialization. */
3282 /* Enqueue the memory block and return it to the user */
3283 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3286 * Check if the size is not greater than the size available
3287 * in the bucket. If so, then the buffer must have been allocated
3288 * from next bucket. We don't need to check the validity of the
3289 * next bucket, otherwise buffer must have been allocated from heap
3292 #ifdef SS_MEM_WL_DEBUG
3293 if (size > bkt->size)
3295 printf("Size = %d bucket size = %d\n", size, bkt->size);
3297 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3299 if(size > bkt->size)
3301 printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
3304 printf("Bucket Size wrong \n");
3309 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
3311 /* Check if the bucket index, if its not valid, return failure */
3312 if(dynMemElem == NULLP)
3317 #ifdef SS_MEM_WL_DEBUG
3318 tmpBktIdx = (U8)*ptr;
3319 tmpVal = (U8)*(ptr+1);
3321 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
3324 printf("bktIdx wrong \n");
3328 if ((bktIdx == 0) && (!stopBtInfo))
3332 btInfo = ®BtInfo[regCb->region];
3333 btIdx = btInfo->btInfoIdx;
3334 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
3336 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
3339 cmRemoveAllocPtrFromList(regCb, (ptr + sizeof(U32)));
3341 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
3344 btIdx &= (NUM_FREE_BUFFERS - 1);
3346 btInfo->btInfo[btIdx].ptr = (PTR)0;
3347 btInfo->btInfo[btIdx].btSize = 0;
3348 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
3349 btInfo->btInfoIdx = btIdx;
3352 if(prvAllocPtr[regCb->region] == ptr)
3354 prvAllocPtr[regCb->region] = NULLP;
3357 cmMemset(ptr, (regCb->region+1), bkt->size);
3360 /* Get the bucket node from the index returned and allocate the memory */
3361 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
3362 dynMemElem->nextBktPtr = ptr;
3363 dynMemElem->numFreeBlks++;
3367 #else /* use pure is on */
3369 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3370 #ifdef SS_4GMX_LCORE
3371 (Void)MxHeapFree(SsiHeap, ptr);
3373 /* (Void)free(ptr); */
3375 /* avail_size += size; */
3379 #endif /* USE_PURE */
3382 } /* end of cmDynFree */
3383 #endif /* SS_USE_ICC_MEMORY */
3391 * Desc: Return the memory block for the memory region.
3394 * Ret: ROK - successful
3395 * RFAILED - unsuccessful.
3397 * Notes: The user calls this function to return the previously allocated
3398 * memory block to the memory region. The memory manager does not
3399 * check the validity of the state of the memory block(like whether
3400 * it was allocated earlier). The caller must be sure that, the
3401 * address specified in the parameter 'ptr' is valid and was
3402 * allocated previously from same region.
3409 /* cm_mem_c_001.main_15 : Additions */
3410 #ifdef T2K_MEM_LEAK_DBG
3420 #ifdef SS_HISTOGRAM_SUPPORT
3433 PRIVATE S16 cmFree(regionCb, ptr, size, line, fileName, entId, hstReg)
3453 PRIVATE S16 cmFree(regionCb, ptr, size)
3459 /* cm_mem_c_001.main_15 : Additions */
3460 #endif /* SS_HISTOGRAM_SUPPORT */
3463 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
3470 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3471 #ifdef SSI_DEBUG_LEVEL1
3473 #endif /* SSI_DEBUG_LEVEL1 */
3474 /* cm_mem_c_001.main_15 : Additions */
3475 #ifdef SS_HISTOGRAM_SUPPORT
3477 #endif /* SS_HISTOGRAM_SUPPORT */
3481 regCb = (CmMmRegCb *)regionCb;
3484 #if (ERRCLASS & ERRCLS_INT_PAR)
3486 /* error check on parameters */
3487 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3492 /* Check if the memory block is from the memory region */
3493 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3494 ((CmMmRegCb *)regCb)->regInfo.size)
3498 /* cm_mem_c_001.main_20 Addition */
3499 if (ptr < regCb->regInfo.start)
3507 * Check if the memory block was allocated from the bucket pool.
3509 if(ptr < regCb->regInfo.start)
3511 Buffer *tmpBuffer = NULLP;
3512 tmpBuffer->b_cont = NULLP;
3515 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3517 /* The memory block was allocated from the bucket pool */
3519 /* Get the map to the mapping table */
3520 idx = ((size - 1) >> regCb->bktQnPwr);
3522 #if (ERRCLASS & ERRCLS_DEBUG)
3523 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3525 /* Some fatal error in the map table initialization. */
3530 /* Enqueue the memory block and return it to the user */
3531 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3534 * Check if the size is not greater than the size available
3535 * in the bucket. If so, then the buffer must have been allocated
3536 * from next bucket. We don't need to check the validity of the
3537 * next bucket, otherwise buffer must have been allocated from heap
3540 if (size > bkt->size)
3542 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3545 /* Acquire the bucket lock */
3546 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3548 (Void) WTLock(&(bkt->bktLock));
3550 (Void) SLock(&(bkt->bktLock));
3553 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3554 #ifdef SSI_DEBUG_LEVEL1
3555 /* increment the dealloc attempt counter at bucket level */
3556 bkt->numDeallocAttempts++;
3558 /* Check the memFlags to see whether this block was allocated */
3559 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3561 /* validate the block to be freed for trampling */
3562 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3564 /* Handle error case of Memory trampling */
3566 /* display an error message here */
3567 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3569 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3570 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3572 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3573 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3575 SDisplay(0, dbgPrntBuf);
3578 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3579 * as the memory blk is already invalidated in cmMmBktSanityChk
3581 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3585 /* Release the lock */
3586 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3588 (Void) WTUnlock(&(bkt->bktLock));
3590 (Void) SUnlock(&(bkt->bktLock));
3598 * this is the case where in the entire bucket has been made unusable
3601 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3603 (Void) WTUnlock(&(bkt->bktLock));
3605 (Void) SUnlock(&(bkt->bktLock));
3608 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3609 RETVALUE(RTRAMPLINGNOK);
3613 /* reset the size */
3614 ptrHdr->requestedSize = 0;
3615 /* check if the block to be freed is already having the state as FREE */
3616 if (CMM_IS_FREE(ptrHdr->memFlags))
3618 /* Handle double deallocation error case */
3620 /* display an error message here */
3621 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3623 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3624 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3626 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3627 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3629 SDisplay(0, dbgPrntBuf);
3632 /* Release the lock */
3633 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3635 (Void) WTUnlock(&(bkt->bktLock));
3637 (Void) SUnlock(&(bkt->bktLock));
3640 /* handle RDBLFREE in SFree/SPutSBuf */
3643 if (CMM_IS_STATIC(ptrHdr->memFlags))
3645 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3646 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3647 /* deduct it from the static memory count */
3648 bkt->staticMemUsed -= bkt->size;
3650 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3652 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3653 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3654 /* deduct it from the dynamic memory count */
3655 bkt->dynamicMemUsed -= bkt->size;
3659 /* This is a case similar to trampled memory */
3661 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3663 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3665 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3667 SDisplay(0, dbgPrntBuf);
3669 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3671 /* do not add to the free list */
3674 /* Release the lock */
3675 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3677 (Void) WTUnlock(&(bkt->bktLock));
3679 (Void) SUnlock(&(bkt->bktLock));
3686 * this is the case where in the entire bucket has been made unusable
3689 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3691 (Void) WTUnlock(&(bkt->bktLock));
3693 (Void) SUnlock(&(bkt->bktLock));
3696 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3697 RETVALUE(RTRAMPLINGNOK);
3701 /* Return the block to memory */
3702 ptrHdr->nextBlk = bkt->nextBlk;
3703 bkt->nextBlk = ptrHdr;
3707 /* sriky: For debugging double deallocation */
3708 cmMemset(ptr, 0, 50);
3710 *((CmMmEntry **)ptr) = bkt->next;
3711 bkt->next = (CmMmEntry *)ptr;
3712 #endif /* SSI_DEBUG_LEVEL1 */
3715 if(bkt->numAlloc <= 0 || bkt->numAlloc > 12000)
3721 printf("\n cmFree: Freed pointer = %x and backtrace:\n", ptr);
3722 printf("****************************************\n");
3723 tmpsize = backtrace(array, 10);
3724 strings = backtrace_symbols(array, tmpsize);
3725 for(i = 0; i < tmpsize; i++)
3726 printf("%s\n", strings[i]);
3727 printf("****************************************\n");
3732 * Decrement the statistics variable of number of memory block
3740 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3742 g_overused[bktIdx] = 0;
3743 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3746 /* cm_mem_c_001.main_15 : Additions */
3747 #ifdef SS_HISTOGRAM_SUPPORT
3748 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3749 * information into the hash list */
3752 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3754 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3758 #endif /* SS_HISTOGRAM_SUPPORT */
3760 #ifdef SS_MEM_LEAK_STS
3761 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3762 cmRlsAllocBlk((PTR)ptr);
3763 #endif /* SS_MEM_LEAK_STS */
3765 /* Release the lock */
3766 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3768 (Void) WTUnlock(&(bkt->bktLock));
3770 (Void) SUnlock(&(bkt->bktLock));
3776 /* The memory block was allocated from the heap pool */
3777 /* cm_mem_c_001.main_15 : Additions */
3778 #ifdef SS_HISTOGRAM_SUPPORT
3779 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3781 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size));
3782 #endif /* SS_HISTOGRAM_SUPPORT */
3783 #else /* use pure is on */
3785 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3786 #ifdef SS_4GMX_LCORE
3787 (Void)MxHeapFree(SsiHeap, ptr);
3793 #endif /* USE_PURE */
3796 } /* end of cmFree */
3803 * Desc: alloc without lock
3806 * Ret: ROK - successful
3807 * RFAILED - unsuccessful.
3813 /*cm_mem_c_001.main_21-added new function*/
3814 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3815 #ifdef T2K_MEM_LEAK_DBG
3816 PRIVATE S16 cmAllocWL
3827 PRIVATE S16 cmAllocWL
3835 PRIVATE S16 cmAllocWL(regionCb, size, flags, ptr)
3845 CmMmBkt *bkt = NULLP;
3848 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3852 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3854 regCb = (CmMmRegCb *)regionCb;
3856 #ifdef SS_MEM_WL_DEBUG
3857 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3863 #if (ERRCLASS & ERRCLS_INT_PAR)
3865 /* error check on parameters */
3866 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3872 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3877 * Check if the requested size is less than or equal to the maximum block
3878 * size in the bucket.
3880 #ifdef MSPD_T2K_TRACK_BUG
3883 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3884 if ( *size <= regCb->bktMaxBlkSize)
3886 /* Get the map to the mapping table */
3887 idx = ((*size - 1) >> regCb->bktQnPwr);
3889 /* Dequeue the memory block and return it to the user */
3890 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3894 * Check if the size request is not greater than the size available
3897 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3898 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3900 /* Try to go to the next bucket if available */
3901 bkt->next = *((CmMmEntry **)(bkt->next));
3904 * Increment the statistics variable of number of memory block
3908 if (bkt->numAlloc > bkt->maxAlloc)
3910 bkt->maxAlloc = bkt->numAlloc;
3913 #ifdef MSPD_T2K_TRACK_BUG
3922 /* Update the size parameter */
3930 /* Memory not available in the bucket pool */
3931 if (regCb->heapFlag && (*size < regCb->heapSize))
3933 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3935 * The heap memory block is available. Allocate the memory block from
3938 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3939 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size));
3942 /* No memory available */
3944 #else /* use pure is on */
3945 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3946 #ifdef SS_4GMX_LCORE
3947 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3948 cmMemset((U8*)ptr, 0, *size);
3950 /* *ptr = (Data*) malloc(*size); */
3952 *ptr = (Data *)malloc(*size);
3954 if ( (*ptr) == NULLP)
3956 /* avail_size -= *size; */
3958 #endif /* USE_PURE */
3960 } /* end of cmAllocWL */
3967 * Desc: free without lock
3970 * Ret: ROK - successful
3971 * RFAILED - unsuccessful.
3978 #ifdef T2K_MEM_LEAK_DBG
3979 PRIVATE S16 cmFreeWL
3989 PRIVATE S16 cmFreeWL
3996 PRIVATE S16 cmFreeWL(regionCb, ptr, size)
4005 CmMmBkt *bkt = NULLP;
4008 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
4012 regCb = (CmMmRegCb *)regionCb;
4014 #ifdef SS_MEM_WL_DEBUG
4015 if(tmpRegTidMap[regCb->region] != (pthread_self()))
4022 #if (ERRCLASS & ERRCLS_INT_PAR)
4024 /* error check on parameters */
4025 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
4030 /* Check if the memory block is from the memory region */
4031 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
4032 ((CmMmRegCb *)regCb)->regInfo.size)
4040 * Check if the memory block was allocated from the bucket pool.
4043 if(ptr < regCb->regInfo.start)
4045 Buffer *tmpbuf = NULLP;
4046 tmpbuf->b_cont = NULLP;
4050 #ifdef MSPD_T2K_TRACK_BUG
4054 if (ptr < (regCb->regInfo.start + regCb->bktSize))
4056 /* The memory block was allocated from the bucket pool */
4058 /* Get the map to the mapping table */
4059 idx = ((size - 1) >> regCb->bktQnPwr);
4061 #if (ERRCLASS & ERRCLS_DEBUG)
4062 if (regCb->mapTbl[idx].bktIdx == 0xFF)
4064 /* Some fatal error in the map table initialization. */
4069 /* Enqueue the memory block and return it to the user */
4070 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
4072 #ifdef MSPD_T2K_TRACK_BUG
4074 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
4081 * Check if the size is not greater than the size available
4082 * in the bucket. If so, then the buffer must have been allocated
4083 * from next bucket. We don't need to check the validity of the
4084 * next bucket, otherwise buffer must have been allocated from heap
4087 if (size > bkt->size)
4089 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
4092 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
4093 *((CmMmEntry **)ptr) = bkt->next;
4094 bkt->next = (CmMmEntry *)ptr;
4097 * Decrement the statistics variable of number of memory block
4103 if ((regCb->region == 2) && (bkt->numAlloc < 50))
4107 btInfo = &allocBtInfo[regCb->region];
4108 btIdx = btInfo->btInfoIdx;
4109 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
4111 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
4114 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
4115 cmInsertAllocPtrToList(regCb, (PTR)*ptr);
4119 btIdx &= (NUM_FREE_BUFFERS - 1);
4121 btInfo->btInfo[btIdx].ptr = (PTR)0;
4122 btInfo->btInfo[btIdx].btSize = 0;
4123 cmMemset(btInfo->btInfo[regCb->mapTbl[idx].bktIdx].btArr, 0, sizeof (btInfo->btInfo[regCb->mapTbl[idx].bktIdx].btArr));
4124 btInfo->btInfoIdx = btIdx;
4131 /* The memory block was allocated from the heap pool */
4132 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size));
4133 #else /* use pure is on */
4135 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4136 #ifdef SS_4GMX_LCORE
4137 (Void)MxHeapFree(SsiHeap, ptr);
4139 /* (Void)free(ptr); */
4141 /* avail_size += size; */
4145 #endif /* USE_PURE */
4148 } /* end of cmFreeWL */
4155 * Desc: Control request function.
4158 * Ret: ROK - successful
4159 * RFAILED - unsuccessful.
4161 * Notes: The current semantics of the control function is defined for two
4162 * types of events: virtual address to physical address translation
4163 * and memory resource check.
4165 * The physical address translation is valid only for the memory
4166 * region physically contiguous and non pagable.
4182 PRIVATE S16 cmCtl(regionCb, event, memCtl)
4192 regCb = (CmMmRegCb *)regionCb;
4194 #if (ERRCLASS & ERRCLS_INT_PAR)
4196 /* error check on parameters */
4197 if ((regCb == NULLP) || (memCtl == NULLP))
4210 #if (ERRCLASS & ERRCLS_INT_PAR)
4211 if ((memCtl->u.vtop.vaddr == NULLP) ||
4212 (memCtl->u.vtop.paddr == NULLP))
4218 /* Check if the virtual to physical address translation is valid */
4219 if (regCb->chFlag & CMM_REG_PHY_VALID)
4221 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
4222 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
4229 case SS_MEM_CHK_RES:
4232 #if (ERRCLASS & ERRCLS_INT_PAR)
4233 if (!(memCtl->u.chkres.size) ||
4234 (memCtl->u.chkres.status == NULLP))
4240 /* Check if the Bucket pool is configured */
4245 U32 avlSize, totSize;
4247 * The bucket pool is configured. The status value returned
4248 * does reflect on the memory availabilty in the bucket pool.
4249 * The value does not consider the available memory in the
4252 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
4253 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
4254 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
4255 avlSize += regCb->heapCb.avlSize;
4256 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
4257 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
4261 /* Bucket pool not configured */
4264 * Find the percentage memory available in the heap pool. The value
4265 * does not consider the fragmentation of the heap pool.
4267 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
4268 (regCb->heapSize/10));
4272 #else /* use pure is on */
4273 *(memCtl->u.chkres.status) = ((avail_size) /
4274 (regCb->regInfo.size/10));
4276 #endif /* USE_PURE */
4282 /* No other event is supported currently */
4287 /* shouldn't reach here */
4289 } /* end of cmCtl */
4297 * Desc: Initialize the bucket and the map table.
4300 * Ret: ROK - successful,
4301 * RFAILED - unsuccessful.
4303 * Notes: This function is called by the cmMmRegInit.
4309 PRIVATE Void cmMmBktInit
4318 PRIVATE Void cmMmBktInit (memAddr, regCb, cfg, bktIdx, lstMapIdx)
4331 U16 blkSetRelThreshold;
4332 CmMmBktLstCb *bktLstCb;
4337 size = cfg->bktCfg[bktIdx].size;
4338 numBlks = cfg->bktCfg[bktIdx].numBlks;
4340 regCb->bktTbl[bktIdx].blkSetRelThreshold = cfg->bktCfg[bktIdx].blkSetRelThreshold;
4341 regCb->bktTbl[bktIdx].blkSetAcquireThreshold = cfg->bktCfg[bktIdx].blkSetAcquireThreshold;
4342 blkSetRelThreshold = cfg->bktCfg[bktIdx].blkSetRelThreshold;
4344 /* Initialize the bucket linked list */
4345 cmLListInit(®Cb->bktTbl[bktIdx].listBktSet);
4347 /* Reset the next pointer */
4348 regCb->bktTbl[bktIdx].next = NULLP;
4350 /* Initialize the link list of the memory block */
4351 next = &(regCb->bktTbl[bktIdx].next);
4352 for (cnt = 0; cnt < numBlks; cnt++)
4355 next = (CmMmEntry **)(*memAddr);
4356 *memAddr = (*memAddr) + size;
4358 /* Maintain the list Cb */
4359 if((cnt != 0) && (!(cnt % blkSetRelThreshold)))
4361 bktLstCb = calloc(1, sizeof(CmMmBktLstCb));
4362 bktLstCb->nextBktPtr = regCb->bktTbl[bktIdx].next;
4363 bktLstCb->numBkt = blkSetRelThreshold;
4364 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listBktSet), (&bktLstCb->memSetNode));
4365 next = &(regCb->bktTbl[bktIdx].next);
4371 bktLstCb = cmLListFirst((®Cb->bktTbl[bktIdx].listBktSet));
4372 regCb->bktTbl[bktIdx].next = bktLstCb->nextBktPtr;
4373 cmLListDelFrm((®Cb->bktTbl[bktIdx].listBktSet), bktLstCb);
4376 /* Initialize the Map entry */
4377 idx = size / cfg->bktQnSize;
4380 * Check if the size is multiple of quantum size. If not we need to initialize
4381 * one more map table entry.
4383 if(size % cfg->bktQnSize)
4388 while ( *lstMapIdx < idx)
4390 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
4392 #if (ERRCLASS & ERRCLS_DEBUG)
4393 regCb->mapTbl[*lstMapIdx].numReq = 0;
4394 regCb->mapTbl[*lstMapIdx].numFailure = 0;
4400 /* Initialize the bucket structure */
4401 regCb->bktTbl[bktIdx].size = size;
4402 regCb->bktTbl[bktIdx].numBlks = numBlks;
4403 regCb->bktTbl[bktIdx].numAlloc = 0;
4404 regCb->bktTbl[bktIdx].maxAlloc = 0;
4406 /* Update the total bucket size */
4407 regCb->bktSize += (size * numBlks);
4409 regCb->bktTbl[bktIdx].bktFailCnt = 0;
4410 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
4413 } /* end of cmMmBktInit */
4421 * Desc: Initialize the heap pool.
4424 * Ret: ROK - successful
4425 * RFAILED - unsuccessful.
4427 * Notes: This function is called by the cmMmRegInit.
4433 PRIVATE Void cmMmHeapInit
4440 PRIVATE Void cmMmHeapInit (memAddr, heapCb, size)
4446 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4447 #ifdef SSI_DEBUG_LEVEL1
4449 #endif /* SSI_DEBUG_LEVEL1 */
4452 /* Initialize the heap control block */
4453 heapCb->vStart = memAddr;
4454 heapCb->vEnd = memAddr + size;
4455 heapCb->avlSize = size;
4456 heapCb->minSize = CMM_MINBUFSIZE;
4458 heapCb->next = (CmHEntry *)memAddr;
4459 heapCb->next->next = NULLP;
4460 /* cm_mem_c_001.main_12 - addition for header initialization */
4461 #ifdef SSI_DEBUG_LEVEL1
4462 heapCb->next->size = size - sizeof(CmHEntry);
4463 heapCb->next->requestedSize = 0;
4464 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4466 heapCb->next->trSignature[idx] = 0xAB;
4468 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
4469 heapCb->staticHeapMemUsed = 0;
4470 heapCb->dynamicHeapMemUsed = 0;
4471 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
4472 sizeof(heapCb->next->memFlags) +
4473 sizeof(heapCb->next->requestedSize);
4474 heapCb->numAllocAttempts = 0;
4475 heapCb->numDeallocAttempts = 0;
4476 heapCb->trampleCount = 0;
4478 heapCb->next->size = size;
4479 #endif /* SSI_DEBUG_LEVEL1 */
4481 #if (ERRCLASS & ERRCLS_DEBUG)
4482 heapCb->numFragBlk = 0;
4484 heapCb->numFailure = 0;
4487 heapCb->heapAllocCnt = 0;
4488 /* cm_mem_c_001.main_15 : Additions */
4489 #ifdef SS_HISTOGRAM_SUPPORT
4490 /* Initialise the memory histogram hash list */
4491 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
4492 #endif /* SS_HISTOGRAM_SUPPORT */
4495 } /* end of cmMmHeapInit */
4503 * Desc: Allocates the memory block from the heap pool.
4506 * Ret: ROK - successful
4507 * RFAILED - unsuccessful.
4509 * Notes: This function is called by the cmAlloc. cmAlloc calls this
4510 * function when there is no memory block available in the bucket
4511 * and the heap pool is configured.
4518 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
4519 /* cm_mem_c_001.main_15 : Additions */
4520 #ifdef SS_HISTOGRAM_SUPPORT
4521 #ifdef SSI_DEBUG_LEVEL1
4523 PRIVATE S16 cmHeapAlloc
4535 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType, line, fileName, entId, hstReg)
4547 PRIVATE S16 cmHeapAlloc
4558 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, line, fileName, entId, hstReg)
4567 #endif /* SSI_DEBUG_LEVEL1 */
4569 #ifdef SSI_DEBUG_LEVEL1
4571 PRIVATE S16 cmHeapAlloc
4579 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType)
4587 PRIVATE S16 cmHeapAlloc
4594 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size)
4599 #endif /* SSI_DEBUG_LEVEL1 */
4600 /* cm_mem_c_001.main_15 : Additions */
4601 #endif /* SS_HISTOGRAM_SUPPORT */
4603 CmHEntry *prvHBlk; /* Previous heap block */
4604 CmHEntry *curHBlk; /* Current heap block */
4606 /* cm_mem_c_001.main_15 : Additions */
4607 #ifdef SS_MEM_LEAK_STS
4609 #endif /* SS_MEM_LEAK_STS */
4610 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4611 #ifdef SSI_DEBUG_LEVEL1
4612 CmHEntry *alocHeapBlk;
4616 #endif /* SSI_DEBUG_LEVEL1 */
4617 /* cm_mem_c_001.main_15 : Additions */
4618 #ifdef SS_HISTOGRAM_SUPPORT
4620 #endif /* SS_HISTOGRAM_SUPPORT */
4623 /* cm_mem_c_001.main_15 : Additions */
4624 /* Acquire the heap lock */
4625 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4627 (Void) WTLock (&(heapCb->heapLock));
4629 (Void) SLock (&(heapCb->heapLock));
4632 #ifdef SS_MEM_LEAK_STS
4634 #endif /* SS_MEM_LEAK_STS */
4635 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4636 #ifdef SSI_DEBUG_LEVEL1
4637 heapCb->numAllocAttempts++;
4638 requestedSize = *size;
4639 #endif /* SSI_DEBUG_LEVEL1 */
4641 /* Roundup the requested size */
4642 *size = CMM_DATALIGN(*size, (heapCb->minSize));
4644 /* Check if the available total size is adequate. */
4645 if ((*size) >= heapCb->avlSize)
4647 /* cm_mem_c_001.main_15 : Additions */
4649 (Void) WTUnlock (&(heapCb->heapLock));
4651 (Void) SUnlock (&(heapCb->heapLock));
4657 /* cm_mem_c_001.main_12 - addition for aligning the header size */
4658 #ifdef SSI_DEBUG_LEVEL1
4659 hdr = PTRALIGN(sizeof(CmHEntry));
4660 #endif /* SSI_DEBUG_LEVEL1 */
4663 * Search through the heap block list in the heap pool of size
4664 * greater than or equal to the requested size.
4667 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
4668 #ifdef SSI_DEBUG_LEVEL1
4669 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
4671 prvHBlk = (CmHEntry *)&(heapCb->next);
4672 #endif /* SSI_DEBUG_LEVEL1 */
4673 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
4674 prvHBlk = prvHBlk->next)
4677 * Since the size of the block is always multiple of CMM_MINBUFSIZE
4678 * and the requested size is rounded to the size multiple of
4679 * CMM_MINBUFSIZE, the difference between the size of the heap block
4680 * and the size to allocate will be either zero or multiple of
4683 if ((*size) <= curHBlk->size)
4685 /* cm_mem_c_001.main_12 - addition for block size calculation */
4686 #ifdef SSI_DEBUG_LEVEL1
4687 tmpSize = curHBlk->size - (*size);
4689 tmpSize = tmpSize - hdr;
4692 if ((tmpSize = (curHBlk->size - (*size))))
4693 #endif /* SSI_DEBUG_LEVEL1 */
4695 /* Heap block of bigger size */
4696 /* cm_mem_c_001.main_12 - addition for allocating memory */
4697 #ifdef SSI_DEBUG_LEVEL1
4698 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
4699 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
4701 * No need to look for memory trampling as this is a new block altogether
4702 * Update the header only for this case as it is new block formed
4704 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4706 alocHeapBlk->trSignature[idx] = 0xAB;
4708 alocHeapBlk->size = *size;
4710 *ptr = (Data *)curHBlk + tmpSize;
4711 #endif /* SSI_DEBUG_LEVEL1 */
4712 curHBlk->size = tmpSize;
4716 /* Heap block is same size of the requested size */
4717 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4718 #ifdef SSI_DEBUG_LEVEL1
4719 /* look for memory trampling as this is a pure block*/
4722 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4724 /* detected a trampled memory block in this bucket */
4726 /* display an error message here */
4727 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4729 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4731 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4733 SDisplay(0, dbgPrntBuf);
4736 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4738 /* Release the lock */
4739 /* cm_mem_c_001.main_13: Replaced SUnlock with
4742 (Void) WTUnlock (&(heapCb->heapLock));
4744 (Void) SUnlock (&(heapCb->heapLock));
4746 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4747 RETVALUE(RTRAMPLINGNOK);
4751 /* Release the lock */
4752 /* cm_mem_c_001.main_13: Replaced SUnlock with
4755 (Void) WTUnlock (&(heapCb->heapLock));
4757 (Void) SUnlock (&(heapCb->heapLock));
4764 *ptr = (Data *)curHBlk + hdr;
4765 alocHeapBlk = curHBlk;
4766 *size = curHBlk->size;
4768 *ptr = (Data *)curHBlk;
4769 #endif /* SSI_DEBUG_LEVEL1 */
4770 prvHBlk->next = curHBlk->next;
4773 /* cm_mem_c_001.main_12 - addition for header updation */
4774 #ifdef SSI_DEBUG_LEVEL1
4775 /* update the header fields */
4776 alocHeapBlk->requestedSize = requestedSize;
4777 alocHeapBlk->memFlags = 0;
4778 if (memType == CMM_STATIC_MEM_FLAG)
4780 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4781 heapCb->staticHeapMemUsed += (*size + hdr);
4785 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4786 heapCb->dynamicHeapMemUsed += (*size + hdr);
4788 heapCb->avlSize -= ((*size) + hdr);
4790 heapCb->avlSize -= (*size);
4791 #endif /* SSI_DEBUG_LEVEL1 */
4797 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4798 *size, num_times, *ptr);
4799 SDisplay(0, prntBuf);
4803 /* cm_mem_c_001.main_15 : Additions */
4804 #ifdef SS_MEM_LEAK_STS
4805 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4806 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4807 #endif /* SS_MEM_LEAK_STS */
4808 /* Release the lock */
4809 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4811 (Void) WTUnlock (&(heapCb->heapLock));
4813 (Void) SUnlock (&(heapCb->heapLock));
4816 #ifdef SS_HISTOGRAM_SUPPORT
4817 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4818 * information into the hash list */
4821 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4823 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4828 #endif /* SS_HISTOGRAM_SUPPORT */
4834 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4840 /* Release the lock */
4841 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4843 (Void) WTUnlock (&(heapCb->heapLock));
4845 (Void) SUnlock (&(heapCb->heapLock));
4850 } /* end of cmHeapAlloc */
4857 * Desc: Return the memory block from the heap pool.
4860 * Ret: ROK - successful
4861 * RFAILED - unsuccessful.
4863 * Notes: This function returns the memory block to the heap pool. This
4864 * function is called by cmFree. The function does not check the
4865 * validity of the memory block. The caller must be sure that the
4866 * block was previously allocated and belongs to the heap pool. The
4867 * function maintain the sorting order of the memory block on the
4868 * starting address of the block. This function also do compaction
4869 * if the neighbouring blocks are already in the heap.
4876 /* cm_mem_c_001.main_15 : Additions */
4877 #ifdef SS_HISTOGRAM_SUPPORT
4879 PRIVATE S16 cmHeapFree
4890 PRIVATE S16 cmHeapFree (heapCb, ptr, size, line, fileName, entId, hstReg)
4901 PRIVATE S16 cmHeapFree
4908 PRIVATE S16 cmHeapFree (heapCb, ptr, size)
4913 /* cm_mem_c_001.main_15 : Additions */
4914 #endif /* SS_HISTOGRAM_SUPPORT */
4917 CmHEntry *curHBlk; /* Current heap block */
4918 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4919 #ifdef SSI_DEBUG_LEVEL1
4921 #endif /* SSI_DEBUG_LEVEL1 */
4922 /* cm_mem_c_001.main_15 : Additions */
4923 #ifdef SS_HISTOGRAM_SUPPORT
4924 Size allocSize = size;
4926 #endif /* SS_HISTOGRAM_SUPPORT */
4930 /* Roundup the requested size */
4931 size = CMM_DATALIGN(size, (heapCb->minSize));
4932 /* cm_mem_c_001.main_15: Additions */
4933 #ifdef SS_HISTOGRAM_SUPPORT
4935 #endif /* SS_HISTOGRAM_SUPPORT */
4937 /* Acquire the heap lock */
4938 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4940 (Void) WTLock (&(heapCb->heapLock));
4942 (Void) SLock (&(heapCb->heapLock));
4945 /* increase the avlSize */
4946 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4947 #ifdef SSI_DEBUG_LEVEL1
4948 hdr = PTRALIGN(sizeof(CmHEntry));
4949 heapCb->avlSize += (size + hdr);
4950 heapCb->numDeallocAttempts++;
4952 heapCb->avlSize += size;
4953 #endif /* SSI_DEBUG_LEVEL1 */
4955 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4956 #ifdef SSI_DEBUG_LEVEL1
4957 p = (CmHEntry *)(ptr - hdr);
4959 p = (CmHEntry *)ptr;
4960 /* cm_mem_c_001.main_15 : Additions */
4961 #ifdef SS_MEM_LEAK_STS
4962 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4963 cmRlsAllocBlk((PTR)ptr);
4964 #endif /* SS_MEM_LEAK_STS */
4965 #endif /* SSI_DEBUG_LEVEL1 */
4968 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4969 #ifdef SSI_DEBUG_LEVEL1
4970 /* look for memory trampling */
4971 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4973 /* detected a trampled memory block in heap */
4975 /* display an error message here */
4976 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4978 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4980 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4982 SDisplay(0, dbgPrntBuf);
4985 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4987 /* Release the lock */
4988 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4990 (Void) WTUnlock (&(heapCb->heapLock));
4992 (Void) SUnlock (&(heapCb->heapLock));
4994 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4995 RETVALUE(RTRAMPLINGNOK);
4999 /* do not add to the free heap */
5000 heapCb->avlSize -= (size + hdr);
5001 /* Release the heap lock */
5002 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5004 (Void) WTUnlock (&(heapCb->heapLock));
5006 (Void) SUnlock (&(heapCb->heapLock));
5013 /* look for any double free */
5014 if (CMM_IS_FREE(p->memFlags))
5017 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5019 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
5021 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
5023 SDisplay(0, dbgPrntBuf);
5026 heapCb->avlSize -= (size + hdr);
5027 /* cm_mem_c_001.main_15 : Additions */
5029 (Void) WTUnlock (&(heapCb->heapLock));
5031 (Void) SUnlock (&(heapCb->heapLock));
5036 #endif /* SSI_DEBUG_LEVEL1 */
5038 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
5041 * The block will be inserted to maintain the sorted order on the
5042 * starting address of the block.
5046 if (!(curHBlk->next) ||
5047 (p < (curHBlk->next)))
5049 /* Heap block should be inserted here */
5052 * Check if the block to be returned can be merged with the
5055 /* cm_mem_c_001.main_12 - addition for header consideration */
5056 #ifdef SSI_DEBUG_LEVEL1
5057 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
5059 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
5060 #endif /* SSI_DEBUG_LEVEL1 */
5062 /* Merge the block */
5063 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
5064 #ifdef SSI_DEBUG_LEVEL1
5065 /* update the flags */
5066 if (CMM_IS_STATIC(p->memFlags))
5067 heapCb->staticHeapMemUsed -= (size + hdr);
5068 else if (CMM_IS_DYNAMIC(p->memFlags))
5069 heapCb->dynamicHeapMemUsed -= (size + hdr);
5070 size = (curHBlk->size += (size + hdr));
5072 size = (curHBlk->size += size);
5073 #endif /*SSI_DEBUG_LEVEL1*/
5078 /* cm_mem_c_001.main_12 - addition for double-free check */
5079 #ifdef SSI_DEBUG_LEVEL1
5080 /* Check for double deallocation in heap */
5081 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
5083 /* Release the lock */
5084 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5086 (Void) WTUnlock (&(heapCb->heapLock));
5088 (Void) SUnlock (&(heapCb->heapLock));
5091 /* This block is already freed in the heap */
5094 /* update the flags as it is a new node */
5095 if (CMM_IS_STATIC(p->memFlags))
5097 heapCb->staticHeapMemUsed -= (size + hdr);
5098 CMM_RESET_STATIC_FLAG(p->memFlags);
5100 else if (CMM_IS_DYNAMIC(p->memFlags))
5102 heapCb->dynamicHeapMemUsed -= (size + hdr);
5103 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5105 CMM_SET_FREE_FLAG(p->memFlags);
5106 p->requestedSize = 0;
5107 #endif /*SSI_DEBUG_LEVEL1*/
5108 /* insert the block */
5109 p->next = curHBlk->next;
5114 /* Try to merge with the next block in the chain */
5115 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
5116 #ifdef SSI_DEBUG_LEVEL1
5117 if (((Data *)p + hdr + size) == (Data *)(p->next))
5119 if (((Data *)p + size) == (Data *)(p->next))
5120 #endif /*SSI_DEBUG_LEVEL1*/
5122 /* p->next can not be NULL */
5123 /* cm_mem_c_001.main_12 - addition for header consideration */
5124 #ifdef SSI_DEBUG_LEVEL1
5125 p->size += (p->next->size + hdr);
5127 p->size += p->next->size;
5128 #endif /*SSI_DEBUG_LEVEL1*/
5129 p->next = p->next->next;
5132 /* Release the lock */
5133 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5135 (Void) WTUnlock (&(heapCb->heapLock));
5137 (Void) SUnlock (&(heapCb->heapLock));
5139 /* cm_mem_c_001.main_15 : Additions */
5140 #ifdef SS_HISTOGRAM_SUPPORT
5141 /* If If Tapa task (entId)is registerd for histogram then insert
5142 Memrory Freed information into the hash list */
5145 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5146 fileName, entId) != ROK)
5148 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5152 #endif /* SS_HISTOGRAM_SUPPORT */
5156 else if (p < curHBlk)
5159 * Check if the block to be returned can be merged with the
5162 /* cm_mem_c_001.main_12 - addition for header consideration */
5163 #ifdef SSI_DEBUG_LEVEL1
5164 if (((Data *)p + hdr + size) == (Data *)curHBlk)
5166 if (((Data *)p + size) == (Data *)curHBlk)
5167 #endif /* SSI_DEBUG_LEVEL1 */
5169 /* Merge the block */
5170 /* cm_mem_c_001.main_12 - addition for header consideration */
5171 #ifdef SSI_DEBUG_LEVEL1
5172 p->size = size + (curHBlk->size + hdr);
5174 p->size = size + curHBlk->size;
5175 #endif /* SSI_DEBUG_LEVEL1 */
5176 p->next = curHBlk->next;
5180 /* insert the block */
5184 /* cm_mem_c_001.main_12 - addition for header updation */
5185 #ifdef SSI_DEBUG_LEVEL1
5186 /* update the flags in both cases as they are new start nodes*/
5187 if (CMM_IS_STATIC(p->memFlags))
5189 heapCb->staticHeapMemUsed -= (size + hdr);
5190 CMM_RESET_STATIC_FLAG(p->memFlags);
5192 else if (CMM_IS_DYNAMIC(p->memFlags))
5194 heapCb->dynamicHeapMemUsed -= (size + hdr);
5195 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5197 CMM_SET_FREE_FLAG(p->memFlags);
5198 p->requestedSize = 0;
5199 #endif /* SSI_DEBUG_LEVEL1 */
5203 /* Release the lock */
5204 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5206 (Void) WTUnlock (&(heapCb->heapLock));
5208 (Void) SUnlock (&(heapCb->heapLock));
5210 /* cm_mem_c_001.main_15 : Additions */
5211 #ifdef SS_HISTOGRAM_SUPPORT
5212 /* If If Tapa task (entId)is registerd for histogram then insert
5213 Memrory Freed information into the hash list */
5216 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5217 fileName, entId) != ROK)
5219 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5223 #endif /* SS_HISTOGRAM_SUPPORT */
5229 if (heapCb->next == NULLP)
5231 /* Heap block is empty. Insert the block in the head. */
5236 /* cm_mem_c_001.main_12 - addition for header updation */
5237 #ifdef SSI_DEBUG_LEVEL1
5238 if (CMM_IS_STATIC(p->memFlags))
5240 heapCb->staticHeapMemUsed -= (size + hdr);
5241 CMM_RESET_STATIC_FLAG(p->memFlags);
5243 else if (CMM_IS_DYNAMIC(p->memFlags))
5245 heapCb->dynamicHeapMemUsed -= (size + hdr);
5246 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5248 CMM_SET_FREE_FLAG(p->memFlags);
5249 p->requestedSize = 0;
5250 #endif /* SSI_DEBUG_LEVEL1 */
5252 /* Release the heap lock */
5253 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5255 (Void) WTUnlock (&(heapCb->heapLock));
5257 (Void) SUnlock (&(heapCb->heapLock));
5259 /* cm_mem_c_001.main_15 : Additions */
5260 #ifdef SS_HISTOGRAM_SUPPORT
5261 /* If If Tapa task (entId)is registerd for histogram then insert
5262 Memrory Freed information into the hash list */
5265 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5266 fileName, entId) != ROK)
5268 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5272 #endif /* SS_HISTOGRAM_SUPPORT */
5276 /* Release the lock */
5277 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5279 (Void) WTUnlock (&(heapCb->heapLock));
5281 (Void) SUnlock (&(heapCb->heapLock));
5285 } /* end of cmHeapFree */
5286 /* cm_mem_c_001.main_15 : Additions */
5288 #ifdef SS_MEM_LEAK_STS
5291 * Fun: cmInitMemLeakMdl
5293 * Desc: Initializes the memory leak detection module
5298 * Notes: This function initializes the memory leak detection module.
5305 PUBLIC Void cmInitMemLeakMdl
5310 PUBLIC Void cmInitMemLeakMdl (Void)
5316 TRC3(cmInitMemLeakMdl);
5318 memLkCb.memLkMdlInit = FALSE;
5319 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5321 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5323 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
5324 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5325 500, 0, FALSE, CM_HASH_KEYTYPE_U32MOD, 0, 0);
5326 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5329 if(memLkCb.fileLkLog == NULLP)
5331 memLkCb.fileLkLog = (FILE *) stdout;
5333 memLkCb.memLkMdlInit = TRUE;
5336 } /* cmInitMemLeakMdl */
5337 /* cm_mem_c_002.main_21 Added for shutdown procedure */
5340 * Fun: cmDeinitMemLeakMdl
5342 * Desc: De-initializes the memory leak detection module
5347 * Notes: This function de-initializes the memory leak detection module.
5354 PUBLIC Void cmDeinitMemLeakMdl
5359 PUBLIC Void cmDeinitMemLeakMdl (Void)
5365 TRC3(cmDeinitMemLeakMdl);
5367 memLkCb.memLkMdlInit = FALSE;
5368 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5370 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5372 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5373 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
5374 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5381 * Fun: cmMemOpenMemLkFile
5383 * Desc: Initializes the memory leak detection module
5388 * Notes: This function initializes the memory leak detection module.
5395 PUBLIC Void cmMemOpenMemLkFile
5400 PUBLIC Void cmMemOpenMemLkFile (arg)
5404 TRC3(cmMemOpenMemLkFile);
5405 memLkCb.fileLkLog = NULLP;
5406 memLkCb.fileLkLog = fopen(arg, "w");
5414 * Desc: Initializes the memory leak detection module
5419 * Notes: This function initializes the memory leak detection module.
5426 PUBLIC Void SLogLkInfo
5431 PUBLIC Void SLogLkInfo (Void)
5435 MemAllocInfo *oldMemInfo;
5436 MemAllocInfo *newMemInfo;
5443 if( memLkCb.memLkMdlInit == FALSE)
5447 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
5448 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5450 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5452 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5454 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5460 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5461 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5462 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
5464 sprintf(prntBuf, "[LBIS]\n");
5465 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5466 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5468 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
5470 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
5472 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5473 sprintf(prntBuf, "Module Name: %s\n",
5474 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
5475 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5476 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
5477 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5478 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
5479 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5480 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
5481 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5482 sprintf(prntBuf,"Memory Allocation Path:\n");
5483 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5484 funcNm = (S8 **)newMemInfo->backTrace;
5485 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
5487 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
5488 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5490 sprintf(prntBuf, "[LBIE]\n\n");
5491 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5492 fflush(memLkCb.fileLkLog);
5493 oldMemInfo = newMemInfo;
5496 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5499 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
5500 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5508 * Desc: Initializes the memory leak detection module
5513 * Notes: This function initializes the memory leak detection module.
5520 PUBLIC Void SFlushLkInfo
5525 PUBLIC Void SFlushLkInfo (Void)
5528 MemAllocInfo *newMemInfo;
5532 #ifdef SS_MEM_LEAK_SOL
5534 #endif /* SS_MEM_LEAK_SOL */
5537 if( memLkCb.memLkMdlInit == FALSE)
5542 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5544 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5546 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5551 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5552 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5553 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
5555 funcNm = (S8 **)newMemInfo->backTrace;
5556 #ifdef SS_MEM_LEAK_SOL
5557 for(i = 0; i < newMemInfo->bTrcSz; i++)
5559 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5560 #ifdef SS_4GMX_LCORE
5561 MxHeapFree(SsiHeap, funcNm[i]);
5565 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(U32) * CM_MAX_STACK_TRACE); */
5567 #endif /* SS_MEM_LEAK_SOl */
5568 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5569 #ifdef SS_4GMX_LCORE
5570 MxHeapFree(SsiHeap, funcNm);
5571 MxHeapFree(SsiHeap, newMemInfo);
5577 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5585 * Fun: cmStorAllocBlk
5587 * Desc: Initializes the memory leak detection module
5592 * Notes: This function initializes the memory leak detection module.
5599 PUBLIC Void cmStorAllocBlk
5607 PUBLIC Void cmStorAllocBlk (addr, reqSz, allocSz, bktIdx)
5614 #ifndef SS_MEM_LEAK_SOL
5615 Ptr trace[CM_MAX_STACK_TRACE];
5616 #endif /* SS_MEM_LEAK_SOL */
5619 MemAllocInfo *allocInfo;
5622 TRC3(cmStorAllocBlk);
5623 if( memLkCb.memLkMdlInit == FALSE)
5628 #ifdef SS_MEM_LEAK_SOL
5629 /* I need to do this for solaris, because it does not implement
5630 * backtrace. Here backtrace is my function. See below for the
5631 * implementation. */
5632 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5633 #ifdef SS_4GMX_LCORE
5634 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(U32) * CM_MAX_STACK_TRACE));
5635 cmMemset((U8*)funcNm, 0, (sizeof(U32) * CM_MAX_STACK_TRACE));
5637 funcNm = (S8 **)calloc(1, (sizeof(U32) * CM_MAX_STACK_TRACE));
5639 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(U32) * CM_MAX_STACK_TRACE); */
5640 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
5641 #else /* SS_MEM_LEAK_SOL */
5642 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5643 funcNm = backtrace_symbols(trace, traceSize);
5644 #endif /* SS_MEM_LEAK_SOL */
5646 moduleId = cmMemGetModuleId(funcNm, traceSize);
5648 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5649 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5650 #ifdef SS_4GMX_LCORE
5651 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
5652 cmMemset((U8*)allocInfo, 0, sizeof(MemAllocInfo));
5654 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
5656 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
5657 allocInfo->memAddr = addr;
5658 allocInfo->reqSz = reqSz;
5659 allocInfo->allocSz = allocSz;
5660 allocInfo->bktIdx = bktIdx;
5661 allocInfo->backTrace = (PTR) funcNm;
5662 allocInfo->moduleId = moduleId;
5663 allocInfo->bTrcSz = traceSize;
5665 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
5666 (PTR)allocInfo, (U8 *)&(allocInfo->memAddr),
5667 sizeof(allocInfo->memAddr));
5668 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
5670 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5672 } /* cmStorAllocBlk */
5676 * Fun: cmMemGetModuleId
5678 * Desc: Initializes the memory leak detection module
5683 * Notes: This function initializes the memory leak detection module.
5690 PUBLIC U8 cmMemGetModuleId
5696 PUBLIC U8 cmMemGetModuleId (funNm, traceSize)
5708 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
5710 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5711 TRC3(cmMemGetModuleId)
5712 for(idx = 0; idx < traceSize; idx++)
5716 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
5718 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
5723 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5725 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5726 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
5727 memUsrMdlStr[mdlFunStrIdx].fPStr,
5731 RETVALUE(mdlFunStrIdx);
5736 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5738 retVal = strcmp((const S8 *)"DEFAULT",
5739 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5742 RETVALUE(mdlFunStrIdx);
5749 } /* cmMemGetModuleId */
5753 * Fun: cmMemGetStrMtchIdx
5755 * Desc: Initializes the memory leak detection module
5760 * Notes: This function initializes the memory leak detection module.
5767 PUBLIC S16 cmMemGetStrMtchIdx
5775 PUBLIC S16 cmMemGetStrMtchIdx(strtIdx, endIdx, str, strLst)
5789 TRC3(cmMemGetStrMtchIdx);
5791 len = strlen((const S8 *)str);
5793 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
5794 cmpStr[len + 1] = '\0';
5797 for(;strtIdx < endIdx && !found; strtIdx++)
5800 tempLen = strlen((const S8 *)strLst[strtIdx]);
5804 while(*(strLst[strtIdx] + idx + len) != '\0')
5806 retVal = strncmp((const S8 *)cmpStr,
5807 ((const S8 *)strLst[strtIdx] + idx), len);
5823 } /* cmMemGetStrMtchIdx */
5827 * Fun: cmRlsAllocBlk
5829 * Desc: Initializes the memory leak detection module
5834 * Notes: This function initializes the memory leak detection module.
5841 PUBLIC Void cmRlsAllocBlk
5846 PUBLIC Void cmRlsAllocBlk(addr)
5850 Ptr trace[CM_MAX_STACK_TRACE];
5856 MemAllocInfo *memAllocInfo;
5858 TRC3(cmRlsAllocBlk);
5859 if( memLkCb.memLkMdlInit == FALSE)
5865 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5867 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5868 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5869 (U8 *)&addr, sizeof(U32), 0,
5870 (PTR *)&memAllocInfo);
5873 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5875 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5876 funcNm = (S8 **) memAllocInfo->backTrace;
5877 #ifdef SS_MEM_LEAK_SOL
5878 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5880 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5881 #ifdef SS_4GMX_LCORE
5882 MxHeapFree(SsiHeap, funcNm[i]);
5887 #endif /* SS_MEM_LEAK_SOL */
5888 #ifdef SS_MEM_LEAK_FREE_TRACE
5892 sprintf( prntBuf, "\n==============================\n");
5894 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5896 sprintf( prntBuf, "Address: [%x]\n", addr);
5898 sprintf( prntBuf, "Address: [%lx]\n", addr);
5901 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5902 funcNm = backtrace_symbols(trace, traceSize);
5903 sprintf( prntBuf, "[bt] Execution path:\n");
5905 for (i=0; i < traceSize; ++i)
5907 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5910 sprintf( prntBuf, "\n==============================\n");
5913 #endif /* SS_MEM_LEAK_FREE_TRACE */
5914 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5915 #ifdef SS_4GMX_LCORE
5916 MxHeapFree(SsiHeap, funcNm);
5917 MxHeapFree(SsiHeap, memAllocInfo);
5924 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5927 #ifndef SS_MEM_LEAK_SOL
5928 if(idx == CM_MEM_USR_MDL)
5931 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5933 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5935 sprintf( prntBuf, "Address: [%u]\n", addr);
5937 sprintf( prntBuf, "Address: [%lu]\n", addr);
5940 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5941 funcNm = backtrace_symbols(trace, traceSize);
5942 sprintf( prntBuf,"[bt] Execution path:\n");
5944 for (i=0; i < traceSize; ++i)
5946 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5949 printf("\n==============================\n");
5950 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5951 #ifdef SS_4GMX_LCORE
5952 MxHeapFree(SsiHeap, funcNm);
5957 #endif /* SS_MEM_LEAK_SOL */
5959 /*cm_mem_c_001.main_25 : */
5961 } /* cmRlsAllocBlk */
5964 #ifdef SS_MEM_LEAK_SOL
5967 * Fun: cmAddrToSymStr
5969 * Desc: Initializes the memory leak detection module
5974 * Notes: This function initializes the memory leak detection module.
5981 PUBLIC S32 cmAddrToSymStr
5988 PUBLIC S32 cmAddrToSymStr(pc, buffer, size)
5998 TRC3(cmAddrToSymStr);
6000 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
6002 RETVALUE(snprintf(buffer, size, "[0x%p]", pc));
6005 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
6006 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
6008 RETVALUE(snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
6011 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
6015 RETVALUE(snprintf(buffer, size, "%s(0x%p [0x%p]",
6017 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
6020 } /* cmAddrToSymStr */
6024 * Fun: cmLeakCallBack
6026 * Desc: Initializes the memory leak detection module
6031 * Notes: This function initializes the memory leak detection module.
6038 PUBLIC S32 cmLeakCallBack
6045 PUBLIC S32 cmLeakCallBack(pc, sigNo, arg)
6052 TRC3(cmLeakCallBack);
6054 Backtrace_t *bt = (Backtrace_t *)arg;
6055 if (bt->bt_actcount >= bt->bt_maxcount)
6057 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
6058 #ifdef SS_4GMX_LCORE
6059 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
6060 cmMemset((U8*)buffer, 0, 510);
6062 buffer = (S8 *)calloc(1, 510);
6064 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
6065 (void) cmAddrToSymStr((void *)pc, buffer, 505);
6066 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
6069 } /* cmLeakCallBack */
6075 * Desc: Initializes the memory leak detection module
6080 * Notes: This function initializes the memory leak detection module.
6087 PUBLIC S32 backtrace
6093 PUBLIC S32 backtrace(buffer, count)
6103 bt.bt_buffer = buffer;
6104 bt.bt_maxcount = count;
6107 if (getcontext(&u) < 0)
6109 (Void) walkcontext(&u, cmLeakCallBack, &bt);
6110 RETVALUE(bt.bt_actcount);
6114 #endif /* SS_MEM_LEAK_SOL */
6116 #endif /* SS_MEM_LEAK_STS */
6117 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
6118 * These include sanity check functions for bucket and heap,
6119 * for printing several memory related statistics
6121 #ifdef SSI_DEBUG_LEVEL1
6124 * Fun: cmMmBktSanityChk
6126 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
6127 * This API gets called when trampling is detected in a memory block.
6129 * Ret: RTRAMPLINGNOK - Trampling, serious error
6130 * RTRAMPLINGOK - Trampling, but OK to proceed
6132 * Notes: This function performs the memory block sanity in a bucket. This
6133 * function is called by cmAlloc and cmFree as part of error handling mechanism.
6134 * Performs sanity check for the whole bucket by traversing each
6135 * of the memory blocks using the pointer bktStartPtr.
6136 * Keeps track of number of tramplings happened. If the count
6137 * exceeds the threshold decided, then invalidates this bucket.
6143 PRIVATE S16 cmMmBktSanityChk
6148 PRIVATE S16 cmMmBktSanityChk(bkt)
6155 TRC2(cmMmBktSanityChk);
6157 bkt->trampleCount = 0;
6159 /* scan the entire memory list of the bucket */
6160 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
6161 blkCnt < (bkt->numBlks); blkCnt++)
6163 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
6165 bkt->trampleCount++;
6166 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
6168 /* Take action to invalidate the entire bucket */
6169 RETVALUE(RTRAMPLINGNOK);
6172 /* reach next memory block in this bucket manually */
6173 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
6177 /* display an error message here */
6178 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
6179 SDisplay(0, dbgPrntBuf);
6182 RETVALUE(RTRAMPLINGOK);
6187 * Fun: cmMmHeapSanityChk
6189 * Desc: Performs the sanity check for the memory blocks in the memory heap.
6190 * This API gets called when trampling is detected in heap(Alloc/Free).
6192 * Ret: RTRAMPLINGNOK - Trampling, serious error
6193 * RTRAMPLINGOK - Trampling, but OK to proceed
6195 * Notes: This function performs the memory block sanity in the heap. This
6196 * function is called by cmHeapAlloc and cmHeapFree as part of error
6197 * handling mechanism. Keeps track of number of tramplings happened.
6198 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
6199 * count is less than threshold, then return RTRAMPLINGOK.
6205 PRIVATE S16 cmMmHeapSanityChk
6210 PRIVATE S16 cmMmHeapSanityChk(heapCb)
6215 TRC2(cmMmHeapSanityChk);
6217 /* increment the trample count */
6218 heapCb->trampleCount++;
6220 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
6222 RETVALUE(RTRAMPLINGNOK);
6225 RETVALUE(RTRAMPLINGOK);
6230 * Fun: cmMmRegIsBlkSane
6232 * Desc: Performs the sanity check for the memory block by checking its header.
6234 * Ret: ROK - If no trampling is detected in the block
6235 * RFAILED - If trampling is detected in the block
6237 * Notes: This function performs the memory block sanity in a block.
6243 PUBLIC S16 cmMmRegIsBlkSane
6248 PUBLIC S16 cmMmRegIsBlkSane(blkPtr)
6254 TRC2(cmMmRegIsBlkSane);
6256 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
6258 if (blkPtr->trSignature[sigCnt] != 0xAB)
6271 * Desc: Computes the hash list index (bin number) for a specified
6272 * key of type (x % 101).
6274 * return (idx % hash_table_size);
6276 * Ret: ROK - successful, *idx contains computed index
6284 PRIVATE S16 cmMmHashFunc
6286 CmMmHashListCp *hashListCp,
6291 PRIVATE S16 cmMmHashFunc (hashListCp, key, idx)
6292 CmMmHashListCp *hashListCp; /* hash list control point */
6293 U32 key; /* key string */
6294 U16 *idx; /* idx to return */
6299 *idx = (U16)(key % hashListCp->numOfbins);
6303 } /* end of cmMmHashFunc () */
6307 * Fun: cmMmHashListInit
6309 * Desc: Initializes a hash list. Parameters are:
6311 * hashListCp control point for hash list
6312 * nmbBins number of bins in the hash list. Storage will
6313 * be allocated for them from the indicated memory
6316 * pool for allocating storage for bins.
6318 * Ret: ROK - initialization successful
6319 * RFAILED - initialization failed, lack of memory
6327 PRIVATE S16 cmMmHashListInit
6329 CmMmHashListCp *hashListCp, /* hash list to initialize */
6330 U16 nmbBins, /* number of hash list bins */
6331 Region region, /* memory region to allocate bins */
6332 Pool pool /* memory pool to allocate bins */
6335 PRIVATE S16 cmMmHashListInit(hashListCp, nmbBins, region, pool)
6336 CmMmHashListCp *hashListCp; /* hash list to initialize */
6337 U16 nmbBins; /* number of hash list bins */
6338 Region region; /* memory region to allocate bins */
6339 Pool pool; /* memory pool to allocate bins */
6343 CmMmHashListEnt *hl;
6345 TRC2(cmMmHashListInit);
6347 /* initialize control point fields */
6348 hashListCp->hashList = NULLP;
6349 hashListCp->numOfbins = 0;
6350 hashListCp->numOfEntries = 0;
6352 /* allocate memory for bins */
6355 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
6356 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
6359 /* initialize bin pointers */
6360 hl = hashListCp->hashList;
6361 for(i = 0; i < nmbBins; i++)
6363 hl[i].size = hl[i].numAttempts = 0;
6366 /* initialize bin size */
6367 hashListCp->numOfbins = nmbBins;
6375 * Fun: cmMmHashListDeinit
6377 * Desc: Deinitializes a hash list. Deallocates memory for bins
6378 * and resets header fields. Parameters are:
6380 * hashListCp control point for hash list
6382 * pool for allocating storage for bins.
6384 * Ret: ROK - successful
6385 * RFAILED - failure, invalid parameters
6393 PRIVATE S16 cmMmHashListDeinit
6395 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
6396 Region region, /* memory region to allocate bins */
6397 Pool pool /* memory pool to allocate bins */
6400 PRIVATE S16 cmMmHashListDeinit(hashListCp, region, pool)
6401 CmMmHashListCp *hashListCp; /* hash list to deinitialize */
6402 Region region; /* memory region to allocate bins */
6403 Pool pool; /* memory pool to allocate bins */
6406 TRC2(cmMmHashListDeinit);
6408 /* deallocate memory for bins */
6409 if (hashListCp->numOfbins)
6410 (Void) SPutSBuf(region, pool,
6411 (Data *) hashListCp->hashList,
6412 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
6414 /* deinitialize control point fields */
6415 hashListCp->hashList = NULLP;
6416 hashListCp->numOfbins = 0;
6417 hashListCp->numOfEntries = 0;
6420 } /* end of cmMmHashListDeinit */
6424 * Fun: cmMmHashListInsert
6426 * Desc: Inserts a new entry in the hash list. Parameters are:
6428 * hashListCp control point for hash list
6429 * key pointer to key string in the new entry
6431 * Ret: ROK - insertion successful
6432 * RFAILED - insertion failed (incorrect parameter values)
6440 PRIVATE S16 cmMmHashListInsert
6442 CmMmHashListCp *hashListCp, /* hash list to add to */
6443 U32 key /* pointer to key */
6446 PRIVATE S16 cmMmHashListInsert(hashListCp, key)
6447 CmMmHashListCp *hashListCp; /* hash list to add to */
6448 U32 key; /* pointer to key */
6451 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
6452 U16 idx; /* index for insertion into hash list */
6455 TRC2(cmMmHashListInsert);
6457 /* check if hashListCp is initialised yet */
6458 if ( hashListCp->numOfbins == 0)
6461 /* compute index for insertion */
6462 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
6465 hashListEnt = hashListCp->hashList;
6467 if (hashListEnt[idx].numAttempts == 0)
6469 /* new entry, insert here */
6470 hashListEnt[idx].size = key;
6471 hashListEnt[idx].numAttempts++;
6472 /* increment count of entries in hash list */
6473 hashListCp->numOfEntries++;
6477 /* this hash is occupied, re-hash it using linear probing */
6478 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
6480 if (hashListEnt[i].size == key)
6482 hashListEnt[i].numAttempts++;
6486 if (hashListEnt[i].numAttempts == 0)
6488 hashListEnt[i].size = key;
6489 hashListEnt[i].numAttempts++;
6490 /* increment count of entries in hash list */
6491 hashListCp->numOfEntries++;
6496 if (i == CMM_STAT_HASH_TBL_LEN)
6498 /* there is no free slot for this key */
6504 } /* end of cmMmHashListInsert */
6506 #endif /* SSI_DEBUG_LEVEL1 */
6507 /* cm_mem_c_001.main_15 : Additions */
6508 #ifdef SS_HISTOGRAM_SUPPORT
6511 * Fun: cmHstGrmHashListInit
6513 * Desc: Initializes a hash list. Parameters are:
6515 * hashListCp control point for hash list
6516 * Ret: ROK - initialization successful
6517 * RFAILED - initialization failed, lack of memory
6525 PRIVATE S16 cmHstGrmHashListInit
6527 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6530 PRIVATE S16 cmHstGrmHashListInit(hashListCp)
6531 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6534 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6535 TRC2(cmHstGrmHashListInit)
6537 /* display an error message here */
6538 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6540 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6542 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6544 SDisplay(0, dbgPrntBuf);
6546 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6552 * Fun: cmHstGrmHashListDeInit
6554 * Desc: De-initializes a hash list. Parameters are:
6556 * hashListCp control point for hash list
6557 * Ret: ROK - initialization successful
6558 * RFAILED - initialization failed, lack of memory
6566 PRIVATE S16 cmHstGrmHashListDeInit
6568 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6571 PRIVATE S16 cmHstGrmHashListDeInit(hashListCp)
6572 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6575 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6576 TRC2(cmHstGrmHashListDeInit)
6578 /* display an error message here */
6579 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6581 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6583 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6585 SDisplay(0, dbgPrntBuf);
6587 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6593 * Fun: cmHstGrmFreeInsert
6595 * Desc: Inserts a Freed information in into the hash list. Parameters are:
6597 * bkt : pointer to bucket for which memory is freed.
6598 * line : Line where memory is freed.
6599 * file : file where memory is freed.
6600 * entId : Tapa task which releases the memory.
6602 * Ret: ROK - insertion successful
6603 * RFAILED - insertion failed (incorrect parameter values)
6611 PRIVATE S16 cmHstGrmFreeInsert
6613 CmHstGrmHashListCp* hashListCp, /* hash list cp */
6614 U32 blkSz, /* size of the block freed */
6615 U32 line, /* Line number */
6616 U8 *fileName, /* file name */
6617 U8 entId /* Tapa task which free the memory */
6620 PRIVATE S16 cmHstGrmFreeInsert(hashListCp, blkSz, line, fileName, entId)
6621 CmHstGrmHashListCp* hashListCp; /* hash list cp */
6622 U32 blkSz; /* size of the block freed */
6623 U32 line; /* line number */
6624 U8 *fileName; /* file Name */
6625 U8 entId; /* Tapa task which frees the memory */
6628 U32 binIdx = 0; /* Bin index to insert the entry into the hash list */
6629 U32 key = 0; /* Key to fine the bin index */
6630 U32 ret = 0; /* Return value */
6631 CmMemEntries *entry = NULLP; /* Entry which contains the information */
6634 TRC2(cmHstGrmFreeInsert);
6636 /* check for the total number of entries in the hash list. *
6637 * If there is no place for new entry return failure */
6638 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6640 /* After comuting the hash bind and key, check the entity already *
6641 existing or not. if we found the entry then update the information */
6642 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6645 entry->freedBytes += blkSz;
6646 entry->bucketFreeReq++;
6650 /* If hash list is full then print the error tna continue */
6651 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6653 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");
6657 /* Take the address of next free entry in the hash bin */
6658 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6660 /* Increase the number of time frees called */
6661 entry->bucketFreeReq++;
6662 entry->freedBytes += blkSz;
6664 /* Fill the information into the entry structure */
6665 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6666 /* Increase the total numbet of entries in the bin */
6667 hashListCp->hashList[binIdx].numOfEntries++;
6669 /* Increase the total number of entries in the hash list */
6670 hashListCp->totalNumEntries++;
6673 } /* end of cmHstGrmFreeInsert */
6678 * Fun: ret = cmHstGrmAllocInsert
6680 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
6682 * hashListCp control point for hash list
6683 * key pointer to key string in the new entry
6685 * Ret: ROK - insertion successful
6686 * RFAILED - insertion failed (incorrect parameter values)
6694 PRIVATE S16 cmHstGrmAllocInsert
6696 CmHstGrmHashListCp *hashListCp,
6704 PRIVATE S16 cmHstGrmAllocInsert(hashListCp, blkSz, reqSz, line, fileName, entId)
6705 CmHstGrmHashListCp *hashListCp;
6716 CmMemEntries *entry = NULLP;
6718 TRC2(cmHstGrmAllocInsert);
6720 /* check for the total number of entries in the hash list. *
6721 * If there is no place for new entry return failure */
6722 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6724 /* After comuting the hash bind and key, check the entity already *
6725 existing or not. if we found the entry then update the information */
6726 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6730 entry->allocBytes += blkSz;
6731 entry->bucketAllocReq++;
6732 entry->wastedBytes += (blkSz - *reqSz);
6736 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6738 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");
6742 /* Take the address of next free entry in the hash bin */
6743 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6745 /* Clauculae the wasted bytes */
6746 /* Here wasted byte is differnce between the byte user
6747 * has requested and the byte the ssi allocated */
6748 entry->wastedBytes += (blkSz - *reqSz);
6749 entry->bucketAllocReq++;
6750 entry->allocBytes += blkSz;
6752 /* Fill the information into the entry structure */
6753 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6754 /* Increase the total numbet of entries in the bin */
6755 hashListCp->hashList[binIdx].numOfEntries++;
6757 /* Increase the total number of entries in the hash list */
6758 hashListCp->totalNumEntries++;
6761 } /* end of cmHstGrmAllocInsert */
6766 * Fun: cmHstGrmGetHashIdxAndKey
6768 * Desc: Finds an entry in the hash list. Parameters are:
6770 * hashListCp control point for hash list
6771 * key pointer to key string in the new entry
6773 * Ret: ROK - insertion successful
6774 * RFAILED - insertion failed (incorrect parameter values)
6782 PRIVATE S16 cmHstGrmGetHashIdxAndKey
6790 PRIVATE S16 cmHstGrmGetHashIdxAndKey(fileName, line, binIdx, key)
6799 TRC2(cmHstGrmGetHashIdxAndKey);
6801 /* Calculate the key using file name and line number */
6802 for(i = 0 ; fileName[i] != '\0'; i++)
6804 *key += fileName[i];
6807 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
6809 } /* end of cmHstGrmFillEntry */
6813 * Fun: cmHstGrmFillEntry
6815 * Desc: Insert the entry into the hash list.
6817 * entry : Infornation which will be inserted into the hash list
6818 * key : Which will be used ti find the entry.
6819 * line : Line number
6820 * fileName : File name
6821 * entId : Tapa task Id
6823 * Ret: ROK - insertion successful
6824 * RFAILED - insertion failed (incorrect parameter values)
6832 PRIVATE S16 cmHstGrmFillEntry
6834 CmMemEntries *entry,
6841 PRIVATE S16 cmHstGrmFillEntry(entry, key, line, fileName, entId)
6842 CmMemEntries *entry;
6851 TRC2(cmHstGrmFillEntry);
6854 entry->entId = entId;
6855 for(idx = 0; fileName[idx] != '\0'; idx++)
6857 entry->fileName[idx] = fileName[idx];
6859 entry->fileName[idx] = '\0';
6861 } /* end of cmHstGrmFillEntry */
6865 * Fun: cmHstGrmFindEntry
6867 * Desc: Finds an entry in the hash list. Parameters are:
6869 * hashListCp control point for hash list
6870 * key pointer to key string in the new entry
6872 * Ret: ROK - insertion successful
6873 * RFAILED - insertion failed (incorrect parameter values)
6881 PRIVATE S16 cmHstGrmFindEntry
6883 CmHstGrmHashListCp *hashListCp,
6886 CmMemEntries **entry
6889 PRIVATE S16 cmHstGrmFindEntry(hashListCp, key, binIdx, entry)
6890 CmHstGrmHashListCp *hashListCp;
6893 CmMemEntries **entry;
6899 CmHstGrmHashListEnt *tmpBin = NULLP;
6901 TRC2(cmHstGrmFindEntry);
6904 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
6906 /* find for the entry in the bin */
6907 tmpBin = &(hashListCp->hashList[*binIdx]);
6908 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
6910 /* If key supplied is matched with the stored key then
6911 * return that entity */
6912 if(tmpBin->entries[numEnt].key == key)
6914 *entry = &(tmpBin->entries[numEnt]);
6916 }/* End of if (tmpBin->entries[numEnt].key) */
6917 }/* end of for (numEnt = 0) */
6919 /* Here we are checking for any room left in the bin. If the room *
6920 exists its mean that there is no entry with the Key. so return *
6922 If there is no room in the bin, then check the other bins to find *
6924 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
6926 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
6929 }/* End of if (binIdx) */
6933 }/* End of else (binIdx) */
6934 } /* End of if (numEnt) */
6937 printf ("Unable to find the entry in hash list\n");
6939 }/* End of else (numEnt) */
6940 }/* end of for (numBin = 0) */
6942 printf("Unable to find the entry in the hash list\n");
6944 } /* end of cmHstGrmFindEntry */
6946 #endif /* SS_HISTOGRAM_SUPPORT */
6947 #ifdef T2K_MEM_LEAK_DBG
6948 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
6949 U32 getT2kMemLeakIndex(U32 address)
6955 XOR 7 with 3 and remove 7
6956 XOR 1 with 5 and remove 1
6959 address -= T2K_MEM_LEAK_START_ADDR;
6961 U8 Nib7 = address & 0x0000000f;
6962 U8 Nib1 = (address & 0x0f000000) >>24;
6963 U8 Nib3 = (address & 0x000f0000) >> 16;
6964 U8 Nib5 = (address & 0x00000f00) >> 8;
6966 /* store 8 ^ 3 in 8Nib */
6968 /* store 1 ^ 6 in 6Nib */
6971 return(((address & 0x000fff00) | (Nib7 << 20) | (Nib5 << 4)) >> 4);
6974 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6977 static U32 t2kMemAllocTick;
6978 static U32 smallTick;
6980 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
6982 U32 idx = getT2kMemLeakIndex(address);
6984 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6986 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6987 "line is %ld \n", address, size, fileName, lineNo);
6990 if(gMemLeakInfo[idx].address == 0)
6992 gMemLeakInfo[idx].address = address;
6993 gMemLeakInfo[idx].size = size;
6994 gMemLeakInfo[idx].lineNo = lineNo;
6995 gMemLeakInfo[idx].fileName = fileName;
6996 gMemLeakInfo[idx].age = t2kMemAllocTick;
6997 gMemLeakInfo[idx].prevRemLineNo = 0;
6998 gMemLeakInfo[idx].prevRemFileName = '\0';
7000 if(smallTick++ == 4096)
7003 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
7008 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
7009 "line is %ld \n",address, idx, fileName, lineNo);
7010 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
7011 "Age:%ld, differnce in Age:%ld",
7012 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
7013 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
7014 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
7016 /* Try inserting into some other location */
7018 int lastIndex = idx + 1;
7019 Bool inserted = FALSE;
7020 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7022 if(gMemLeakInfo[lastIndex].address == 0)
7024 gMemLeakInfo[lastIndex].address = address;
7025 gMemLeakInfo[lastIndex].size = size;
7026 gMemLeakInfo[lastIndex].lineNo = lineNo;
7027 gMemLeakInfo[lastIndex].fileName = fileName;
7028 gMemLeakInfo[lastIndex].age = (++t2kMemAllocTick) >> 14; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7032 lastIndex = idx + (i * i * i);
7037 printf("Something is wrong, trying to insert %x idx = %d no free i = %d\n",address, idx, i);
7045 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
7047 U32 idx = getT2kMemLeakIndex(address);
7049 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
7051 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
7057 if(gMemLeakInfo[idx].address == address)
7059 gMemLeakInfo[idx].address = 0;
7060 gMemLeakInfo[idx].age = 0;
7061 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
7062 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
7064 gMemLeakInfo[idx].lastDelLineNum = line;
7065 gMemLeakInfo[idx].lastDelFileName = file;
7066 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
7070 printf("Something is wrong, trying to remove %lx idx = %ld from"
7071 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
7072 gMemLeakInfo[idx].address);
7075 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
7076 gMemLeakInfo[idx].lastDelLineNum);
7078 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
7080 printf("Previous File:%s, Previous Line:%ld\n",
7081 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
7084 /* Try removing from some other location where it might have been stored*/
7086 int lastIndex = idx + 1;
7087 Bool removed = FALSE;
7088 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7090 if(gMemLeakInfo[lastIndex].address == address)
7092 gMemLeakInfo[lastIndex].address = 0;
7093 gMemLeakInfo[lastIndex].size = 0;
7094 gMemLeakInfo[lastIndex].lineNo = 0;
7095 gMemLeakInfo[lastIndex].fileName = 0;
7096 gMemLeakInfo[lastIndex].age = 0; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7100 lastIndex = idx + (i*i*i);
7105 printf("Something is wrong, trying to remove %x idx = %d lastIndex = %d FreeCalled from File=%s, line=%d\n",address, idx, lastIndex,file,line);
7112 PUBLIC void DumpT2kMemLeakInfoToFile()
7116 FILE *fp = fopen("memLeakInfo.txt","wb");
7120 printf("Could not open file for dumping mem leak info\n");
7124 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
7126 if(gMemLeakInfo[i].address != 0)
7128 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
7129 if(onlyFileName == NULL)
7131 onlyFileName = gMemLeakInfo[i].fileName;
7134 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
7135 gMemLeakInfo[i].size,
7136 gMemLeakInfo[i].age,
7137 gMemLeakInfo[i].lineNo,
7142 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
7148 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7150 /* For Updating SOC Specific Memory Information */
7152 PUBLIC S16 UpdateSocMemInfo
7158 PUBLIC S16 UpdateSocMemInfo(areaIndex,mInfo)
7160 CmLteMemInfo *mInfo;
7166 void *iccHdl = NULLP;
7170 U32 poolTotAvail[4];
7172 idxReg = mInfo->numRegions;
7173 mInfo->numRegions = mInfo->numRegions + 1;
7174 /* Calling Soc specific API to get shared memory status */
7175 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
7176 iccHdl = ssGetIccHdl(areaIndex);
7178 /* Populating global memory information */
7179 mInfo->regInfo[idxReg].numPools = numPool;
7180 mInfo->regInfo[idxReg].regionId = areaIndex;
7181 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
7183 /* Calling INTEL API's to Get Free MEM BLOCKS */
7184 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7185 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7186 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7187 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7189 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
7190 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
7191 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
7192 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
7194 poolSize[0] = ICC_POOL_ZERO_SIZE;
7195 poolSize[1] = ICC_POOL_ONE_SIZE;
7196 poolSize[2] = ICC_POOL_TWO_SIZE;
7197 poolSize[3] = ICC_POOL_THREE_SIZE;
7199 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
7200 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
7201 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
7202 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
7204 for(idxPool=0; idxPool<numPool;idxPool++)
7206 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
7207 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
7208 poolTotAvail[idxPool];
7209 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
7210 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
7211 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
7213 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
7214 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
7223 * Fun: isL2MemUsageBelowLowerThreshold
7225 * Desc: Checks for the Lower threshold of ICC memory.
7227 * region region for obtaining the ICC handle
7229 * Ret: TRUE - Threshold has reached
7230 * FALSE - Threshold has not reached
7238 PUBLIC U32 isL2MemUsageBelowLowerThreshold(
7242 PUBLIC U32 isL2MemUsageBelowLowerThreshold(region)
7246 void * iccHdl = ssGetIccHdl(region);
7248 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7249 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7251 /* We are below the threshold if free count in BOTH of the pools
7252 * is above the ICC_MEM_LOWER_THRESHOLD % */
7253 if(((poolZeroFreeCnt * 100) >
7254 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
7255 ((poolOneFreeCnt * 100) >
7256 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
7267 * Fun: isMemUsageBelowLowerThreshold
7269 * Desc: Checks for the Lower threshold of ICC memory.
7271 * region region for obtaining the ICC handle
7273 * Ret: TRUE - Threshold has reached
7274 * FALSE - Threshold has not reached
7282 PUBLIC U32 isMemUsageBelowLowerThreshold(
7286 PUBLIC U32 isMemUsageBelowLowerThreshold(region)
7290 void * iccHdl = ssGetIccHdl(region);
7292 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7293 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7294 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7295 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7297 /* We are below the threshold if free count in BOTH of the pools
7298 * is above the ICC_MEM_LOWER_THRESHOLD % */
7299 if(((poolZeroFreeCnt * 100) >
7300 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
7301 ((poolOneFreeCnt * 100) >
7302 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
7303 ((poolTwoFreeCnt * 100) >
7304 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
7305 ((poolThreeFreeCnt * 100) >
7306 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
7316 * Fun: isMemUsageAboveUpperThreshold
7318 * Desc: Checks for the Upper threshold of ICC memory.
7320 * region region for obtaining the ICC handle
7322 * Ret: TRUE - Threshold has reached
7323 * FALSE - Threshold has not reached
7331 PRIVATE U32 isMemUsageAboveUpperThreshold(
7335 PRIVATE U32 isMemUsageAboveUpperThreshold(region)
7339 void * iccHdl = ssGetIccHdl(region);
7341 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7342 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7343 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7344 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7346 /* We are above the threshold if free count in either of the pools
7347 * is below the ICC_MEM_UPPER_THRESHOLD % */
7348 if(((poolZeroFreeCnt * 100) <
7349 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
7350 ((poolOneFreeCnt * 100) <
7351 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
7352 ((poolTwoFreeCnt * 100) <
7353 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
7354 ((poolThreeFreeCnt * 100) <
7355 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
7363 /* ccpu00142274- Function to check if we have reached the
7364 * Threshold for dropping UL packets at the RLC. This function
7365 * measures the free count of the ICC memory and based on the
7366 * volume of packets it sets an alarm to drop packets.
7367 * In DL, the PDCP packets are dropped at Admission Control, but
7368 * at UL we need to check if its an AM(Data only and
7369 * not Status PDU) or UM packet and free the PDU
7370 * Note: With the current design, we have PDCP DL and RLC UL
7371 * running in the same thread and the below function will be
7372 * accessed in tandem. But if PDCP DL and RLC UL are made to run
7373 * in different threads then there might be a race condition.
7374 * Please revisit this function in such a case.
7378 * Fun: isMemThreshReached
7380 * Desc: Checks whether the system has reached the
7381 * designated threshold of ICC memory.
7383 * region region for obtaining the ICC handle
7385 * Ret: ROK - Threshold has not reached
7386 * RFAILED - Threshold has reached
7394 PUBLIC U32 isMemThreshReached(
7398 PUBLIC U32 isMemThreshReached(reg)
7402 TRC3(isMemThreshReached)
7405 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
7410 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
7412 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
7413 memoryCheckCounter = 0;
7419 #endif /* SS_LOCKLESS_MEMORY */
7421 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
7422 U32 getT2kMemLeakIndex(U32 address)
7428 XOR 7 with 3 and remove 7
7429 XOR 1 with 5 and remove 1
7432 address -= T2K_MEM_LEAK_START_ADDR;
7434 U8 Nib7 = address & 0x0000000f;
7435 U8 Nib1 = (address & 0x0f000000) >>24;
7436 U8 Nib3 = (address & 0x000f0000) >> 16;
7437 U8 Nib5 = (address & 0x00000f00) >> 8;
7439 /* store 8 ^ 3 in 8Nib */
7441 /* store 1 ^ 6 in 6Nib */
7444 return(((address & 0x000fff00) | (Nib7 << 20) | (Nib5 << 4)) >> 4);
7447 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
7450 static U32 t2kMemAllocTick;
7451 static U32 smallTick;
7453 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
7455 U32 index = getT2kMemLeakIndex(address);
7457 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
7459 printf("address in InsertToT2kMemLeakInfo is %x size = %d file is %s line is %d \n", address, size, fileName, lineNo);
7462 if(gMemLeakInfo[index].address == 0)
7464 gMemLeakInfo[index].address = address;
7465 gMemLeakInfo[index].size = size;
7466 gMemLeakInfo[index].lineNo = lineNo;
7467 gMemLeakInfo[index].fileName = fileName;
7468 gMemLeakInfo[index].age = t2kMemAllocTick;
7469 gMemLeakInfo[index].prevRemLineNo = 0;
7470 gMemLeakInfo[index].prevRemFileName = '\0';
7472 if(smallTick++ == 4096)
7475 gMemLeakInfo[index].age = (++t2kMemAllocTick);
7480 printf("Something is wrong, trying to insert %x index = %d file is %s line is %d \n",address, index, fileName, lineNo);
7481 printf("Address present :%x, from File:%s, Line:%d, Size:%d, Age:%d",
7482 gMemLeakInfo[index].address, gMemLeakInfo[index].fileName,
7483 gMemLeakInfo[index].lineNo, gMemLeakInfo[index].size,
7484 gMemLeakInfo[index].age);
7486 /* Try inserting into some other location */
7488 int lastIndex = index + 1;
7489 Bool inserted = FALSE;
7490 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7492 if(gMemLeakInfo[lastIndex].address == 0)
7494 gMemLeakInfo[lastIndex].address = address;
7495 gMemLeakInfo[lastIndex].size = size;
7496 gMemLeakInfo[lastIndex].lineNo = lineNo;
7497 gMemLeakInfo[lastIndex].fileName = fileName;
7498 gMemLeakInfo[lastIndex].age = (++t2kMemAllocTick) >> 14; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7502 lastIndex = index + (i * i * i);
7507 printf("Something is wrong, trying to insert %x index = %d no free i = %d\n",address, index, i);
7515 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
7517 U32 index = getT2kMemLeakIndex(address);
7519 if(index >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
7521 printf("Index out of range = %d address is %x file = %s line = %d. We are going to crash!!!\n",
7527 if(gMemLeakInfo[index].address == address)
7529 gMemLeakInfo[index].address = 0;
7530 gMemLeakInfo[index].age = 0;
7531 gMemLeakInfo[index].prevRemLineNo = gMemLeakInfo[index].lineNo;
7532 gMemLeakInfo[index].prevRemFileName = gMemLeakInfo[index].fileName;
7534 /*printf("Something is wrong, Trying to double free Address = %x, Index = %d \n",address,index);*/
7538 printf("Something is wrong, trying to remove %x index = %d from File=%s, line=%d address present is %x\n",address, index, file,line,
7539 gMemLeakInfo[index].address);
7540 if(gMemLeakInfo[index].prevRemFileName != NULLP)
7542 printf("Previous File:%s, Previous Line:%d\n",
7543 gMemLeakInfo[index].prevRemFileName, gMemLeakInfo[index].prevRemLineNo);
7546 /* Try removing from some other location where it might have been stored*/
7548 int lastIndex = index + 1;
7549 Bool removed = FALSE;
7550 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7552 if(gMemLeakInfo[lastIndex].address == address)
7554 gMemLeakInfo[lastIndex].address = 0;
7555 gMemLeakInfo[lastIndex].size = 0;
7556 gMemLeakInfo[lastIndex].lineNo = 0;
7557 gMemLeakInfo[lastIndex].fileName = 0;
7558 gMemLeakInfo[lastIndex].age = 0; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7562 lastIndex = index + (i*i*i);
7567 printf("Something is wrong, trying to remove %x index = %d lastIndex = %d FreeCalled from File=%s, line=%d\n",address, index, lastIndex,file,line);
7574 void DumpT2kMemLeakInfoToFile()
7578 FILE *fp = fopen("memLeakInfo.txt","wb");
7582 printf("Could not open file for dumping mem leak info\n");
7586 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
7588 if(gMemLeakInfo[i].address != 0)
7590 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
7591 if(onlyFileName == NULL)
7593 onlyFileName = gMemLeakInfo[i].fileName;
7596 fprintf(fp, "%p s=%d a=%d l=%d f=%s\n",gMemLeakInfo[i].address,
7597 gMemLeakInfo[i].size,
7598 gMemLeakInfo[i].age,
7599 gMemLeakInfo[i].lineNo,
7604 fprintf(fp,"Current t2kMemAllocTick = %d\n",t2kMemAllocTick);
7610 /**********************************************************************
7612 **********************************************************************/