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();
437 DumpRLCDlDebugInformation();
438 DumpRLCUlDebugInformation();
440 //printSchCellInfo();
445 /* private variable declarations */
448 * Fun: cmMmStatBktInit
450 * Desc: Initialize the bucket and the map table.
453 * Ret: ROK - successful,
454 * RFAILED - unsuccessful.
456 * Notes: This function is called by the cmMmRegInit.
462 PRIVATE Void cmMmStatBktInit
471 PRIVATE Void cmMmStatBktInit (memAddr, regCb, cfg, bktIdx, lstMapIdx)
483 /* cm_mem_c_001.main_12 - addition for temporary variables */
484 #ifdef SSI_DEBUG_LEVEL1
485 CmMmBlkHdr **nextBlk;
489 #endif /* SSI_DEBUG_LEVEL1 */
491 TRC2(cmMmStatBktInit);
494 size = cfg->bktCfg[bktIdx].size;
495 numBlks = cfg->bktCfg[bktIdx].numBlks;
497 /* cm_mem_c_001.main_12 - addition for header initialization */
498 #ifdef SSI_DEBUG_LEVEL1
499 /* Reset the next block pointer */
500 regCb->bktTbl[bktIdx].nextBlk = NULLP;
502 /* Initialize the link list of the memory block */
503 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
505 for (cnt = 0; cnt < numBlks; cnt++)
507 *nextBlk = (CmMmBlkHdr *)*memAddr;
509 /* initialize the memory block header */
510 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
512 (*nextBlk)->trSignature[sigCnt] = 0xAB;
515 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
516 (*nextBlk)->requestedSize = 0;
517 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
518 nextBlk = &((*nextBlk)->nextBlk);
524 /* Initialize the bucket linked list */
526 /* Reset the next pointer */
527 regCb->bktTbl[bktIdx].next = NULLP;
529 /* Initialize the link list of the memory block */
530 next = &(regCb->bktTbl[bktIdx].next);
531 for (cnt = 0; cnt < numBlks; cnt++)
534 next = (CmMmEntry **)(*memAddr);
535 *memAddr = (*memAddr) + size;
540 #endif /* SSI_DEBUG_LEVEL1 */
542 /* Initialize the Map entry */
543 idx = size / cfg->bktQnSize;
546 * Check if the size is multiple of quantum size. If not we need to initialize
547 * one more map table entry.
549 if(size % cfg->bktQnSize)
554 while ( *lstMapIdx < idx)
556 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
558 #if (ERRCLASS & ERRCLS_DEBUG)
559 regCb->mapTbl[*lstMapIdx].numReq = 0;
560 regCb->mapTbl[*lstMapIdx].numFailure = 0;
566 /* Initialize the bucket structure */
567 regCb->bktTbl[bktIdx].size = size;
568 regCb->bktTbl[bktIdx].numBlks = numBlks;
569 regCb->bktTbl[bktIdx].numAlloc = 0;
570 regCb->bktTbl[bktIdx].maxAlloc = 0;
572 /* Update the total bucket size */
573 /* cm_mem_c_001.main_12 - addition for considering the header size */
574 #ifdef SSI_DEBUG_LEVEL1
575 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
577 regCb->bktSize += (size * numBlks);
578 #endif /* SSI_DEBUG_LEVEL1 */
580 regCb->bktTbl[bktIdx].bktFailCnt = 0;
581 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
583 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
584 #ifdef SSI_DEBUG_LEVEL1
585 /* Initialize other required pointers */
586 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
587 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
588 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
589 regCb->bktTbl[bktIdx].staticMemUsed = 0;
590 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
591 regCb->bktTbl[bktIdx].trampleCount = 0;
592 #endif /*SSI_DEBUG_LEVEL1*/
593 /* cm_mem_c_001.main_15 : Additions */
594 #ifdef SS_HISTOGRAM_SUPPORT
595 /* Initialise the memory histogram hash list */
596 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
597 #endif /* SS_HISTOGRAM_SUPPORT */
600 } /* end of cmMmStatBktInit */
604 * Fun: cmMmStatRegInit
606 * Desc: Configure the memory region for allocation. The function
607 * registers the memory region with System Service by calling
611 * Ret: ROK - successful,
612 * RFAILED - unsuccessful.
614 * Notes: The memory owner calls this function to initialize the memory
615 * manager with the information of the memory region. Before
616 * calling this function, the memory owner should allocate memory
617 * for the memory region. The memory owner should also provide the
618 * memory for the control block needed by the memory manager. The
619 * memory owner should allocate the memory for the region control
620 * block as cachable memory. This may increase the average
621 * throughput in allocation and deallocation as the region control
622 * block is mostly accessed by the CMM.
628 PUBLIC S16 cmMmStatRegInit
635 PUBLIC S16 cmMmStatRegInit(region, regCb, cfg)
645 #if (ERRCLASS & ERRCLS_INT_PAR)
648 Txt errMsg[256] = {'\0'};
653 #if (ERRCLASS & ERRCLS_INT_PAR)
655 /* error check on parameters */
656 if ((regCb == NULLP) || (cfg == NULLP))
661 /* Error check on the configuration fields */
662 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
663 (cfg->numBkts > CMM_MAX_BKT_ENT))
667 /* Check if the quantum size is power of 2 */
668 if ((cfg->numBkts) &&
669 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
671 /* cm_mem_c_001.main_20 Addition */
672 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
678 * Check if the size of the memory region is enough, whether bucket sizes
679 * are multiples of quantumn size, and also whether two consecutive buckets
680 * falls within same quanta.
682 lstQnSize = cfg->bktQnSize;
685 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
687 /* check if bucket size is mutiple of quantum size */
688 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
690 /* cm_mem_c_001.main_20 Addition */
691 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
693 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
694 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
696 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
697 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
703 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
706 * Two consecutive buckets are not separated by quantum size.
708 /* cm_mem_c_001.main_20 Addition */
709 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
713 /* cm_mem_c_001.main_20 Addition */
714 if (((cfg->bktCfg[bktIdx].size) /\
715 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
717 /* Error check whether the size of the mapping table is sufficient */
718 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
720 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
721 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
723 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
724 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
731 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
732 cfg->bktCfg[bktIdx].numBlks);
734 if (regCb->bktSize > cfg->size)
736 /* Size of the memory region is less than the required size */
738 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
743 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
748 /* Initialize the region control block */
749 regCb->region = region;
750 regCb->regInfo.regCb = regCb;
751 regCb->regInfo.start = cfg->vAddr;
752 regCb->regInfo.size = cfg->size;
755 avail_size = cfg->size;
756 #endif /* USE_PURE */
758 if ( cfg->chFlag & CMM_REG_OUTBOARD)
760 /* Out_of_board memory */
761 regCb->regInfo.flags = CMM_REG_OUTBOARD;
765 regCb->regInfo.flags = 0;
770 if(region == SS_MAX_REGS - 1)
772 regCb->regInfo.alloc = cmAlloc;
773 regCb->regInfo.free = cmFree;
774 regCb->regInfo.ctl = cmCtl;
778 regCb->regInfo.alloc = cmAllocWL;
779 regCb->regInfo.free = cmFreeWL;
780 regCb->regInfo.ctl = cmCtl;
783 regCb->regInfo.alloc = cmAlloc;
784 regCb->regInfo.free = cmFree;
785 regCb->regInfo.ctl = cmCtl;
788 /* Initialize the physical address */
789 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
791 regCb->pAddr = cfg->pAddr;
794 /* Initial address of the memory region block */
795 memAddr = cfg->vAddr;
797 /* Initialize the fields related to the bucket pool */
798 regCb->bktMaxBlkSize = 0;
803 /* Last bucket has the maximum size */
804 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
806 /* Get the power of the bktQnSize */
808 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
813 /* Initilaize the bktIndex of the map entries to FF */
814 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
816 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
820 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
822 /* Allocate the lock for the bucket pool */
823 cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
826 /* Used while freeing the bktLock in cmMmRegDeInit */
827 regCb->numBkts = cfg->numBkts;
831 * Initialize the heap pool if size the memory region region is more
832 * than the size of the bucket pool
835 regCb->heapFlag = FALSE;
837 /* Align the memory address */
838 memAddr = (Data *)(PTRALIGN(memAddr));
840 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
843 * Round the heap size so that the heap size is multiple
846 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
850 /* Allocate the lock for the heap pool */
851 regCb->heapFlag = TRUE;
852 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
855 /* Call SRegRegion to register the memory region with SSI */
856 if (SRegRegion(region, ®Cb->regInfo) != ROK)
862 } /* end of cmMmRegInit*/
867 * Fun: ssPutDynBufSet
869 * Desc: Puts the set of dynamic buffers into the global region
872 * Ret: ROK - successful,
873 * RFAILED - unsuccessful.
881 PUBLIC S16 ssPutDynBufSet
884 CmMmBktLstCb *bktLstCb
887 PUBLIC S16 ssPutDynBufSet(bktIdx, bktLstCb)
889 CmMmBktLstCb *bktLstCb;
892 CmMmGlobRegCb *globReg;
895 TRC1(ssPutDynBufSet);
897 globReg = &osCp.globRegCb;
899 if(bktIdx > CMM_MAX_BKT_ENT)
904 bktCb = &(globReg->bktTbl[bktIdx]);
906 /* Lock the global region first */
907 SLock(&(globReg->regLock));
909 cmLListAdd2Tail(&(bktCb->listBktSet), bktLstCb);
911 SUnlock(&(globReg->regLock));
918 * Fun: ssGetDynBufSet
920 * Desc: Gets the set of dynamic buffers into the global region
923 * Ret: ROK - successful,
924 * RFAILED - unsuccessful.
932 PUBLIC S16 ssGetDynBufSet
935 CmMmBktLstCb **bktLstCb
938 PUBLIC S16 ssGetDynBufSet(bktIdx, bktLstCb)
940 CmMmBktLstCb **bktLstCb;
943 CmMmGlobRegCb *globReg;
947 TRC1(ssGetDynBufSet);
949 globReg = &osCp.globRegCb;
951 if(bktIdx > CMM_MAX_BKT_ENT)
957 bktCb = &(globReg->bktTbl[bktIdx]);
959 /* Lock the global region first */
960 SLock(&(globReg->regLock));
962 lstNode = cmLListFirst(&(bktCb->listBktSet));
966 SUnlock(&(globReg->regLock));
970 cmLListDelFrm(&(bktCb->listBktSet), lstNode);
971 SUnlock(&(globReg->regLock));
973 *bktLstCb = (CmMmBktLstCb *)lstNode->node;
982 * Fun: cmMmGlobRegInit
984 * Desc: Configure the memory region for allocation. The function
985 * registers the memory region with System Service by calling
989 * Ret: ROK - successful,
990 * RFAILED - unsuccessful.
998 PUBLIC S16 cmMmGlobRegInit
1000 CmMmGlobRegCb *regCb
1003 PUBLIC S16 cmMmGlobRegInit(regCb)
1004 CmMmGlobRegCb *regCb;
1013 CmMmBlkSetElement *blkLstElem;
1016 #if (ERRCLASS & ERRCLS_INT_PAR)
1019 Txt errMsg[256] = {'\0'};
1022 TRC2(cmMmGlobRegInit);
1024 #ifdef SS_MEM_WL_DEBUG
1025 if (cmInitBtInfo() == RFAILED)
1030 for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
1032 /* Initial address of the memory region block */
1033 memAddr = ®Cb->bktTbl[bktIdx].startAddr;
1034 bucketSetSize = regCb->bktTbl[bktIdx].bucketSetSize;
1035 size = regCb->bktTbl[bktIdx].size;
1037 /* Initialize the bucket linked list */
1038 cmLListInit(®Cb->bktTbl[bktIdx].listValidBktSet);
1039 cmLListInit(®Cb->bktTbl[bktIdx].listFreeBktSet);
1040 SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
1042 /* Initialize the link list of the memory block */
1043 next = &(regCb->bktTbl[bktIdx].next);
1045 numBlks = regCb->bktTbl[bktIdx].numBlks;
1046 for (cnt = 1; cnt <= numBlks; cnt++)
1049 next = (CmMmEntry **)(*memAddr);
1050 *memAddr = (*memAddr) + size;
1052 /* Maintain the list Cb */
1053 if(!(cnt % bucketSetSize))
1055 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1056 blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
1057 blkLstElem->numFreeBlks = bucketSetSize;
1058 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1059 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
1060 next = &(regCb->bktTbl[bktIdx].next);
1067 } /* end of cmMmGlobRegInit*/
1069 #ifdef SS_USE_ICC_MEMORY
1072 * Fun: cmIccAllocWithLock
1074 * Desc: Allocate a memory block for use by dynamic buffers.
1075 * This handler uses the lock to avoid the two thread
1076 * trying to allocate the memory at same time. This
1077 * handler must be used only for non-data plane thread
1078 * it causes delay due to lock.
1081 * Ret: ROK - successful
1082 * RFAILED - unsuccessful.
1089 #ifdef T2K_MEM_LEAK_DBG
1091 PRIVATE S16 cmIccAllocWithLock
1093 Void *regionCb, /* Pointer to a region */
1094 Size *size, /* size needs to be allocated */
1095 U32 flags, /* Flags used */
1096 Data **ptr, /* Reference to pointer for which need to be allocate */
1103 PRIVATE S16 cmIccAllocWithLock
1105 Void *regionCb, /* Pointer to a region */
1106 Size *size, /* size needs to be allocated */
1107 U32 flags, /* Flags used */
1108 Data **ptr /* Reference to pointer for which need to be allocate */
1111 PRIVATE S16 cmIccAllocWithLock(regionCb, size, flags, ptr)
1112 Void *regionCb; /* Pointer to a region */
1113 Size *size; /* size needs to be allocated */
1114 U32 flags; /* Flags used */
1115 Data **ptr; /* Reference to pointer for which need to be allocate */
1119 CmMmDynRegCb *regCb;
1122 TRC2(cmIccAllocWithLock);
1124 regCb = (CmMmDynRegCb *)regionCb;
1126 if((SLock(&iccAllocFreeLock)) != ROK)
1128 printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
1132 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1134 if((SUnlock(&iccAllocFreeLock)) != ROK)
1136 printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
1140 if ((memPtr) == NULLP)
1143 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1144 printf("Exiting...\n");
1149 #ifdef T2K_MEM_LEAK_DBG
1150 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1152 printf("Address returned is %p size = %ld\n",memPtr,*size);
1155 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1161 } /* end of cmIccAllocWithLock */
1165 * Fun: cmIccFreeWithLock
1167 * Desc: Return the Dynamic memory block for the memory region.
1168 * This handler uses the lock to avoid the two thread
1169 * trying to free the memory at same time. This
1170 * handler must be used only for non-data plane thread
1171 * it causes delay due to lock.
1173 * Ret: ROK - successful
1174 * RFAILED - unsuccessful.
1182 #ifdef T2K_MEM_LEAK_DBG
1184 PRIVATE S16 cmIccFreeWithLock
1186 Void *regionCb, /* Pointer to region cb */
1187 Data *ptr, /* Memory block needs to be freed */
1188 Size size, /* Size of the block */
1195 PRIVATE S16 cmIccFreeWithLock
1197 Void *regionCb, /* Pointer to region cb */
1198 Data *ptr, /* Memory block needs to be freed */
1199 Size size /* Size of the block */
1202 PRIVATE S16 cmIccFreeWithLock(regionCb, ptr, size)
1203 Void *regionCb; /* Pointer to region cb */
1204 Data *ptr; /* Memory block needs to be freed */
1205 Size size; /* Size of the block */
1209 CmMmDynRegCb *regCb;
1211 TRC2(cmIccFreeWithLock);
1213 regCb = (CmMmDynRegCb *)regionCb;
1215 if((SLock(&iccAllocFreeLock)) != ROK)
1217 printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
1221 #ifdef T2K_MEM_LEAK_DBG
1222 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1225 TL_Free(regCb->iccHdl, ptr);
1227 if((SUnlock(&iccAllocFreeLock)) != ROK)
1229 printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1234 } /* end of cmIccFree */
1240 * Desc: Allocate a memory block for use by dynamic buffers
1243 * Ret: ROK - successful
1244 * RFAILED - unsuccessful.
1251 #ifdef T2K_MEM_LEAK_DBG
1253 PRIVATE S16 cmIccAlloc
1255 Void *regionCb, /* Pointer to a region */
1256 Size *size, /* size needs to be allocated */
1257 U32 flags, /* Flags used */
1258 Data **ptr, /* Reference to pointer for which need to be allocate */
1266 PRIVATE S16 cmIccAlloc
1268 Void *regionCb, /* Pointer to a region */
1269 Size *size, /* size needs to be allocated */
1270 U32 flags, /* Flags used */
1271 Data **ptr /* Reference to pointer for which need to be allocate */
1274 PRIVATE S16 cmIccAlloc(regionCb, size, flags, ptr)
1275 Void *regionCb; /* Pointer to a region */
1276 Size *size; /* size needs to be allocated */
1277 U32 flags; /* Flags used */
1278 Data **ptr; /* Reference to pointer for which need to be allocate */
1283 CmMmDynRegCb *regCb;
1288 regCb = (CmMmDynRegCb *)regionCb;
1290 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1292 if ((memPtr) == NULLP)
1295 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1296 printf("Exiting...\n");
1300 #ifdef T2K_MEM_LEAK_DBG
1301 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1303 printf("Address returned is %p size = %ld\n",memPtr,*size);
1306 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1309 *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1311 *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1316 } /* end of cmIccAlloc */
1322 * Desc: Return the Dynamic memory block for the memory region.
1325 * Ret: ROK - successful
1326 * RFAILED - unsuccessful.
1334 #ifdef T2K_MEM_LEAK_DBG
1335 PRIVATE S16 cmIccFree
1337 Void *regionCb, /* Pointer to region cb */
1338 Data *ptr, /* Memory block needs to be freed */
1339 Size size, /* Size of the block */
1345 PRIVATE S16 cmIccFree
1347 Void *regionCb, /* Pointer to region cb */
1348 Data *ptr, /* Memory block needs to be freed */
1349 Size size /* Size of the block */
1352 PRIVATE S16 cmIccFree(regionCb, ptr, size)
1353 Void *regionCb; /* Pointer to region cb */
1354 Data *ptr; /* Memory block needs to be freed */
1355 Size size; /* Size of the block */
1359 CmMmDynRegCb *regCb;
1362 regCb = (CmMmDynRegCb *)regionCb;
1365 // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1367 #ifdef T2K_MEM_LEAK_DBG
1368 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1372 TL_Free(regCb->iccHdl, ptr);
1374 /* memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1376 TL_Free(regCb->iccHdl, memPtr);
1378 /*TL_Free(regCb->iccHdl, ptr);*/
1382 printf("FREE -ICC Addr Before PA2VA %x After PA2VA %x\n", memPtr, ptr);
1387 } /* end of cmIccFree */
1391 * Fun: cmMmDynRegInit
1393 * Desc: Configure the memory region for allocation. The function
1394 * registers the memory region with System Service by calling
1398 * Ret: ROK - successful,
1399 * RFAILED - unsuccessful.
1401 * Notes: The memory owner calls this function to initialize the memory
1402 * manager with the information of the memory region. Before
1403 * calling this function, the memory owner should allocate memory
1404 * for the memory region. The memory owner should also provide the
1405 * memory for the control block needed by the memory manager. The
1406 * memory owner should allocate the memory for the region control
1407 * block as cachable memory. This may increase the average
1408 * throughput in allocation and deallocation as the region control
1409 * block is mostly accessed by the CMM.
1415 PUBLIC S16 cmMmDynRegInit
1420 PUBLIC S16 cmMmDynRegInit(regCb)
1421 CmMmDynRegCb *regCb;
1425 #ifdef T2200_2GB_DDR_CHANGES
1426 Txt regIccStr[10] = {'\0'};
1428 Txt regIccStr[64] = {'\0'};
1431 TRC2(cmMmDynRegInit);
1433 /* Register the region/memory with ICC and get the handler for same. The id is starting
1434 * from region+1 as the zero is used by PHY code */
1435 #ifdef T2200_2GB_DDR_CHANGES
1436 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1439 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1441 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1443 // snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1445 if(clusterMode == RADIO_CLUSTER_MODE)
1447 if(regCb->region == 3)
1448 {/* ICC packet receiver */
1449 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1452 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1453 //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1457 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1458 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1459 //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1462 #ifdef T2200_2GB_DDR_CHANGES
1463 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1465 sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1470 printf(" %s \n",regIccStr);
1471 regCb->iccHdl = TL_Open(regIccStr, 0);
1473 printf("\nICC Region is %d\n",regCb->region);
1475 /* Call SRegRegion to register the memory region with SSI */
1476 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1478 /* Register the lock region for SS_MAX_REGS - 1 region */
1479 if((SS_MAX_REGS - 1) == regCb->region)
1481 regInfo.alloc = cmIccAllocWithLock;
1482 regInfo.free = cmIccFreeWithLock;
1483 regInfo.regCb = regCb;
1484 if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1486 printf("Failed to initialize the lock region lock\n");
1491 regInfo.alloc = cmIccAlloc;
1492 regInfo.free = cmIccFree;
1493 regInfo.regCb = regCb;
1496 if (SRegDynRegion(regCb->region, ®Info) != ROK)
1502 } /* end of cmMmDynRegInit*/
1504 #else /* SS_USE_ICC_MEMORY */
1508 * Fun: cmMmDynRegInit
1510 * Desc: Configure the memory region for allocation. The function
1511 * registers the memory region with System Service by calling
1515 * Ret: ROK - successful,
1516 * RFAILED - unsuccessful.
1518 * Notes: The memory owner calls this function to initialize the memory
1519 * manager with the information of the memory region. Before
1520 * calling this function, the memory owner should allocate memory
1521 * for the memory region. The memory owner should also provide the
1522 * memory for the control block needed by the memory manager. The
1523 * memory owner should allocate the memory for the region control
1524 * block as cachable memory. This may increase the average
1525 * throughput in allocation and deallocation as the region control
1526 * block is mostly accessed by the CMM.
1532 PUBLIC S16 cmMmDynRegInit
1537 PUBLIC S16 cmMmDynRegInit(regCb)
1538 CmMmDynRegCb *regCb;
1545 CmMmBlkSetElement *blkLstElem;
1547 Size bktQnSize = MT_BKTQNSIZE;
1552 TRC2(cmMmDynRegInit);
1554 /* Initialize the region control block */
1555 region = regCb->region;
1556 numBkts = regCb->numBkts;
1558 /* Initilaize the bktIndex of the map entries to FF */
1559 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1561 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1566 for(cnt = 0; cnt < numBkts; cnt++)
1568 /* Initialize the Map entry */
1569 size = regCb->bktTbl[cnt].size;
1570 idx = size / bktQnSize;
1573 * Check if the size is multiple of quantum size. If not we need to initialize
1574 * one more map table entry.
1576 if(size % bktQnSize)
1581 while ( lstMapIdx < idx)
1583 regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1588 regCb->bktQnPwr = 0;
1590 while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1595 /* Initialize the bucket structure */
1597 regCb->bktTbl[bktIdx].numAlloc = 0;
1598 regCb->bktTbl[bktIdx].maxAlloc = 0;
1600 /* Update the total bucket size */
1601 regCb->bktSize += (regCb->bktTbl[bktIdx].size * regCb->bktTbl[bktIdx].numBkt);
1603 regCb->bktTbl[bktIdx].bktFailCnt = 0;
1604 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
1606 if(regCb->bktMaxBlkSize < regCb->bktTbl[bktIdx].size)
1608 regCb->bktMaxBlkSize = regCb->bktTbl[bktIdx].size;
1612 for(idx = 0; idx < numBkts; idx++)
1614 regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1616 for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1618 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1619 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1620 cmLListAdd2Tail((®Cb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1624 /* Call SRegRegion to register the memory region with SSI */
1625 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1627 if((SS_MAX_REGS - 1) == regCb->region)
1629 regInfo.alloc = cmDynAllocWithLock;
1630 regInfo.free = cmDynFreeWithLock;
1631 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1633 printf("Failed to initialize the lock region lock\n");
1640 static dynLockCreated;
1641 regInfo.alloc = cmDynAllocWithLock;
1642 regInfo.free = cmDynFreeWithLock;
1643 if ( dynLockCreated == 0)
1645 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1647 printf("Failed to initialize the lock region lock\n");
1654 regInfo.alloc = cmDynAlloc;
1655 regInfo.free = cmDynFree;
1659 regInfo.regCb = regCb;
1661 if (SRegDynRegion(region, ®Info) != ROK)
1667 } /* end of cmMmDynRegInit*/
1669 #endif /* SS_USE_ICC_MEMORY */
1674 * Fun: cmMmRegDeInit
1676 * Desc: Deinitialize the memory region. The function call SDeregRegion
1677 * to deregister the memory region with System Service.
1680 * Ret: ROK - successful
1681 * RFAILED - unsuccessful.
1683 * Notes: The memory owner calls this function to deinitialize the region.
1684 * The memory manager does not return the memory to the system.
1685 * Before calling this function, the memory owner must be sure that
1686 * no layer is using any memory block from this region. On
1687 * successful return from the function, any request to the memory
1688 * manager to allocate/deallocate memory will fail. The memory owner
1689 * can reuse the memory for other region or return the memory to the
1690 * system memory pool.
1698 PUBLIC S16 cmMmRegDeInit
1703 PUBLIC S16 cmMmRegDeInit(regCb)
1709 TRC2(cmMmRegDeInit);
1711 #if (ERRCLASS & ERRCLS_INT_PAR)
1713 /* error check on parameters */
1721 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1722 #ifdef SSI_DEBUG_LEVEL1
1723 /* Deinitialize the hash table used for debug info storage at region level */
1724 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
1728 #endif /* SSI_DEBUG_LEVEL1 */
1730 /* Call SDeregRegion first to deregister the memory region with SSI */
1731 (Void) SDeregRegion (regCb->region);
1735 /* Bucket pool is configured */
1737 /* Free the initialzed locks of the buckets */
1738 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1740 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1741 WTDestroyLock for NT */
1742 /* cm_mem_c_001.main_24 fix for memory corruption*/
1745 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1747 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1749 /* cm_mem_c_001.main_15:Additions */
1750 #ifdef SS_HISTOGRAM_SUPPORT
1751 /* De-initialise the memory histogram hash list */
1752 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1753 #endif /* SS_HISTOGRAM_SUPPORT */
1757 if (regCb->heapFlag)
1759 /* Heap pool is configured */
1761 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1762 WTDestroyLock for NT */
1764 WTDestroyLock(®Cb->heapCb.heapLock);
1766 SDestroyLock(®Cb->heapCb.heapLock);
1772 } /* end of cmMmRegDeInit */
1775 #ifndef SS_USE_ICC_MEMORY
1778 * Fun: cmGetMemBlkSetForAlloc
1780 * Desc: Retruns the pointer to the element which is used for
1781 * allocating the buffer. Also, it does the threshold check
1782 * and get the additional memory block set from the global
1786 * Ret: Pointer to memory block set - successful
1787 * NULL - unsuccessful.
1790 * Current implementation of the is function is made assuming that
1791 * there will maximum two set of nodes only.
1798 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1800 U8 bucketIndex, /* Index to the bucket list */
1801 CmMmDynBktCb *bkt /* Bucket list control block */
1804 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc(bucketIndex, bkt)
1805 U8 bucketIndex; /* Index to the bucket list */
1806 CmMmDynBktCb *bkt; /* Bucket list control block */
1809 CmMmBlkSetElement *memBlkSetElem;
1810 CmMmBlkSetElement *nextMemBlkSetElem;
1811 CmLList *memSetNode;
1812 CmLList *nextMemSetNode;
1814 /* Check if we are coming here for the first time, if yes get a new
1815 * block set from global region */
1816 if(bkt->crntMemBlkSetElem == NULLP)
1818 /* set the current index to initial one and get the bucket set from
1820 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1822 /* Check if the element exits or not */
1823 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1828 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1829 /* Get the new block set from the gloabl region and return the same */
1830 ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1831 RETVALUE(bkt->crntMemBlkSetElem);
1833 /* If this is not the first time, take the bucket list CB from the
1835 memBlkSetElem = bkt->crntMemBlkSetElem;
1836 /* If the current index doesnot have any free buckets, it check in
1837 * the next bucket node */
1838 if(memBlkSetElem->numFreeBlks == 0)
1840 /* Get the next element in the list and if it is not present, then
1841 * get the first node */
1842 memSetNode = cmLListNext(&bkt->memBlkSetElem);
1844 if(memSetNode == NULLP)
1846 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1848 memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1850 /* if next node also empty, return failure */
1851 if(memBlkSetElem->numFreeBlks == 0)
1855 /* store the new index in the current node which will be
1856 * used in the next time. */
1857 bkt->crntMemBlkSetElem = memBlkSetElem;
1861 if(memBlkSetElem->nextBktPtr == NULLP)
1863 ssGetDynMemBlkSet(bucketIndex, memBlkSetElem);
1866 /* If we have reached the threshold value, get the next set of buckets from
1867 * the global region and place it */
1868 if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1870 /* Get the next element for the threshold check. If next is not present,
1871 * get the first one. Here, we are not using the cmLList macros to get
1872 * to the next node or first node as those macros are working on the crnt
1873 * node and will change the crnt. As we dont want to change the crnt node
1874 * at this point, we are directly using the listCp prameter to get next
1876 nextMemSetNode = memBlkSetElem->memSetNode.next;
1878 if(nextMemSetNode == NULLP)
1880 nextMemSetNode = bkt->memBlkSetElem.first;
1883 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1885 if(nextMemBlkSetElem->numFreeBlks == 0)
1887 /* The last parameter is used wheather to block for the block set aquiring
1888 or not. Here, the logic is such that, when the current node number of
1889 free blocks becomes one and the next node has zero free blocks,
1890 we must get the block set from global region.
1891 For example, if acquire threashold is 20 and current node has only one
1892 free block and next node has zero free blocks we block to aquire lock
1893 and get the set from global region else, we try for lock, if we get
1894 the lock, the get the block set else it is get in next go
1896 ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1897 (memBlkSetElem->numFreeBlks - 1));
1901 /* On successful, return the bucket node to calling function */
1902 RETVALUE(memBlkSetElem);
1903 } /* cmGetMemBlkSetForAlloc */
1908 * Fun: cmGetMemBlkSetForFree
1910 * Desc: Retruns the pointer to the element which is used for
1911 * freeing the buffer. Also, it does the threshold check
1912 * and release the additional memory block set to the global
1916 * Ret: Pointer to memory block set - successful
1917 * NULL - unsuccessful.
1920 * Current implementation of the is function is made assuming that
1921 * there will maximum two set of nodes only.
1928 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree
1930 U8 bucketIndex, /* Index to the bucket list */
1931 CmMmDynBktCb *bkt /* Bucket list control block */
1934 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree(bucketIndex, bkt)
1935 U8 bucketIndex; /* Index to the bucket list */
1936 CmMmDynBktCb *bkt; /* Bucket list control block */
1939 CmMmBlkSetElement *memBlkSetElem;
1940 CmMmBlkSetElement *nextMemBlkSetElem;
1941 CmLList *memSetNode;
1942 CmLList *nextMemSetNode;
1944 /* Check if we are coming here for the first time, if yes get a new
1945 * block set from global region */
1946 if(bkt->crntMemBlkSetElem == NULLP)
1948 /* set the current index to initial one */
1949 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1951 /* Check if the element exits or not */
1952 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1956 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1957 RETVALUE(bkt->crntMemBlkSetElem);
1959 /* If this is not the first time, take the bucket list CB from the
1961 memBlkSetElem = bkt->crntMemBlkSetElem;
1962 /* If the current index doesnot have any free buckets, it check in
1963 * the next bucket node */
1964 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1966 /* Get the next element in the list and if it is not present, then
1967 * get the first node */
1968 nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1970 if(nextMemSetNode == NULLP)
1972 nextMemSetNode = cmLListFirst(&bkt->memBlkSetElem);
1974 memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1976 /* if next node also empty, return failure */
1977 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1981 /* store the new index in the current node which will be
1982 * used in the next time. */
1983 bkt->crntMemBlkSetElem = memBlkSetElem;
1986 /* If we have reached the threshold value and have additional block set,
1987 * release the additional block set back to global region */
1988 if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold)
1990 /* Get the next element for the threshold check. If next is not present,
1991 * get the first one. Here, we are not using the cmLList macros to get
1992 * to the next node or first node as those macros are working on the crnt
1993 * node and will change the crnt. As we dont want to change the crnt node
1994 * at this point, we are directly using the listCp prameter to get next
1996 nextMemSetNode = memBlkSetElem->memSetNode.next;
1997 if(nextMemSetNode == NULLP)
1999 nextMemSetNode = bkt->memBlkSetElem.first;
2002 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
2003 if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
2005 /* The last parameter is used wheather to block for the block set aquiring
2006 or not. Here, the logic is such that, when the current node number of
2007 free blocks becomes one less than the bucket set size and the next node
2008 is has full free blocks, we must free the block set back to global region
2009 For example, if bucket set size if 100 and release threashold is 80 and
2010 current node has number of free blocks 99 and next node has 100 free blocks
2011 we block to aquire lock and free it back to global region else, we try for
2012 lock, if we get the lock, the block set is freed else its freed in next go
2014 ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
2015 (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
2017 nextMemBlkSetElem->numFreeBlks = 0;
2018 nextMemBlkSetElem->nextBktPtr = NULLP;
2023 /* On successful, return the bucket node to calling function */
2024 RETVALUE(memBlkSetElem);
2026 #endif /* SS_USE_ICC_MEMORY */
2027 #endif /* USE_PURE */
2029 #ifdef SS_MEM_WL_DEBUG
2032 * Fun: cmRemoveAllocPtrFromList
2034 * Desc: Remove a node with Free PTR from hashlist. The memory
2035 * of the node is Freed to the same region
2038 * Ret: ROK - successful
2039 * RFAILED - unsuccessful.
2048 PRIVATE S16 cmRemoveAllocPtrFromList
2050 CmMmDynRegCb *regionCb, /* Pointer to a region */
2054 PRIVATE S16 cmRemoveAllocPtrFromList(regionCb, ptr)
2055 CmMmDynRegCb *regionCb; /* Pointer to a region */
2060 CmMemDoubleFree *memNode = NULLP;
2062 SLock(&memDoubleFreeLock);
2063 if((cmHashListFind(&(memDoubleFree), (U8*)&ptr,
2064 sizeof(U32), 0, (PTR *)&memNode)) != ROK)
2071 tmpBtSize = backtrace(tmpBtArr, 10);
2072 strings = backtrace_symbols(tmpBtArr, tmpBtSize);
2073 printf("**** Trying to free non allocated block BT is: \n");
2074 for(idx = 0; idx < tmpBtSize; idx++)
2076 printf("%s\n", strings[idx]);
2078 printf("*****************************************\n");
2079 printf("Analysis from Array storing BT for freeing and allocation\n");
2080 cmAnalyseBtInfo(ptr, regionCb->region);
2081 SUnlock(&memDoubleFreeLock);
2085 if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
2087 SUnlock(&memDoubleFreeLock);
2090 SUnlock(&memDoubleFreeLock);
2091 SPutSBuf(regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
2098 * Fun: cmInsertAllocPtrToList
2100 * Desc: Insert a node with allocated PTR into hashlist. The memory
2101 * for the node is allocated from the same region
2104 * Ret: ROK - successful
2105 * RFAILED - unsuccessful.
2114 PRIVATE S16 cmInsertAllocPtrToList
2116 CmMmDynRegCb *regionCb, /* Pointer to a region */
2120 PRIVATE S16 cmInsertAllocPtrToList(regionCb, ptr)
2121 CmMmDynRegCb *regionCb; /* Pointer to a region */
2126 CmMemDoubleFree *memNode;
2128 SGetSBuf(regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
2129 if(memNode == NULLP)
2134 memNode->memBlkPtr = ptr;
2135 SLock(&memDoubleFreeLock);
2136 if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (U8*)&memNode->memBlkPtr,
2137 sizeof(PTR))) != ROK)
2139 SUnlock(&memDoubleFreeLock);
2142 SUnlock(&memDoubleFreeLock);
2149 #ifndef SS_USE_ICC_MEMORY
2152 * Fun: cmDynAllocWithLock
2154 * Desc: Allocate a memory block for use by dynamic buffers
2157 * Ret: ROK - successful
2158 * RFAILED - unsuccessful.
2165 /* cm_mem_c_001.main_15 : Additions */
2168 PRIVATE S16 cmDynAllocWithLock
2170 Void *regionCb, /* Pointer to a region */
2171 Size *size, /* size needs to be allocated */
2172 U32 flags, /* Flags used */
2173 Data **ptr /* Reference to pointer for which need to be allocate */
2176 PRIVATE S16 cmDynAllocWithLock(regionCb, size, flags, ptr)
2177 Void *regionCb; /* Pointer to a region */
2178 Size *size; /* size needs to be allocated */
2179 U32 flags; /* Flags used */
2180 Data **ptr; /* Reference to pointer for which need to be allocate */
2187 if((SLock(&dynAllocFreeLock)) != ROK)
2189 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
2193 ret = cmDynAlloc (regionCb, size,flags,ptr);
2195 if((SUnlock(&dynAllocFreeLock)) != ROK)
2197 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
2202 } /* end of cmDynAlloc */
2208 * Desc: Allocate a memory block for use by dynamic buffers
2211 * Ret: ROK - successful
2212 * RFAILED - unsuccessful.
2219 /* cm_mem_c_001.main_15 : Additions */
2222 PRIVATE S16 cmDynAlloc
2224 Void *regionCb, /* Pointer to a region */
2225 Size *size, /* size needs to be allocated */
2226 U32 flags, /* Flags used */
2227 Data **ptr /* Reference to pointer for which need to be allocate */
2230 PRIVATE S16 cmDynAlloc(regionCb, size, flags, ptr)
2231 Void *regionCb; /* Pointer to a region */
2232 Size *size; /* size needs to be allocated */
2233 U32 flags; /* Flags used */
2234 Data **ptr; /* Reference to pointer for which need to be allocate */
2237 CmMmDynRegCb *regCb;
2241 regCb = (CmMmDynRegCb *)regionCb;
2243 #ifdef SS_MEM_WL_DEBUG
2244 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
2250 #if (ERRCLASS & ERRCLS_INT_PAR)
2252 /* error check on parameters */
2253 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2262 * Check if the requested size is less than or equal to the maximum block
2263 * size in the bucket.
2266 #ifdef SS_MEM_WL_DEBUG
2267 if ( (*size + 4) <= regCb->bktMaxBlkSize)
2269 if ( (*size) <= regCb->bktMaxBlkSize)
2273 CmMmBlkSetElement *dynMemElem;
2277 /* Get the map to the mapping table */
2278 #ifdef SS_MEM_WL_DEBUG
2279 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
2281 idx = (((*size) - 1) >> regCb->bktQnPwr);
2284 #if (ERRCLASS & ERRCLS_DEBUG)
2285 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2287 printf("Failed to get the buffer of size %d\n", *size);
2288 /* Some fatal error in the map table initialization. */
2296 /* Dequeue the memory block and return it to the user */
2297 bktIdx = regCb->mapTbl[idx].bktIdx;
2298 bkt = &(regCb->bktTbl[bktIdx]);
2299 #ifdef SS_MEM_WL_DEBUG
2300 if(bkt->size < (*size+4))
2302 if(bkt->size < (*size))
2306 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2309 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
2311 /* Check if the bucket index, if its not valid, return failure */
2312 if(dynMemElem == NULLP)
2315 printf("Failed to get the buffer of size %ld\n", *size);
2317 printf("Failed to get the buffer of size %d\n", *size);
2322 #ifdef SS_MEM_WL_DEBUG
2323 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
2329 /* Get the bucket node from the index returned and allocate the memory */
2330 *ptr = dynMemElem->nextBktPtr;
2335 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
2336 dynMemElem->numFreeBlks--;
2338 #ifdef SS_MEM_WL_DEBUG
2339 prvAllocPtr[regCb->region] = *ptr;
2341 if(regCb->region == 6)
2342 printf("cmDynAlloc: PTR = %x\n", *ptr);
2343 **ptr = (U32) ((bktIdx << 4) | 0x0f);
2346 **ptr = (U8) bktIdx;
2350 *ptr += sizeof (U32);
2352 if ((bktIdx == 0) && (!stopBtInfo))
2356 btInfo = &allocBtInfo[regCb->region];
2357 btIdx = btInfo->btInfoIdx;
2358 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2360 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2362 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2364 cmInsertAllocPtrToList(regCb, (PTR)*ptr);
2368 btIdx &= (NUM_FREE_BUFFERS - 1);
2370 btInfo->btInfo[btIdx].ptr = (PTR)0;
2371 btInfo->btInfo[btIdx].btSize = 0;
2372 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2373 btInfo->btInfoIdx = btIdx;
2380 /* If the size is not matching, return failure to caller */
2382 printf("Failed to get the buffer of size %ld\n", *size);
2384 printf("Failed to get the buffer of size %d\n", *size);
2388 #else /* use pure is on */
2390 #ifdef SS_4GMX_LCORE
2391 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2392 cmMemset((U8*)ptr, 0, *size);
2394 /* *ptr = (Data*) malloc(*size); */
2396 *ptr = (Data *)malloc(*size);
2398 if ( (*ptr) == NULLP)
2400 /* avail_size -= *size; */
2402 #endif /* USE_PURE */
2404 } /* end of cmDynAlloc */
2405 #endif /* SS_USE_ICC_MEMORY */
2408 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2410 int g_overused[5] = {0};
2417 * Desc: Allocate a memory block for the memory region.
2420 * Ret: ROK - successful
2421 * RFAILED - unsuccessful.
2424 * The function allocates a memory block of size atleast equal to
2425 * the requested size. The size parameter will be updated with the
2426 * actual size of the memory block allocated for the request. The
2427 * CMM tries to allocate the memory block form the bucket pool. If
2428 * there is no memory in the bucket the CMM allocates the memory
2429 * block form the heap pool. This function is always called by the
2430 * System Service module.
2432 * The caller of the function should try to use the out value of
2433 * the size while returning the memory block to the region. However
2434 * the current design of the memory manager does not enforce to pass
2435 * the actual size of the memory block. (Due to the SGetSBuf
2436 * semantics the layer will not able to pass the correct size of the
2437 * memory block while calling SPutSBuf).
2443 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2445 /* cm_mem_c_001.main_15 : Additions */
2446 #ifdef T2K_MEM_LEAK_DBG
2457 #ifdef SS_HISTOGRAM_SUPPORT
2458 #ifdef SSI_DEBUG_LEVEL1
2473 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType, line, fileName, entId, hstReg)
2498 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, line, fileName, entId, hstReg)
2508 #endif /* SSI_DEBUG_LEVEL1 */
2512 #ifdef SSI_DEBUG_LEVEL1
2523 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType)
2540 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr)
2548 #endif /* SSI_DEBUG_LEVEL1 */
2549 /* cm_mem_c_001.main_15: Additions */
2550 #endif /* SS_HISTOGRAM_SUPPORT */
2553 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2560 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2564 /* cm_mem_c_001.main_15 : Additions */
2565 #ifdef SS_MEM_LEAK_STS
2567 #endif /* SS_MEM_LEAK_STS */
2568 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2569 #ifdef SSI_DEBUG_LEVEL1
2570 CmMmBlkHdr *alocBlk;
2571 #endif /* SSI_DEBUG_LEVEL1 */
2572 /* cm_mem_c_001.main_15 : Additions */
2573 #ifdef SS_HISTOGRAM_SUPPORT
2575 #endif /* SS_HISTOGRAM_SUPPORT */
2582 /* cm_mem_c_001.main_15 : Additions */
2583 #ifdef SS_MEM_LEAK_STS
2585 #endif /* SS_MEM_LEAK_STS */
2587 regCb = (CmMmRegCb *)regionCb;
2589 #if (ERRCLASS & ERRCLS_INT_PAR)
2591 /* error check on parameters */
2592 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2598 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2599 #ifdef SSI_DEBUG_LEVEL1
2600 #if (ERRCLASS & ERRCLS_INT_PAR)
2601 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2605 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2606 #endif /* SSI_DEBUG_LEVEL1 */
2613 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2614 #ifdef SSI_DEBUG_LEVEL1
2615 /* Update the hash list */
2616 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2618 /* display that, this entry could not be made in the hash list */
2620 /* display an error message here */
2621 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2623 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2624 *size, regCb->region);
2626 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2627 *size, regCb->region);
2629 SDisplay(0, dbgPrntBuf);
2632 #endif /* SSI_DEBUG_LEVEL1 */
2635 * Check if the requested size is less than or equal to the maximum block
2636 * size in the bucket.
2638 if ( *size <= regCb->bktMaxBlkSize)
2640 /* Get the map to the mapping table */
2641 idx = ((*size - 1) >> regCb->bktQnPwr);
2643 #if (ERRCLASS & ERRCLS_DEBUG)
2644 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2646 /* Some fatal error in the map table initialization. */
2651 /* Dequeue the memory block and return it to the user */
2652 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2655 /* While loop is introduced to use the "break statement inside */
2659 * Check if the size request is not greater than the size available
2662 if (*size > bkt->size)
2664 /* Try to go to the next bucket if available */
2665 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2666 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2668 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2672 /* This is the last bucket, try to allocate from heap */
2677 /* Acquire the bucket lock */
2678 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2680 (Void) WTLock(&(bkt->bktLock));
2682 (Void) SLock(&(bkt->bktLock));
2685 #if (ERRCLASS & ERRCLS_DEBUG)
2686 regCb->mapTbl[idx].numReq++;
2687 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2689 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2690 #ifdef SSI_DEBUG_LEVEL1
2691 /* increment the allocation attempt counter at bucket level */
2692 bkt->numAllocAttempts++;
2694 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2695 the allocation is always from (bkt->nextBlk) */
2698 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2700 /* detected a trampled memory block in this bucket */
2702 /* display an error message here */
2703 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2705 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2706 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2708 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2709 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2711 SDisplay(0, dbgPrntBuf);
2714 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2716 /* Release the lock */
2717 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2719 (Void) WTUnlock(&(bkt->bktLock));
2721 (Void) SUnlock(&(bkt->bktLock));
2723 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2724 RETVALUE(RTRAMPLINGNOK);
2728 /* Release the lock */
2729 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2731 (Void) WTUnlock(&(bkt->bktLock));
2733 (Void) SUnlock(&(bkt->bktLock));
2735 /* return RFAILED */
2741 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2743 if ((*ptr = bkt->next))
2744 #endif /* SSI_DEBUG_LEVEL1 */
2746 /* cm_mem_c_001.main_12 - addition for header */
2747 #ifdef SSI_DEBUG_LEVEL1
2748 /* point to next block header */
2749 alocBlk = bkt->nextBlk;
2750 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2752 bkt->next = *((CmMmEntry **)(bkt->next));
2753 #endif /* SSI_DEBUG_LEVEL1 */
2756 * Increment the statistics variable of number of memory block
2760 if (bkt->numAlloc > bkt->maxAlloc)
2762 bkt->maxAlloc = bkt->numAlloc;
2765 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2767 g_overused[bktIdx] = 1;
2768 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2772 if(bkt->numAlloc < 100)
2773 printf("cmAlloc: Allocated PTR = %x size = %d\n", *ptr, *size);
2776 /* cm_mem_c_001.main_12 - addition for header manipulation */
2777 #ifdef SSI_DEBUG_LEVEL1
2778 /* update the size for which this memory block has been allocated */
2779 alocBlk->requestedSize = *size;
2780 /* update the memory block header */
2781 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2782 if (memType == CMM_STATIC_MEM_FLAG)
2784 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2785 /* add it to the static memory allocated */
2786 bkt->staticMemUsed += bkt->size;
2790 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2791 /* add it to the dynamic memory allocated */
2792 bkt->dynamicMemUsed += bkt->size;
2794 #endif /* SSI_DEBUG_LEVEL1 */
2796 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2800 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2803 "[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++);
2806 "[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++);
2808 SDisplay(0, prntBuf);
2816 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2817 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2818 SDisplay(0, prntBuf);
2820 #endif /* MEMCAL_DEBUG */
2821 /* cm_mem_c_001.main_15 : Additions */
2822 #ifdef SS_HISTOGRAM_SUPPORT
2823 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2824 * information into the hash list */
2827 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2829 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2834 #endif /* SS_HISTOGRAM_SUPPORT */
2836 /* Update the size parameter */
2838 #ifdef SS_MEM_LEAK_STS
2839 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2840 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2841 regCb->mapTbl[idx].bktIdx);
2842 #endif /* SS_MEM_LEAK_STS */
2844 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2846 /* Release the lock */
2847 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2849 (Void) WTUnlock(&(bkt->bktLock));
2851 (Void) SUnlock(&(bkt->bktLock));
2860 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2863 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2866 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2868 SDisplay(0, prntBuf);
2872 #if (ERRCLASS & ERRCLS_DEBUG)
2873 regCb->mapTbl[idx].numFailure++;
2874 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2876 /* Release the lock */
2877 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2879 (Void) WTUnlock(&(bkt->bktLock));
2881 (Void) SUnlock(&(bkt->bktLock));
2890 regCb->heapCb.heapAllocCnt++;
2892 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2895 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2896 regCb->heapCb.heapAllocCnt);
2899 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2900 regCb->heapCb.heapAllocCnt);
2902 SDisplay(0, prntBuf);
2907 /* Memory not available in the bucket pool */
2908 if (regCb->heapFlag && (*size < regCb->heapSize))
2911 if (flags) tryHeap = 1;
2914 * The heap memory block is available. Allocate the memory block from
2917 /* cm_mem_c_001.main_15: Additions */
2918 #ifdef SS_HISTOGRAM_SUPPORT
2919 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2920 #ifdef SSI_DEBUG_LEVEL1
2921 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2923 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2924 #endif /* SSI_DEBUG_LEVEL1 */
2926 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2927 #ifdef SSI_DEBUG_LEVEL1
2928 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2930 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size));
2931 #endif /* SSI_DEBUG_LEVEL1 */
2932 #endif /* SS_HISTOGRAM_SUPPORT */
2935 /* No memory available */
2937 #else /* use pure is on */
2938 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2939 #ifdef SS_4GMX_LCORE
2940 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2941 cmMemset((U8*)ptr, 0, *size);
2943 *ptr = (Data*) malloc(*size);
2945 if ( (*ptr) == NULLP)
2947 avail_size -= *size;
2949 #endif /* USE_PURE */
2951 } /* end of cmAlloc */
2953 #ifdef SS_MEM_WL_DEBUG
2956 * Fun: cmInitDoubleFreeList
2958 * Desc: Initialize the hashlist used for detecting double free
2960 * Ret: ROK - successful
2961 * RFAILED - unsuccessful.
2970 PUBLIC S16 cmInitDoubleFreeList
2975 PUBLIC S16 cmInitDoubleFreeList()
2979 CmMemDoubleFree memNode;
2981 TRC2(cmInitDoubleFreeList);
2983 offset = (U16)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2985 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2986 CM_HASH_KEYTYPE_U32MOD, 0, 0)) != ROK);
2990 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2995 #ifdef SS_MEM_WL_DEBUG
3000 * Desc: Return the Dynamic memory block for the memory region.
3003 * Ret: ROK - successful
3004 * RFAILED - unsuccessful.
3013 PRIVATE S16 cmInitBtInfo
3017 PRIVATE S16 cmInitBtInfo (Void)
3020 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
3021 if (regBtInfo == NULLP)
3025 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
3026 if(allocBtInfo == NULLP)
3033 #endif /* SS_MEM_WL_DEBUG */
3036 * Fun: cmAnalyseBtInfo
3038 * Desc: Return the Dynamic memory block for the memory region.
3041 * Ret: ROK - successful
3042 * RFAILED - unsuccessful.
3051 PUBLIC Void cmAnalyseBtInfo
3053 PTR ptr, /* Memory block needs to be freed */
3057 PUBLIC Void cmAnalyseBtInfo (ptr,idx)
3058 PTR ptr; /* Memory block needs to be freed */
3068 for(regIdx = 0; regIdx < 8; regIdx++)
3070 btInfo = & regBtInfo[regIdx];
3071 btIdx = btInfo->btInfoIdx;
3073 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
3076 if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
3077 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr)
3080 if(btInfo->btInfo[btIdx].btSize != 0)
3084 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
3085 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);
3086 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
3088 printf("%s\n", strings[i]);
3090 printf("*******************************************************\n");
3098 btIdx = NUM_FREE_BUFFERS - 1;
3105 /* for(regIdx = 0; regIdx < 8; regIdx++)
3108 btInfo = &allocBtInfo[idx];
3109 btIdx = btInfo->btInfoIdx;
3111 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
3113 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
3114 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
3115 if(btInfo->btInfo[btIdx].btSize != 0)
3119 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
3120 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);
3121 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
3123 printf("%s\n", strings[i]);
3125 printf("*******************************************************\n");
3133 btIdx = NUM_FREE_BUFFERS - 1;
3142 #ifndef SS_USE_ICC_MEMORY
3145 * Fun: cmDynFreeWithLock
3147 * Desc: Return the Dynamic memory block for the memory region.
3150 * Ret: ROK - successful
3151 * RFAILED - unsuccessful.
3160 PRIVATE S16 cmDynFreeWithLock
3162 Void *regionCb, /* Pointer to region cb */
3163 Data *ptr, /* Memory block needs to be freed */
3164 Size size /* Size of the block */
3167 PRIVATE S16 cmDynFreeWithLock(regionCb, ptr, size)
3168 Void *regionCb; /* Pointer to region cb */
3169 Data *ptr; /* Memory block needs to be freed */
3170 Size size; /* Size of the block */
3175 if((SLock(&dynAllocFreeLock)) != ROK)
3177 printf("dynAllocWithLock: Failed to get the DYN lock\n");
3181 ret = cmDynFree(regionCb, ptr,size);
3183 if((SUnlock(&dynAllocFreeLock)) != ROK)
3185 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
3191 } /* end of cmDynFree */
3197 * Desc: Return the Dynamic memory block for the memory region.
3200 * Ret: ROK - successful
3201 * RFAILED - unsuccessful.
3210 PRIVATE S16 cmDynFree
3212 Void *regionCb, /* Pointer to region cb */
3213 Data *ptr, /* Memory block needs to be freed */
3214 Size size /* Size of the block */
3217 PRIVATE S16 cmDynFree(regionCb, ptr, size)
3218 Void *regionCb; /* Pointer to region cb */
3219 Data *ptr; /* Memory block needs to be freed */
3220 Size size; /* Size of the block */
3223 CmMmDynRegCb *regCb;
3227 CmMmDynBktCb *bkt = NULLP;
3228 CmMmBlkSetElement *dynMemElem;
3230 #ifdef SS_MEM_WL_DEBUG
3237 regCb = (CmMmDynRegCb *)regionCb;
3238 #ifdef SS_MEM_WL_DEBUG
3239 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3246 #if (ERRCLASS & ERRCLS_INT_PAR)
3247 /* error check on parameters */
3248 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3253 /* Check if the memory block is from the memory region */
3254 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3255 ((CmMmRegCb *)regCb)->regInfo.size)
3259 /* cm_mem_c_001.main_20 Addition */
3260 if (ptr < regCb->regInfo.start)
3267 #ifdef SS_MEM_WL_DEBUG
3268 ptr -= sizeof (U32);
3271 /* The memory block was allocated from the bucket pool */
3273 /* Get the map to the mapping table */
3274 idx = ((size - 1) >> regCb->bktQnPwr);
3276 #if (ERRCLASS & ERRCLS_DEBUG)
3277 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3279 /* Some fatal error in the map table initialization. */
3284 /* Enqueue the memory block and return it to the user */
3285 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3288 * Check if the size is not greater than the size available
3289 * in the bucket. If so, then the buffer must have been allocated
3290 * from next bucket. We don't need to check the validity of the
3291 * next bucket, otherwise buffer must have been allocated from heap
3294 #ifdef SS_MEM_WL_DEBUG
3295 if (size > bkt->size)
3297 printf("Size = %d bucket size = %d\n", size, bkt->size);
3299 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3301 if(size > bkt->size)
3303 printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
3306 printf("Bucket Size wrong \n");
3311 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
3313 /* Check if the bucket index, if its not valid, return failure */
3314 if(dynMemElem == NULLP)
3319 #ifdef SS_MEM_WL_DEBUG
3320 tmpBktIdx = (U8)*ptr;
3321 tmpVal = (U8)*(ptr+1);
3323 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
3326 printf("bktIdx wrong \n");
3330 if ((bktIdx == 0) && (!stopBtInfo))
3334 btInfo = ®BtInfo[regCb->region];
3335 btIdx = btInfo->btInfoIdx;
3336 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
3338 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
3341 cmRemoveAllocPtrFromList(regCb, (ptr + sizeof(U32)));
3343 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
3346 btIdx &= (NUM_FREE_BUFFERS - 1);
3348 btInfo->btInfo[btIdx].ptr = (PTR)0;
3349 btInfo->btInfo[btIdx].btSize = 0;
3350 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
3351 btInfo->btInfoIdx = btIdx;
3354 if(prvAllocPtr[regCb->region] == ptr)
3356 prvAllocPtr[regCb->region] = NULLP;
3359 cmMemset(ptr, (regCb->region+1), bkt->size);
3362 /* Get the bucket node from the index returned and allocate the memory */
3363 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
3364 dynMemElem->nextBktPtr = ptr;
3365 dynMemElem->numFreeBlks++;
3369 #else /* use pure is on */
3371 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3372 #ifdef SS_4GMX_LCORE
3373 (Void)MxHeapFree(SsiHeap, ptr);
3375 /* (Void)free(ptr); */
3377 /* avail_size += size; */
3381 #endif /* USE_PURE */
3384 } /* end of cmDynFree */
3385 #endif /* SS_USE_ICC_MEMORY */
3393 * Desc: Return the memory block for the memory region.
3396 * Ret: ROK - successful
3397 * RFAILED - unsuccessful.
3399 * Notes: The user calls this function to return the previously allocated
3400 * memory block to the memory region. The memory manager does not
3401 * check the validity of the state of the memory block(like whether
3402 * it was allocated earlier). The caller must be sure that, the
3403 * address specified in the parameter 'ptr' is valid and was
3404 * allocated previously from same region.
3411 /* cm_mem_c_001.main_15 : Additions */
3412 #ifdef T2K_MEM_LEAK_DBG
3422 #ifdef SS_HISTOGRAM_SUPPORT
3435 PRIVATE S16 cmFree(regionCb, ptr, size, line, fileName, entId, hstReg)
3455 PRIVATE S16 cmFree(regionCb, ptr, size)
3461 /* cm_mem_c_001.main_15 : Additions */
3462 #endif /* SS_HISTOGRAM_SUPPORT */
3465 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
3472 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3473 #ifdef SSI_DEBUG_LEVEL1
3475 #endif /* SSI_DEBUG_LEVEL1 */
3476 /* cm_mem_c_001.main_15 : Additions */
3477 #ifdef SS_HISTOGRAM_SUPPORT
3479 #endif /* SS_HISTOGRAM_SUPPORT */
3483 regCb = (CmMmRegCb *)regionCb;
3486 #if (ERRCLASS & ERRCLS_INT_PAR)
3488 /* error check on parameters */
3489 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3494 /* Check if the memory block is from the memory region */
3495 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3496 ((CmMmRegCb *)regCb)->regInfo.size)
3500 /* cm_mem_c_001.main_20 Addition */
3501 if (ptr < regCb->regInfo.start)
3509 * Check if the memory block was allocated from the bucket pool.
3511 if(ptr < regCb->regInfo.start)
3513 Buffer *tmpBuffer = NULLP;
3514 tmpBuffer->b_cont = NULLP;
3517 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3519 /* The memory block was allocated from the bucket pool */
3521 /* Get the map to the mapping table */
3522 idx = ((size - 1) >> regCb->bktQnPwr);
3524 #if (ERRCLASS & ERRCLS_DEBUG)
3525 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3527 /* Some fatal error in the map table initialization. */
3532 /* Enqueue the memory block and return it to the user */
3533 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3536 * Check if the size is not greater than the size available
3537 * in the bucket. If so, then the buffer must have been allocated
3538 * from next bucket. We don't need to check the validity of the
3539 * next bucket, otherwise buffer must have been allocated from heap
3542 if (size > bkt->size)
3544 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3547 /* Acquire the bucket lock */
3548 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3550 (Void) WTLock(&(bkt->bktLock));
3552 (Void) SLock(&(bkt->bktLock));
3555 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3556 #ifdef SSI_DEBUG_LEVEL1
3557 /* increment the dealloc attempt counter at bucket level */
3558 bkt->numDeallocAttempts++;
3560 /* Check the memFlags to see whether this block was allocated */
3561 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3563 /* validate the block to be freed for trampling */
3564 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3566 /* Handle error case of Memory trampling */
3568 /* display an error message here */
3569 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3571 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3572 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3574 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3575 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3577 SDisplay(0, dbgPrntBuf);
3580 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3581 * as the memory blk is already invalidated in cmMmBktSanityChk
3583 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3587 /* Release the lock */
3588 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3590 (Void) WTUnlock(&(bkt->bktLock));
3592 (Void) SUnlock(&(bkt->bktLock));
3600 * this is the case where in the entire bucket has been made unusable
3603 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3605 (Void) WTUnlock(&(bkt->bktLock));
3607 (Void) SUnlock(&(bkt->bktLock));
3610 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3611 RETVALUE(RTRAMPLINGNOK);
3615 /* reset the size */
3616 ptrHdr->requestedSize = 0;
3617 /* check if the block to be freed is already having the state as FREE */
3618 if (CMM_IS_FREE(ptrHdr->memFlags))
3620 /* Handle double deallocation error case */
3622 /* display an error message here */
3623 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3625 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3626 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3628 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3629 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3631 SDisplay(0, dbgPrntBuf);
3634 /* Release the lock */
3635 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3637 (Void) WTUnlock(&(bkt->bktLock));
3639 (Void) SUnlock(&(bkt->bktLock));
3642 /* handle RDBLFREE in SFree/SPutSBuf */
3645 if (CMM_IS_STATIC(ptrHdr->memFlags))
3647 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3648 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3649 /* deduct it from the static memory count */
3650 bkt->staticMemUsed -= bkt->size;
3652 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3654 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3655 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3656 /* deduct it from the dynamic memory count */
3657 bkt->dynamicMemUsed -= bkt->size;
3661 /* This is a case similar to trampled memory */
3663 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3665 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3667 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3669 SDisplay(0, dbgPrntBuf);
3671 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3673 /* do not add to the free list */
3676 /* Release the lock */
3677 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3679 (Void) WTUnlock(&(bkt->bktLock));
3681 (Void) SUnlock(&(bkt->bktLock));
3688 * this is the case where in the entire bucket has been made unusable
3691 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3693 (Void) WTUnlock(&(bkt->bktLock));
3695 (Void) SUnlock(&(bkt->bktLock));
3698 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3699 RETVALUE(RTRAMPLINGNOK);
3703 /* Return the block to memory */
3704 ptrHdr->nextBlk = bkt->nextBlk;
3705 bkt->nextBlk = ptrHdr;
3709 /* sriky: For debugging double deallocation */
3710 cmMemset(ptr, 0, 50);
3712 *((CmMmEntry **)ptr) = bkt->next;
3713 bkt->next = (CmMmEntry *)ptr;
3714 #endif /* SSI_DEBUG_LEVEL1 */
3717 if(bkt->numAlloc <= 0 || bkt->numAlloc > 12000)
3723 printf("\n cmFree: Freed pointer = %x and backtrace:\n", ptr);
3724 printf("****************************************\n");
3725 tmpsize = backtrace(array, 10);
3726 strings = backtrace_symbols(array, tmpsize);
3727 for(i = 0; i < tmpsize; i++)
3728 printf("%s\n", strings[i]);
3729 printf("****************************************\n");
3734 * Decrement the statistics variable of number of memory block
3742 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3744 g_overused[bktIdx] = 0;
3745 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3748 /* cm_mem_c_001.main_15 : Additions */
3749 #ifdef SS_HISTOGRAM_SUPPORT
3750 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3751 * information into the hash list */
3754 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3756 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3760 #endif /* SS_HISTOGRAM_SUPPORT */
3762 #ifdef SS_MEM_LEAK_STS
3763 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3764 cmRlsAllocBlk((PTR)ptr);
3765 #endif /* SS_MEM_LEAK_STS */
3767 /* Release the lock */
3768 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3770 (Void) WTUnlock(&(bkt->bktLock));
3772 (Void) SUnlock(&(bkt->bktLock));
3778 /* The memory block was allocated from the heap pool */
3779 /* cm_mem_c_001.main_15 : Additions */
3780 #ifdef SS_HISTOGRAM_SUPPORT
3781 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3783 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size));
3784 #endif /* SS_HISTOGRAM_SUPPORT */
3785 #else /* use pure is on */
3787 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3788 #ifdef SS_4GMX_LCORE
3789 (Void)MxHeapFree(SsiHeap, ptr);
3795 #endif /* USE_PURE */
3798 } /* end of cmFree */
3805 * Desc: alloc without lock
3808 * Ret: ROK - successful
3809 * RFAILED - unsuccessful.
3815 /*cm_mem_c_001.main_21-added new function*/
3816 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3817 #ifdef T2K_MEM_LEAK_DBG
3818 PRIVATE S16 cmAllocWL
3829 PRIVATE S16 cmAllocWL
3837 PRIVATE S16 cmAllocWL(regionCb, size, flags, ptr)
3847 CmMmBkt *bkt = NULLP;
3850 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3854 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3856 regCb = (CmMmRegCb *)regionCb;
3858 #ifdef SS_MEM_WL_DEBUG
3859 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3865 #if (ERRCLASS & ERRCLS_INT_PAR)
3867 /* error check on parameters */
3868 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3874 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3879 * Check if the requested size is less than or equal to the maximum block
3880 * size in the bucket.
3882 #ifdef MSPD_T2K_TRACK_BUG
3885 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3886 if ( *size <= regCb->bktMaxBlkSize)
3888 /* Get the map to the mapping table */
3889 idx = ((*size - 1) >> regCb->bktQnPwr);
3891 /* Dequeue the memory block and return it to the user */
3892 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3896 * Check if the size request is not greater than the size available
3899 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3900 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3902 /* Try to go to the next bucket if available */
3903 bkt->next = *((CmMmEntry **)(bkt->next));
3906 * Increment the statistics variable of number of memory block
3910 if (bkt->numAlloc > bkt->maxAlloc)
3912 bkt->maxAlloc = bkt->numAlloc;
3915 #ifdef MSPD_T2K_TRACK_BUG
3924 /* Update the size parameter */
3932 /* Memory not available in the bucket pool */
3933 if (regCb->heapFlag && (*size < regCb->heapSize))
3935 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3937 * The heap memory block is available. Allocate the memory block from
3940 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3941 RETVALUE(cmHeapAlloc(&(regCb->heapCb), ptr, size));
3944 /* No memory available */
3946 #else /* use pure is on */
3947 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3948 #ifdef SS_4GMX_LCORE
3949 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3950 cmMemset((U8*)ptr, 0, *size);
3952 /* *ptr = (Data*) malloc(*size); */
3954 *ptr = (Data *)malloc(*size);
3956 if ( (*ptr) == NULLP)
3958 /* avail_size -= *size; */
3960 #endif /* USE_PURE */
3962 } /* end of cmAllocWL */
3969 * Desc: free without lock
3972 * Ret: ROK - successful
3973 * RFAILED - unsuccessful.
3980 #ifdef T2K_MEM_LEAK_DBG
3981 PRIVATE S16 cmFreeWL
3991 PRIVATE S16 cmFreeWL
3998 PRIVATE S16 cmFreeWL(regionCb, ptr, size)
4007 CmMmBkt *bkt = NULLP;
4010 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
4014 regCb = (CmMmRegCb *)regionCb;
4016 #ifdef SS_MEM_WL_DEBUG
4017 if(tmpRegTidMap[regCb->region] != (pthread_self()))
4024 #if (ERRCLASS & ERRCLS_INT_PAR)
4026 /* error check on parameters */
4027 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
4032 /* Check if the memory block is from the memory region */
4033 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
4034 ((CmMmRegCb *)regCb)->regInfo.size)
4042 * Check if the memory block was allocated from the bucket pool.
4045 if(ptr < regCb->regInfo.start)
4047 Buffer *tmpbuf = NULLP;
4048 tmpbuf->b_cont = NULLP;
4052 #ifdef MSPD_T2K_TRACK_BUG
4056 if (ptr < (regCb->regInfo.start + regCb->bktSize))
4058 /* The memory block was allocated from the bucket pool */
4060 /* Get the map to the mapping table */
4061 idx = ((size - 1) >> regCb->bktQnPwr);
4063 #if (ERRCLASS & ERRCLS_DEBUG)
4064 if (regCb->mapTbl[idx].bktIdx == 0xFF)
4066 /* Some fatal error in the map table initialization. */
4071 /* Enqueue the memory block and return it to the user */
4072 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
4074 #ifdef MSPD_T2K_TRACK_BUG
4076 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
4083 * Check if the size is not greater than the size available
4084 * in the bucket. If so, then the buffer must have been allocated
4085 * from next bucket. We don't need to check the validity of the
4086 * next bucket, otherwise buffer must have been allocated from heap
4089 if (size > bkt->size)
4091 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
4094 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
4095 *((CmMmEntry **)ptr) = bkt->next;
4096 bkt->next = (CmMmEntry *)ptr;
4099 * Decrement the statistics variable of number of memory block
4105 if ((regCb->region == 2) && (bkt->numAlloc < 50))
4109 btInfo = &allocBtInfo[regCb->region];
4110 btIdx = btInfo->btInfoIdx;
4111 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
4113 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
4116 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
4117 cmInsertAllocPtrToList(regCb, (PTR)*ptr);
4121 btIdx &= (NUM_FREE_BUFFERS - 1);
4123 btInfo->btInfo[btIdx].ptr = (PTR)0;
4124 btInfo->btInfo[btIdx].btSize = 0;
4125 cmMemset(btInfo->btInfo[regCb->mapTbl[idx].bktIdx].btArr, 0, sizeof (btInfo->btInfo[regCb->mapTbl[idx].bktIdx].btArr));
4126 btInfo->btInfoIdx = btIdx;
4133 /* The memory block was allocated from the heap pool */
4134 RETVALUE(cmHeapFree (&(regCb->heapCb), ptr, size));
4135 #else /* use pure is on */
4137 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
4138 #ifdef SS_4GMX_LCORE
4139 (Void)MxHeapFree(SsiHeap, ptr);
4141 /* (Void)free(ptr); */
4143 /* avail_size += size; */
4147 #endif /* USE_PURE */
4150 } /* end of cmFreeWL */
4157 * Desc: Control request function.
4160 * Ret: ROK - successful
4161 * RFAILED - unsuccessful.
4163 * Notes: The current semantics of the control function is defined for two
4164 * types of events: virtual address to physical address translation
4165 * and memory resource check.
4167 * The physical address translation is valid only for the memory
4168 * region physically contiguous and non pagable.
4184 PRIVATE S16 cmCtl(regionCb, event, memCtl)
4194 regCb = (CmMmRegCb *)regionCb;
4196 #if (ERRCLASS & ERRCLS_INT_PAR)
4198 /* error check on parameters */
4199 if ((regCb == NULLP) || (memCtl == NULLP))
4212 #if (ERRCLASS & ERRCLS_INT_PAR)
4213 if ((memCtl->u.vtop.vaddr == NULLP) ||
4214 (memCtl->u.vtop.paddr == NULLP))
4220 /* Check if the virtual to physical address translation is valid */
4221 if (regCb->chFlag & CMM_REG_PHY_VALID)
4223 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
4224 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
4231 case SS_MEM_CHK_RES:
4234 #if (ERRCLASS & ERRCLS_INT_PAR)
4235 if (!(memCtl->u.chkres.size) ||
4236 (memCtl->u.chkres.status == NULLP))
4242 /* Check if the Bucket pool is configured */
4247 U32 avlSize, totSize;
4249 * The bucket pool is configured. The status value returned
4250 * does reflect on the memory availabilty in the bucket pool.
4251 * The value does not consider the available memory in the
4254 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
4255 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
4256 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
4257 avlSize += regCb->heapCb.avlSize;
4258 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
4259 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
4263 /* Bucket pool not configured */
4266 * Find the percentage memory available in the heap pool. The value
4267 * does not consider the fragmentation of the heap pool.
4269 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
4270 (regCb->heapSize/10));
4274 #else /* use pure is on */
4275 *(memCtl->u.chkres.status) = ((avail_size) /
4276 (regCb->regInfo.size/10));
4278 #endif /* USE_PURE */
4284 /* No other event is supported currently */
4289 /* shouldn't reach here */
4291 } /* end of cmCtl */
4299 * Desc: Initialize the bucket and the map table.
4302 * Ret: ROK - successful,
4303 * RFAILED - unsuccessful.
4305 * Notes: This function is called by the cmMmRegInit.
4311 PRIVATE Void cmMmBktInit
4320 PRIVATE Void cmMmBktInit (memAddr, regCb, cfg, bktIdx, lstMapIdx)
4333 U16 blkSetRelThreshold;
4334 CmMmBktLstCb *bktLstCb;
4339 size = cfg->bktCfg[bktIdx].size;
4340 numBlks = cfg->bktCfg[bktIdx].numBlks;
4342 regCb->bktTbl[bktIdx].blkSetRelThreshold = cfg->bktCfg[bktIdx].blkSetRelThreshold;
4343 regCb->bktTbl[bktIdx].blkSetAcquireThreshold = cfg->bktCfg[bktIdx].blkSetAcquireThreshold;
4344 blkSetRelThreshold = cfg->bktCfg[bktIdx].blkSetRelThreshold;
4346 /* Initialize the bucket linked list */
4347 cmLListInit(®Cb->bktTbl[bktIdx].listBktSet);
4349 /* Reset the next pointer */
4350 regCb->bktTbl[bktIdx].next = NULLP;
4352 /* Initialize the link list of the memory block */
4353 next = &(regCb->bktTbl[bktIdx].next);
4354 for (cnt = 0; cnt < numBlks; cnt++)
4357 next = (CmMmEntry **)(*memAddr);
4358 *memAddr = (*memAddr) + size;
4360 /* Maintain the list Cb */
4361 if((cnt != 0) && (!(cnt % blkSetRelThreshold)))
4363 bktLstCb = calloc(1, sizeof(CmMmBktLstCb));
4364 bktLstCb->nextBktPtr = regCb->bktTbl[bktIdx].next;
4365 bktLstCb->numBkt = blkSetRelThreshold;
4366 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listBktSet), (&bktLstCb->memSetNode));
4367 next = &(regCb->bktTbl[bktIdx].next);
4373 bktLstCb = cmLListFirst((®Cb->bktTbl[bktIdx].listBktSet));
4374 regCb->bktTbl[bktIdx].next = bktLstCb->nextBktPtr;
4375 cmLListDelFrm((®Cb->bktTbl[bktIdx].listBktSet), bktLstCb);
4378 /* Initialize the Map entry */
4379 idx = size / cfg->bktQnSize;
4382 * Check if the size is multiple of quantum size. If not we need to initialize
4383 * one more map table entry.
4385 if(size % cfg->bktQnSize)
4390 while ( *lstMapIdx < idx)
4392 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
4394 #if (ERRCLASS & ERRCLS_DEBUG)
4395 regCb->mapTbl[*lstMapIdx].numReq = 0;
4396 regCb->mapTbl[*lstMapIdx].numFailure = 0;
4402 /* Initialize the bucket structure */
4403 regCb->bktTbl[bktIdx].size = size;
4404 regCb->bktTbl[bktIdx].numBlks = numBlks;
4405 regCb->bktTbl[bktIdx].numAlloc = 0;
4406 regCb->bktTbl[bktIdx].maxAlloc = 0;
4408 /* Update the total bucket size */
4409 regCb->bktSize += (size * numBlks);
4411 regCb->bktTbl[bktIdx].bktFailCnt = 0;
4412 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
4415 } /* end of cmMmBktInit */
4423 * Desc: Initialize the heap pool.
4426 * Ret: ROK - successful
4427 * RFAILED - unsuccessful.
4429 * Notes: This function is called by the cmMmRegInit.
4435 PRIVATE Void cmMmHeapInit
4442 PRIVATE Void cmMmHeapInit (memAddr, heapCb, size)
4448 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4449 #ifdef SSI_DEBUG_LEVEL1
4451 #endif /* SSI_DEBUG_LEVEL1 */
4454 /* Initialize the heap control block */
4455 heapCb->vStart = memAddr;
4456 heapCb->vEnd = memAddr + size;
4457 heapCb->avlSize = size;
4458 heapCb->minSize = CMM_MINBUFSIZE;
4460 heapCb->next = (CmHEntry *)memAddr;
4461 heapCb->next->next = NULLP;
4462 /* cm_mem_c_001.main_12 - addition for header initialization */
4463 #ifdef SSI_DEBUG_LEVEL1
4464 heapCb->next->size = size - sizeof(CmHEntry);
4465 heapCb->next->requestedSize = 0;
4466 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4468 heapCb->next->trSignature[idx] = 0xAB;
4470 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
4471 heapCb->staticHeapMemUsed = 0;
4472 heapCb->dynamicHeapMemUsed = 0;
4473 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
4474 sizeof(heapCb->next->memFlags) +
4475 sizeof(heapCb->next->requestedSize);
4476 heapCb->numAllocAttempts = 0;
4477 heapCb->numDeallocAttempts = 0;
4478 heapCb->trampleCount = 0;
4480 heapCb->next->size = size;
4481 #endif /* SSI_DEBUG_LEVEL1 */
4483 #if (ERRCLASS & ERRCLS_DEBUG)
4484 heapCb->numFragBlk = 0;
4486 heapCb->numFailure = 0;
4489 heapCb->heapAllocCnt = 0;
4490 /* cm_mem_c_001.main_15 : Additions */
4491 #ifdef SS_HISTOGRAM_SUPPORT
4492 /* Initialise the memory histogram hash list */
4493 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
4494 #endif /* SS_HISTOGRAM_SUPPORT */
4497 } /* end of cmMmHeapInit */
4505 * Desc: Allocates the memory block from the heap pool.
4508 * Ret: ROK - successful
4509 * RFAILED - unsuccessful.
4511 * Notes: This function is called by the cmAlloc. cmAlloc calls this
4512 * function when there is no memory block available in the bucket
4513 * and the heap pool is configured.
4520 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
4521 /* cm_mem_c_001.main_15 : Additions */
4522 #ifdef SS_HISTOGRAM_SUPPORT
4523 #ifdef SSI_DEBUG_LEVEL1
4525 PRIVATE S16 cmHeapAlloc
4537 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType, line, fileName, entId, hstReg)
4549 PRIVATE S16 cmHeapAlloc
4560 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, line, fileName, entId, hstReg)
4569 #endif /* SSI_DEBUG_LEVEL1 */
4571 #ifdef SSI_DEBUG_LEVEL1
4573 PRIVATE S16 cmHeapAlloc
4581 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType)
4589 PRIVATE S16 cmHeapAlloc
4596 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size)
4601 #endif /* SSI_DEBUG_LEVEL1 */
4602 /* cm_mem_c_001.main_15 : Additions */
4603 #endif /* SS_HISTOGRAM_SUPPORT */
4605 CmHEntry *prvHBlk; /* Previous heap block */
4606 CmHEntry *curHBlk; /* Current heap block */
4608 /* cm_mem_c_001.main_15 : Additions */
4609 #ifdef SS_MEM_LEAK_STS
4611 #endif /* SS_MEM_LEAK_STS */
4612 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4613 #ifdef SSI_DEBUG_LEVEL1
4614 CmHEntry *alocHeapBlk;
4618 #endif /* SSI_DEBUG_LEVEL1 */
4619 /* cm_mem_c_001.main_15 : Additions */
4620 #ifdef SS_HISTOGRAM_SUPPORT
4622 #endif /* SS_HISTOGRAM_SUPPORT */
4625 /* cm_mem_c_001.main_15 : Additions */
4626 /* Acquire the heap lock */
4627 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4629 (Void) WTLock (&(heapCb->heapLock));
4631 (Void) SLock (&(heapCb->heapLock));
4634 #ifdef SS_MEM_LEAK_STS
4636 #endif /* SS_MEM_LEAK_STS */
4637 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4638 #ifdef SSI_DEBUG_LEVEL1
4639 heapCb->numAllocAttempts++;
4640 requestedSize = *size;
4641 #endif /* SSI_DEBUG_LEVEL1 */
4643 /* Roundup the requested size */
4644 *size = CMM_DATALIGN(*size, (heapCb->minSize));
4646 /* Check if the available total size is adequate. */
4647 if ((*size) >= heapCb->avlSize)
4649 /* cm_mem_c_001.main_15 : Additions */
4651 (Void) WTUnlock (&(heapCb->heapLock));
4653 (Void) SUnlock (&(heapCb->heapLock));
4659 /* cm_mem_c_001.main_12 - addition for aligning the header size */
4660 #ifdef SSI_DEBUG_LEVEL1
4661 hdr = PTRALIGN(sizeof(CmHEntry));
4662 #endif /* SSI_DEBUG_LEVEL1 */
4665 * Search through the heap block list in the heap pool of size
4666 * greater than or equal to the requested size.
4669 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
4670 #ifdef SSI_DEBUG_LEVEL1
4671 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
4673 prvHBlk = (CmHEntry *)&(heapCb->next);
4674 #endif /* SSI_DEBUG_LEVEL1 */
4675 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
4676 prvHBlk = prvHBlk->next)
4679 * Since the size of the block is always multiple of CMM_MINBUFSIZE
4680 * and the requested size is rounded to the size multiple of
4681 * CMM_MINBUFSIZE, the difference between the size of the heap block
4682 * and the size to allocate will be either zero or multiple of
4685 if ((*size) <= curHBlk->size)
4687 /* cm_mem_c_001.main_12 - addition for block size calculation */
4688 #ifdef SSI_DEBUG_LEVEL1
4689 tmpSize = curHBlk->size - (*size);
4691 tmpSize = tmpSize - hdr;
4694 if ((tmpSize = (curHBlk->size - (*size))))
4695 #endif /* SSI_DEBUG_LEVEL1 */
4697 /* Heap block of bigger size */
4698 /* cm_mem_c_001.main_12 - addition for allocating memory */
4699 #ifdef SSI_DEBUG_LEVEL1
4700 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
4701 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
4703 * No need to look for memory trampling as this is a new block altogether
4704 * Update the header only for this case as it is new block formed
4706 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4708 alocHeapBlk->trSignature[idx] = 0xAB;
4710 alocHeapBlk->size = *size;
4712 *ptr = (Data *)curHBlk + tmpSize;
4713 #endif /* SSI_DEBUG_LEVEL1 */
4714 curHBlk->size = tmpSize;
4718 /* Heap block is same size of the requested size */
4719 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4720 #ifdef SSI_DEBUG_LEVEL1
4721 /* look for memory trampling as this is a pure block*/
4724 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4726 /* detected a trampled memory block in this bucket */
4728 /* display an error message here */
4729 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4731 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4733 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4735 SDisplay(0, dbgPrntBuf);
4738 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4740 /* Release the lock */
4741 /* cm_mem_c_001.main_13: Replaced SUnlock with
4744 (Void) WTUnlock (&(heapCb->heapLock));
4746 (Void) SUnlock (&(heapCb->heapLock));
4748 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4749 RETVALUE(RTRAMPLINGNOK);
4753 /* Release the lock */
4754 /* cm_mem_c_001.main_13: Replaced SUnlock with
4757 (Void) WTUnlock (&(heapCb->heapLock));
4759 (Void) SUnlock (&(heapCb->heapLock));
4766 *ptr = (Data *)curHBlk + hdr;
4767 alocHeapBlk = curHBlk;
4768 *size = curHBlk->size;
4770 *ptr = (Data *)curHBlk;
4771 #endif /* SSI_DEBUG_LEVEL1 */
4772 prvHBlk->next = curHBlk->next;
4775 /* cm_mem_c_001.main_12 - addition for header updation */
4776 #ifdef SSI_DEBUG_LEVEL1
4777 /* update the header fields */
4778 alocHeapBlk->requestedSize = requestedSize;
4779 alocHeapBlk->memFlags = 0;
4780 if (memType == CMM_STATIC_MEM_FLAG)
4782 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4783 heapCb->staticHeapMemUsed += (*size + hdr);
4787 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4788 heapCb->dynamicHeapMemUsed += (*size + hdr);
4790 heapCb->avlSize -= ((*size) + hdr);
4792 heapCb->avlSize -= (*size);
4793 #endif /* SSI_DEBUG_LEVEL1 */
4799 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4800 *size, num_times, *ptr);
4801 SDisplay(0, prntBuf);
4805 /* cm_mem_c_001.main_15 : Additions */
4806 #ifdef SS_MEM_LEAK_STS
4807 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4808 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4809 #endif /* SS_MEM_LEAK_STS */
4810 /* Release the lock */
4811 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4813 (Void) WTUnlock (&(heapCb->heapLock));
4815 (Void) SUnlock (&(heapCb->heapLock));
4818 #ifdef SS_HISTOGRAM_SUPPORT
4819 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4820 * information into the hash list */
4823 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4825 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4830 #endif /* SS_HISTOGRAM_SUPPORT */
4836 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4842 /* Release the lock */
4843 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4845 (Void) WTUnlock (&(heapCb->heapLock));
4847 (Void) SUnlock (&(heapCb->heapLock));
4852 } /* end of cmHeapAlloc */
4859 * Desc: Return the memory block from the heap pool.
4862 * Ret: ROK - successful
4863 * RFAILED - unsuccessful.
4865 * Notes: This function returns the memory block to the heap pool. This
4866 * function is called by cmFree. The function does not check the
4867 * validity of the memory block. The caller must be sure that the
4868 * block was previously allocated and belongs to the heap pool. The
4869 * function maintain the sorting order of the memory block on the
4870 * starting address of the block. This function also do compaction
4871 * if the neighbouring blocks are already in the heap.
4878 /* cm_mem_c_001.main_15 : Additions */
4879 #ifdef SS_HISTOGRAM_SUPPORT
4881 PRIVATE S16 cmHeapFree
4892 PRIVATE S16 cmHeapFree (heapCb, ptr, size, line, fileName, entId, hstReg)
4903 PRIVATE S16 cmHeapFree
4910 PRIVATE S16 cmHeapFree (heapCb, ptr, size)
4915 /* cm_mem_c_001.main_15 : Additions */
4916 #endif /* SS_HISTOGRAM_SUPPORT */
4919 CmHEntry *curHBlk; /* Current heap block */
4920 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4921 #ifdef SSI_DEBUG_LEVEL1
4923 #endif /* SSI_DEBUG_LEVEL1 */
4924 /* cm_mem_c_001.main_15 : Additions */
4925 #ifdef SS_HISTOGRAM_SUPPORT
4926 Size allocSize = size;
4928 #endif /* SS_HISTOGRAM_SUPPORT */
4932 /* Roundup the requested size */
4933 size = CMM_DATALIGN(size, (heapCb->minSize));
4934 /* cm_mem_c_001.main_15: Additions */
4935 #ifdef SS_HISTOGRAM_SUPPORT
4937 #endif /* SS_HISTOGRAM_SUPPORT */
4939 /* Acquire the heap lock */
4940 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4942 (Void) WTLock (&(heapCb->heapLock));
4944 (Void) SLock (&(heapCb->heapLock));
4947 /* increase the avlSize */
4948 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4949 #ifdef SSI_DEBUG_LEVEL1
4950 hdr = PTRALIGN(sizeof(CmHEntry));
4951 heapCb->avlSize += (size + hdr);
4952 heapCb->numDeallocAttempts++;
4954 heapCb->avlSize += size;
4955 #endif /* SSI_DEBUG_LEVEL1 */
4957 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4958 #ifdef SSI_DEBUG_LEVEL1
4959 p = (CmHEntry *)(ptr - hdr);
4961 p = (CmHEntry *)ptr;
4962 /* cm_mem_c_001.main_15 : Additions */
4963 #ifdef SS_MEM_LEAK_STS
4964 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4965 cmRlsAllocBlk((PTR)ptr);
4966 #endif /* SS_MEM_LEAK_STS */
4967 #endif /* SSI_DEBUG_LEVEL1 */
4970 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4971 #ifdef SSI_DEBUG_LEVEL1
4972 /* look for memory trampling */
4973 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4975 /* detected a trampled memory block in heap */
4977 /* display an error message here */
4978 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4980 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4982 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4984 SDisplay(0, dbgPrntBuf);
4987 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4989 /* Release the lock */
4990 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4992 (Void) WTUnlock (&(heapCb->heapLock));
4994 (Void) SUnlock (&(heapCb->heapLock));
4996 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4997 RETVALUE(RTRAMPLINGNOK);
5001 /* do not add to the free heap */
5002 heapCb->avlSize -= (size + hdr);
5003 /* Release the heap lock */
5004 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5006 (Void) WTUnlock (&(heapCb->heapLock));
5008 (Void) SUnlock (&(heapCb->heapLock));
5015 /* look for any double free */
5016 if (CMM_IS_FREE(p->memFlags))
5019 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5021 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
5023 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
5025 SDisplay(0, dbgPrntBuf);
5028 heapCb->avlSize -= (size + hdr);
5029 /* cm_mem_c_001.main_15 : Additions */
5031 (Void) WTUnlock (&(heapCb->heapLock));
5033 (Void) SUnlock (&(heapCb->heapLock));
5038 #endif /* SSI_DEBUG_LEVEL1 */
5040 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
5043 * The block will be inserted to maintain the sorted order on the
5044 * starting address of the block.
5048 if (!(curHBlk->next) ||
5049 (p < (curHBlk->next)))
5051 /* Heap block should be inserted here */
5054 * Check if the block to be returned can be merged with the
5057 /* cm_mem_c_001.main_12 - addition for header consideration */
5058 #ifdef SSI_DEBUG_LEVEL1
5059 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
5061 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
5062 #endif /* SSI_DEBUG_LEVEL1 */
5064 /* Merge the block */
5065 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
5066 #ifdef SSI_DEBUG_LEVEL1
5067 /* update the flags */
5068 if (CMM_IS_STATIC(p->memFlags))
5069 heapCb->staticHeapMemUsed -= (size + hdr);
5070 else if (CMM_IS_DYNAMIC(p->memFlags))
5071 heapCb->dynamicHeapMemUsed -= (size + hdr);
5072 size = (curHBlk->size += (size + hdr));
5074 size = (curHBlk->size += size);
5075 #endif /*SSI_DEBUG_LEVEL1*/
5080 /* cm_mem_c_001.main_12 - addition for double-free check */
5081 #ifdef SSI_DEBUG_LEVEL1
5082 /* Check for double deallocation in heap */
5083 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
5085 /* Release the lock */
5086 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5088 (Void) WTUnlock (&(heapCb->heapLock));
5090 (Void) SUnlock (&(heapCb->heapLock));
5093 /* This block is already freed in the heap */
5096 /* update the flags as it is a new node */
5097 if (CMM_IS_STATIC(p->memFlags))
5099 heapCb->staticHeapMemUsed -= (size + hdr);
5100 CMM_RESET_STATIC_FLAG(p->memFlags);
5102 else if (CMM_IS_DYNAMIC(p->memFlags))
5104 heapCb->dynamicHeapMemUsed -= (size + hdr);
5105 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5107 CMM_SET_FREE_FLAG(p->memFlags);
5108 p->requestedSize = 0;
5109 #endif /*SSI_DEBUG_LEVEL1*/
5110 /* insert the block */
5111 p->next = curHBlk->next;
5116 /* Try to merge with the next block in the chain */
5117 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
5118 #ifdef SSI_DEBUG_LEVEL1
5119 if (((Data *)p + hdr + size) == (Data *)(p->next))
5121 if (((Data *)p + size) == (Data *)(p->next))
5122 #endif /*SSI_DEBUG_LEVEL1*/
5124 /* p->next can not be NULL */
5125 /* cm_mem_c_001.main_12 - addition for header consideration */
5126 #ifdef SSI_DEBUG_LEVEL1
5127 p->size += (p->next->size + hdr);
5129 p->size += p->next->size;
5130 #endif /*SSI_DEBUG_LEVEL1*/
5131 p->next = p->next->next;
5134 /* Release the lock */
5135 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5137 (Void) WTUnlock (&(heapCb->heapLock));
5139 (Void) SUnlock (&(heapCb->heapLock));
5141 /* cm_mem_c_001.main_15 : Additions */
5142 #ifdef SS_HISTOGRAM_SUPPORT
5143 /* If If Tapa task (entId)is registerd for histogram then insert
5144 Memrory Freed information into the hash list */
5147 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5148 fileName, entId) != ROK)
5150 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5154 #endif /* SS_HISTOGRAM_SUPPORT */
5158 else if (p < curHBlk)
5161 * Check if the block to be returned can be merged with the
5164 /* cm_mem_c_001.main_12 - addition for header consideration */
5165 #ifdef SSI_DEBUG_LEVEL1
5166 if (((Data *)p + hdr + size) == (Data *)curHBlk)
5168 if (((Data *)p + size) == (Data *)curHBlk)
5169 #endif /* SSI_DEBUG_LEVEL1 */
5171 /* Merge the block */
5172 /* cm_mem_c_001.main_12 - addition for header consideration */
5173 #ifdef SSI_DEBUG_LEVEL1
5174 p->size = size + (curHBlk->size + hdr);
5176 p->size = size + curHBlk->size;
5177 #endif /* SSI_DEBUG_LEVEL1 */
5178 p->next = curHBlk->next;
5182 /* insert the block */
5186 /* cm_mem_c_001.main_12 - addition for header updation */
5187 #ifdef SSI_DEBUG_LEVEL1
5188 /* update the flags in both cases as they are new start nodes*/
5189 if (CMM_IS_STATIC(p->memFlags))
5191 heapCb->staticHeapMemUsed -= (size + hdr);
5192 CMM_RESET_STATIC_FLAG(p->memFlags);
5194 else if (CMM_IS_DYNAMIC(p->memFlags))
5196 heapCb->dynamicHeapMemUsed -= (size + hdr);
5197 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5199 CMM_SET_FREE_FLAG(p->memFlags);
5200 p->requestedSize = 0;
5201 #endif /* SSI_DEBUG_LEVEL1 */
5205 /* Release the lock */
5206 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5208 (Void) WTUnlock (&(heapCb->heapLock));
5210 (Void) SUnlock (&(heapCb->heapLock));
5212 /* cm_mem_c_001.main_15 : Additions */
5213 #ifdef SS_HISTOGRAM_SUPPORT
5214 /* If If Tapa task (entId)is registerd for histogram then insert
5215 Memrory Freed information into the hash list */
5218 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5219 fileName, entId) != ROK)
5221 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5225 #endif /* SS_HISTOGRAM_SUPPORT */
5231 if (heapCb->next == NULLP)
5233 /* Heap block is empty. Insert the block in the head. */
5238 /* cm_mem_c_001.main_12 - addition for header updation */
5239 #ifdef SSI_DEBUG_LEVEL1
5240 if (CMM_IS_STATIC(p->memFlags))
5242 heapCb->staticHeapMemUsed -= (size + hdr);
5243 CMM_RESET_STATIC_FLAG(p->memFlags);
5245 else if (CMM_IS_DYNAMIC(p->memFlags))
5247 heapCb->dynamicHeapMemUsed -= (size + hdr);
5248 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
5250 CMM_SET_FREE_FLAG(p->memFlags);
5251 p->requestedSize = 0;
5252 #endif /* SSI_DEBUG_LEVEL1 */
5254 /* Release the heap lock */
5255 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5257 (Void) WTUnlock (&(heapCb->heapLock));
5259 (Void) SUnlock (&(heapCb->heapLock));
5261 /* cm_mem_c_001.main_15 : Additions */
5262 #ifdef SS_HISTOGRAM_SUPPORT
5263 /* If If Tapa task (entId)is registerd for histogram then insert
5264 Memrory Freed information into the hash list */
5267 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
5268 fileName, entId) != ROK)
5270 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
5274 #endif /* SS_HISTOGRAM_SUPPORT */
5278 /* Release the lock */
5279 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
5281 (Void) WTUnlock (&(heapCb->heapLock));
5283 (Void) SUnlock (&(heapCb->heapLock));
5287 } /* end of cmHeapFree */
5288 /* cm_mem_c_001.main_15 : Additions */
5290 #ifdef SS_MEM_LEAK_STS
5293 * Fun: cmInitMemLeakMdl
5295 * Desc: Initializes the memory leak detection module
5300 * Notes: This function initializes the memory leak detection module.
5307 PUBLIC Void cmInitMemLeakMdl
5312 PUBLIC Void cmInitMemLeakMdl (Void)
5318 TRC3(cmInitMemLeakMdl);
5320 memLkCb.memLkMdlInit = FALSE;
5321 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5323 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5325 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
5326 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5327 500, 0, FALSE, CM_HASH_KEYTYPE_U32MOD, 0, 0);
5328 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5331 if(memLkCb.fileLkLog == NULLP)
5333 memLkCb.fileLkLog = (FILE *) stdout;
5335 memLkCb.memLkMdlInit = TRUE;
5338 } /* cmInitMemLeakMdl */
5339 /* cm_mem_c_002.main_21 Added for shutdown procedure */
5342 * Fun: cmDeinitMemLeakMdl
5344 * Desc: De-initializes the memory leak detection module
5349 * Notes: This function de-initializes the memory leak detection module.
5356 PUBLIC Void cmDeinitMemLeakMdl
5361 PUBLIC Void cmDeinitMemLeakMdl (Void)
5367 TRC3(cmDeinitMemLeakMdl);
5369 memLkCb.memLkMdlInit = FALSE;
5370 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5372 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5374 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5375 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
5376 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
5383 * Fun: cmMemOpenMemLkFile
5385 * Desc: Initializes the memory leak detection module
5390 * Notes: This function initializes the memory leak detection module.
5397 PUBLIC Void cmMemOpenMemLkFile
5402 PUBLIC Void cmMemOpenMemLkFile (arg)
5406 TRC3(cmMemOpenMemLkFile);
5407 memLkCb.fileLkLog = NULLP;
5408 memLkCb.fileLkLog = fopen(arg, "w");
5416 * Desc: Initializes the memory leak detection module
5421 * Notes: This function initializes the memory leak detection module.
5428 PUBLIC Void SLogLkInfo
5433 PUBLIC Void SLogLkInfo (Void)
5437 MemAllocInfo *oldMemInfo;
5438 MemAllocInfo *newMemInfo;
5445 if( memLkCb.memLkMdlInit == FALSE)
5449 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
5450 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5452 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5454 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5456 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5462 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5463 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5464 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
5466 sprintf(prntBuf, "[LBIS]\n");
5467 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5468 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5470 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
5472 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
5474 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5475 sprintf(prntBuf, "Module Name: %s\n",
5476 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
5477 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5478 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
5479 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5480 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
5481 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5482 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
5483 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5484 sprintf(prntBuf,"Memory Allocation Path:\n");
5485 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5486 funcNm = (S8 **)newMemInfo->backTrace;
5487 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
5489 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
5490 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5492 sprintf(prntBuf, "[LBIE]\n\n");
5493 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5494 fflush(memLkCb.fileLkLog);
5495 oldMemInfo = newMemInfo;
5498 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5501 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
5502 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5510 * Desc: Initializes the memory leak detection module
5515 * Notes: This function initializes the memory leak detection module.
5522 PUBLIC Void SFlushLkInfo
5527 PUBLIC Void SFlushLkInfo (Void)
5530 MemAllocInfo *newMemInfo;
5534 #ifdef SS_MEM_LEAK_SOL
5536 #endif /* SS_MEM_LEAK_SOL */
5539 if( memLkCb.memLkMdlInit == FALSE)
5544 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5546 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5548 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5553 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5554 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5555 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
5557 funcNm = (S8 **)newMemInfo->backTrace;
5558 #ifdef SS_MEM_LEAK_SOL
5559 for(i = 0; i < newMemInfo->bTrcSz; i++)
5561 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5562 #ifdef SS_4GMX_LCORE
5563 MxHeapFree(SsiHeap, funcNm[i]);
5567 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(U32) * CM_MAX_STACK_TRACE); */
5569 #endif /* SS_MEM_LEAK_SOl */
5570 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5571 #ifdef SS_4GMX_LCORE
5572 MxHeapFree(SsiHeap, funcNm);
5573 MxHeapFree(SsiHeap, newMemInfo);
5579 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5587 * Fun: cmStorAllocBlk
5589 * Desc: Initializes the memory leak detection module
5594 * Notes: This function initializes the memory leak detection module.
5601 PUBLIC Void cmStorAllocBlk
5609 PUBLIC Void cmStorAllocBlk (addr, reqSz, allocSz, bktIdx)
5616 #ifndef SS_MEM_LEAK_SOL
5617 Ptr trace[CM_MAX_STACK_TRACE];
5618 #endif /* SS_MEM_LEAK_SOL */
5621 MemAllocInfo *allocInfo;
5624 TRC3(cmStorAllocBlk);
5625 if( memLkCb.memLkMdlInit == FALSE)
5630 #ifdef SS_MEM_LEAK_SOL
5631 /* I need to do this for solaris, because it does not implement
5632 * backtrace. Here backtrace is my function. See below for the
5633 * implementation. */
5634 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5635 #ifdef SS_4GMX_LCORE
5636 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(U32) * CM_MAX_STACK_TRACE));
5637 cmMemset((U8*)funcNm, 0, (sizeof(U32) * CM_MAX_STACK_TRACE));
5639 funcNm = (S8 **)calloc(1, (sizeof(U32) * CM_MAX_STACK_TRACE));
5641 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(U32) * CM_MAX_STACK_TRACE); */
5642 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
5643 #else /* SS_MEM_LEAK_SOL */
5644 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5645 funcNm = backtrace_symbols(trace, traceSize);
5646 #endif /* SS_MEM_LEAK_SOL */
5648 moduleId = cmMemGetModuleId(funcNm, traceSize);
5650 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5651 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5652 #ifdef SS_4GMX_LCORE
5653 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
5654 cmMemset((U8*)allocInfo, 0, sizeof(MemAllocInfo));
5656 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
5658 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
5659 allocInfo->memAddr = addr;
5660 allocInfo->reqSz = reqSz;
5661 allocInfo->allocSz = allocSz;
5662 allocInfo->bktIdx = bktIdx;
5663 allocInfo->backTrace = (PTR) funcNm;
5664 allocInfo->moduleId = moduleId;
5665 allocInfo->bTrcSz = traceSize;
5667 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
5668 (PTR)allocInfo, (U8 *)&(allocInfo->memAddr),
5669 sizeof(allocInfo->memAddr));
5670 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
5672 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5674 } /* cmStorAllocBlk */
5678 * Fun: cmMemGetModuleId
5680 * Desc: Initializes the memory leak detection module
5685 * Notes: This function initializes the memory leak detection module.
5692 PUBLIC U8 cmMemGetModuleId
5698 PUBLIC U8 cmMemGetModuleId (funNm, traceSize)
5710 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
5712 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5713 TRC3(cmMemGetModuleId)
5714 for(idx = 0; idx < traceSize; idx++)
5718 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
5720 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
5725 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5727 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5728 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
5729 memUsrMdlStr[mdlFunStrIdx].fPStr,
5733 RETVALUE(mdlFunStrIdx);
5738 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5740 retVal = strcmp((const S8 *)"DEFAULT",
5741 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5744 RETVALUE(mdlFunStrIdx);
5751 } /* cmMemGetModuleId */
5755 * Fun: cmMemGetStrMtchIdx
5757 * Desc: Initializes the memory leak detection module
5762 * Notes: This function initializes the memory leak detection module.
5769 PUBLIC S16 cmMemGetStrMtchIdx
5777 PUBLIC S16 cmMemGetStrMtchIdx(strtIdx, endIdx, str, strLst)
5791 TRC3(cmMemGetStrMtchIdx);
5793 len = strlen((const S8 *)str);
5795 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
5796 cmpStr[len + 1] = '\0';
5799 for(;strtIdx < endIdx && !found; strtIdx++)
5802 tempLen = strlen((const S8 *)strLst[strtIdx]);
5806 while(*(strLst[strtIdx] + idx + len) != '\0')
5808 retVal = strncmp((const S8 *)cmpStr,
5809 ((const S8 *)strLst[strtIdx] + idx), len);
5825 } /* cmMemGetStrMtchIdx */
5829 * Fun: cmRlsAllocBlk
5831 * Desc: Initializes the memory leak detection module
5836 * Notes: This function initializes the memory leak detection module.
5843 PUBLIC Void cmRlsAllocBlk
5848 PUBLIC Void cmRlsAllocBlk(addr)
5852 Ptr trace[CM_MAX_STACK_TRACE];
5858 MemAllocInfo *memAllocInfo;
5860 TRC3(cmRlsAllocBlk);
5861 if( memLkCb.memLkMdlInit == FALSE)
5867 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5869 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5870 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5871 (U8 *)&addr, sizeof(U32), 0,
5872 (PTR *)&memAllocInfo);
5875 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5877 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5878 funcNm = (S8 **) memAllocInfo->backTrace;
5879 #ifdef SS_MEM_LEAK_SOL
5880 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5882 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5883 #ifdef SS_4GMX_LCORE
5884 MxHeapFree(SsiHeap, funcNm[i]);
5889 #endif /* SS_MEM_LEAK_SOL */
5890 #ifdef SS_MEM_LEAK_FREE_TRACE
5894 sprintf( prntBuf, "\n==============================\n");
5896 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5898 sprintf( prntBuf, "Address: [%x]\n", addr);
5900 sprintf( prntBuf, "Address: [%lx]\n", addr);
5903 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5904 funcNm = backtrace_symbols(trace, traceSize);
5905 sprintf( prntBuf, "[bt] Execution path:\n");
5907 for (i=0; i < traceSize; ++i)
5909 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5912 sprintf( prntBuf, "\n==============================\n");
5915 #endif /* SS_MEM_LEAK_FREE_TRACE */
5916 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5917 #ifdef SS_4GMX_LCORE
5918 MxHeapFree(SsiHeap, funcNm);
5919 MxHeapFree(SsiHeap, memAllocInfo);
5926 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5929 #ifndef SS_MEM_LEAK_SOL
5930 if(idx == CM_MEM_USR_MDL)
5933 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5935 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5937 sprintf( prntBuf, "Address: [%u]\n", addr);
5939 sprintf( prntBuf, "Address: [%lu]\n", addr);
5942 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5943 funcNm = backtrace_symbols(trace, traceSize);
5944 sprintf( prntBuf,"[bt] Execution path:\n");
5946 for (i=0; i < traceSize; ++i)
5948 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5951 printf("\n==============================\n");
5952 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5953 #ifdef SS_4GMX_LCORE
5954 MxHeapFree(SsiHeap, funcNm);
5959 #endif /* SS_MEM_LEAK_SOL */
5961 /*cm_mem_c_001.main_25 : */
5963 } /* cmRlsAllocBlk */
5966 #ifdef SS_MEM_LEAK_SOL
5969 * Fun: cmAddrToSymStr
5971 * Desc: Initializes the memory leak detection module
5976 * Notes: This function initializes the memory leak detection module.
5983 PUBLIC S32 cmAddrToSymStr
5990 PUBLIC S32 cmAddrToSymStr(pc, buffer, size)
6000 TRC3(cmAddrToSymStr);
6002 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
6004 RETVALUE(snprintf(buffer, size, "[0x%p]", pc));
6007 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
6008 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
6010 RETVALUE(snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
6013 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
6017 RETVALUE(snprintf(buffer, size, "%s(0x%p [0x%p]",
6019 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
6022 } /* cmAddrToSymStr */
6026 * Fun: cmLeakCallBack
6028 * Desc: Initializes the memory leak detection module
6033 * Notes: This function initializes the memory leak detection module.
6040 PUBLIC S32 cmLeakCallBack
6047 PUBLIC S32 cmLeakCallBack(pc, sigNo, arg)
6054 TRC3(cmLeakCallBack);
6056 Backtrace_t *bt = (Backtrace_t *)arg;
6057 if (bt->bt_actcount >= bt->bt_maxcount)
6059 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
6060 #ifdef SS_4GMX_LCORE
6061 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
6062 cmMemset((U8*)buffer, 0, 510);
6064 buffer = (S8 *)calloc(1, 510);
6066 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
6067 (void) cmAddrToSymStr((void *)pc, buffer, 505);
6068 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
6071 } /* cmLeakCallBack */
6077 * Desc: Initializes the memory leak detection module
6082 * Notes: This function initializes the memory leak detection module.
6089 PUBLIC S32 backtrace
6095 PUBLIC S32 backtrace(buffer, count)
6105 bt.bt_buffer = buffer;
6106 bt.bt_maxcount = count;
6109 if (getcontext(&u) < 0)
6111 (Void) walkcontext(&u, cmLeakCallBack, &bt);
6112 RETVALUE(bt.bt_actcount);
6116 #endif /* SS_MEM_LEAK_SOL */
6118 #endif /* SS_MEM_LEAK_STS */
6119 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
6120 * These include sanity check functions for bucket and heap,
6121 * for printing several memory related statistics
6123 #ifdef SSI_DEBUG_LEVEL1
6126 * Fun: cmMmBktSanityChk
6128 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
6129 * This API gets called when trampling is detected in a memory block.
6131 * Ret: RTRAMPLINGNOK - Trampling, serious error
6132 * RTRAMPLINGOK - Trampling, but OK to proceed
6134 * Notes: This function performs the memory block sanity in a bucket. This
6135 * function is called by cmAlloc and cmFree as part of error handling mechanism.
6136 * Performs sanity check for the whole bucket by traversing each
6137 * of the memory blocks using the pointer bktStartPtr.
6138 * Keeps track of number of tramplings happened. If the count
6139 * exceeds the threshold decided, then invalidates this bucket.
6145 PRIVATE S16 cmMmBktSanityChk
6150 PRIVATE S16 cmMmBktSanityChk(bkt)
6157 TRC2(cmMmBktSanityChk);
6159 bkt->trampleCount = 0;
6161 /* scan the entire memory list of the bucket */
6162 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
6163 blkCnt < (bkt->numBlks); blkCnt++)
6165 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
6167 bkt->trampleCount++;
6168 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
6170 /* Take action to invalidate the entire bucket */
6171 RETVALUE(RTRAMPLINGNOK);
6174 /* reach next memory block in this bucket manually */
6175 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
6179 /* display an error message here */
6180 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
6181 SDisplay(0, dbgPrntBuf);
6184 RETVALUE(RTRAMPLINGOK);
6189 * Fun: cmMmHeapSanityChk
6191 * Desc: Performs the sanity check for the memory blocks in the memory heap.
6192 * This API gets called when trampling is detected in heap(Alloc/Free).
6194 * Ret: RTRAMPLINGNOK - Trampling, serious error
6195 * RTRAMPLINGOK - Trampling, but OK to proceed
6197 * Notes: This function performs the memory block sanity in the heap. This
6198 * function is called by cmHeapAlloc and cmHeapFree as part of error
6199 * handling mechanism. Keeps track of number of tramplings happened.
6200 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
6201 * count is less than threshold, then return RTRAMPLINGOK.
6207 PRIVATE S16 cmMmHeapSanityChk
6212 PRIVATE S16 cmMmHeapSanityChk(heapCb)
6217 TRC2(cmMmHeapSanityChk);
6219 /* increment the trample count */
6220 heapCb->trampleCount++;
6222 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
6224 RETVALUE(RTRAMPLINGNOK);
6227 RETVALUE(RTRAMPLINGOK);
6232 * Fun: cmMmRegIsBlkSane
6234 * Desc: Performs the sanity check for the memory block by checking its header.
6236 * Ret: ROK - If no trampling is detected in the block
6237 * RFAILED - If trampling is detected in the block
6239 * Notes: This function performs the memory block sanity in a block.
6245 PUBLIC S16 cmMmRegIsBlkSane
6250 PUBLIC S16 cmMmRegIsBlkSane(blkPtr)
6256 TRC2(cmMmRegIsBlkSane);
6258 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
6260 if (blkPtr->trSignature[sigCnt] != 0xAB)
6273 * Desc: Computes the hash list index (bin number) for a specified
6274 * key of type (x % 101).
6276 * return (idx % hash_table_size);
6278 * Ret: ROK - successful, *idx contains computed index
6286 PRIVATE S16 cmMmHashFunc
6288 CmMmHashListCp *hashListCp,
6293 PRIVATE S16 cmMmHashFunc (hashListCp, key, idx)
6294 CmMmHashListCp *hashListCp; /* hash list control point */
6295 U32 key; /* key string */
6296 U16 *idx; /* idx to return */
6301 *idx = (U16)(key % hashListCp->numOfbins);
6305 } /* end of cmMmHashFunc () */
6309 * Fun: cmMmHashListInit
6311 * Desc: Initializes a hash list. Parameters are:
6313 * hashListCp control point for hash list
6314 * nmbBins number of bins in the hash list. Storage will
6315 * be allocated for them from the indicated memory
6318 * pool for allocating storage for bins.
6320 * Ret: ROK - initialization successful
6321 * RFAILED - initialization failed, lack of memory
6329 PRIVATE S16 cmMmHashListInit
6331 CmMmHashListCp *hashListCp, /* hash list to initialize */
6332 U16 nmbBins, /* number of hash list bins */
6333 Region region, /* memory region to allocate bins */
6334 Pool pool /* memory pool to allocate bins */
6337 PRIVATE S16 cmMmHashListInit(hashListCp, nmbBins, region, pool)
6338 CmMmHashListCp *hashListCp; /* hash list to initialize */
6339 U16 nmbBins; /* number of hash list bins */
6340 Region region; /* memory region to allocate bins */
6341 Pool pool; /* memory pool to allocate bins */
6345 CmMmHashListEnt *hl;
6347 TRC2(cmMmHashListInit);
6349 /* initialize control point fields */
6350 hashListCp->hashList = NULLP;
6351 hashListCp->numOfbins = 0;
6352 hashListCp->numOfEntries = 0;
6354 /* allocate memory for bins */
6357 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
6358 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
6361 /* initialize bin pointers */
6362 hl = hashListCp->hashList;
6363 for(i = 0; i < nmbBins; i++)
6365 hl[i].size = hl[i].numAttempts = 0;
6368 /* initialize bin size */
6369 hashListCp->numOfbins = nmbBins;
6377 * Fun: cmMmHashListDeinit
6379 * Desc: Deinitializes a hash list. Deallocates memory for bins
6380 * and resets header fields. Parameters are:
6382 * hashListCp control point for hash list
6384 * pool for allocating storage for bins.
6386 * Ret: ROK - successful
6387 * RFAILED - failure, invalid parameters
6395 PRIVATE S16 cmMmHashListDeinit
6397 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
6398 Region region, /* memory region to allocate bins */
6399 Pool pool /* memory pool to allocate bins */
6402 PRIVATE S16 cmMmHashListDeinit(hashListCp, region, pool)
6403 CmMmHashListCp *hashListCp; /* hash list to deinitialize */
6404 Region region; /* memory region to allocate bins */
6405 Pool pool; /* memory pool to allocate bins */
6408 TRC2(cmMmHashListDeinit);
6410 /* deallocate memory for bins */
6411 if (hashListCp->numOfbins)
6412 (Void) SPutSBuf(region, pool,
6413 (Data *) hashListCp->hashList,
6414 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
6416 /* deinitialize control point fields */
6417 hashListCp->hashList = NULLP;
6418 hashListCp->numOfbins = 0;
6419 hashListCp->numOfEntries = 0;
6422 } /* end of cmMmHashListDeinit */
6426 * Fun: cmMmHashListInsert
6428 * Desc: Inserts a new entry in the hash list. Parameters are:
6430 * hashListCp control point for hash list
6431 * key pointer to key string in the new entry
6433 * Ret: ROK - insertion successful
6434 * RFAILED - insertion failed (incorrect parameter values)
6442 PRIVATE S16 cmMmHashListInsert
6444 CmMmHashListCp *hashListCp, /* hash list to add to */
6445 U32 key /* pointer to key */
6448 PRIVATE S16 cmMmHashListInsert(hashListCp, key)
6449 CmMmHashListCp *hashListCp; /* hash list to add to */
6450 U32 key; /* pointer to key */
6453 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
6454 U16 idx; /* index for insertion into hash list */
6457 TRC2(cmMmHashListInsert);
6459 /* check if hashListCp is initialised yet */
6460 if ( hashListCp->numOfbins == 0)
6463 /* compute index for insertion */
6464 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
6467 hashListEnt = hashListCp->hashList;
6469 if (hashListEnt[idx].numAttempts == 0)
6471 /* new entry, insert here */
6472 hashListEnt[idx].size = key;
6473 hashListEnt[idx].numAttempts++;
6474 /* increment count of entries in hash list */
6475 hashListCp->numOfEntries++;
6479 /* this hash is occupied, re-hash it using linear probing */
6480 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
6482 if (hashListEnt[i].size == key)
6484 hashListEnt[i].numAttempts++;
6488 if (hashListEnt[i].numAttempts == 0)
6490 hashListEnt[i].size = key;
6491 hashListEnt[i].numAttempts++;
6492 /* increment count of entries in hash list */
6493 hashListCp->numOfEntries++;
6498 if (i == CMM_STAT_HASH_TBL_LEN)
6500 /* there is no free slot for this key */
6506 } /* end of cmMmHashListInsert */
6508 #endif /* SSI_DEBUG_LEVEL1 */
6509 /* cm_mem_c_001.main_15 : Additions */
6510 #ifdef SS_HISTOGRAM_SUPPORT
6513 * Fun: cmHstGrmHashListInit
6515 * Desc: Initializes a hash list. Parameters are:
6517 * hashListCp control point for hash list
6518 * Ret: ROK - initialization successful
6519 * RFAILED - initialization failed, lack of memory
6527 PRIVATE S16 cmHstGrmHashListInit
6529 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6532 PRIVATE S16 cmHstGrmHashListInit(hashListCp)
6533 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6536 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6537 TRC2(cmHstGrmHashListInit)
6539 /* display an error message here */
6540 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6542 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6544 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6546 SDisplay(0, dbgPrntBuf);
6548 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6554 * Fun: cmHstGrmHashListDeInit
6556 * Desc: De-initializes a hash list. Parameters are:
6558 * hashListCp control point for hash list
6559 * Ret: ROK - initialization successful
6560 * RFAILED - initialization failed, lack of memory
6568 PRIVATE S16 cmHstGrmHashListDeInit
6570 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6573 PRIVATE S16 cmHstGrmHashListDeInit(hashListCp)
6574 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6577 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6578 TRC2(cmHstGrmHashListDeInit)
6580 /* display an error message here */
6581 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6583 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6585 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6587 SDisplay(0, dbgPrntBuf);
6589 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6595 * Fun: cmHstGrmFreeInsert
6597 * Desc: Inserts a Freed information in into the hash list. Parameters are:
6599 * bkt : pointer to bucket for which memory is freed.
6600 * line : Line where memory is freed.
6601 * file : file where memory is freed.
6602 * entId : Tapa task which releases the memory.
6604 * Ret: ROK - insertion successful
6605 * RFAILED - insertion failed (incorrect parameter values)
6613 PRIVATE S16 cmHstGrmFreeInsert
6615 CmHstGrmHashListCp* hashListCp, /* hash list cp */
6616 U32 blkSz, /* size of the block freed */
6617 U32 line, /* Line number */
6618 U8 *fileName, /* file name */
6619 U8 entId /* Tapa task which free the memory */
6622 PRIVATE S16 cmHstGrmFreeInsert(hashListCp, blkSz, line, fileName, entId)
6623 CmHstGrmHashListCp* hashListCp; /* hash list cp */
6624 U32 blkSz; /* size of the block freed */
6625 U32 line; /* line number */
6626 U8 *fileName; /* file Name */
6627 U8 entId; /* Tapa task which frees the memory */
6630 U32 binIdx = 0; /* Bin index to insert the entry into the hash list */
6631 U32 key = 0; /* Key to fine the bin index */
6632 U32 ret = 0; /* Return value */
6633 CmMemEntries *entry = NULLP; /* Entry which contains the information */
6636 TRC2(cmHstGrmFreeInsert);
6638 /* check for the total number of entries in the hash list. *
6639 * If there is no place for new entry return failure */
6640 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6642 /* After comuting the hash bind and key, check the entity already *
6643 existing or not. if we found the entry then update the information */
6644 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6647 entry->freedBytes += blkSz;
6648 entry->bucketFreeReq++;
6652 /* If hash list is full then print the error tna continue */
6653 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6655 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");
6659 /* Take the address of next free entry in the hash bin */
6660 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6662 /* Increase the number of time frees called */
6663 entry->bucketFreeReq++;
6664 entry->freedBytes += blkSz;
6666 /* Fill the information into the entry structure */
6667 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6668 /* Increase the total numbet of entries in the bin */
6669 hashListCp->hashList[binIdx].numOfEntries++;
6671 /* Increase the total number of entries in the hash list */
6672 hashListCp->totalNumEntries++;
6675 } /* end of cmHstGrmFreeInsert */
6680 * Fun: ret = cmHstGrmAllocInsert
6682 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
6684 * hashListCp control point for hash list
6685 * key pointer to key string in the new entry
6687 * Ret: ROK - insertion successful
6688 * RFAILED - insertion failed (incorrect parameter values)
6696 PRIVATE S16 cmHstGrmAllocInsert
6698 CmHstGrmHashListCp *hashListCp,
6706 PRIVATE S16 cmHstGrmAllocInsert(hashListCp, blkSz, reqSz, line, fileName, entId)
6707 CmHstGrmHashListCp *hashListCp;
6718 CmMemEntries *entry = NULLP;
6720 TRC2(cmHstGrmAllocInsert);
6722 /* check for the total number of entries in the hash list. *
6723 * If there is no place for new entry return failure */
6724 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6726 /* After comuting the hash bind and key, check the entity already *
6727 existing or not. if we found the entry then update the information */
6728 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6732 entry->allocBytes += blkSz;
6733 entry->bucketAllocReq++;
6734 entry->wastedBytes += (blkSz - *reqSz);
6738 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6740 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");
6744 /* Take the address of next free entry in the hash bin */
6745 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6747 /* Clauculae the wasted bytes */
6748 /* Here wasted byte is differnce between the byte user
6749 * has requested and the byte the ssi allocated */
6750 entry->wastedBytes += (blkSz - *reqSz);
6751 entry->bucketAllocReq++;
6752 entry->allocBytes += blkSz;
6754 /* Fill the information into the entry structure */
6755 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6756 /* Increase the total numbet of entries in the bin */
6757 hashListCp->hashList[binIdx].numOfEntries++;
6759 /* Increase the total number of entries in the hash list */
6760 hashListCp->totalNumEntries++;
6763 } /* end of cmHstGrmAllocInsert */
6768 * Fun: cmHstGrmGetHashIdxAndKey
6770 * Desc: Finds an entry in the hash list. Parameters are:
6772 * hashListCp control point for hash list
6773 * key pointer to key string in the new entry
6775 * Ret: ROK - insertion successful
6776 * RFAILED - insertion failed (incorrect parameter values)
6784 PRIVATE S16 cmHstGrmGetHashIdxAndKey
6792 PRIVATE S16 cmHstGrmGetHashIdxAndKey(fileName, line, binIdx, key)
6801 TRC2(cmHstGrmGetHashIdxAndKey);
6803 /* Calculate the key using file name and line number */
6804 for(i = 0 ; fileName[i] != '\0'; i++)
6806 *key += fileName[i];
6809 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
6811 } /* end of cmHstGrmFillEntry */
6815 * Fun: cmHstGrmFillEntry
6817 * Desc: Insert the entry into the hash list.
6819 * entry : Infornation which will be inserted into the hash list
6820 * key : Which will be used ti find the entry.
6821 * line : Line number
6822 * fileName : File name
6823 * entId : Tapa task Id
6825 * Ret: ROK - insertion successful
6826 * RFAILED - insertion failed (incorrect parameter values)
6834 PRIVATE S16 cmHstGrmFillEntry
6836 CmMemEntries *entry,
6843 PRIVATE S16 cmHstGrmFillEntry(entry, key, line, fileName, entId)
6844 CmMemEntries *entry;
6853 TRC2(cmHstGrmFillEntry);
6856 entry->entId = entId;
6857 for(idx = 0; fileName[idx] != '\0'; idx++)
6859 entry->fileName[idx] = fileName[idx];
6861 entry->fileName[idx] = '\0';
6863 } /* end of cmHstGrmFillEntry */
6867 * Fun: cmHstGrmFindEntry
6869 * Desc: Finds an entry in the hash list. Parameters are:
6871 * hashListCp control point for hash list
6872 * key pointer to key string in the new entry
6874 * Ret: ROK - insertion successful
6875 * RFAILED - insertion failed (incorrect parameter values)
6883 PRIVATE S16 cmHstGrmFindEntry
6885 CmHstGrmHashListCp *hashListCp,
6888 CmMemEntries **entry
6891 PRIVATE S16 cmHstGrmFindEntry(hashListCp, key, binIdx, entry)
6892 CmHstGrmHashListCp *hashListCp;
6895 CmMemEntries **entry;
6901 CmHstGrmHashListEnt *tmpBin = NULLP;
6903 TRC2(cmHstGrmFindEntry);
6906 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
6908 /* find for the entry in the bin */
6909 tmpBin = &(hashListCp->hashList[*binIdx]);
6910 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
6912 /* If key supplied is matched with the stored key then
6913 * return that entity */
6914 if(tmpBin->entries[numEnt].key == key)
6916 *entry = &(tmpBin->entries[numEnt]);
6918 }/* End of if (tmpBin->entries[numEnt].key) */
6919 }/* end of for (numEnt = 0) */
6921 /* Here we are checking for any room left in the bin. If the room *
6922 exists its mean that there is no entry with the Key. so return *
6924 If there is no room in the bin, then check the other bins to find *
6926 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
6928 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
6931 }/* End of if (binIdx) */
6935 }/* End of else (binIdx) */
6936 } /* End of if (numEnt) */
6939 printf ("Unable to find the entry in hash list\n");
6941 }/* End of else (numEnt) */
6942 }/* end of for (numBin = 0) */
6944 printf("Unable to find the entry in the hash list\n");
6946 } /* end of cmHstGrmFindEntry */
6948 #endif /* SS_HISTOGRAM_SUPPORT */
6949 #ifdef T2K_MEM_LEAK_DBG
6950 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
6951 U32 getT2kMemLeakIndex(U32 address)
6957 XOR 7 with 3 and remove 7
6958 XOR 1 with 5 and remove 1
6961 address -= T2K_MEM_LEAK_START_ADDR;
6963 U8 Nib7 = address & 0x0000000f;
6964 U8 Nib1 = (address & 0x0f000000) >>24;
6965 U8 Nib3 = (address & 0x000f0000) >> 16;
6966 U8 Nib5 = (address & 0x00000f00) >> 8;
6968 /* store 8 ^ 3 in 8Nib */
6970 /* store 1 ^ 6 in 6Nib */
6973 return(((address & 0x000fff00) | (Nib7 << 20) | (Nib5 << 4)) >> 4);
6976 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6979 static U32 t2kMemAllocTick;
6980 static U32 smallTick;
6982 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
6984 U32 idx = getT2kMemLeakIndex(address);
6986 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6988 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6989 "line is %ld \n", address, size, fileName, lineNo);
6992 if(gMemLeakInfo[idx].address == 0)
6994 gMemLeakInfo[idx].address = address;
6995 gMemLeakInfo[idx].size = size;
6996 gMemLeakInfo[idx].lineNo = lineNo;
6997 gMemLeakInfo[idx].fileName = fileName;
6998 gMemLeakInfo[idx].age = t2kMemAllocTick;
6999 gMemLeakInfo[idx].prevRemLineNo = 0;
7000 gMemLeakInfo[idx].prevRemFileName = '\0';
7002 if(smallTick++ == 4096)
7005 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
7010 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
7011 "line is %ld \n",address, idx, fileName, lineNo);
7012 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
7013 "Age:%ld, differnce in Age:%ld",
7014 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
7015 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
7016 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
7018 /* Try inserting into some other location */
7020 int lastIndex = idx + 1;
7021 Bool inserted = FALSE;
7022 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7024 if(gMemLeakInfo[lastIndex].address == 0)
7026 gMemLeakInfo[lastIndex].address = address;
7027 gMemLeakInfo[lastIndex].size = size;
7028 gMemLeakInfo[lastIndex].lineNo = lineNo;
7029 gMemLeakInfo[lastIndex].fileName = fileName;
7030 gMemLeakInfo[lastIndex].age = (++t2kMemAllocTick) >> 14; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7034 lastIndex = idx + (i * i * i);
7039 printf("Something is wrong, trying to insert %x idx = %d no free i = %d\n",address, idx, i);
7047 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
7049 U32 idx = getT2kMemLeakIndex(address);
7051 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
7053 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
7059 if(gMemLeakInfo[idx].address == address)
7061 gMemLeakInfo[idx].address = 0;
7062 gMemLeakInfo[idx].age = 0;
7063 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
7064 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
7066 gMemLeakInfo[idx].lastDelLineNum = line;
7067 gMemLeakInfo[idx].lastDelFileName = file;
7068 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
7072 printf("Something is wrong, trying to remove %lx idx = %ld from"
7073 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
7074 gMemLeakInfo[idx].address);
7077 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
7078 gMemLeakInfo[idx].lastDelLineNum);
7080 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
7082 printf("Previous File:%s, Previous Line:%ld\n",
7083 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
7086 /* Try removing from some other location where it might have been stored*/
7088 int lastIndex = idx + 1;
7089 Bool removed = FALSE;
7090 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7092 if(gMemLeakInfo[lastIndex].address == address)
7094 gMemLeakInfo[lastIndex].address = 0;
7095 gMemLeakInfo[lastIndex].size = 0;
7096 gMemLeakInfo[lastIndex].lineNo = 0;
7097 gMemLeakInfo[lastIndex].fileName = 0;
7098 gMemLeakInfo[lastIndex].age = 0; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7102 lastIndex = idx + (i*i*i);
7107 printf("Something is wrong, trying to remove %x idx = %d lastIndex = %d FreeCalled from File=%s, line=%d\n",address, idx, lastIndex,file,line);
7114 PUBLIC void DumpT2kMemLeakInfoToFile()
7118 FILE *fp = fopen("memLeakInfo.txt","wb");
7122 printf("Could not open file for dumping mem leak info\n");
7126 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
7128 if(gMemLeakInfo[i].address != 0)
7130 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
7131 if(onlyFileName == NULL)
7133 onlyFileName = gMemLeakInfo[i].fileName;
7136 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
7137 gMemLeakInfo[i].size,
7138 gMemLeakInfo[i].age,
7139 gMemLeakInfo[i].lineNo,
7144 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
7150 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7152 /* For Updating SOC Specific Memory Information */
7154 PUBLIC S16 UpdateSocMemInfo
7160 PUBLIC S16 UpdateSocMemInfo(areaIndex,mInfo)
7162 CmLteMemInfo *mInfo;
7168 void *iccHdl = NULLP;
7172 U32 poolTotAvail[4];
7174 idxReg = mInfo->numRegions;
7175 mInfo->numRegions = mInfo->numRegions + 1;
7176 /* Calling Soc specific API to get shared memory status */
7177 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
7178 iccHdl = ssGetIccHdl(areaIndex);
7180 /* Populating global memory information */
7181 mInfo->regInfo[idxReg].numPools = numPool;
7182 mInfo->regInfo[idxReg].regionId = areaIndex;
7183 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
7185 /* Calling INTEL API's to Get Free MEM BLOCKS */
7186 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7187 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7188 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7189 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7191 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
7192 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
7193 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
7194 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
7196 poolSize[0] = ICC_POOL_ZERO_SIZE;
7197 poolSize[1] = ICC_POOL_ONE_SIZE;
7198 poolSize[2] = ICC_POOL_TWO_SIZE;
7199 poolSize[3] = ICC_POOL_THREE_SIZE;
7201 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
7202 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
7203 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
7204 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
7206 for(idxPool=0; idxPool<numPool;idxPool++)
7208 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
7209 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
7210 poolTotAvail[idxPool];
7211 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
7212 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
7213 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
7215 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
7216 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
7225 * Fun: isL2MemUsageBelowLowerThreshold
7227 * Desc: Checks for the Lower threshold of ICC memory.
7229 * region region for obtaining the ICC handle
7231 * Ret: TRUE - Threshold has reached
7232 * FALSE - Threshold has not reached
7240 PUBLIC U32 isL2MemUsageBelowLowerThreshold(
7244 PUBLIC U32 isL2MemUsageBelowLowerThreshold(region)
7248 void * iccHdl = ssGetIccHdl(region);
7250 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7251 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7253 /* We are below the threshold if free count in BOTH of the pools
7254 * is above the ICC_MEM_LOWER_THRESHOLD % */
7255 if(((poolZeroFreeCnt * 100) >
7256 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
7257 ((poolOneFreeCnt * 100) >
7258 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
7269 * Fun: isMemUsageBelowLowerThreshold
7271 * Desc: Checks for the Lower threshold of ICC memory.
7273 * region region for obtaining the ICC handle
7275 * Ret: TRUE - Threshold has reached
7276 * FALSE - Threshold has not reached
7284 PUBLIC U32 isMemUsageBelowLowerThreshold(
7288 PUBLIC U32 isMemUsageBelowLowerThreshold(region)
7292 void * iccHdl = ssGetIccHdl(region);
7294 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7295 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7296 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7297 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7299 /* We are below the threshold if free count in BOTH of the pools
7300 * is above the ICC_MEM_LOWER_THRESHOLD % */
7301 if(((poolZeroFreeCnt * 100) >
7302 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
7303 ((poolOneFreeCnt * 100) >
7304 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
7305 ((poolTwoFreeCnt * 100) >
7306 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
7307 ((poolThreeFreeCnt * 100) >
7308 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
7318 * Fun: isMemUsageAboveUpperThreshold
7320 * Desc: Checks for the Upper threshold of ICC memory.
7322 * region region for obtaining the ICC handle
7324 * Ret: TRUE - Threshold has reached
7325 * FALSE - Threshold has not reached
7333 PRIVATE U32 isMemUsageAboveUpperThreshold(
7337 PRIVATE U32 isMemUsageAboveUpperThreshold(region)
7341 void * iccHdl = ssGetIccHdl(region);
7343 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
7344 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
7345 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
7346 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
7348 /* We are above the threshold if free count in either of the pools
7349 * is below the ICC_MEM_UPPER_THRESHOLD % */
7350 if(((poolZeroFreeCnt * 100) <
7351 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
7352 ((poolOneFreeCnt * 100) <
7353 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
7354 ((poolTwoFreeCnt * 100) <
7355 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
7356 ((poolThreeFreeCnt * 100) <
7357 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
7365 /* ccpu00142274- Function to check if we have reached the
7366 * Threshold for dropping UL packets at the RLC. This function
7367 * measures the free count of the ICC memory and based on the
7368 * volume of packets it sets an alarm to drop packets.
7369 * In DL, the PDCP packets are dropped at Admission Control, but
7370 * at UL we need to check if its an AM(Data only and
7371 * not Status PDU) or UM packet and free the PDU
7372 * Note: With the current design, we have PDCP DL and RLC UL
7373 * running in the same thread and the below function will be
7374 * accessed in tandem. But if PDCP DL and RLC UL are made to run
7375 * in different threads then there might be a race condition.
7376 * Please revisit this function in such a case.
7380 * Fun: isMemThreshReached
7382 * Desc: Checks whether the system has reached the
7383 * designated threshold of ICC memory.
7385 * region region for obtaining the ICC handle
7387 * Ret: ROK - Threshold has not reached
7388 * RFAILED - Threshold has reached
7396 PUBLIC U32 isMemThreshReached(
7400 PUBLIC U32 isMemThreshReached(reg)
7404 TRC3(isMemThreshReached)
7407 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
7412 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
7414 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
7415 memoryCheckCounter = 0;
7421 #endif /* SS_LOCKLESS_MEMORY */
7423 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
7424 U32 getT2kMemLeakIndex(U32 address)
7430 XOR 7 with 3 and remove 7
7431 XOR 1 with 5 and remove 1
7434 address -= T2K_MEM_LEAK_START_ADDR;
7436 U8 Nib7 = address & 0x0000000f;
7437 U8 Nib1 = (address & 0x0f000000) >>24;
7438 U8 Nib3 = (address & 0x000f0000) >> 16;
7439 U8 Nib5 = (address & 0x00000f00) >> 8;
7441 /* store 8 ^ 3 in 8Nib */
7443 /* store 1 ^ 6 in 6Nib */
7446 return(((address & 0x000fff00) | (Nib7 << 20) | (Nib5 << 4)) >> 4);
7449 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
7452 static U32 t2kMemAllocTick;
7453 static U32 smallTick;
7455 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
7457 U32 index = getT2kMemLeakIndex(address);
7459 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
7461 printf("address in InsertToT2kMemLeakInfo is %x size = %d file is %s line is %d \n", address, size, fileName, lineNo);
7464 if(gMemLeakInfo[index].address == 0)
7466 gMemLeakInfo[index].address = address;
7467 gMemLeakInfo[index].size = size;
7468 gMemLeakInfo[index].lineNo = lineNo;
7469 gMemLeakInfo[index].fileName = fileName;
7470 gMemLeakInfo[index].age = t2kMemAllocTick;
7471 gMemLeakInfo[index].prevRemLineNo = 0;
7472 gMemLeakInfo[index].prevRemFileName = '\0';
7474 if(smallTick++ == 4096)
7477 gMemLeakInfo[index].age = (++t2kMemAllocTick);
7482 printf("Something is wrong, trying to insert %x index = %d file is %s line is %d \n",address, index, fileName, lineNo);
7483 printf("Address present :%x, from File:%s, Line:%d, Size:%d, Age:%d",
7484 gMemLeakInfo[index].address, gMemLeakInfo[index].fileName,
7485 gMemLeakInfo[index].lineNo, gMemLeakInfo[index].size,
7486 gMemLeakInfo[index].age);
7488 /* Try inserting into some other location */
7490 int lastIndex = index + 1;
7491 Bool inserted = FALSE;
7492 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7494 if(gMemLeakInfo[lastIndex].address == 0)
7496 gMemLeakInfo[lastIndex].address = address;
7497 gMemLeakInfo[lastIndex].size = size;
7498 gMemLeakInfo[lastIndex].lineNo = lineNo;
7499 gMemLeakInfo[lastIndex].fileName = fileName;
7500 gMemLeakInfo[lastIndex].age = (++t2kMemAllocTick) >> 14; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7504 lastIndex = index + (i * i * i);
7509 printf("Something is wrong, trying to insert %x index = %d no free i = %d\n",address, index, i);
7517 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
7519 U32 index = getT2kMemLeakIndex(address);
7521 if(index >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
7523 printf("Index out of range = %d address is %x file = %s line = %d. We are going to crash!!!\n",
7529 if(gMemLeakInfo[index].address == address)
7531 gMemLeakInfo[index].address = 0;
7532 gMemLeakInfo[index].age = 0;
7533 gMemLeakInfo[index].prevRemLineNo = gMemLeakInfo[index].lineNo;
7534 gMemLeakInfo[index].prevRemFileName = gMemLeakInfo[index].fileName;
7536 /*printf("Something is wrong, Trying to double free Address = %x, Index = %d \n",address,index);*/
7540 printf("Something is wrong, trying to remove %x index = %d from File=%s, line=%d address present is %x\n",address, index, file,line,
7541 gMemLeakInfo[index].address);
7542 if(gMemLeakInfo[index].prevRemFileName != NULLP)
7544 printf("Previous File:%s, Previous Line:%d\n",
7545 gMemLeakInfo[index].prevRemFileName, gMemLeakInfo[index].prevRemLineNo);
7548 /* Try removing from some other location where it might have been stored*/
7550 int lastIndex = index + 1;
7551 Bool removed = FALSE;
7552 for(i = 2; lastIndex < T2K_MEM_LEAK_INFO_TABLE_SIZE && i < 30; i++)
7554 if(gMemLeakInfo[lastIndex].address == address)
7556 gMemLeakInfo[lastIndex].address = 0;
7557 gMemLeakInfo[lastIndex].size = 0;
7558 gMemLeakInfo[lastIndex].lineNo = 0;
7559 gMemLeakInfo[lastIndex].fileName = 0;
7560 gMemLeakInfo[lastIndex].age = 0; /*For every 16384 memory block allocations,Alloc Tick is incremented by 1*/
7564 lastIndex = index + (i*i*i);
7569 printf("Something is wrong, trying to remove %x index = %d lastIndex = %d FreeCalled from File=%s, line=%d\n",address, index, lastIndex,file,line);
7576 void DumpT2kMemLeakInfoToFile()
7580 FILE *fp = fopen("memLeakInfo.txt","wb");
7584 printf("Could not open file for dumping mem leak info\n");
7588 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
7590 if(gMemLeakInfo[i].address != 0)
7592 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
7593 if(onlyFileName == NULL)
7595 onlyFileName = gMemLeakInfo[i].fileName;
7598 fprintf(fp, "%p s=%d a=%d l=%d f=%s\n",gMemLeakInfo[i].address,
7599 gMemLeakInfo[i].size,
7600 gMemLeakInfo[i].age,
7601 gMemLeakInfo[i].lineNo,
7606 fprintf(fp,"Current t2kMemAllocTick = %d\n",t2kMemAllocTick);
7612 /**********************************************************************
7614 **********************************************************************/