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 U8 stopBtInfo = FALSE;
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 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 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler */
293 /* public variable declarations */
296 #endif /* USE_PURE */
297 /* cm_mem_c_001.main_15:Additions */
298 #ifdef SS_MEM_LEAK_STS
299 MemUsrMdlStr memUsrMdlStr[]=
301 MEMRAW2STR(DEFAULT, STACK),
302 MEMRAW2STR(tc, PDCP_LAYER),
303 MEMRAW2STR(Tc, PDCP_LAYER),
304 MEMRAW2STR(mg, GCP_LAYER),
305 MEMRAW2STR(Mg, GCP_LAYER),
310 #endif /* SS_MEM_LEAK_STS */
312 /* cm_mem_c_008.104 - Addition for memory calculator tool */
314 PRIVATE Txt prntBuf[200]; /* print buffer */
315 PRIVATE U8 tryHeap=0;
318 /* cm_mem_c_001.main_12 - addition for ssi enhancements prints */
319 /* cm_mem_c_001.main_20 Additions */
320 #if (defined(SSI_DEBUG_LEVEL1) || defined(SS_HISTOGRAM_SUPPORT))
322 PRIVATE Txt dbgPrntBuf[200]; /* print buffer */
324 #endif /*SSI_DEBUG_LEVEL1 || SS_HISTOGRAM_SUPPORT */
326 #ifdef T2K_MEM_LEAK_DBG
327 /* convert to decimal (0x(end_addr - start_addr)>>8)*2 */
328 #define T2K_MEM_LEAK_INFO_TABLE_SIZE 3670014 /* New Sercomm Board*/
329 //#define T2K_MEM_LEAK_INFO_TABLE_SIZE 3145726 /*Old Sercomm Board*/
330 /* 0x94200000 is the starting address allocated by ICC,
331 * whenever that changes pleasse change here */
332 //#define T2K_MEM_LEAK_START_ADDR 0x9d400000 /*Old Sercomm Board*/
333 #define T2K_MEM_LEAK_START_ADDR 0x9d200000 /*New Sercomm Board*/
337 EXTERN pthread_t tmpRegTidMap[20];
338 extern Bool g_usettitmr;
339 void DumpLayersDebugInformation()
341 DumpSSIDemandQDebugInformation();
342 /* dump layers information only after we start receiving the TTIs */
346 if (clusterMode == RADIO_CLUSTER_MODE)
348 DumpRLCDlDebugInformation();
350 #ifndef UL_RLC_NET_CLUSTER
351 DumpRLCUlDebugInformation();
357 #ifdef UL_RLC_NET_CLUSTER
358 DumpRLCUlDebugInformation();
360 DumpPDCPDlDebugInformation();
361 DumpPDCPUlDebugInformation();
364 //DumpPDCPDlDebugInformation();
365 //DumpPDCPUlDebugInformation();
366 #ifndef ODU_TEST_STUB
367 DumpRLCDlDebugInformation();
368 DumpRLCUlDebugInformation();
370 //printSchCellInfo();
375 /* private variable declarations */
378 * Fun: cmMmStatBktInit
380 * Desc: Initialize the bucket and the map table.
383 * Ret: ROK - successful,
384 * RFAILED - unsuccessful.
386 * Notes: This function is called by the cmMmRegInit.
392 PRIVATE Void cmMmStatBktInit
401 PRIVATE Void cmMmStatBktInit (memAddr, regCb, cfg, bktIdx, lstMapIdx)
413 /* cm_mem_c_001.main_12 - addition for temporary variables */
414 #ifdef SSI_DEBUG_LEVEL1
415 CmMmBlkHdr **nextBlk;
419 #endif /* SSI_DEBUG_LEVEL1 */
423 size = cfg->bktCfg[bktIdx].size;
424 numBlks = cfg->bktCfg[bktIdx].numBlks;
426 /* cm_mem_c_001.main_12 - addition for header initialization */
427 #ifdef SSI_DEBUG_LEVEL1
428 /* Reset the next block pointer */
429 regCb->bktTbl[bktIdx].nextBlk = NULLP;
431 /* Initialize the link list of the memory block */
432 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
434 for (cnt = 0; cnt < numBlks; cnt++)
436 *nextBlk = (CmMmBlkHdr *)*memAddr;
438 /* initialize the memory block header */
439 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
441 (*nextBlk)->trSignature[sigCnt] = 0xAB;
444 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
445 (*nextBlk)->requestedSize = 0;
446 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
447 nextBlk = &((*nextBlk)->nextBlk);
453 /* Initialize the bucket linked list */
455 /* Reset the next pointer */
456 regCb->bktTbl[bktIdx].next = NULLP;
458 /* Initialize the link list of the memory block */
459 next = &(regCb->bktTbl[bktIdx].next);
460 for (cnt = 0; cnt < numBlks; cnt++)
463 next = (CmMmEntry **)(*memAddr);
464 *memAddr = (*memAddr) + size;
469 #endif /* SSI_DEBUG_LEVEL1 */
471 /* Initialize the Map entry */
472 idx = size / cfg->bktQnSize;
475 * Check if the size is multiple of quantum size. If not we need to initialize
476 * one more map table entry.
478 if(size % cfg->bktQnSize)
483 while ( *lstMapIdx < idx)
485 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
487 #if (ERRCLASS & ERRCLS_DEBUG)
488 regCb->mapTbl[*lstMapIdx].numReq = 0;
489 regCb->mapTbl[*lstMapIdx].numFailure = 0;
495 /* Initialize the bucket structure */
496 regCb->bktTbl[bktIdx].size = size;
497 regCb->bktTbl[bktIdx].numBlks = numBlks;
498 regCb->bktTbl[bktIdx].numAlloc = 0;
499 regCb->bktTbl[bktIdx].maxAlloc = 0;
501 /* Update the total bucket size */
502 /* cm_mem_c_001.main_12 - addition for considering the header size */
503 #ifdef SSI_DEBUG_LEVEL1
504 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
506 regCb->bktSize += (size * numBlks);
507 #endif /* SSI_DEBUG_LEVEL1 */
509 regCb->bktTbl[bktIdx].bktFailCnt = 0;
510 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
512 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
513 #ifdef SSI_DEBUG_LEVEL1
514 /* Initialize other required pointers */
515 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
516 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
517 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
518 regCb->bktTbl[bktIdx].staticMemUsed = 0;
519 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
520 regCb->bktTbl[bktIdx].trampleCount = 0;
521 #endif /*SSI_DEBUG_LEVEL1*/
522 /* cm_mem_c_001.main_15 : Additions */
523 #ifdef SS_HISTOGRAM_SUPPORT
524 /* Initialise the memory histogram hash list */
525 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
526 #endif /* SS_HISTOGRAM_SUPPORT */
529 } /* end of cmMmStatBktInit */
533 * Fun: cmMmStatRegInit
535 * Desc: Configure the memory region for allocation. The function
536 * registers the memory region with System Service by calling
540 * Ret: ROK - successful,
541 * RFAILED - unsuccessful.
543 * Notes: The memory owner calls this function to initialize the memory
544 * manager with the information of the memory region. Before
545 * calling this function, the memory owner should allocate memory
546 * for the memory region. The memory owner should also provide the
547 * memory for the control block needed by the memory manager. The
548 * memory owner should allocate the memory for the region control
549 * block as cachable memory. This may increase the average
550 * throughput in allocation and deallocation as the region control
551 * block is mostly accessed by the CMM.
564 S16 cmMmStatRegInit(region, regCb, cfg)
574 #if (ERRCLASS & ERRCLS_INT_PAR)
577 Txt errMsg[256] = {'\0'};
581 #if (ERRCLASS & ERRCLS_INT_PAR)
583 /* error check on parameters */
584 if ((regCb == NULLP) || (cfg == NULLP))
589 /* Error check on the configuration fields */
590 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
591 (cfg->numBkts > CMM_MAX_BKT_ENT))
595 /* Check if the quantum size is power of 2 */
596 if ((cfg->numBkts) &&
597 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
599 /* cm_mem_c_001.main_20 Addition */
600 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
606 * Check if the size of the memory region is enough, whether bucket sizes
607 * are multiples of quantumn size, and also whether two consecutive buckets
608 * falls within same quanta.
610 lstQnSize = cfg->bktQnSize;
613 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
615 /* check if bucket size is mutiple of quantum size */
616 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
618 /* cm_mem_c_001.main_20 Addition */
619 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
621 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
622 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
624 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
625 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
631 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
634 * Two consecutive buckets are not separated by quantum size.
636 /* cm_mem_c_001.main_20 Addition */
637 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
641 /* cm_mem_c_001.main_20 Addition */
642 if (((cfg->bktCfg[bktIdx].size) /\
643 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
645 /* Error check whether the size of the mapping table is sufficient */
646 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
648 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
649 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
651 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
652 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
659 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
660 cfg->bktCfg[bktIdx].numBlks);
662 if (regCb->bktSize > cfg->size)
664 /* Size of the memory region is less than the required size */
666 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
671 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
676 /* Initialize the region control block */
677 regCb->region = region;
678 regCb->regInfo.regCb = regCb;
679 regCb->regInfo.start = cfg->vAddr;
680 regCb->regInfo.size = cfg->size;
683 avail_size = cfg->size;
684 #endif /* USE_PURE */
686 if ( cfg->chFlag & CMM_REG_OUTBOARD)
688 /* Out_of_board memory */
689 regCb->regInfo.flags = CMM_REG_OUTBOARD;
693 regCb->regInfo.flags = 0;
698 if(region == SS_MAX_REGS - 1)
700 regCb->regInfo.alloc = cmAlloc;
701 regCb->regInfo.free = cmFree;
702 regCb->regInfo.ctl = cmCtl;
706 regCb->regInfo.alloc = cmAllocWL;
707 regCb->regInfo.free = cmFreeWL;
708 regCb->regInfo.ctl = cmCtl;
711 regCb->regInfo.alloc = cmAlloc;
712 regCb->regInfo.free = cmFree;
713 regCb->regInfo.ctl = cmCtl;
716 /* Initialize the physical address */
717 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
719 regCb->pAddr = cfg->pAddr;
722 /* Initial address of the memory region block */
723 memAddr = cfg->vAddr;
725 /* Initialize the fields related to the bucket pool */
726 regCb->bktMaxBlkSize = 0;
731 /* Last bucket has the maximum size */
732 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
734 /* Get the power of the bktQnSize */
736 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
741 /* Initilaize the bktIndex of the map entries to FF */
742 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
744 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
748 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
750 /* Allocate the lock for the bucket pool */
751 cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
754 /* Used while freeing the bktLock in cmMmRegDeInit */
755 regCb->numBkts = cfg->numBkts;
759 * Initialize the heap pool if size the memory region region is more
760 * than the size of the bucket pool
763 regCb->heapFlag = FALSE;
765 /* Align the memory address */
766 memAddr = (Data *)(PTRALIGN(memAddr));
768 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
771 * Round the heap size so that the heap size is multiple
774 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
778 /* Allocate the lock for the heap pool */
779 regCb->heapFlag = TRUE;
780 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
783 /* Call SRegRegion to register the memory region with SSI */
784 if (SRegRegion(region, ®Cb->regInfo) != ROK)
790 } /* end of cmMmRegInit*/
795 * Fun: cmMmGlobRegInit
797 * Desc: Configure the memory region for allocation. The function
798 * registers the memory region with System Service by calling
802 * Ret: ROK - successful,
803 * RFAILED - unsuccessful.
816 S16 cmMmGlobRegInit(regCb)
817 CmMmGlobRegCb *regCb;
826 CmMmBlkSetElement *blkLstElem;
829 #if (ERRCLASS & ERRCLS_INT_PAR)
832 Txt errMsg[256] = {'\0'};
836 #ifdef SS_MEM_WL_DEBUG
837 if (cmInitBtInfo() == RFAILED)
842 for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
844 /* Initial address of the memory region block */
845 memAddr = ®Cb->bktTbl[bktIdx].startAddr;
846 bucketSetSize = regCb->bktTbl[bktIdx].bucketSetSize;
847 size = regCb->bktTbl[bktIdx].size;
849 /* Initialize the bucket linked list */
850 cmLListInit(®Cb->bktTbl[bktIdx].listValidBktSet);
851 cmLListInit(®Cb->bktTbl[bktIdx].listFreeBktSet);
852 SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
854 /* Initialize the link list of the memory block */
855 next = &(regCb->bktTbl[bktIdx].next);
857 numBlks = regCb->bktTbl[bktIdx].numBlks;
858 for (cnt = 1; cnt <= numBlks; cnt++)
861 next = (CmMmEntry **)(*memAddr);
862 *memAddr = (*memAddr) + size;
864 /* Maintain the list Cb */
865 if(!(cnt % bucketSetSize))
867 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
868 blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
869 blkLstElem->numFreeBlks = bucketSetSize;
870 blkLstElem->memSetNode.node = (PTR)blkLstElem;
871 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
872 next = &(regCb->bktTbl[bktIdx].next);
879 } /* end of cmMmGlobRegInit*/
881 #ifdef SS_USE_ICC_MEMORY
884 * Fun: cmIccAllocWithLock
886 * Desc: Allocate a memory block for use by dynamic buffers.
887 * This handler uses the lock to avoid the two thread
888 * trying to allocate the memory at same time. This
889 * handler must be used only for non-data plane thread
890 * it causes delay due to lock.
893 * Ret: ROK - successful
894 * RFAILED - unsuccessful.
901 #ifdef T2K_MEM_LEAK_DBG
903 PRIVATE S16 cmIccAllocWithLock
905 Void *regionCb, /* Pointer to a region */
906 Size *size, /* size needs to be allocated */
907 U32 flags, /* Flags used */
908 Data **ptr, /* Reference to pointer for which need to be allocate */
915 PRIVATE S16 cmIccAllocWithLock
917 Void *regionCb, /* Pointer to a region */
918 Size *size, /* size needs to be allocated */
919 U32 flags, /* Flags used */
920 Data **ptr /* Reference to pointer for which need to be allocate */
923 PRIVATE S16 cmIccAllocWithLock(regionCb, size, flags, ptr)
924 Void *regionCb; /* Pointer to a region */
925 Size *size; /* size needs to be allocated */
926 U32 flags; /* Flags used */
927 Data **ptr; /* Reference to pointer for which need to be allocate */
935 regCb = (CmMmDynRegCb *)regionCb;
937 if((SLock(&iccAllocFreeLock)) != ROK)
939 printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
943 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
945 if((SUnlock(&iccAllocFreeLock)) != ROK)
947 printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
951 if ((memPtr) == NULLP)
954 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
955 printf("Exiting...\n");
960 #ifdef T2K_MEM_LEAK_DBG
961 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
963 printf("Address returned is %p size = %ld\n",memPtr,*size);
966 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
972 } /* end of cmIccAllocWithLock */
976 * Fun: cmIccFreeWithLock
978 * Desc: Return the Dynamic memory block for the memory region.
979 * This handler uses the lock to avoid the two thread
980 * trying to free the memory at same time. This
981 * handler must be used only for non-data plane thread
982 * it causes delay due to lock.
984 * Ret: ROK - successful
985 * RFAILED - unsuccessful.
993 #ifdef T2K_MEM_LEAK_DBG
995 PRIVATE S16 cmIccFreeWithLock
997 Void *regionCb, /* Pointer to region cb */
998 Data *ptr, /* Memory block needs to be freed */
999 Size size, /* Size of the block */
1006 PRIVATE S16 cmIccFreeWithLock
1008 Void *regionCb, /* Pointer to region cb */
1009 Data *ptr, /* Memory block needs to be freed */
1010 Size size /* Size of the block */
1013 PRIVATE S16 cmIccFreeWithLock(regionCb, ptr, size)
1014 Void *regionCb; /* Pointer to region cb */
1015 Data *ptr; /* Memory block needs to be freed */
1016 Size size; /* Size of the block */
1020 CmMmDynRegCb *regCb;
1023 regCb = (CmMmDynRegCb *)regionCb;
1025 if((SLock(&iccAllocFreeLock)) != ROK)
1027 printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
1031 #ifdef T2K_MEM_LEAK_DBG
1032 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1035 TL_Free(regCb->iccHdl, ptr);
1037 if((SUnlock(&iccAllocFreeLock)) != ROK)
1039 printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1044 } /* end of cmIccFree */
1050 * Desc: Allocate a memory block for use by dynamic buffers
1053 * Ret: ROK - successful
1054 * RFAILED - unsuccessful.
1061 #ifdef T2K_MEM_LEAK_DBG
1063 PRIVATE S16 cmIccAlloc
1065 Void *regionCb, /* Pointer to a region */
1066 Size *size, /* size needs to be allocated */
1067 U32 flags, /* Flags used */
1068 Data **ptr, /* Reference to pointer for which need to be allocate */
1076 PRIVATE S16 cmIccAlloc
1078 Void *regionCb, /* Pointer to a region */
1079 Size *size, /* size needs to be allocated */
1080 U32 flags, /* Flags used */
1081 Data **ptr /* Reference to pointer for which need to be allocate */
1084 PRIVATE S16 cmIccAlloc(regionCb, size, flags, ptr)
1085 Void *regionCb; /* Pointer to a region */
1086 Size *size; /* size needs to be allocated */
1087 U32 flags; /* Flags used */
1088 Data **ptr; /* Reference to pointer for which need to be allocate */
1093 CmMmDynRegCb *regCb;
1097 regCb = (CmMmDynRegCb *)regionCb;
1099 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1101 if ((memPtr) == NULLP)
1104 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1105 printf("Exiting...\n");
1109 #ifdef T2K_MEM_LEAK_DBG
1110 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1112 printf("Address returned is %p size = %ld\n",memPtr,*size);
1115 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1118 *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1120 *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1125 } /* end of cmIccAlloc */
1131 * Desc: Return the Dynamic memory block for the memory region.
1134 * Ret: ROK - successful
1135 * RFAILED - unsuccessful.
1143 #ifdef T2K_MEM_LEAK_DBG
1144 PRIVATE S16 cmIccFree
1146 Void *regionCb, /* Pointer to region cb */
1147 Data *ptr, /* Memory block needs to be freed */
1148 Size size, /* Size of the block */
1154 PRIVATE S16 cmIccFree
1156 Void *regionCb, /* Pointer to region cb */
1157 Data *ptr, /* Memory block needs to be freed */
1158 Size size /* Size of the block */
1161 PRIVATE S16 cmIccFree(regionCb, ptr, size)
1162 Void *regionCb; /* Pointer to region cb */
1163 Data *ptr; /* Memory block needs to be freed */
1164 Size size; /* Size of the block */
1168 CmMmDynRegCb *regCb;
1170 regCb = (CmMmDynRegCb *)regionCb;
1173 // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1175 #ifdef T2K_MEM_LEAK_DBG
1176 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1180 TL_Free(regCb->iccHdl, ptr);
1182 /* memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1184 TL_Free(regCb->iccHdl, memPtr);
1186 /*TL_Free(regCb->iccHdl, ptr);*/
1190 } /* end of cmIccFree */
1194 * Fun: cmMmDynRegInit
1196 * Desc: Configure the memory region for allocation. The function
1197 * registers the memory region with System Service by calling
1201 * Ret: ROK - successful,
1202 * RFAILED - unsuccessful.
1204 * Notes: The memory owner calls this function to initialize the memory
1205 * manager with the information of the memory region. Before
1206 * calling this function, the memory owner should allocate memory
1207 * for the memory region. The memory owner should also provide the
1208 * memory for the control block needed by the memory manager. The
1209 * memory owner should allocate the memory for the region control
1210 * block as cachable memory. This may increase the average
1211 * throughput in allocation and deallocation as the region control
1212 * block is mostly accessed by the CMM.
1223 S16 cmMmDynRegInit(regCb)
1224 CmMmDynRegCb *regCb;
1228 #ifdef T2200_2GB_DDR_CHANGES
1229 Txt regIccStr[10] = {'\0'};
1231 Txt regIccStr[64] = {'\0'};
1235 /* Register the region/memory with ICC and get the handler for same. The id is starting
1236 * from region+1 as the zero is used by PHY code */
1237 #ifdef T2200_2GB_DDR_CHANGES
1238 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1241 if(clusterMode == RADIO_CLUSTER_MODE)
1243 if(regCb->region == 3)
1244 {/* ICC packet receiver */
1245 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1248 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1249 //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1253 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1254 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1255 //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1258 #ifdef T2200_2GB_DDR_CHANGES
1259 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1261 sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1265 printf(" %s \n",regIccStr);
1266 regCb->iccHdl = TL_Open(regIccStr, 0);
1268 printf("\nICC Region is %d\n",regCb->region);
1270 /* Call SRegRegion to register the memory region with SSI */
1271 memset(®Info, 0, sizeof(regInfo));
1273 /* Register the lock region for SS_MAX_REGS - 1 region */
1274 if((SS_MAX_REGS - 1) == regCb->region)
1276 regInfo.alloc = cmIccAllocWithLock;
1277 regInfo.free = cmIccFreeWithLock;
1278 regInfo.regCb = regCb;
1279 if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1281 printf("Failed to initialize the lock region lock\n");
1286 regInfo.alloc = cmIccAlloc;
1287 regInfo.free = cmIccFree;
1288 regInfo.regCb = regCb;
1291 if (SRegDynRegion(regCb->region, ®Info) != ROK)
1297 } /* end of cmMmDynRegInit*/
1299 #else /* SS_USE_ICC_MEMORY */
1303 * Fun: cmMmDynRegInit
1305 * Desc: Configure the memory region for allocation. The function
1306 * registers the memory region with System Service by calling
1310 * Ret: ROK - successful,
1311 * RFAILED - unsuccessful.
1313 * Notes: The memory owner calls this function to initialize the memory
1314 * manager with the information of the memory region. Before
1315 * calling this function, the memory owner should allocate memory
1316 * for the memory region. The memory owner should also provide the
1317 * memory for the control block needed by the memory manager. The
1318 * memory owner should allocate the memory for the region control
1319 * block as cachable memory. This may increase the average
1320 * throughput in allocation and deallocation as the region control
1321 * block is mostly accessed by the CMM.
1332 S16 cmMmDynRegInit(regCb)
1333 CmMmDynRegCb *regCb;
1340 CmMmBlkSetElement *blkLstElem;
1342 Size bktQnSize = MT_BKTQNSIZE;
1348 /* Initialize the region control block */
1349 region = regCb->region;
1350 numBkts = regCb->numBkts;
1352 /* Initilaize the bktIndex of the map entries to FF */
1353 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1355 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1360 for(cnt = 0; cnt < numBkts; cnt++)
1362 /* Initialize the Map entry */
1363 size = regCb->bktTbl[cnt].size;
1364 idx = size / bktQnSize;
1367 * Check if the size is multiple of quantum size. If not we need to initialize
1368 * one more map table entry.
1370 if(size % bktQnSize)
1375 while ( lstMapIdx < idx)
1377 regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1382 regCb->bktQnPwr = 0;
1384 while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1389 /* Initialize the bucket structure */
1390 for(idx = 0; idx < numBkts; idx++)
1392 regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1394 for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1396 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1397 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1398 cmLListAdd2Tail((®Cb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1402 /* Call SRegRegion to register the memory region with SSI */
1403 memset(®Info, 0, sizeof(regInfo));
1404 if((SS_MAX_REGS - 1) == regCb->region)
1406 regInfo.alloc = cmDynAllocWithLock;
1407 regInfo.free = cmDynFreeWithLock;
1408 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1410 printf("Failed to initialize the lock region lock\n");
1415 regInfo.alloc = cmDynAlloc;
1416 regInfo.free = cmDynFree;
1419 regInfo.regCb = regCb;
1421 if (SRegDynRegion(region, ®Info) != ROK)
1427 } /* end of cmMmDynRegInit*/
1429 #endif /* SS_USE_ICC_MEMORY */
1434 * Fun: cmMmRegDeInit
1436 * Desc: Deinitialize the memory region. The function call SDeregRegion
1437 * to deregister the memory region with System Service.
1440 * Ret: ROK - successful
1441 * RFAILED - unsuccessful.
1443 * Notes: The memory owner calls this function to deinitialize the region.
1444 * The memory manager does not return the memory to the system.
1445 * Before calling this function, the memory owner must be sure that
1446 * no layer is using any memory block from this region. On
1447 * successful return from the function, any request to the memory
1448 * manager to allocate/deallocate memory will fail. The memory owner
1449 * can reuse the memory for other region or return the memory to the
1450 * system memory pool.
1463 S16 cmMmRegDeInit(regCb)
1470 #if (ERRCLASS & ERRCLS_INT_PAR)
1472 /* error check on parameters */
1480 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1481 #ifdef SSI_DEBUG_LEVEL1
1482 /* Deinitialize the hash table used for debug info storage at region level */
1483 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
1487 #endif /* SSI_DEBUG_LEVEL1 */
1489 /* Call SDeregRegion first to deregister the memory region with SSI */
1490 (Void) SDeregRegion (regCb->region);
1494 /* Bucket pool is configured */
1496 /* Free the initialzed locks of the buckets */
1497 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1499 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1500 WTDestroyLock for NT */
1501 /* cm_mem_c_001.main_24 fix for memory corruption*/
1504 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1506 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1508 /* cm_mem_c_001.main_15:Additions */
1509 #ifdef SS_HISTOGRAM_SUPPORT
1510 /* De-initialise the memory histogram hash list */
1511 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1512 #endif /* SS_HISTOGRAM_SUPPORT */
1516 if (regCb->heapFlag)
1518 /* Heap pool is configured */
1520 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1521 WTDestroyLock for NT */
1523 WTDestroyLock(®Cb->heapCb.heapLock);
1525 SDestroyLock(®Cb->heapCb.heapLock);
1531 } /* end of cmMmRegDeInit */
1534 #ifndef SS_USE_ICC_MEMORY
1537 * Fun: cmGetMemBlkSetForAlloc
1539 * Desc: Retruns the pointer to the element which is used for
1540 * allocating the buffer. Also, it does the threshold check
1541 * and get the additional memory block set from the global
1545 * Ret: Pointer to memory block set - successful
1546 * NULL - unsuccessful.
1549 * Current implementation of the is function is made assuming that
1550 * there will maximum two set of nodes only.
1557 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1559 U8 bucketIndex, /* Index to the bucket list */
1560 CmMmDynBktCb *bkt /* Bucket list control block */
1563 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc(bucketIndex, bkt)
1564 U8 bucketIndex; /* Index to the bucket list */
1565 CmMmDynBktCb *bkt; /* Bucket list control block */
1568 CmMmBlkSetElement *memBlkSetElem;
1569 CmMmBlkSetElement *nextMemBlkSetElem;
1570 CmLList *memSetNode;
1571 CmLList *nextMemSetNode;
1573 /* Check if we are coming here for the first time, if yes get a new
1574 * block set from global region */
1575 if(bkt->crntMemBlkSetElem == NULLP)
1577 /* set the current index to initial one and get the bucket set from
1579 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1581 /* Check if the element exits or not */
1582 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1587 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1588 /* Get the new block set from the gloabl region and return the same */
1589 ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1590 return (bkt->crntMemBlkSetElem);
1592 /* If this is not the first time, take the bucket list CB from the
1594 memBlkSetElem = bkt->crntMemBlkSetElem;
1595 /* If the current index doesnot have any free buckets, it check in
1596 * the next bucket node */
1597 if(memBlkSetElem->numFreeBlks == 0)
1599 /* Get the next element in the list and if it is not present, then
1600 * get the first node */
1601 memSetNode = cmLListNext(&bkt->memBlkSetElem);
1603 if(memSetNode == NULLP)
1605 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1607 memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1609 /* if next node also empty, return failure */
1610 if(memBlkSetElem->numFreeBlks == 0)
1614 /* store the new index in the current node which will be
1615 * used in the next time. */
1616 bkt->crntMemBlkSetElem = memBlkSetElem;
1619 /* If we have reached the threshold value, get the next set of buckets from
1620 * the global region and place it */
1621 if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1623 /* Get the next element for the threshold check. If next is not present,
1624 * get the first one. Here, we are not using the cmLList macros to get
1625 * to the next node or first node as those macros are working on the crnt
1626 * node and will change the crnt. As we dont want to change the crnt node
1627 * at this point, we are directly using the listCp prameter to get next
1629 nextMemSetNode = memBlkSetElem->memSetNode.next;
1631 if(nextMemSetNode == NULLP)
1633 nextMemSetNode = bkt->memBlkSetElem.first;
1636 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1638 if(nextMemBlkSetElem->numFreeBlks == 0)
1640 /* The last parameter is used wheather to block for the block set aquiring
1641 or not. Here, the logic is such that, when the current node number of
1642 free blocks becomes one and the next node has zero free blocks,
1643 we must get the block set from global region.
1644 For example, if acquire threashold is 20 and current node has only one
1645 free block and next node has zero free blocks we block to aquire lock
1646 and get the set from global region else, we try for lock, if we get
1647 the lock, the get the block set else it is get in next go
1649 ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1650 (memBlkSetElem->numFreeBlks - 1));
1654 /* On successful, return the bucket node to calling function */
1655 return (memBlkSetElem);
1656 } /* cmGetMemBlkSetForAlloc */
1661 * Fun: cmGetMemBlkSetForFree
1663 * Desc: Retruns the pointer to the element which is used for
1664 * freeing the buffer. Also, it does the threshold check
1665 * and release the additional memory block set to the global
1669 * Ret: Pointer to memory block set - successful
1670 * NULL - unsuccessful.
1673 * Current implementation of the is function is made assuming that
1674 * there will maximum two set of nodes only.
1681 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree
1683 U8 bucketIndex, /* Index to the bucket list */
1684 CmMmDynBktCb *bkt /* Bucket list control block */
1687 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree(bucketIndex, bkt)
1688 U8 bucketIndex; /* Index to the bucket list */
1689 CmMmDynBktCb *bkt; /* Bucket list control block */
1692 CmMmBlkSetElement *memBlkSetElem;
1693 CmMmBlkSetElement *nextMemBlkSetElem;
1694 CmLList *memSetNode;
1695 CmLList *nextMemSetNode;
1697 /* Check if we are coming here for the first time, if yes get a new
1698 * block set from global region */
1699 if(bkt->crntMemBlkSetElem == NULLP)
1701 /* set the current index to initial one */
1702 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1704 /* Check if the element exits or not */
1705 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1709 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1710 return (bkt->crntMemBlkSetElem);
1712 /* If this is not the first time, take the bucket list CB from the
1714 memBlkSetElem = bkt->crntMemBlkSetElem;
1715 /* If the current index doesnot have any free buckets, it check in
1716 * the next bucket node */
1717 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1719 /* Get the next element in the list and if it is not present, then
1720 * get the first node */
1721 nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1723 if(nextMemSetNode == NULLP)
1725 nextMemSetNode = cmLListFirst(&bkt->memBlkSetElem);
1727 memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1729 /* if next node also empty, return failure */
1730 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1734 /* store the new index in the current node which will be
1735 * used in the next time. */
1736 bkt->crntMemBlkSetElem = memBlkSetElem;
1739 /* If we have reached the threshold value and have additional block set,
1740 * release the additional block set back to global region */
1741 if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold)
1743 /* Get the next element for the threshold check. If next is not present,
1744 * get the first one. Here, we are not using the cmLList macros to get
1745 * to the next node or first node as those macros are working on the crnt
1746 * node and will change the crnt. As we dont want to change the crnt node
1747 * at this point, we are directly using the listCp prameter to get next
1749 nextMemSetNode = memBlkSetElem->memSetNode.next;
1750 if(nextMemSetNode == NULLP)
1752 nextMemSetNode = bkt->memBlkSetElem.first;
1755 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1756 if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
1758 /* The last parameter is used wheather to block for the block set aquiring
1759 or not. Here, the logic is such that, when the current node number of
1760 free blocks becomes one less than the bucket set size and the next node
1761 is has full free blocks, we must free the block set back to global region
1762 For example, if bucket set size if 100 and release threashold is 80 and
1763 current node has number of free blocks 99 and next node has 100 free blocks
1764 we block to aquire lock and free it back to global region else, we try for
1765 lock, if we get the lock, the block set is freed else its freed in next go
1767 ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1768 (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
1772 /* On successful, return the bucket node to calling function */
1773 return (memBlkSetElem);
1775 #endif /* SS_USE_ICC_MEMORY */
1776 #endif /* USE_PURE */
1778 #ifdef SS_MEM_WL_DEBUG
1781 * Fun: cmRemoveAllocPtrFromList
1783 * Desc: Remove a node with Free PTR from hashlist. The memory
1784 * of the node is Freed to the same region
1787 * Ret: ROK - successful
1788 * RFAILED - unsuccessful.
1797 PRIVATE S16 cmRemoveAllocPtrFromList
1799 CmMmDynRegCb *regionCb, /* Pointer to a region */
1803 PRIVATE S16 cmRemoveAllocPtrFromList(regionCb, ptr)
1804 CmMmDynRegCb *regionCb; /* Pointer to a region */
1809 CmMemDoubleFree *memNode = NULLP;
1811 SLock(&memDoubleFreeLock);
1812 if((cmHashListFind(&(memDoubleFree), (U8*)&ptr,
1813 sizeof(U32), 0, (PTR *)&memNode)) != ROK)
1820 tmpBtSize = backtrace(tmpBtArr, 10);
1821 strings = backtrace_symbols(tmpBtArr, tmpBtSize);
1822 printf("**** Trying to free non allocated block BT is: \n");
1823 for(idx = 0; idx < tmpBtSize; idx++)
1825 printf("%s\n", strings[idx]);
1827 printf("*****************************************\n");
1828 printf("Analysis from Array storing BT for freeing and allocation\n");
1829 cmAnalyseBtInfo(ptr, regionCb->region);
1830 SUnlock(&memDoubleFreeLock);
1834 if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
1836 SUnlock(&memDoubleFreeLock);
1839 SUnlock(&memDoubleFreeLock);
1840 SPutSBuf(regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
1847 * Fun: cmInsertAllocPtrToList
1849 * Desc: Insert a node with allocated PTR into hashlist. The memory
1850 * for the node is allocated from the same region
1853 * Ret: ROK - successful
1854 * RFAILED - unsuccessful.
1863 PRIVATE S16 cmInsertAllocPtrToList
1865 CmMmDynRegCb *regionCb, /* Pointer to a region */
1869 PRIVATE S16 cmInsertAllocPtrToList(regionCb, ptr)
1870 CmMmDynRegCb *regionCb; /* Pointer to a region */
1875 CmMemDoubleFree *memNode;
1877 SGetSBuf(regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
1878 if(memNode == NULLP)
1883 memNode->memBlkPtr = ptr;
1884 SLock(&memDoubleFreeLock);
1885 if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (U8*)&memNode->memBlkPtr,
1886 sizeof(PTR))) != ROK)
1888 SUnlock(&memDoubleFreeLock);
1891 SUnlock(&memDoubleFreeLock);
1898 #ifndef SS_USE_ICC_MEMORY
1901 * Fun: cmDynAllocWithLock
1903 * Desc: Allocate a memory block for use by dynamic buffers
1906 * Ret: ROK - successful
1907 * RFAILED - unsuccessful.
1914 /* cm_mem_c_001.main_15 : Additions */
1917 PRIVATE S16 cmDynAllocWithLock
1919 Void *regionCb, /* Pointer to a region */
1920 Size *size, /* size needs to be allocated */
1921 U32 flags, /* Flags used */
1922 Data **ptr /* Reference to pointer for which need to be allocate */
1925 PRIVATE S16 cmDynAllocWithLock(regionCb, size, flags, ptr)
1926 Void *regionCb; /* Pointer to a region */
1927 Size *size; /* size needs to be allocated */
1928 U32 flags; /* Flags used */
1929 Data **ptr; /* Reference to pointer for which need to be allocate */
1935 if((SLock(&dynAllocFreeLock)) != ROK)
1937 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1941 ret = cmDynAlloc (regionCb, size,flags,ptr);
1943 if((SUnlock(&dynAllocFreeLock)) != ROK)
1945 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1950 } /* end of cmDynAlloc */
1956 * Desc: Allocate a memory block for use by dynamic buffers
1959 * Ret: ROK - successful
1960 * RFAILED - unsuccessful.
1967 /* cm_mem_c_001.main_15 : Additions */
1970 PRIVATE S16 cmDynAlloc
1972 Void *regionCb, /* Pointer to a region */
1973 Size *size, /* size needs to be allocated */
1974 U32 flags, /* Flags used */
1975 Data **ptr /* Reference to pointer for which need to be allocate */
1978 PRIVATE S16 cmDynAlloc(regionCb, size, flags, ptr)
1979 Void *regionCb; /* Pointer to a region */
1980 Size *size; /* size needs to be allocated */
1981 U32 flags; /* Flags used */
1982 Data **ptr; /* Reference to pointer for which need to be allocate */
1985 CmMmDynRegCb *regCb;
1988 regCb = (CmMmDynRegCb *)regionCb;
1990 #ifdef SS_MEM_WL_DEBUG
1991 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
1997 #if (ERRCLASS & ERRCLS_INT_PAR)
1999 /* error check on parameters */
2000 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2009 * Check if the requested size is less than or equal to the maximum block
2010 * size in the bucket.
2013 #ifdef SS_MEM_WL_DEBUG
2014 if ( (*size + 4) <= regCb->bktMaxBlkSize)
2016 if ( (*size) <= regCb->bktMaxBlkSize)
2020 CmMmBlkSetElement *dynMemElem;
2024 /* Get the map to the mapping table */
2025 #ifdef SS_MEM_WL_DEBUG
2026 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
2028 idx = (((*size) - 1) >> regCb->bktQnPwr);
2031 #if (ERRCLASS & ERRCLS_DEBUG)
2032 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2034 printf("Failed to get the buffer of size %d\n", *size);
2035 /* Some fatal error in the map table initialization. */
2043 /* Dequeue the memory block and return it to the user */
2044 bktIdx = regCb->mapTbl[idx].bktIdx;
2045 bkt = &(regCb->bktTbl[bktIdx]);
2046 #ifdef SS_MEM_WL_DEBUG
2047 if(bkt->size < (*size+4))
2049 if(bkt->size < (*size))
2053 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2056 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
2058 /* Check if the bucket index, if its not valid, return failure */
2059 if(dynMemElem == NULLP)
2062 printf("Failed to get the buffer of size %ld\n", *size);
2064 printf("Failed to get the buffer of size %d\n", *size);
2069 #ifdef SS_MEM_WL_DEBUG
2070 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
2076 /* Get the bucket node from the index returned and allocate the memory */
2077 *ptr = dynMemElem->nextBktPtr;
2082 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
2083 dynMemElem->numFreeBlks--;
2085 #ifdef SS_MEM_WL_DEBUG
2086 prvAllocPtr[regCb->region] = *ptr;
2088 **ptr = (U8) bktIdx;
2092 *ptr += sizeof (U32);
2094 if ((bktIdx == 0) && (!stopBtInfo))
2098 btInfo = &allocBtInfo[regCb->region];
2099 btIdx = btInfo->btInfoIdx;
2100 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2102 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2104 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2107 btIdx &= (NUM_FREE_BUFFERS - 1);
2109 btInfo->btInfo[btIdx].ptr = (PTR)0;
2110 btInfo->btInfo[btIdx].btSize = 0;
2111 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2112 btInfo->btInfoIdx = btIdx;
2119 /* If the size is not matching, return failure to caller */
2121 printf("Failed to get the buffer of size %ld\n", *size);
2123 printf("Failed to get the buffer of size %d\n", *size);
2127 #else /* use pure is on */
2129 #ifdef SS_4GMX_LCORE
2130 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2131 memset(ptr, 0, *size);
2133 /* *ptr = (Data*) malloc(*size); */
2135 *ptr = (Data *)malloc(*size);
2137 if ( (*ptr) == NULLP)
2139 /* avail_size -= *size; */
2141 #endif /* USE_PURE */
2143 } /* end of cmDynAlloc */
2144 #endif /* SS_USE_ICC_MEMORY */
2147 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2149 int g_overused[5] = {0};
2156 * Desc: Allocate a memory block for the memory region.
2159 * Ret: ROK - successful
2160 * RFAILED - unsuccessful.
2163 * The function allocates a memory block of size atleast equal to
2164 * the requested size. The size parameter will be updated with the
2165 * actual size of the memory block allocated for the request. The
2166 * CMM tries to allocate the memory block form the bucket pool. If
2167 * there is no memory in the bucket the CMM allocates the memory
2168 * block form the heap pool. This function is always called by the
2169 * System Service module.
2171 * The caller of the function should try to use the out value of
2172 * the size while returning the memory block to the region. However
2173 * the current design of the memory manager does not enforce to pass
2174 * the actual size of the memory block. (Due to the SGetSBuf
2175 * semantics the layer will not able to pass the correct size of the
2176 * memory block while calling SPutSBuf).
2182 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2184 /* cm_mem_c_001.main_15 : Additions */
2185 #ifdef T2K_MEM_LEAK_DBG
2196 #ifdef SS_HISTOGRAM_SUPPORT
2197 #ifdef SSI_DEBUG_LEVEL1
2212 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType, line, fileName, entId, hstReg)
2237 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, line, fileName, entId, hstReg)
2247 #endif /* SSI_DEBUG_LEVEL1 */
2251 #ifdef SSI_DEBUG_LEVEL1
2262 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType)
2279 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr)
2287 #endif /* SSI_DEBUG_LEVEL1 */
2288 /* cm_mem_c_001.main_15: Additions */
2289 #endif /* SS_HISTOGRAM_SUPPORT */
2292 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2299 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2303 /* cm_mem_c_001.main_15 : Additions */
2304 #ifdef SS_MEM_LEAK_STS
2306 #endif /* SS_MEM_LEAK_STS */
2307 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2308 #ifdef SSI_DEBUG_LEVEL1
2309 CmMmBlkHdr *alocBlk;
2310 #endif /* SSI_DEBUG_LEVEL1 */
2311 /* cm_mem_c_001.main_15 : Additions */
2312 #ifdef SS_HISTOGRAM_SUPPORT
2314 #endif /* SS_HISTOGRAM_SUPPORT */
2320 /* cm_mem_c_001.main_15 : Additions */
2321 #ifdef SS_MEM_LEAK_STS
2323 #endif /* SS_MEM_LEAK_STS */
2325 regCb = (CmMmRegCb *)regionCb;
2327 #if (ERRCLASS & ERRCLS_INT_PAR)
2329 /* error check on parameters */
2330 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2336 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2337 #ifdef SSI_DEBUG_LEVEL1
2338 #if (ERRCLASS & ERRCLS_INT_PAR)
2339 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2343 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2344 #endif /* SSI_DEBUG_LEVEL1 */
2351 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2352 #ifdef SSI_DEBUG_LEVEL1
2353 /* Update the hash list */
2354 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2356 /* display that, this entry could not be made in the hash list */
2358 /* display an error message here */
2359 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2361 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2362 *size, regCb->region);
2364 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2365 *size, regCb->region);
2367 SDisplay(0, dbgPrntBuf);
2370 #endif /* SSI_DEBUG_LEVEL1 */
2373 * Check if the requested size is less than or equal to the maximum block
2374 * size in the bucket.
2376 if ( *size <= regCb->bktMaxBlkSize)
2378 /* Get the map to the mapping table */
2379 idx = ((*size - 1) >> regCb->bktQnPwr);
2381 #if (ERRCLASS & ERRCLS_DEBUG)
2382 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2384 /* Some fatal error in the map table initialization. */
2389 /* Dequeue the memory block and return it to the user */
2390 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2393 /* While loop is introduced to use the "break statement inside */
2397 * Check if the size request is not greater than the size available
2400 if (*size > bkt->size)
2402 /* Try to go to the next bucket if available */
2403 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2404 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2406 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2410 /* This is the last bucket, try to allocate from heap */
2415 /* Acquire the bucket lock */
2416 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2418 (Void) WTLock(&(bkt->bktLock));
2420 (Void) SLock(&(bkt->bktLock));
2423 #if (ERRCLASS & ERRCLS_DEBUG)
2424 regCb->mapTbl[idx].numReq++;
2425 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2427 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2428 #ifdef SSI_DEBUG_LEVEL1
2429 /* increment the allocation attempt counter at bucket level */
2430 bkt->numAllocAttempts++;
2432 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2433 the allocation is always from (bkt->nextBlk) */
2436 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2438 /* detected a trampled memory block in this bucket */
2440 /* display an error message here */
2441 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2443 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2444 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2446 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2447 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2449 SDisplay(0, dbgPrntBuf);
2452 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2454 /* Release the lock */
2455 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2457 (Void) WTUnlock(&(bkt->bktLock));
2459 (Void) SUnlock(&(bkt->bktLock));
2461 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2462 return (RTRAMPLINGNOK);
2466 /* Release the lock */
2467 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2469 (Void) WTUnlock(&(bkt->bktLock));
2471 (Void) SUnlock(&(bkt->bktLock));
2473 /* return RFAILED */
2479 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2481 if ((*ptr = bkt->next))
2482 #endif /* SSI_DEBUG_LEVEL1 */
2484 /* cm_mem_c_001.main_12 - addition for header */
2485 #ifdef SSI_DEBUG_LEVEL1
2486 /* point to next block header */
2487 alocBlk = bkt->nextBlk;
2488 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2490 bkt->next = *((CmMmEntry **)(bkt->next));
2491 #endif /* SSI_DEBUG_LEVEL1 */
2494 * Increment the statistics variable of number of memory block
2498 if (bkt->numAlloc > bkt->maxAlloc)
2500 bkt->maxAlloc = bkt->numAlloc;
2503 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2505 g_overused[bktIdx] = 1;
2506 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2510 /* cm_mem_c_001.main_12 - addition for header manipulation */
2511 #ifdef SSI_DEBUG_LEVEL1
2512 /* update the size for which this memory block has been allocated */
2513 alocBlk->requestedSize = *size;
2514 /* update the memory block header */
2515 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2516 if (memType == CMM_STATIC_MEM_FLAG)
2518 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2519 /* add it to the static memory allocated */
2520 bkt->staticMemUsed += bkt->size;
2524 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2525 /* add it to the dynamic memory allocated */
2526 bkt->dynamicMemUsed += bkt->size;
2528 #endif /* SSI_DEBUG_LEVEL1 */
2530 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2534 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2537 "[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++);
2540 "[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++);
2542 SDisplay(0, prntBuf);
2550 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2551 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2552 SDisplay(0, prntBuf);
2554 #endif /* MEMCAL_DEBUG */
2555 /* cm_mem_c_001.main_15 : Additions */
2556 #ifdef SS_HISTOGRAM_SUPPORT
2557 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2558 * information into the hash list */
2561 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2563 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2568 #endif /* SS_HISTOGRAM_SUPPORT */
2570 /* Update the size parameter */
2572 #ifdef SS_MEM_LEAK_STS
2573 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2574 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2575 regCb->mapTbl[idx].bktIdx);
2576 #endif /* SS_MEM_LEAK_STS */
2578 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2580 /* Release the lock */
2581 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2583 (Void) WTUnlock(&(bkt->bktLock));
2585 (Void) SUnlock(&(bkt->bktLock));
2594 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2597 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2600 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2602 SDisplay(0, prntBuf);
2606 #if (ERRCLASS & ERRCLS_DEBUG)
2607 regCb->mapTbl[idx].numFailure++;
2608 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2610 /* Release the lock */
2611 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2613 (Void) WTUnlock(&(bkt->bktLock));
2615 (Void) SUnlock(&(bkt->bktLock));
2624 regCb->heapCb.heapAllocCnt++;
2626 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2629 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2630 regCb->heapCb.heapAllocCnt);
2633 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2634 regCb->heapCb.heapAllocCnt);
2636 SDisplay(0, prntBuf);
2641 /* Memory not available in the bucket pool */
2642 if (regCb->heapFlag && (*size < regCb->heapSize))
2645 if (flags) tryHeap = 1;
2648 * The heap memory block is available. Allocate the memory block from
2651 /* cm_mem_c_001.main_15: Additions */
2652 #ifdef SS_HISTOGRAM_SUPPORT
2653 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2654 #ifdef SSI_DEBUG_LEVEL1
2655 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2657 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2658 #endif /* SSI_DEBUG_LEVEL1 */
2660 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2661 #ifdef SSI_DEBUG_LEVEL1
2662 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2664 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2665 #endif /* SSI_DEBUG_LEVEL1 */
2666 #endif /* SS_HISTOGRAM_SUPPORT */
2669 /* No memory available */
2671 #else /* use pure is on */
2672 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2673 #ifdef SS_4GMX_LCORE
2674 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2675 memset(ptr, 0, *size);
2677 *ptr = (Data*) malloc(*size);
2679 if ( (*ptr) == NULLP)
2681 avail_size -= *size;
2683 #endif /* USE_PURE */
2685 } /* end of cmAlloc */
2687 #ifdef SS_MEM_WL_DEBUG
2690 * Fun: cmInitDoubleFreeList
2692 * Desc: Initialize the hashlist used for detecting double free
2694 * Ret: ROK - successful
2695 * RFAILED - unsuccessful.
2704 S16 cmInitDoubleFreeList
2709 S16 cmInitDoubleFreeList()
2713 CmMemDoubleFree memNode;
2716 offset = (U16)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2718 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2719 CM_HASH_KEYTYPE_U32MOD, 0, 0)) != ROK);
2723 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2728 #ifdef SS_MEM_WL_DEBUG
2733 * Desc: Return the Dynamic memory block for the memory region.
2736 * Ret: ROK - successful
2737 * RFAILED - unsuccessful.
2746 PRIVATE S16 cmInitBtInfo
2750 PRIVATE S16 cmInitBtInfo (Void)
2753 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2754 if (regBtInfo == NULLP)
2758 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2759 if(allocBtInfo == NULLP)
2766 #endif /* SS_MEM_WL_DEBUG */
2769 * Fun: cmAnalyseBtInfo
2771 * Desc: Return the Dynamic memory block for the memory region.
2774 * Ret: ROK - successful
2775 * RFAILED - unsuccessful.
2784 Void cmAnalyseBtInfo
2786 PTR ptr, /* Memory block needs to be freed */
2790 Void cmAnalyseBtInfo (ptr,idx)
2791 PTR ptr; /* Memory block needs to be freed */
2800 /* for(regIdx = 0; regIdx < 8; regIdx++)
2803 btInfo = &allocBtInfo[idx];
2804 btIdx = btInfo->btInfoIdx;
2806 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
2808 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
2809 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
2810 if(btInfo->btInfo[btIdx].btSize != 0)
2814 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2815 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);
2816 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2818 printf("%s\n", strings[i]);
2820 printf("*******************************************************\n");
2828 btIdx = NUM_FREE_BUFFERS - 1;
2837 #ifndef SS_USE_ICC_MEMORY
2840 * Fun: cmDynFreeWithLock
2842 * Desc: Return the Dynamic memory block for the memory region.
2845 * Ret: ROK - successful
2846 * RFAILED - unsuccessful.
2855 PRIVATE S16 cmDynFreeWithLock
2857 Void *regionCb, /* Pointer to region cb */
2858 Data *ptr, /* Memory block needs to be freed */
2859 Size size /* Size of the block */
2862 PRIVATE S16 cmDynFreeWithLock(regionCb, ptr, size)
2863 Void *regionCb; /* Pointer to region cb */
2864 Data *ptr; /* Memory block needs to be freed */
2865 Size size; /* Size of the block */
2870 if((SLock(&dynAllocFreeLock)) != ROK)
2872 printf("dynAllocWithLock: Failed to get the DYN lock\n");
2876 ret = cmDynFree(regionCb, ptr,size);
2878 if((SUnlock(&dynAllocFreeLock)) != ROK)
2880 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2886 } /* end of cmDynFree */
2892 * Desc: Return the Dynamic memory block for the memory region.
2895 * Ret: ROK - successful
2896 * RFAILED - unsuccessful.
2905 PRIVATE S16 cmDynFree
2907 Void *regionCb, /* Pointer to region cb */
2908 Data *ptr, /* Memory block needs to be freed */
2909 Size size /* Size of the block */
2912 PRIVATE S16 cmDynFree(regionCb, ptr, size)
2913 Void *regionCb; /* Pointer to region cb */
2914 Data *ptr; /* Memory block needs to be freed */
2915 Size size; /* Size of the block */
2918 CmMmDynRegCb *regCb;
2922 CmMmDynBktCb *bkt = NULLP;
2923 CmMmBlkSetElement *dynMemElem;
2925 #ifdef SS_MEM_WL_DEBUG
2931 regCb = (CmMmDynRegCb *)regionCb;
2932 #ifdef SS_MEM_WL_DEBUG
2933 if((tmpRegTidMap[regCb->region] != (pthread_self())))
2940 #if (ERRCLASS & ERRCLS_INT_PAR)
2941 /* error check on parameters */
2942 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2947 /* Check if the memory block is from the memory region */
2948 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2949 ((CmMmRegCb *)regCb)->regInfo.size)
2953 /* cm_mem_c_001.main_20 Addition */
2954 if (ptr < regCb->regInfo.start)
2961 #ifdef SS_MEM_WL_DEBUG
2962 ptr -= sizeof (U32);
2965 /* The memory block was allocated from the bucket pool */
2967 /* Get the map to the mapping table */
2968 idx = ((size - 1) >> regCb->bktQnPwr);
2970 #if (ERRCLASS & ERRCLS_DEBUG)
2971 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2973 /* Some fatal error in the map table initialization. */
2978 /* Enqueue the memory block and return it to the user */
2979 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2982 * Check if the size is not greater than the size available
2983 * in the bucket. If so, then the buffer must have been allocated
2984 * from next bucket. We don't need to check the validity of the
2985 * next bucket, otherwise buffer must have been allocated from heap
2988 #ifdef SS_MEM_WL_DEBUG
2989 if (size > bkt->size)
2991 printf("Size = %d bucket size = %d\n", size, bkt->size);
2993 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
2995 if(size > bkt->size)
2997 printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
3000 printf("Bucket Size wrong \n");
3005 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
3007 /* Check if the bucket index, if its not valid, return failure */
3008 if(dynMemElem == NULLP)
3013 #ifdef SS_MEM_WL_DEBUG
3014 tmpBktIdx = (U8)*ptr;
3015 tmpVal = (U8)*(ptr+1);
3017 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
3020 printf("bktIdx wrong \n");
3024 if ((bktIdx == 0) && (!stopBtInfo))
3028 btInfo = ®BtInfo[regCb->region];
3029 btIdx = btInfo->btInfoIdx;
3030 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
3032 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
3034 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
3037 btIdx &= (NUM_FREE_BUFFERS - 1);
3039 btInfo->btInfo[btIdx].ptr = (PTR)0;
3040 btInfo->btInfo[btIdx].btSize = 0;
3041 memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
3042 btInfo->btInfoIdx = btIdx;
3045 if(prvAllocPtr[regCb->region] == ptr)
3047 prvAllocPtr[regCb->region] = NULLP;
3050 memset(ptr, (regCb->region+1), bkt->size);
3053 /* Get the bucket node from the index returned and allocate the memory */
3054 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
3055 dynMemElem->nextBktPtr = ptr;
3056 dynMemElem->numFreeBlks++;
3060 #else /* use pure is on */
3061 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3062 #ifdef SS_4GMX_LCORE
3063 (Void)MxHeapFree(SsiHeap, ptr);
3065 /* (Void)free(ptr); */
3067 /* avail_size += size; */
3071 #endif /* USE_PURE */
3074 } /* end of cmDynFree */
3075 #endif /* SS_USE_ICC_MEMORY */
3083 * Desc: Return the memory block for the memory region.
3086 * Ret: ROK - successful
3087 * RFAILED - unsuccessful.
3089 * Notes: The user calls this function to return the previously allocated
3090 * memory block to the memory region. The memory manager does not
3091 * check the validity of the state of the memory block(like whether
3092 * it was allocated earlier). The caller must be sure that, the
3093 * address specified in the parameter 'ptr' is valid and was
3094 * allocated previously from same region.
3101 /* cm_mem_c_001.main_15 : Additions */
3102 #ifdef T2K_MEM_LEAK_DBG
3112 #ifdef SS_HISTOGRAM_SUPPORT
3125 PRIVATE S16 cmFree(regionCb, ptr, size, line, fileName, entId, hstReg)
3145 PRIVATE S16 cmFree(regionCb, ptr, size)
3151 /* cm_mem_c_001.main_15 : Additions */
3152 #endif /* SS_HISTOGRAM_SUPPORT */
3155 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
3162 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3163 #ifdef SSI_DEBUG_LEVEL1
3165 #endif /* SSI_DEBUG_LEVEL1 */
3166 /* cm_mem_c_001.main_15 : Additions */
3167 #ifdef SS_HISTOGRAM_SUPPORT
3169 #endif /* SS_HISTOGRAM_SUPPORT */
3172 regCb = (CmMmRegCb *)regionCb;
3175 #if (ERRCLASS & ERRCLS_INT_PAR)
3177 /* error check on parameters */
3178 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3183 /* Check if the memory block is from the memory region */
3184 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3185 ((CmMmRegCb *)regCb)->regInfo.size)
3189 /* cm_mem_c_001.main_20 Addition */
3190 if (ptr < regCb->regInfo.start)
3198 * Check if the memory block was allocated from the bucket pool.
3200 if(ptr < regCb->regInfo.start)
3202 Buffer *tmpBuffer = NULLP;
3203 tmpBuffer->b_cont = NULLP;
3206 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3208 /* The memory block was allocated from the bucket pool */
3210 /* Get the map to the mapping table */
3211 idx = ((size - 1) >> regCb->bktQnPwr);
3213 #if (ERRCLASS & ERRCLS_DEBUG)
3214 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3216 /* Some fatal error in the map table initialization. */
3221 /* Enqueue the memory block and return it to the user */
3222 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3225 * Check if the size is not greater than the size available
3226 * in the bucket. If so, then the buffer must have been allocated
3227 * from next bucket. We don't need to check the validity of the
3228 * next bucket, otherwise buffer must have been allocated from heap
3231 if (size > bkt->size)
3233 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3236 /* Acquire the bucket lock */
3237 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3239 (Void) WTLock(&(bkt->bktLock));
3241 (Void) SLock(&(bkt->bktLock));
3244 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3245 #ifdef SSI_DEBUG_LEVEL1
3246 /* increment the dealloc attempt counter at bucket level */
3247 bkt->numDeallocAttempts++;
3249 /* Check the memFlags to see whether this block was allocated */
3250 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3252 /* validate the block to be freed for trampling */
3253 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3255 /* Handle error case of Memory trampling */
3257 /* display an error message here */
3258 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3260 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3261 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3263 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3264 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3266 SDisplay(0, dbgPrntBuf);
3269 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3270 * as the memory blk is already invalidated in cmMmBktSanityChk
3272 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3276 /* Release the lock */
3277 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3279 (Void) WTUnlock(&(bkt->bktLock));
3281 (Void) SUnlock(&(bkt->bktLock));
3289 * this is the case where in the entire bucket has been made unusable
3292 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3294 (Void) WTUnlock(&(bkt->bktLock));
3296 (Void) SUnlock(&(bkt->bktLock));
3299 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3300 return (RTRAMPLINGNOK);
3304 /* reset the size */
3305 ptrHdr->requestedSize = 0;
3306 /* check if the block to be freed is already having the state as FREE */
3307 if (CMM_IS_FREE(ptrHdr->memFlags))
3309 /* Handle double deallocation error case */
3311 /* display an error message here */
3312 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3314 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3315 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3317 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3318 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3320 SDisplay(0, dbgPrntBuf);
3323 /* Release the lock */
3324 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3326 (Void) WTUnlock(&(bkt->bktLock));
3328 (Void) SUnlock(&(bkt->bktLock));
3331 /* handle RDBLFREE in SFree/SPutSBuf */
3334 if (CMM_IS_STATIC(ptrHdr->memFlags))
3336 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3337 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3338 /* deduct it from the static memory count */
3339 bkt->staticMemUsed -= bkt->size;
3341 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3343 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3344 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3345 /* deduct it from the dynamic memory count */
3346 bkt->dynamicMemUsed -= bkt->size;
3350 /* This is a case similar to trampled memory */
3352 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3354 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3356 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3358 SDisplay(0, dbgPrntBuf);
3360 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3362 /* do not add to the free list */
3365 /* Release the lock */
3366 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3368 (Void) WTUnlock(&(bkt->bktLock));
3370 (Void) SUnlock(&(bkt->bktLock));
3377 * this is the case where in the entire bucket has been made unusable
3380 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3382 (Void) WTUnlock(&(bkt->bktLock));
3384 (Void) SUnlock(&(bkt->bktLock));
3387 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3388 return (RTRAMPLINGNOK);
3392 /* Return the block to memory */
3393 ptrHdr->nextBlk = bkt->nextBlk;
3394 bkt->nextBlk = ptrHdr;
3397 *((CmMmEntry **)ptr) = bkt->next;
3398 bkt->next = (CmMmEntry *)ptr;
3399 #endif /* SSI_DEBUG_LEVEL1 */
3402 * Decrement the statistics variable of number of memory block
3410 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3412 g_overused[bktIdx] = 0;
3413 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3416 /* cm_mem_c_001.main_15 : Additions */
3417 #ifdef SS_HISTOGRAM_SUPPORT
3418 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3419 * information into the hash list */
3422 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3424 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3428 #endif /* SS_HISTOGRAM_SUPPORT */
3430 #ifdef SS_MEM_LEAK_STS
3431 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3432 cmRlsAllocBlk((PTR)ptr);
3433 #endif /* SS_MEM_LEAK_STS */
3435 /* Release the lock */
3436 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3438 (Void) WTUnlock(&(bkt->bktLock));
3440 (Void) SUnlock(&(bkt->bktLock));
3446 /* The memory block was allocated from the heap pool */
3447 /* cm_mem_c_001.main_15 : Additions */
3448 #ifdef SS_HISTOGRAM_SUPPORT
3449 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3451 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3452 #endif /* SS_HISTOGRAM_SUPPORT */
3453 #else /* use pure is on */
3454 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3455 #ifdef SS_4GMX_LCORE
3456 (Void)MxHeapFree(SsiHeap, ptr);
3462 #endif /* USE_PURE */
3465 } /* end of cmFree */
3472 * Desc: alloc without lock
3475 * Ret: ROK - successful
3476 * RFAILED - unsuccessful.
3482 /*cm_mem_c_001.main_21-added new function*/
3483 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3484 #ifdef T2K_MEM_LEAK_DBG
3485 PRIVATE S16 cmAllocWL
3496 PRIVATE S16 cmAllocWL
3504 PRIVATE S16 cmAllocWL(regionCb, size, flags, ptr)
3514 CmMmBkt *bkt = NULLP;
3517 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3520 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3522 regCb = (CmMmRegCb *)regionCb;
3524 #ifdef SS_MEM_WL_DEBUG
3525 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3531 #if (ERRCLASS & ERRCLS_INT_PAR)
3533 /* error check on parameters */
3534 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3540 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3545 * Check if the requested size is less than or equal to the maximum block
3546 * size in the bucket.
3548 #ifdef MSPD_T2K_TRACK_BUG
3551 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3552 if ( *size <= regCb->bktMaxBlkSize)
3554 /* Get the map to the mapping table */
3555 idx = ((*size - 1) >> regCb->bktQnPwr);
3557 /* Dequeue the memory block and return it to the user */
3558 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3562 * Check if the size request is not greater than the size available
3565 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3566 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3568 /* Try to go to the next bucket if available */
3569 bkt->next = *((CmMmEntry **)(bkt->next));
3572 * Increment the statistics variable of number of memory block
3576 if (bkt->numAlloc > bkt->maxAlloc)
3578 bkt->maxAlloc = bkt->numAlloc;
3581 #ifdef MSPD_T2K_TRACK_BUG
3590 /* Update the size parameter */
3598 /* Memory not available in the bucket pool */
3599 if (regCb->heapFlag && (*size < regCb->heapSize))
3601 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3603 * The heap memory block is available. Allocate the memory block from
3606 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3607 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3610 /* No memory available */
3612 #else /* use pure is on */
3613 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3614 #ifdef SS_4GMX_LCORE
3615 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3616 memset(ptr, 0, *size);
3618 /* *ptr = (Data*) malloc(*size); */
3620 *ptr = (Data *)malloc(*size);
3622 if ( (*ptr) == NULLP)
3624 /* avail_size -= *size; */
3626 #endif /* USE_PURE */
3628 } /* end of cmAllocWL */
3635 * Desc: free without lock
3638 * Ret: ROK - successful
3639 * RFAILED - unsuccessful.
3646 #ifdef T2K_MEM_LEAK_DBG
3647 PRIVATE S16 cmFreeWL
3657 PRIVATE S16 cmFreeWL
3664 PRIVATE S16 cmFreeWL(regionCb, ptr, size)
3673 CmMmBkt *bkt = NULLP;
3676 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3679 regCb = (CmMmRegCb *)regionCb;
3681 #ifdef SS_MEM_WL_DEBUG
3682 if(tmpRegTidMap[regCb->region] != (pthread_self()))
3689 #if (ERRCLASS & ERRCLS_INT_PAR)
3691 /* error check on parameters */
3692 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3697 /* Check if the memory block is from the memory region */
3698 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3699 ((CmMmRegCb *)regCb)->regInfo.size)
3707 * Check if the memory block was allocated from the bucket pool.
3709 #ifdef MSPD_T2K_TRACK_BUG
3713 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3715 /* The memory block was allocated from the bucket pool */
3717 /* Get the map to the mapping table */
3718 idx = ((size - 1) >> regCb->bktQnPwr);
3720 #if (ERRCLASS & ERRCLS_DEBUG)
3721 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3723 /* Some fatal error in the map table initialization. */
3728 /* Enqueue the memory block and return it to the user */
3729 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3731 #ifdef MSPD_T2K_TRACK_BUG
3733 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3740 * Check if the size is not greater than the size available
3741 * in the bucket. If so, then the buffer must have been allocated
3742 * from next bucket. We don't need to check the validity of the
3743 * next bucket, otherwise buffer must have been allocated from heap
3746 if (size > bkt->size)
3748 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3751 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3752 *((CmMmEntry **)ptr) = bkt->next;
3753 bkt->next = (CmMmEntry *)ptr;
3756 * Decrement the statistics variable of number of memory block
3764 /* The memory block was allocated from the heap pool */
3765 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3766 #else /* use pure is on */
3767 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3768 #ifdef SS_4GMX_LCORE
3769 (Void)MxHeapFree(SsiHeap, ptr);
3771 /* (Void)free(ptr); */
3773 /* avail_size += size; */
3777 #endif /* USE_PURE */
3780 } /* end of cmFreeWL */
3787 * Desc: Control request function.
3790 * Ret: ROK - successful
3791 * RFAILED - unsuccessful.
3793 * Notes: The current semantics of the control function is defined for two
3794 * types of events: virtual address to physical address translation
3795 * and memory resource check.
3797 * The physical address translation is valid only for the memory
3798 * region physically contiguous and non pagable.
3814 PRIVATE S16 cmCtl(regionCb, event, memCtl)
3823 regCb = (CmMmRegCb *)regionCb;
3825 #if (ERRCLASS & ERRCLS_INT_PAR)
3827 /* error check on parameters */
3828 if ((regCb == NULLP) || (memCtl == NULLP))
3841 #if (ERRCLASS & ERRCLS_INT_PAR)
3842 if ((memCtl->u.vtop.vaddr == NULLP) ||
3843 (memCtl->u.vtop.paddr == NULLP))
3849 /* Check if the virtual to physical address translation is valid */
3850 if (regCb->chFlag & CMM_REG_PHY_VALID)
3852 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3853 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3860 case SS_MEM_CHK_RES:
3863 #if (ERRCLASS & ERRCLS_INT_PAR)
3864 if (!(memCtl->u.chkres.size) ||
3865 (memCtl->u.chkres.status == NULLP))
3871 /* Check if the Bucket pool is configured */
3876 U32 avlSize, totSize;
3878 * The bucket pool is configured. The status value returned
3879 * does reflect on the memory availabilty in the bucket pool.
3880 * The value does not consider the available memory in the
3883 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3884 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3885 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3886 avlSize += regCb->heapCb.avlSize;
3887 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3888 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
3892 /* Bucket pool not configured */
3895 * Find the percentage memory available in the heap pool. The value
3896 * does not consider the fragmentation of the heap pool.
3898 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3899 (regCb->heapSize/10));
3903 #else /* use pure is on */
3904 *(memCtl->u.chkres.status) = ((avail_size) /
3905 (regCb->regInfo.size/10));
3907 #endif /* USE_PURE */
3913 /* No other event is supported currently */
3918 /* shouldn't reach here */
3920 } /* end of cmCtl */
3927 * Desc: Initialize the heap pool.
3930 * Ret: ROK - successful
3931 * RFAILED - unsuccessful.
3933 * Notes: This function is called by the cmMmRegInit.
3939 PRIVATE Void cmMmHeapInit
3946 PRIVATE Void cmMmHeapInit (memAddr, heapCb, size)
3952 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3953 #ifdef SSI_DEBUG_LEVEL1
3955 #endif /* SSI_DEBUG_LEVEL1 */
3957 /* Initialize the heap control block */
3958 heapCb->vStart = memAddr;
3959 heapCb->vEnd = memAddr + size;
3960 heapCb->avlSize = size;
3961 heapCb->minSize = CMM_MINBUFSIZE;
3963 heapCb->next = (CmHEntry *)memAddr;
3964 heapCb->next->next = NULLP;
3965 /* cm_mem_c_001.main_12 - addition for header initialization */
3966 #ifdef SSI_DEBUG_LEVEL1
3967 heapCb->next->size = size - sizeof(CmHEntry);
3968 heapCb->next->requestedSize = 0;
3969 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3971 heapCb->next->trSignature[idx] = 0xAB;
3973 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3974 heapCb->staticHeapMemUsed = 0;
3975 heapCb->dynamicHeapMemUsed = 0;
3976 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3977 sizeof(heapCb->next->memFlags) +
3978 sizeof(heapCb->next->requestedSize);
3979 heapCb->numAllocAttempts = 0;
3980 heapCb->numDeallocAttempts = 0;
3981 heapCb->trampleCount = 0;
3983 heapCb->next->size = size;
3984 #endif /* SSI_DEBUG_LEVEL1 */
3986 #if (ERRCLASS & ERRCLS_DEBUG)
3987 heapCb->numFragBlk = 0;
3989 heapCb->numFailure = 0;
3992 heapCb->heapAllocCnt = 0;
3993 /* cm_mem_c_001.main_15 : Additions */
3994 #ifdef SS_HISTOGRAM_SUPPORT
3995 /* Initialise the memory histogram hash list */
3996 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3997 #endif /* SS_HISTOGRAM_SUPPORT */
4000 } /* end of cmMmHeapInit */
4008 * Desc: Allocates the memory block from the heap pool.
4011 * Ret: ROK - successful
4012 * RFAILED - unsuccessful.
4014 * Notes: This function is called by the cmAlloc. cmAlloc calls this
4015 * function when there is no memory block available in the bucket
4016 * and the heap pool is configured.
4023 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
4024 /* cm_mem_c_001.main_15 : Additions */
4025 #ifdef SS_HISTOGRAM_SUPPORT
4026 #ifdef SSI_DEBUG_LEVEL1
4028 PRIVATE S16 cmHeapAlloc
4040 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType, line, fileName, entId, hstReg)
4052 PRIVATE S16 cmHeapAlloc
4063 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, line, fileName, entId, hstReg)
4072 #endif /* SSI_DEBUG_LEVEL1 */
4074 #ifdef SSI_DEBUG_LEVEL1
4076 PRIVATE S16 cmHeapAlloc
4084 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType)
4092 PRIVATE S16 cmHeapAlloc
4099 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size)
4104 #endif /* SSI_DEBUG_LEVEL1 */
4105 /* cm_mem_c_001.main_15 : Additions */
4106 #endif /* SS_HISTOGRAM_SUPPORT */
4108 CmHEntry *prvHBlk; /* Previous heap block */
4109 CmHEntry *curHBlk; /* Current heap block */
4111 /* cm_mem_c_001.main_15 : Additions */
4112 #ifdef SS_MEM_LEAK_STS
4114 #endif /* SS_MEM_LEAK_STS */
4115 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4116 #ifdef SSI_DEBUG_LEVEL1
4117 CmHEntry *alocHeapBlk;
4121 #endif /* SSI_DEBUG_LEVEL1 */
4122 /* cm_mem_c_001.main_15 : Additions */
4123 #ifdef SS_HISTOGRAM_SUPPORT
4125 #endif /* SS_HISTOGRAM_SUPPORT */
4127 /* cm_mem_c_001.main_15 : Additions */
4128 /* Acquire the heap lock */
4129 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4131 (Void) WTLock (&(heapCb->heapLock));
4133 (Void) SLock (&(heapCb->heapLock));
4136 #ifdef SS_MEM_LEAK_STS
4138 #endif /* SS_MEM_LEAK_STS */
4139 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4140 #ifdef SSI_DEBUG_LEVEL1
4141 heapCb->numAllocAttempts++;
4142 requestedSize = *size;
4143 #endif /* SSI_DEBUG_LEVEL1 */
4145 /* Roundup the requested size */
4146 *size = CMM_DATALIGN(*size, (heapCb->minSize));
4148 /* Check if the available total size is adequate. */
4149 if ((*size) >= heapCb->avlSize)
4151 /* cm_mem_c_001.main_15 : Additions */
4153 (Void) WTUnlock (&(heapCb->heapLock));
4155 (Void) SUnlock (&(heapCb->heapLock));
4161 /* cm_mem_c_001.main_12 - addition for aligning the header size */
4162 #ifdef SSI_DEBUG_LEVEL1
4163 hdr = PTRALIGN(sizeof(CmHEntry));
4164 #endif /* SSI_DEBUG_LEVEL1 */
4167 * Search through the heap block list in the heap pool of size
4168 * greater than or equal to the requested size.
4171 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
4172 #ifdef SSI_DEBUG_LEVEL1
4173 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
4175 prvHBlk = (CmHEntry *)&(heapCb->next);
4176 #endif /* SSI_DEBUG_LEVEL1 */
4177 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
4178 prvHBlk = prvHBlk->next)
4181 * Since the size of the block is always multiple of CMM_MINBUFSIZE
4182 * and the requested size is rounded to the size multiple of
4183 * CMM_MINBUFSIZE, the difference between the size of the heap block
4184 * and the size to allocate will be either zero or multiple of
4187 if ((*size) <= curHBlk->size)
4189 /* cm_mem_c_001.main_12 - addition for block size calculation */
4190 #ifdef SSI_DEBUG_LEVEL1
4191 tmpSize = curHBlk->size - (*size);
4193 tmpSize = tmpSize - hdr;
4196 if ((tmpSize = (curHBlk->size - (*size))))
4197 #endif /* SSI_DEBUG_LEVEL1 */
4199 /* Heap block of bigger size */
4200 /* cm_mem_c_001.main_12 - addition for allocating memory */
4201 #ifdef SSI_DEBUG_LEVEL1
4202 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
4203 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
4205 * No need to look for memory trampling as this is a new block altogether
4206 * Update the header only for this case as it is new block formed
4208 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4210 alocHeapBlk->trSignature[idx] = 0xAB;
4212 alocHeapBlk->size = *size;
4214 *ptr = (Data *)curHBlk + tmpSize;
4215 #endif /* SSI_DEBUG_LEVEL1 */
4216 curHBlk->size = tmpSize;
4220 /* Heap block is same size of the requested size */
4221 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4222 #ifdef SSI_DEBUG_LEVEL1
4223 /* look for memory trampling as this is a pure block*/
4226 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4228 /* detected a trampled memory block in this bucket */
4230 /* display an error message here */
4231 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4233 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4235 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4237 SDisplay(0, dbgPrntBuf);
4240 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4242 /* Release the lock */
4243 /* cm_mem_c_001.main_13: Replaced SUnlock with
4246 (Void) WTUnlock (&(heapCb->heapLock));
4248 (Void) SUnlock (&(heapCb->heapLock));
4250 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4251 return (RTRAMPLINGNOK);
4255 /* Release the lock */
4256 /* cm_mem_c_001.main_13: Replaced SUnlock with
4259 (Void) WTUnlock (&(heapCb->heapLock));
4261 (Void) SUnlock (&(heapCb->heapLock));
4268 *ptr = (Data *)curHBlk + hdr;
4269 alocHeapBlk = curHBlk;
4270 *size = curHBlk->size;
4272 *ptr = (Data *)curHBlk;
4273 #endif /* SSI_DEBUG_LEVEL1 */
4274 prvHBlk->next = curHBlk->next;
4277 /* cm_mem_c_001.main_12 - addition for header updation */
4278 #ifdef SSI_DEBUG_LEVEL1
4279 /* update the header fields */
4280 alocHeapBlk->requestedSize = requestedSize;
4281 alocHeapBlk->memFlags = 0;
4282 if (memType == CMM_STATIC_MEM_FLAG)
4284 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4285 heapCb->staticHeapMemUsed += (*size + hdr);
4289 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4290 heapCb->dynamicHeapMemUsed += (*size + hdr);
4292 heapCb->avlSize -= ((*size) + hdr);
4294 heapCb->avlSize -= (*size);
4295 #endif /* SSI_DEBUG_LEVEL1 */
4301 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4302 *size, num_times, *ptr);
4303 SDisplay(0, prntBuf);
4307 /* cm_mem_c_001.main_15 : Additions */
4308 #ifdef SS_MEM_LEAK_STS
4309 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4310 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4311 #endif /* SS_MEM_LEAK_STS */
4312 /* Release the lock */
4313 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4315 (Void) WTUnlock (&(heapCb->heapLock));
4317 (Void) SUnlock (&(heapCb->heapLock));
4320 #ifdef SS_HISTOGRAM_SUPPORT
4321 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4322 * information into the hash list */
4325 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4327 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4332 #endif /* SS_HISTOGRAM_SUPPORT */
4338 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4344 /* Release the lock */
4345 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4347 (Void) WTUnlock (&(heapCb->heapLock));
4349 (Void) SUnlock (&(heapCb->heapLock));
4354 } /* end of cmHeapAlloc */
4361 * Desc: Return the memory block from the heap pool.
4364 * Ret: ROK - successful
4365 * RFAILED - unsuccessful.
4367 * Notes: This function returns the memory block to the heap pool. This
4368 * function is called by cmFree. The function does not check the
4369 * validity of the memory block. The caller must be sure that the
4370 * block was previously allocated and belongs to the heap pool. The
4371 * function maintain the sorting order of the memory block on the
4372 * starting address of the block. This function also do compaction
4373 * if the neighbouring blocks are already in the heap.
4380 /* cm_mem_c_001.main_15 : Additions */
4381 #ifdef SS_HISTOGRAM_SUPPORT
4383 PRIVATE S16 cmHeapFree
4394 PRIVATE S16 cmHeapFree (heapCb, ptr, size, line, fileName, entId, hstReg)
4405 PRIVATE S16 cmHeapFree
4412 PRIVATE S16 cmHeapFree (heapCb, ptr, size)
4417 /* cm_mem_c_001.main_15 : Additions */
4418 #endif /* SS_HISTOGRAM_SUPPORT */
4421 CmHEntry *curHBlk; /* Current heap block */
4422 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4423 #ifdef SSI_DEBUG_LEVEL1
4425 #endif /* SSI_DEBUG_LEVEL1 */
4426 /* cm_mem_c_001.main_15 : Additions */
4427 #ifdef SS_HISTOGRAM_SUPPORT
4428 Size allocSize = size;
4430 #endif /* SS_HISTOGRAM_SUPPORT */
4433 /* Roundup the requested size */
4434 size = CMM_DATALIGN(size, (heapCb->minSize));
4435 /* cm_mem_c_001.main_15: Additions */
4436 #ifdef SS_HISTOGRAM_SUPPORT
4438 #endif /* SS_HISTOGRAM_SUPPORT */
4440 /* Acquire the heap lock */
4441 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4443 (Void) WTLock (&(heapCb->heapLock));
4445 (Void) SLock (&(heapCb->heapLock));
4448 /* increase the avlSize */
4449 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4450 #ifdef SSI_DEBUG_LEVEL1
4451 hdr = PTRALIGN(sizeof(CmHEntry));
4452 heapCb->avlSize += (size + hdr);
4453 heapCb->numDeallocAttempts++;
4455 heapCb->avlSize += size;
4456 #endif /* SSI_DEBUG_LEVEL1 */
4458 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4459 #ifdef SSI_DEBUG_LEVEL1
4460 p = (CmHEntry *)(ptr - hdr);
4462 p = (CmHEntry *)ptr;
4463 /* cm_mem_c_001.main_15 : Additions */
4464 #ifdef SS_MEM_LEAK_STS
4465 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4466 cmRlsAllocBlk((PTR)ptr);
4467 #endif /* SS_MEM_LEAK_STS */
4468 #endif /* SSI_DEBUG_LEVEL1 */
4471 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4472 #ifdef SSI_DEBUG_LEVEL1
4473 /* look for memory trampling */
4474 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4476 /* detected a trampled memory block in heap */
4478 /* display an error message here */
4479 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4481 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4483 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4485 SDisplay(0, dbgPrntBuf);
4488 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4490 /* Release the lock */
4491 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4493 (Void) WTUnlock (&(heapCb->heapLock));
4495 (Void) SUnlock (&(heapCb->heapLock));
4497 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4498 return (RTRAMPLINGNOK);
4502 /* do not add to the free heap */
4503 heapCb->avlSize -= (size + hdr);
4504 /* Release the heap lock */
4505 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4507 (Void) WTUnlock (&(heapCb->heapLock));
4509 (Void) SUnlock (&(heapCb->heapLock));
4516 /* look for any double free */
4517 if (CMM_IS_FREE(p->memFlags))
4520 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4522 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4524 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4526 SDisplay(0, dbgPrntBuf);
4529 heapCb->avlSize -= (size + hdr);
4530 /* cm_mem_c_001.main_15 : Additions */
4532 (Void) WTUnlock (&(heapCb->heapLock));
4534 (Void) SUnlock (&(heapCb->heapLock));
4539 #endif /* SSI_DEBUG_LEVEL1 */
4541 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4544 * The block will be inserted to maintain the sorted order on the
4545 * starting address of the block.
4549 if (!(curHBlk->next) ||
4550 (p < (curHBlk->next)))
4552 /* Heap block should be inserted here */
4555 * Check if the block to be returned can be merged with the
4558 /* cm_mem_c_001.main_12 - addition for header consideration */
4559 #ifdef SSI_DEBUG_LEVEL1
4560 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4562 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4563 #endif /* SSI_DEBUG_LEVEL1 */
4565 /* Merge the block */
4566 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4567 #ifdef SSI_DEBUG_LEVEL1
4568 /* update the flags */
4569 if (CMM_IS_STATIC(p->memFlags))
4570 heapCb->staticHeapMemUsed -= (size + hdr);
4571 else if (CMM_IS_DYNAMIC(p->memFlags))
4572 heapCb->dynamicHeapMemUsed -= (size + hdr);
4573 size = (curHBlk->size += (size + hdr));
4575 size = (curHBlk->size += size);
4576 #endif /*SSI_DEBUG_LEVEL1*/
4581 /* cm_mem_c_001.main_12 - addition for double-free check */
4582 #ifdef SSI_DEBUG_LEVEL1
4583 /* Check for double deallocation in heap */
4584 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4586 /* Release the lock */
4587 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4589 (Void) WTUnlock (&(heapCb->heapLock));
4591 (Void) SUnlock (&(heapCb->heapLock));
4594 /* This block is already freed in the heap */
4597 /* update the flags as it is a new node */
4598 if (CMM_IS_STATIC(p->memFlags))
4600 heapCb->staticHeapMemUsed -= (size + hdr);
4601 CMM_RESET_STATIC_FLAG(p->memFlags);
4603 else if (CMM_IS_DYNAMIC(p->memFlags))
4605 heapCb->dynamicHeapMemUsed -= (size + hdr);
4606 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4608 CMM_SET_FREE_FLAG(p->memFlags);
4609 p->requestedSize = 0;
4610 #endif /*SSI_DEBUG_LEVEL1*/
4611 /* insert the block */
4612 p->next = curHBlk->next;
4617 /* Try to merge with the next block in the chain */
4618 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4619 #ifdef SSI_DEBUG_LEVEL1
4620 if (((Data *)p + hdr + size) == (Data *)(p->next))
4622 if (((Data *)p + size) == (Data *)(p->next))
4623 #endif /*SSI_DEBUG_LEVEL1*/
4625 /* p->next can not be NULL */
4626 /* cm_mem_c_001.main_12 - addition for header consideration */
4627 #ifdef SSI_DEBUG_LEVEL1
4628 p->size += (p->next->size + hdr);
4630 p->size += p->next->size;
4631 #endif /*SSI_DEBUG_LEVEL1*/
4632 p->next = p->next->next;
4635 /* Release the lock */
4636 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4638 (Void) WTUnlock (&(heapCb->heapLock));
4640 (Void) SUnlock (&(heapCb->heapLock));
4642 /* cm_mem_c_001.main_15 : Additions */
4643 #ifdef SS_HISTOGRAM_SUPPORT
4644 /* If If Tapa task (entId)is registerd for histogram then insert
4645 Memrory Freed information into the hash list */
4648 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4649 fileName, entId) != ROK)
4651 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4655 #endif /* SS_HISTOGRAM_SUPPORT */
4659 else if (p < curHBlk)
4662 * Check if the block to be returned can be merged with the
4665 /* cm_mem_c_001.main_12 - addition for header consideration */
4666 #ifdef SSI_DEBUG_LEVEL1
4667 if (((Data *)p + hdr + size) == (Data *)curHBlk)
4669 if (((Data *)p + size) == (Data *)curHBlk)
4670 #endif /* SSI_DEBUG_LEVEL1 */
4672 /* Merge the block */
4673 /* cm_mem_c_001.main_12 - addition for header consideration */
4674 #ifdef SSI_DEBUG_LEVEL1
4675 p->size = size + (curHBlk->size + hdr);
4677 p->size = size + curHBlk->size;
4678 #endif /* SSI_DEBUG_LEVEL1 */
4679 p->next = curHBlk->next;
4683 /* insert the block */
4687 /* cm_mem_c_001.main_12 - addition for header updation */
4688 #ifdef SSI_DEBUG_LEVEL1
4689 /* update the flags in both cases as they are new start nodes*/
4690 if (CMM_IS_STATIC(p->memFlags))
4692 heapCb->staticHeapMemUsed -= (size + hdr);
4693 CMM_RESET_STATIC_FLAG(p->memFlags);
4695 else if (CMM_IS_DYNAMIC(p->memFlags))
4697 heapCb->dynamicHeapMemUsed -= (size + hdr);
4698 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4700 CMM_SET_FREE_FLAG(p->memFlags);
4701 p->requestedSize = 0;
4702 #endif /* SSI_DEBUG_LEVEL1 */
4706 /* Release the lock */
4707 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4709 (Void) WTUnlock (&(heapCb->heapLock));
4711 (Void) SUnlock (&(heapCb->heapLock));
4713 /* cm_mem_c_001.main_15 : Additions */
4714 #ifdef SS_HISTOGRAM_SUPPORT
4715 /* If If Tapa task (entId)is registerd for histogram then insert
4716 Memrory Freed information into the hash list */
4719 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4720 fileName, entId) != ROK)
4722 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4726 #endif /* SS_HISTOGRAM_SUPPORT */
4732 if (heapCb->next == NULLP)
4734 /* Heap block is empty. Insert the block in the head. */
4739 /* cm_mem_c_001.main_12 - addition for header updation */
4740 #ifdef SSI_DEBUG_LEVEL1
4741 if (CMM_IS_STATIC(p->memFlags))
4743 heapCb->staticHeapMemUsed -= (size + hdr);
4744 CMM_RESET_STATIC_FLAG(p->memFlags);
4746 else if (CMM_IS_DYNAMIC(p->memFlags))
4748 heapCb->dynamicHeapMemUsed -= (size + hdr);
4749 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4751 CMM_SET_FREE_FLAG(p->memFlags);
4752 p->requestedSize = 0;
4753 #endif /* SSI_DEBUG_LEVEL1 */
4755 /* Release the heap lock */
4756 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4758 (Void) WTUnlock (&(heapCb->heapLock));
4760 (Void) SUnlock (&(heapCb->heapLock));
4762 /* cm_mem_c_001.main_15 : Additions */
4763 #ifdef SS_HISTOGRAM_SUPPORT
4764 /* If If Tapa task (entId)is registerd for histogram then insert
4765 Memrory Freed information into the hash list */
4768 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4769 fileName, entId) != ROK)
4771 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4775 #endif /* SS_HISTOGRAM_SUPPORT */
4779 /* Release the lock */
4780 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4782 (Void) WTUnlock (&(heapCb->heapLock));
4784 (Void) SUnlock (&(heapCb->heapLock));
4788 } /* end of cmHeapFree */
4789 /* cm_mem_c_001.main_15 : Additions */
4791 #ifdef SS_MEM_LEAK_STS
4794 * Fun: cmInitMemLeakMdl
4796 * Desc: Initializes the memory leak detection module
4801 * Notes: This function initializes the memory leak detection module.
4808 Void cmInitMemLeakMdl
4813 Void cmInitMemLeakMdl (Void)
4820 memLkCb.memLkMdlInit = FALSE;
4821 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4823 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4825 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4826 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4827 500, 0, FALSE, CM_HASH_KEYTYPE_U32MOD, 0, 0);
4828 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4831 if(memLkCb.fileLkLog == NULLP)
4833 memLkCb.fileLkLog = (FILE *) stdout;
4835 memLkCb.memLkMdlInit = TRUE;
4838 } /* cmInitMemLeakMdl */
4839 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4842 * Fun: cmDeinitMemLeakMdl
4844 * Desc: De-initializes the memory leak detection module
4849 * Notes: This function de-initializes the memory leak detection module.
4856 Void cmDeinitMemLeakMdl
4861 Void cmDeinitMemLeakMdl (Void)
4868 memLkCb.memLkMdlInit = FALSE;
4869 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4871 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4873 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4874 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4875 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4882 * Fun: cmMemOpenMemLkFile
4884 * Desc: Initializes the memory leak detection module
4889 * Notes: This function initializes the memory leak detection module.
4896 Void cmMemOpenMemLkFile
4901 Void cmMemOpenMemLkFile (arg)
4905 memLkCb.fileLkLog = NULLP;
4906 memLkCb.fileLkLog = fopen(arg, "w");
4914 * Desc: Initializes the memory leak detection module
4919 * Notes: This function initializes the memory leak detection module.
4931 Void SLogLkInfo (Void)
4935 MemAllocInfo *oldMemInfo;
4936 MemAllocInfo *newMemInfo;
4942 if( memLkCb.memLkMdlInit == FALSE)
4946 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4947 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4949 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4951 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4953 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4959 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4960 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4961 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4963 sprintf(prntBuf, "[LBIS]\n");
4964 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4965 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4967 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4969 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
4971 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4972 sprintf(prntBuf, "Module Name: %s\n",
4973 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
4974 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4975 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
4976 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4977 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
4978 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4979 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
4980 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4981 sprintf(prntBuf,"Memory Allocation Path:\n");
4982 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4983 funcNm = (S8 **)newMemInfo->backTrace;
4984 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
4986 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
4987 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4989 sprintf(prntBuf, "[LBIE]\n\n");
4990 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4991 fflush(memLkCb.fileLkLog);
4992 oldMemInfo = newMemInfo;
4995 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4998 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
4999 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5007 * Desc: Initializes the memory leak detection module
5012 * Notes: This function initializes the memory leak detection module.
5024 Void SFlushLkInfo (Void)
5027 MemAllocInfo *newMemInfo;
5031 #ifdef SS_MEM_LEAK_SOL
5033 #endif /* SS_MEM_LEAK_SOL */
5035 if( memLkCb.memLkMdlInit == FALSE)
5040 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5042 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5044 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5049 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5050 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5051 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
5053 funcNm = (S8 **)newMemInfo->backTrace;
5054 #ifdef SS_MEM_LEAK_SOL
5055 for(i = 0; i < newMemInfo->bTrcSz; i++)
5057 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5058 #ifdef SS_4GMX_LCORE
5059 MxHeapFree(SsiHeap, funcNm[i]);
5063 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(U32) * CM_MAX_STACK_TRACE); */
5065 #endif /* SS_MEM_LEAK_SOl */
5066 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5067 #ifdef SS_4GMX_LCORE
5068 MxHeapFree(SsiHeap, funcNm);
5069 MxHeapFree(SsiHeap, newMemInfo);
5075 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5083 * Fun: cmStorAllocBlk
5085 * Desc: Initializes the memory leak detection module
5090 * Notes: This function initializes the memory leak detection module.
5105 Void cmStorAllocBlk (addr, reqSz, allocSz, bktIdx)
5112 #ifndef SS_MEM_LEAK_SOL
5113 Ptr trace[CM_MAX_STACK_TRACE];
5114 #endif /* SS_MEM_LEAK_SOL */
5117 MemAllocInfo *allocInfo;
5120 if( memLkCb.memLkMdlInit == FALSE)
5125 #ifdef SS_MEM_LEAK_SOL
5126 /* I need to do this for solaris, because it does not implement
5127 * backtrace. Here backtrace is my function. See below for the
5128 * implementation. */
5129 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5130 #ifdef SS_4GMX_LCORE
5131 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(U32) * CM_MAX_STACK_TRACE));
5132 memset(funcNm, 0, (sizeof(U32) * CM_MAX_STACK_TRACE));
5134 funcNm = (S8 **)calloc(1, (sizeof(U32) * CM_MAX_STACK_TRACE));
5136 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(U32) * CM_MAX_STACK_TRACE); */
5137 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
5138 #else /* SS_MEM_LEAK_SOL */
5139 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5140 funcNm = backtrace_symbols(trace, traceSize);
5141 #endif /* SS_MEM_LEAK_SOL */
5143 moduleId = cmMemGetModuleId(funcNm, traceSize);
5145 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5146 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5147 #ifdef SS_4GMX_LCORE
5148 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
5149 memset(allocInfo, 0, sizeof(MemAllocInfo));
5151 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
5153 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
5154 allocInfo->memAddr = addr;
5155 allocInfo->reqSz = reqSz;
5156 allocInfo->allocSz = allocSz;
5157 allocInfo->bktIdx = bktIdx;
5158 allocInfo->backTrace = (PTR) funcNm;
5159 allocInfo->moduleId = moduleId;
5160 allocInfo->bTrcSz = traceSize;
5162 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
5163 (PTR)allocInfo, (U8 *)&(allocInfo->memAddr),
5164 sizeof(allocInfo->memAddr));
5165 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
5167 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5169 } /* cmStorAllocBlk */
5173 * Fun: cmMemGetModuleId
5175 * Desc: Initializes the memory leak detection module
5180 * Notes: This function initializes the memory leak detection module.
5193 U8 cmMemGetModuleId (funNm, traceSize)
5205 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
5207 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5208 for(idx = 0; idx < traceSize; idx++)
5212 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
5214 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
5219 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5221 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5222 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
5223 memUsrMdlStr[mdlFunStrIdx].fPStr,
5227 return (mdlFunStrIdx);
5232 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5234 retVal = strcmp((const S8 *)"DEFAULT",
5235 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5238 return (mdlFunStrIdx);
5245 } /* cmMemGetModuleId */
5249 * Fun: cmMemGetStrMtchIdx
5251 * Desc: Initializes the memory leak detection module
5256 * Notes: This function initializes the memory leak detection module.
5263 S16 cmMemGetStrMtchIdx
5271 S16 cmMemGetStrMtchIdx(strtIdx, endIdx, str, strLst)
5286 len = strlen((const S8 *)str);
5288 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
5289 cmpStr[len + 1] = '\0';
5292 for(;strtIdx < endIdx && !found; strtIdx++)
5295 tempLen = strlen((const S8 *)strLst[strtIdx]);
5299 while(*(strLst[strtIdx] + idx + len) != '\0')
5301 retVal = strncmp((const S8 *)cmpStr,
5302 ((const S8 *)strLst[strtIdx] + idx), len);
5318 } /* cmMemGetStrMtchIdx */
5322 * Fun: cmRlsAllocBlk
5324 * Desc: Initializes the memory leak detection module
5329 * Notes: This function initializes the memory leak detection module.
5341 Void cmRlsAllocBlk(addr)
5345 Ptr trace[CM_MAX_STACK_TRACE];
5351 MemAllocInfo *memAllocInfo;
5353 if( memLkCb.memLkMdlInit == FALSE)
5359 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5361 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5362 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5363 (U8 *)&addr, sizeof(U32), 0,
5364 (PTR *)&memAllocInfo);
5367 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5369 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5370 funcNm = (S8 **) memAllocInfo->backTrace;
5371 #ifdef SS_MEM_LEAK_SOL
5372 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5374 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5375 #ifdef SS_4GMX_LCORE
5376 MxHeapFree(SsiHeap, funcNm[i]);
5381 #endif /* SS_MEM_LEAK_SOL */
5382 #ifdef SS_MEM_LEAK_FREE_TRACE
5386 sprintf( prntBuf, "\n==============================\n");
5388 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5390 sprintf( prntBuf, "Address: [%x]\n", addr);
5392 sprintf( prntBuf, "Address: [%lx]\n", addr);
5395 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5396 funcNm = backtrace_symbols(trace, traceSize);
5397 sprintf( prntBuf, "[bt] Execution path:\n");
5399 for (i=0; i < traceSize; ++i)
5401 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5404 sprintf( prntBuf, "\n==============================\n");
5407 #endif /* SS_MEM_LEAK_FREE_TRACE */
5408 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5409 #ifdef SS_4GMX_LCORE
5410 MxHeapFree(SsiHeap, funcNm);
5411 MxHeapFree(SsiHeap, memAllocInfo);
5418 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5421 #ifndef SS_MEM_LEAK_SOL
5422 if(idx == CM_MEM_USR_MDL)
5425 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5427 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5429 sprintf( prntBuf, "Address: [%u]\n", addr);
5431 sprintf( prntBuf, "Address: [%lu]\n", addr);
5434 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5435 funcNm = backtrace_symbols(trace, traceSize);
5436 sprintf( prntBuf,"[bt] Execution path:\n");
5438 for (i=0; i < traceSize; ++i)
5440 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5443 printf("\n==============================\n");
5444 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5445 #ifdef SS_4GMX_LCORE
5446 MxHeapFree(SsiHeap, funcNm);
5451 #endif /* SS_MEM_LEAK_SOL */
5453 /*cm_mem_c_001.main_25 : */
5455 } /* cmRlsAllocBlk */
5458 #ifdef SS_MEM_LEAK_SOL
5461 * Fun: cmAddrToSymStr
5463 * Desc: Initializes the memory leak detection module
5468 * Notes: This function initializes the memory leak detection module.
5482 S32 cmAddrToSymStr(pc, buffer, size)
5493 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5495 return (snprintf(buffer, size, "[0x%p]", pc));
5498 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5499 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5501 return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5504 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5508 return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5510 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5513 } /* cmAddrToSymStr */
5517 * Fun: cmLeakCallBack
5519 * Desc: Initializes the memory leak detection module
5524 * Notes: This function initializes the memory leak detection module.
5538 S32 cmLeakCallBack(pc, sigNo, arg)
5546 Backtrace_t *bt = (Backtrace_t *)arg;
5547 if (bt->bt_actcount >= bt->bt_maxcount)
5549 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5550 #ifdef SS_4GMX_LCORE
5551 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
5552 memset(buffer, 0, 510);
5554 buffer = (S8 *)calloc(1, 510);
5556 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
5557 (void) cmAddrToSymStr((void *)pc, buffer, 505);
5558 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5561 } /* cmLeakCallBack */
5567 * Desc: Initializes the memory leak detection module
5572 * Notes: This function initializes the memory leak detection module.
5585 S32 backtrace(buffer, count)
5594 bt.bt_buffer = buffer;
5595 bt.bt_maxcount = count;
5598 if (getcontext(&u) < 0)
5600 (Void) walkcontext(&u, cmLeakCallBack, &bt);
5601 return (bt.bt_actcount);
5605 #endif /* SS_MEM_LEAK_SOL */
5607 #endif /* SS_MEM_LEAK_STS */
5608 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5609 * These include sanity check functions for bucket and heap,
5610 * for printing several memory related statistics
5612 #ifdef SSI_DEBUG_LEVEL1
5615 * Fun: cmMmBktSanityChk
5617 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
5618 * This API gets called when trampling is detected in a memory block.
5620 * Ret: RTRAMPLINGNOK - Trampling, serious error
5621 * RTRAMPLINGOK - Trampling, but OK to proceed
5623 * Notes: This function performs the memory block sanity in a bucket. This
5624 * function is called by cmAlloc and cmFree as part of error handling mechanism.
5625 * Performs sanity check for the whole bucket by traversing each
5626 * of the memory blocks using the pointer bktStartPtr.
5627 * Keeps track of number of tramplings happened. If the count
5628 * exceeds the threshold decided, then invalidates this bucket.
5634 PRIVATE S16 cmMmBktSanityChk
5639 PRIVATE S16 cmMmBktSanityChk(bkt)
5647 bkt->trampleCount = 0;
5649 /* scan the entire memory list of the bucket */
5650 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5651 blkCnt < (bkt->numBlks); blkCnt++)
5653 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5655 bkt->trampleCount++;
5656 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5658 /* Take action to invalidate the entire bucket */
5659 return (RTRAMPLINGNOK);
5662 /* reach next memory block in this bucket manually */
5663 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5667 /* display an error message here */
5668 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5669 SDisplay(0, dbgPrntBuf);
5672 return (RTRAMPLINGOK);
5677 * Fun: cmMmHeapSanityChk
5679 * Desc: Performs the sanity check for the memory blocks in the memory heap.
5680 * This API gets called when trampling is detected in heap(Alloc/Free).
5682 * Ret: RTRAMPLINGNOK - Trampling, serious error
5683 * RTRAMPLINGOK - Trampling, but OK to proceed
5685 * Notes: This function performs the memory block sanity in the heap. This
5686 * function is called by cmHeapAlloc and cmHeapFree as part of error
5687 * handling mechanism. Keeps track of number of tramplings happened.
5688 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5689 * count is less than threshold, then return RTRAMPLINGOK.
5695 PRIVATE S16 cmMmHeapSanityChk
5700 PRIVATE S16 cmMmHeapSanityChk(heapCb)
5706 /* increment the trample count */
5707 heapCb->trampleCount++;
5709 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5711 return (RTRAMPLINGNOK);
5714 return (RTRAMPLINGOK);
5719 * Fun: cmMmRegIsBlkSane
5721 * Desc: Performs the sanity check for the memory block by checking its header.
5723 * Ret: ROK - If no trampling is detected in the block
5724 * RFAILED - If trampling is detected in the block
5726 * Notes: This function performs the memory block sanity in a block.
5732 S16 cmMmRegIsBlkSane
5737 S16 cmMmRegIsBlkSane(blkPtr)
5744 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5746 if (blkPtr->trSignature[sigCnt] != 0xAB)
5759 * Desc: Computes the hash list index (bin number) for a specified
5760 * key of type (x % 101).
5762 * return (idx % hash_table_size);
5764 * Ret: ROK - successful, *idx contains computed index
5772 PRIVATE S16 cmMmHashFunc
5774 CmMmHashListCp *hashListCp,
5779 PRIVATE S16 cmMmHashFunc (hashListCp, key, idx)
5780 CmMmHashListCp *hashListCp; /* hash list control point */
5781 U32 key; /* key string */
5782 U16 *idx; /* idx to return */
5786 *idx = (U16)(key % hashListCp->numOfbins);
5790 } /* end of cmMmHashFunc () */
5794 * Fun: cmMmHashListInit
5796 * Desc: Initializes a hash list. Parameters are:
5798 * hashListCp control point for hash list
5799 * nmbBins number of bins in the hash list. Storage will
5800 * be allocated for them from the indicated memory
5803 * pool for allocating storage for bins.
5805 * Ret: ROK - initialization successful
5806 * RFAILED - initialization failed, lack of memory
5814 PRIVATE S16 cmMmHashListInit
5816 CmMmHashListCp *hashListCp, /* hash list to initialize */
5817 U16 nmbBins, /* number of hash list bins */
5818 Region region, /* memory region to allocate bins */
5819 Pool pool /* memory pool to allocate bins */
5822 PRIVATE S16 cmMmHashListInit(hashListCp, nmbBins, region, pool)
5823 CmMmHashListCp *hashListCp; /* hash list to initialize */
5824 U16 nmbBins; /* number of hash list bins */
5825 Region region; /* memory region to allocate bins */
5826 Pool pool; /* memory pool to allocate bins */
5830 CmMmHashListEnt *hl;
5833 /* initialize control point fields */
5834 hashListCp->hashList = NULLP;
5835 hashListCp->numOfbins = 0;
5836 hashListCp->numOfEntries = 0;
5838 /* allocate memory for bins */
5841 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
5842 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5845 /* initialize bin pointers */
5846 hl = hashListCp->hashList;
5847 for(i = 0; i < nmbBins; i++)
5849 hl[i].size = hl[i].numAttempts = 0;
5852 /* initialize bin size */
5853 hashListCp->numOfbins = nmbBins;
5861 * Fun: cmMmHashListDeinit
5863 * Desc: Deinitializes a hash list. Deallocates memory for bins
5864 * and resets header fields. Parameters are:
5866 * hashListCp control point for hash list
5868 * pool for allocating storage for bins.
5870 * Ret: ROK - successful
5871 * RFAILED - failure, invalid parameters
5879 PRIVATE S16 cmMmHashListDeinit
5881 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
5882 Region region, /* memory region to allocate bins */
5883 Pool pool /* memory pool to allocate bins */
5886 PRIVATE S16 cmMmHashListDeinit(hashListCp, region, pool)
5887 CmMmHashListCp *hashListCp; /* hash list to deinitialize */
5888 Region region; /* memory region to allocate bins */
5889 Pool pool; /* memory pool to allocate bins */
5893 /* deallocate memory for bins */
5894 if (hashListCp->numOfbins)
5895 (Void) SPutSBuf(region, pool,
5896 (Data *) hashListCp->hashList,
5897 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5899 /* deinitialize control point fields */
5900 hashListCp->hashList = NULLP;
5901 hashListCp->numOfbins = 0;
5902 hashListCp->numOfEntries = 0;
5905 } /* end of cmMmHashListDeinit */
5909 * Fun: cmMmHashListInsert
5911 * Desc: Inserts a new entry in the hash list. Parameters are:
5913 * hashListCp control point for hash list
5914 * key pointer to key string in the new entry
5916 * Ret: ROK - insertion successful
5917 * RFAILED - insertion failed (incorrect parameter values)
5925 PRIVATE S16 cmMmHashListInsert
5927 CmMmHashListCp *hashListCp, /* hash list to add to */
5928 U32 key /* pointer to key */
5931 PRIVATE S16 cmMmHashListInsert(hashListCp, key)
5932 CmMmHashListCp *hashListCp; /* hash list to add to */
5933 U32 key; /* pointer to key */
5936 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
5937 U16 idx; /* index for insertion into hash list */
5941 /* check if hashListCp is initialised yet */
5942 if ( hashListCp->numOfbins == 0)
5945 /* compute index for insertion */
5946 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5949 hashListEnt = hashListCp->hashList;
5951 if (hashListEnt[idx].numAttempts == 0)
5953 /* new entry, insert here */
5954 hashListEnt[idx].size = key;
5955 hashListEnt[idx].numAttempts++;
5956 /* increment count of entries in hash list */
5957 hashListCp->numOfEntries++;
5961 /* this hash is occupied, re-hash it using linear probing */
5962 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5964 if (hashListEnt[i].size == key)
5966 hashListEnt[i].numAttempts++;
5970 if (hashListEnt[i].numAttempts == 0)
5972 hashListEnt[i].size = key;
5973 hashListEnt[i].numAttempts++;
5974 /* increment count of entries in hash list */
5975 hashListCp->numOfEntries++;
5980 if (i == CMM_STAT_HASH_TBL_LEN)
5982 /* there is no free slot for this key */
5988 } /* end of cmMmHashListInsert */
5990 #endif /* SSI_DEBUG_LEVEL1 */
5991 /* cm_mem_c_001.main_15 : Additions */
5992 #ifdef SS_HISTOGRAM_SUPPORT
5995 * Fun: cmHstGrmHashListInit
5997 * Desc: Initializes a hash list. Parameters are:
5999 * hashListCp control point for hash list
6000 * Ret: ROK - initialization successful
6001 * RFAILED - initialization failed, lack of memory
6009 PRIVATE S16 cmHstGrmHashListInit
6011 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6014 PRIVATE S16 cmHstGrmHashListInit(hashListCp)
6015 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6018 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6020 /* display an error message here */
6021 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6023 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6025 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6027 SDisplay(0, dbgPrntBuf);
6029 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6035 * Fun: cmHstGrmHashListDeInit
6037 * Desc: De-initializes a hash list. Parameters are:
6039 * hashListCp control point for hash list
6040 * Ret: ROK - initialization successful
6041 * RFAILED - initialization failed, lack of memory
6049 PRIVATE S16 cmHstGrmHashListDeInit
6051 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6054 PRIVATE S16 cmHstGrmHashListDeInit(hashListCp)
6055 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6058 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6060 /* display an error message here */
6061 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6063 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6065 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6067 SDisplay(0, dbgPrntBuf);
6069 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6075 * Fun: cmHstGrmFreeInsert
6077 * Desc: Inserts a Freed information in into the hash list. Parameters are:
6079 * bkt : pointer to bucket for which memory is freed.
6080 * line : Line where memory is freed.
6081 * file : file where memory is freed.
6082 * entId : Tapa task which releases the memory.
6084 * Ret: ROK - insertion successful
6085 * RFAILED - insertion failed (incorrect parameter values)
6093 PRIVATE S16 cmHstGrmFreeInsert
6095 CmHstGrmHashListCp* hashListCp, /* hash list cp */
6096 U32 blkSz, /* size of the block freed */
6097 U32 line, /* Line number */
6098 U8 *fileName, /* file name */
6099 U8 entId /* Tapa task which free the memory */
6102 PRIVATE S16 cmHstGrmFreeInsert(hashListCp, blkSz, line, fileName, entId)
6103 CmHstGrmHashListCp* hashListCp; /* hash list cp */
6104 U32 blkSz; /* size of the block freed */
6105 U32 line; /* line number */
6106 U8 *fileName; /* file Name */
6107 U8 entId; /* Tapa task which frees the memory */
6110 U32 binIdx = 0; /* Bin index to insert the entry into the hash list */
6111 U32 key = 0; /* Key to fine the bin index */
6112 U32 ret = 0; /* Return value */
6113 CmMemEntries *entry = NULLP; /* Entry which contains the information */
6117 /* check for the total number of entries in the hash list. *
6118 * If there is no place for new entry return failure */
6119 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6121 /* After comuting the hash bind and key, check the entity already *
6122 existing or not. if we found the entry then update the information */
6123 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6126 entry->freedBytes += blkSz;
6127 entry->bucketFreeReq++;
6131 /* If hash list is full then print the error tna continue */
6132 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6134 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");
6138 /* Take the address of next free entry in the hash bin */
6139 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6141 /* Increase the number of time frees called */
6142 entry->bucketFreeReq++;
6143 entry->freedBytes += blkSz;
6145 /* Fill the information into the entry structure */
6146 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6147 /* Increase the total numbet of entries in the bin */
6148 hashListCp->hashList[binIdx].numOfEntries++;
6150 /* Increase the total number of entries in the hash list */
6151 hashListCp->totalNumEntries++;
6154 } /* end of cmHstGrmFreeInsert */
6159 * Fun: ret = cmHstGrmAllocInsert
6161 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
6163 * hashListCp control point for hash list
6164 * key pointer to key string in the new entry
6166 * Ret: ROK - insertion successful
6167 * RFAILED - insertion failed (incorrect parameter values)
6175 PRIVATE S16 cmHstGrmAllocInsert
6177 CmHstGrmHashListCp *hashListCp,
6185 PRIVATE S16 cmHstGrmAllocInsert(hashListCp, blkSz, reqSz, line, fileName, entId)
6186 CmHstGrmHashListCp *hashListCp;
6197 CmMemEntries *entry = NULLP;
6200 /* check for the total number of entries in the hash list. *
6201 * If there is no place for new entry return failure */
6202 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6204 /* After comuting the hash bind and key, check the entity already *
6205 existing or not. if we found the entry then update the information */
6206 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6210 entry->allocBytes += blkSz;
6211 entry->bucketAllocReq++;
6212 entry->wastedBytes += (blkSz - *reqSz);
6216 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6218 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");
6222 /* Take the address of next free entry in the hash bin */
6223 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6225 /* Clauculae the wasted bytes */
6226 /* Here wasted byte is differnce between the byte user
6227 * has requested and the byte the ssi allocated */
6228 entry->wastedBytes += (blkSz - *reqSz);
6229 entry->bucketAllocReq++;
6230 entry->allocBytes += blkSz;
6232 /* Fill the information into the entry structure */
6233 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6234 /* Increase the total numbet of entries in the bin */
6235 hashListCp->hashList[binIdx].numOfEntries++;
6237 /* Increase the total number of entries in the hash list */
6238 hashListCp->totalNumEntries++;
6241 } /* end of cmHstGrmAllocInsert */
6246 * Fun: cmHstGrmGetHashIdxAndKey
6248 * Desc: Finds an entry in the hash list. Parameters are:
6250 * hashListCp control point for hash list
6251 * key pointer to key string in the new entry
6253 * Ret: ROK - insertion successful
6254 * RFAILED - insertion failed (incorrect parameter values)
6262 PRIVATE S16 cmHstGrmGetHashIdxAndKey
6270 PRIVATE S16 cmHstGrmGetHashIdxAndKey(fileName, line, binIdx, key)
6280 /* Calculate the key using file name and line number */
6281 for(i = 0 ; fileName[i] != '\0'; i++)
6283 *key += fileName[i];
6286 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
6288 } /* end of cmHstGrmFillEntry */
6292 * Fun: cmHstGrmFillEntry
6294 * Desc: Insert the entry into the hash list.
6296 * entry : Infornation which will be inserted into the hash list
6297 * key : Which will be used ti find the entry.
6298 * line : Line number
6299 * fileName : File name
6300 * entId : Tapa task Id
6302 * Ret: ROK - insertion successful
6303 * RFAILED - insertion failed (incorrect parameter values)
6311 PRIVATE S16 cmHstGrmFillEntry
6313 CmMemEntries *entry,
6320 PRIVATE S16 cmHstGrmFillEntry(entry, key, line, fileName, entId)
6321 CmMemEntries *entry;
6332 entry->entId = entId;
6333 for(idx = 0; fileName[idx] != '\0'; idx++)
6335 entry->fileName[idx] = fileName[idx];
6337 entry->fileName[idx] = '\0';
6339 } /* end of cmHstGrmFillEntry */
6343 * Fun: cmHstGrmFindEntry
6345 * Desc: Finds an entry in the hash list. Parameters are:
6347 * hashListCp control point for hash list
6348 * key pointer to key string in the new entry
6350 * Ret: ROK - insertion successful
6351 * RFAILED - insertion failed (incorrect parameter values)
6359 PRIVATE S16 cmHstGrmFindEntry
6361 CmHstGrmHashListCp *hashListCp,
6364 CmMemEntries **entry
6367 PRIVATE S16 cmHstGrmFindEntry(hashListCp, key, binIdx, entry)
6368 CmHstGrmHashListCp *hashListCp;
6371 CmMemEntries **entry;
6377 CmHstGrmHashListEnt *tmpBin = NULLP;
6381 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
6383 /* find for the entry in the bin */
6384 tmpBin = &(hashListCp->hashList[*binIdx]);
6385 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
6387 /* If key supplied is matched with the stored key then
6388 * return that entity */
6389 if(tmpBin->entries[numEnt].key == key)
6391 *entry = &(tmpBin->entries[numEnt]);
6393 }/* End of if (tmpBin->entries[numEnt].key) */
6394 }/* end of for (numEnt = 0) */
6396 /* Here we are checking for any room left in the bin. If the room *
6397 exists its mean that there is no entry with the Key. so return *
6399 If there is no room in the bin, then check the other bins to find *
6401 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
6403 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
6406 }/* End of if (binIdx) */
6410 }/* End of else (binIdx) */
6411 } /* End of if (numEnt) */
6414 printf ("Unable to find the entry in hash list\n");
6416 }/* End of else (numEnt) */
6417 }/* end of for (numBin = 0) */
6419 printf("Unable to find the entry in the hash list\n");
6421 } /* end of cmHstGrmFindEntry */
6423 #endif /* SS_HISTOGRAM_SUPPORT */
6424 #ifdef T2K_MEM_LEAK_DBG
6425 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
6426 U32 getT2kMemLeakIndex(U32 address)
6428 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6431 static U32 t2kMemAllocTick;
6432 static U32 smallTick;
6434 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
6436 U32 idx = getT2kMemLeakIndex(address);
6438 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6440 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6441 "line is %ld \n", address, size, fileName, lineNo);
6444 if(gMemLeakInfo[idx].address == 0)
6446 gMemLeakInfo[idx].address = address;
6447 gMemLeakInfo[idx].size = size;
6448 gMemLeakInfo[idx].lineNo = lineNo;
6449 gMemLeakInfo[idx].fileName = fileName;
6450 gMemLeakInfo[idx].age = t2kMemAllocTick;
6451 gMemLeakInfo[idx].prevRemLineNo = 0;
6452 gMemLeakInfo[idx].prevRemFileName = '\0';
6454 if(smallTick++ == 4096)
6457 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
6462 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
6463 "line is %ld \n",address, idx, fileName, lineNo);
6464 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
6465 "Age:%ld, differnce in Age:%ld",
6466 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
6467 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
6468 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
6473 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
6475 U32 idx = getT2kMemLeakIndex(address);
6477 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
6479 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
6485 if(gMemLeakInfo[idx].address == address)
6487 gMemLeakInfo[idx].address = 0;
6488 gMemLeakInfo[idx].age = 0;
6489 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6490 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
6492 gMemLeakInfo[idx].lastDelLineNum = line;
6493 gMemLeakInfo[idx].lastDelFileName = file;
6494 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6498 printf("Something is wrong, trying to remove %lx idx = %ld from"
6499 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
6500 gMemLeakInfo[idx].address);
6503 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6504 gMemLeakInfo[idx].lastDelLineNum);
6506 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6508 printf("Previous File:%s, Previous Line:%ld\n",
6509 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6514 void DumpT2kMemLeakInfoToFile()
6518 FILE *fp = fopen("memLeakInfo.txt","wb");
6522 printf("Could not open file for dumping mem leak info\n");
6526 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6528 if(gMemLeakInfo[i].address != 0)
6530 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6531 if(onlyFileName == NULL)
6533 onlyFileName = gMemLeakInfo[i].fileName;
6536 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
6537 gMemLeakInfo[i].size,
6538 gMemLeakInfo[i].age,
6539 gMemLeakInfo[i].lineNo,
6544 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6550 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6552 /* For Updating SOC Specific Memory Information */
6554 S16 UpdateSocMemInfo
6560 S16 UpdateSocMemInfo(areaIndex,mInfo)
6562 CmLteMemInfo *mInfo;
6568 void *iccHdl = NULLP;
6572 U32 poolTotAvail[4];
6574 idxReg = mInfo->numRegions;
6575 mInfo->numRegions = mInfo->numRegions + 1;
6576 /* Calling Soc specific API to get shared memory status */
6577 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6578 iccHdl = ssGetIccHdl(areaIndex);
6580 /* Populating global memory information */
6581 mInfo->regInfo[idxReg].numPools = numPool;
6582 mInfo->regInfo[idxReg].regionId = areaIndex;
6583 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6585 /* Calling INTEL API's to Get Free MEM BLOCKS */
6586 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6587 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6588 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6589 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6591 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6592 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6593 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6594 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6596 poolSize[0] = ICC_POOL_ZERO_SIZE;
6597 poolSize[1] = ICC_POOL_ONE_SIZE;
6598 poolSize[2] = ICC_POOL_TWO_SIZE;
6599 poolSize[3] = ICC_POOL_THREE_SIZE;
6601 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6602 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6603 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6604 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6606 for(idxPool=0; idxPool<numPool;idxPool++)
6608 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6609 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
6610 poolTotAvail[idxPool];
6611 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6612 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
6613 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6615 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
6616 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6625 * Fun: isL2MemUsageBelowLowerThreshold
6627 * Desc: Checks for the Lower threshold of ICC memory.
6629 * region region for obtaining the ICC handle
6631 * Ret: TRUE - Threshold has reached
6632 * FALSE - Threshold has not reached
6640 U32 isL2MemUsageBelowLowerThreshold(
6644 U32 isL2MemUsageBelowLowerThreshold(region)
6648 void * iccHdl = ssGetIccHdl(region);
6650 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6651 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6653 /* We are below the threshold if free count in BOTH of the pools
6654 * is above the ICC_MEM_LOWER_THRESHOLD % */
6655 if(((poolZeroFreeCnt * 100) >
6656 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6657 ((poolOneFreeCnt * 100) >
6658 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6669 * Fun: isMemUsageBelowLowerThreshold
6671 * Desc: Checks for the Lower threshold of ICC memory.
6673 * region region for obtaining the ICC handle
6675 * Ret: TRUE - Threshold has reached
6676 * FALSE - Threshold has not reached
6684 U32 isMemUsageBelowLowerThreshold(
6688 U32 isMemUsageBelowLowerThreshold(region)
6692 void * iccHdl = ssGetIccHdl(region);
6694 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6695 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6696 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6697 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6699 /* We are below the threshold if free count in BOTH of the pools
6700 * is above the ICC_MEM_LOWER_THRESHOLD % */
6701 if(((poolZeroFreeCnt * 100) >
6702 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6703 ((poolOneFreeCnt * 100) >
6704 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6705 ((poolTwoFreeCnt * 100) >
6706 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6707 ((poolThreeFreeCnt * 100) >
6708 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6718 * Fun: isMemUsageAboveUpperThreshold
6720 * Desc: Checks for the Upper threshold of ICC memory.
6722 * region region for obtaining the ICC handle
6724 * Ret: TRUE - Threshold has reached
6725 * FALSE - Threshold has not reached
6733 PRIVATE U32 isMemUsageAboveUpperThreshold(
6737 PRIVATE U32 isMemUsageAboveUpperThreshold(region)
6741 void * iccHdl = ssGetIccHdl(region);
6743 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6744 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6745 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6746 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6748 /* We are above the threshold if free count in either of the pools
6749 * is below the ICC_MEM_UPPER_THRESHOLD % */
6750 if(((poolZeroFreeCnt * 100) <
6751 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6752 ((poolOneFreeCnt * 100) <
6753 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6754 ((poolTwoFreeCnt * 100) <
6755 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6756 ((poolThreeFreeCnt * 100) <
6757 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6765 /* ccpu00142274- Function to check if we have reached the
6766 * Threshold for dropping UL packets at the RLC. This function
6767 * measures the free count of the ICC memory and based on the
6768 * volume of packets it sets an alarm to drop packets.
6769 * In DL, the PDCP packets are dropped at Admission Control, but
6770 * at UL we need to check if its an AM(Data only and
6771 * not Status PDU) or UM packet and free the PDU
6772 * Note: With the current design, we have PDCP DL and RLC UL
6773 * running in the same thread and the below function will be
6774 * accessed in tandem. But if PDCP DL and RLC UL are made to run
6775 * in different threads then there might be a race condition.
6776 * Please revisit this function in such a case.
6780 * Fun: isMemThreshReached
6782 * Desc: Checks whether the system has reached the
6783 * designated threshold of ICC memory.
6785 * region region for obtaining the ICC handle
6787 * Ret: ROK - Threshold has not reached
6788 * RFAILED - Threshold has reached
6796 U32 isMemThreshReached(
6800 U32 isMemThreshReached(reg)
6806 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6811 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6813 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6814 memoryCheckCounter = 0;
6820 #endif /* SS_LOCKLESS_MEMORY */
6821 /**********************************************************************
6823 **********************************************************************/