1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
20 /********************************************************************20**
22 Name: Common Memory Manager
26 Desc: C source code for the Commom Memory Manager module.
30 *********************************************************************21*/
33 /************************************************************************
35 The following functions are provided in this file.
37 cmMmRegInit Memory Region Initialization.
38 cmMmRegDeInit Memory Region Deinitialization.
40 ************************************************************************/
44 /* header include files (.h) */
45 #include "envopt.h" /* environment options */
46 #include "envdep.h" /* environment dependent */
47 #include "envind.h" /* environment independent */
49 #include "gen.h" /* general */
50 #include "ssi.h" /* system services */
51 #include "cm_mem.h" /* Common memory manager cm_mem_c_001.main_15 */
53 #ifdef SS_MEM_LEAK_STS
56 #ifdef SS_MEM_LEAK_SOL
59 #include <sys/machelf.h>
60 #else /* SS_MEM_LEAK_SOL */
62 #endif /* SS_MEM_LEAK_SOL */
63 #include <sys/types.h>
64 #endif /* SS_MEM_LEAK_STS */
67 #ifdef SS_MULTICORE_SUPPORT /* cm_mem_c_001.main_14 */
68 #include "ss_dep.h" /* implementation-specific */
69 #include "ss_queue.h" /* queues */
70 #include "ss_task.h" /* tasking */
72 #ifdef SS_MULTICORE_SUPPORT
73 #include "ss_dep.h" /* implementation-specific */
74 #include "ss_queue.h" /* queues */
75 #include "ss_task.h" /* tasking */
79 /* header/extern include files (.x) */
80 #include "gen.x" /* general */
81 #include "ssi.x" /* system services */
82 #ifdef SS_MULTICORE_SUPPORT
83 #include "ss_dep.x" /* implementation-specific */
84 #include "ss_queue.x" /* queues */
85 #include "ss_task.x" /* system services */
87 #include "cm_hash.x" /* common hash functions */
89 #include "cm_mem_wl.x" /* Common memory manager */
90 /* cm_mem_c_001.main_15: Addition */
91 #include "cm_lib.x" /* common library functions */
97 #ifdef SS_MULTICORE_SUPPORT
98 #include "ss_dep.x" /* implementation-specific */
99 #include "ss_queue.x" /* queues */
100 #include "ss_task.x" /* system services */
105 #endif /* USE_PURE */
107 #include <execinfo.h>
110 #include <sys/time.h>
112 #ifdef SS_USE_ICC_MEMORY
114 #endif /* SS_USE_ICC_MEMORY */
117 #include "mt_plat_t33.h"
118 extern S32 clusterMode;
125 /*ccpu00142274 - UL mem based flow control changes */
126 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
129 PRIVATE U32 memoryCheckCounter;
131 #define NUM_CALLS_TO_CHECK_MEM_AGAIN 80 /* Number of calls after which need to check mem */
133 #ifdef T2200_2GB_DDR_CHANGES
134 #define ICC_MEM_UPPER_THRESHOLD 20 /* Only 20% of the available memory blocks are free */
135 #define ICC_MEM_LOWER_THRESHOLD 10 /* Only 10% of the available memory blocks are free */
137 #define ICC_MEM_UPPER_THRESHOLD 10 /* Only 20% of the available memory blocks are free */
138 #define ICC_MEM_LOWER_THRESHOLD 8 /* Only 10% of the available memory blocks are free */
141 #define ICC_MEM_UPPER_THRESHOLD 9 /* Only 20% of the available memory blocks are free */
142 #define ICC_MEM_LOWER_THRESHOLD 12 /* Only 30% of the available memory blocks are free */
144 #define ICC_POOL_ZERO_SIZE 384
145 #define ICC_POOL_ONE_SIZE 1920
146 #define ICC_POOL_TWO_SIZE 3968
147 #ifdef T2200_2GB_DDR_CHANGES
148 #define ICC_POOL_THREE_SIZE 16256
150 #define ICC_POOL_THREE_SIZE 8064
153 #ifdef T2200_2GB_DDR_CHANGES
154 #define ICC_POOL_ZERO_TOTAL_BLKS 139809 /* this and the next should be dynamic*/
155 #define ICC_POOL_ONE_TOTAL_BLKS 209714
156 #define ICC_POOL_TWO_TOTAL_BLKS 27961
157 #define ICC_POOL_THREE_TOTAL_BLKS 27961
159 #define ICC_POOL_ZERO_TOTAL_BLKS 55106 /* this and the next should be dynamic*/
160 #define ICC_POOL_ONE_TOTAL_BLKS 68567
161 #define ICC_POOL_TWO_TOTAL_BLKS 13819
162 #define ICC_POOL_THREE_TOTAL_BLKS 10902
165 /* The below configuration used for icc_part_size=573M in boot args, if icc part
166 * size changes then need to change the below configuration values*/
168 #define ICC_POOL_ZERO_TOTAL_BLKS 78232
169 #define ICC_POOL_ONE_TOTAL_BLKS 117349
170 #define ICC_POOL_TWO_TOTAL_BLKS 15645
171 #define ICC_POOL_THREE_TOTAL_BLKS 15645
173 #define ICC_POOL_ZERO_TOTAL_BLKS 79437
174 #define ICC_POOL_ONE_TOTAL_BLKS 80009
175 #define ICC_POOL_TWO_TOTAL_BLKS 16864
176 #define ICC_POOL_THREE_TOTAL_BLKS 11970
185 /* forward references */
186 /* cm_mem_c_001.main_12 - prototype is changed to accept memType(static/dynamic) */
187 /* cm_mem_c_001.main_15: Addition */
188 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler*/
193 CmHashListCp memDoubleFree; /* Added to find the double free */
194 SLockId memDoubleFreeLock;
195 #define NUM_BT_TRACES 12
196 typedef struct cmMemFreeInfo
200 void *btArr[NUM_BT_TRACES];
201 struct timeval timeStamp;
205 #define NUM_FREE_BUFFERS 128
206 typedef struct cmBtInfo
209 CmMemFreeInfo btInfo[NUM_FREE_BUFFERS];
213 CmBtInfo *allocBtInfo;
215 typedef struct cmMemDoubleFree
217 CmHashListEnt tmpListEnt;
218 CmMemFreeInfo traceInfo;
223 PUBLIC U8 stopBtInfo = FALSE;
224 PUBLIC Buffer *palBuffer;
225 EXTERN Buffer *mtTskBuffer1;
226 EXTERN Buffer *mtTskBuffer2;
228 #ifdef SS_USE_ICC_MEMORY
229 PRIVATE pthread_mutex_t iccAllocFreeLock;
231 PRIVATE pthread_mutex_t dynAllocFreeLock;
232 #endif /* SS_USE_ICC_MEMORY */
234 #ifdef SS_MEM_WL_DEBUG
235 PRIVATE S16 cmInitBtInfo ARGS((void));
238 #ifdef SS_USE_ICC_MEMORY
239 #ifdef T2K_MEM_LEAK_DBG
240 PRIVATE S16 cmIccAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr, char*, U32));
241 PRIVATE S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
242 PRIVATE S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr, char*, U32));
243 PRIVATE S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
244 PUBLIC void InsertToT2kMemLeakInfo ARGS((U32 address, U32 size, U32 lineNo, char* fileName));
245 void RemoveFromT2kMemLeakInfo ARGS((U32 address, char *file, U32 line));
246 PRIVATE U32 getT2kMemLeakIndex ARGS((U32 address));
248 PRIVATE S16 cmIccAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
249 PRIVATE S16 cmIccFree ARGS((Void *regionCb, Data *ptr, Size size));
250 PRIVATE S16 cmIccAllocWithLock ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
251 PRIVATE S16 cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size));
253 #else /* SS_USE_ICC_MEMORY */
254 PRIVATE S16 cmDynAllocWithLock ARGS((Void *regionCb,Size *size,U32 flags,Data **ptr));
255 PRIVATE S16 cmDynFreeWithLock ARGS((Void *regionCb,Data *ptr, Size size));
256 PRIVATE S16 cmDynAlloc ARGS((Void *regionCb,Size *size,U32 flags,Data **ptr));
257 PRIVATE S16 cmDynFree ARGS((Void *regionCb,Data *ptr, Size size));
258 #endif /* SS_USE_ICC_MEMORY */
261 #ifdef T2K_MEM_LEAK_DBG
262 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
263 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
265 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
266 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
268 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
269 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
271 PRIVATE S16 cmAlloc ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
272 PRIVATE S16 cmFree ARGS((Void *regionCb, Data *ptr, Size size));
274 #ifdef T2K_MEM_LEAK_DBG
275 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr,char*,U32));
276 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size,char*, U32));
278 PRIVATE S16 cmAllocWL ARGS((Void *regionCb, Size *size, U32 flags, Data **ptr));
279 PRIVATE S16 cmFreeWL ARGS((Void *regionCb, Data *ptr, Size size));
282 PRIVATE S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
283 PRIVATE S16 cmHeapFree ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
285 PRIVATE S16 cmCtl ARGS((Void *regionCb, Event event, SMemCtl *memCtl));
286 PRIVATE Void cmMmHeapInit ARGS((Data *memAddr, CmMmHeapCb *heapCb, Size size));
288 /* 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 PUBLIC 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 */
421 TRC2(cmMmStatBktInit);
424 size = cfg->bktCfg[bktIdx].size;
425 numBlks = cfg->bktCfg[bktIdx].numBlks;
427 /* cm_mem_c_001.main_12 - addition for header initialization */
428 #ifdef SSI_DEBUG_LEVEL1
429 /* Reset the next block pointer */
430 regCb->bktTbl[bktIdx].nextBlk = NULLP;
432 /* Initialize the link list of the memory block */
433 nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
435 for (cnt = 0; cnt < numBlks; cnt++)
437 *nextBlk = (CmMmBlkHdr *)*memAddr;
439 /* initialize the memory block header */
440 for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
442 (*nextBlk)->trSignature[sigCnt] = 0xAB;
445 CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
446 (*nextBlk)->requestedSize = 0;
447 *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
448 nextBlk = &((*nextBlk)->nextBlk);
454 /* Initialize the bucket linked list */
456 /* Reset the next pointer */
457 regCb->bktTbl[bktIdx].next = NULLP;
459 /* Initialize the link list of the memory block */
460 next = &(regCb->bktTbl[bktIdx].next);
461 for (cnt = 0; cnt < numBlks; cnt++)
464 next = (CmMmEntry **)(*memAddr);
465 *memAddr = (*memAddr) + size;
470 #endif /* SSI_DEBUG_LEVEL1 */
472 /* Initialize the Map entry */
473 idx = size / cfg->bktQnSize;
476 * Check if the size is multiple of quantum size. If not we need to initialize
477 * one more map table entry.
479 if(size % cfg->bktQnSize)
484 while ( *lstMapIdx < idx)
486 regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
488 #if (ERRCLASS & ERRCLS_DEBUG)
489 regCb->mapTbl[*lstMapIdx].numReq = 0;
490 regCb->mapTbl[*lstMapIdx].numFailure = 0;
496 /* Initialize the bucket structure */
497 regCb->bktTbl[bktIdx].size = size;
498 regCb->bktTbl[bktIdx].numBlks = numBlks;
499 regCb->bktTbl[bktIdx].numAlloc = 0;
500 regCb->bktTbl[bktIdx].maxAlloc = 0;
502 /* Update the total bucket size */
503 /* cm_mem_c_001.main_12 - addition for considering the header size */
504 #ifdef SSI_DEBUG_LEVEL1
505 regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
507 regCb->bktSize += (size * numBlks);
508 #endif /* SSI_DEBUG_LEVEL1 */
510 regCb->bktTbl[bktIdx].bktFailCnt = 0;
511 regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
513 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
514 #ifdef SSI_DEBUG_LEVEL1
515 /* Initialize other required pointers */
516 regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
517 regCb->bktTbl[bktIdx].numAllocAttempts = 0;
518 regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
519 regCb->bktTbl[bktIdx].staticMemUsed = 0;
520 regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
521 regCb->bktTbl[bktIdx].trampleCount = 0;
522 #endif /*SSI_DEBUG_LEVEL1*/
523 /* cm_mem_c_001.main_15 : Additions */
524 #ifdef SS_HISTOGRAM_SUPPORT
525 /* Initialise the memory histogram hash list */
526 cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
527 #endif /* SS_HISTOGRAM_SUPPORT */
530 } /* end of cmMmStatBktInit */
534 * Fun: cmMmStatRegInit
536 * Desc: Configure the memory region for allocation. The function
537 * registers the memory region with System Service by calling
541 * Ret: ROK - successful,
542 * RFAILED - unsuccessful.
544 * Notes: The memory owner calls this function to initialize the memory
545 * manager with the information of the memory region. Before
546 * calling this function, the memory owner should allocate memory
547 * for the memory region. The memory owner should also provide the
548 * memory for the control block needed by the memory manager. The
549 * memory owner should allocate the memory for the region control
550 * block as cachable memory. This may increase the average
551 * throughput in allocation and deallocation as the region control
552 * block is mostly accessed by the CMM.
558 PUBLIC S16 cmMmStatRegInit
565 PUBLIC S16 cmMmStatRegInit(region, regCb, cfg)
575 #if (ERRCLASS & ERRCLS_INT_PAR)
578 Txt errMsg[256] = {'\0'};
583 #if (ERRCLASS & ERRCLS_INT_PAR)
585 /* error check on parameters */
586 if ((regCb == NULLP) || (cfg == NULLP))
591 /* Error check on the configuration fields */
592 if ((!cfg->size) || (cfg->vAddr == NULLP) ||
593 (cfg->numBkts > CMM_MAX_BKT_ENT))
597 /* Check if the quantum size is power of 2 */
598 if ((cfg->numBkts) &&
599 ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
601 /* cm_mem_c_001.main_20 Addition */
602 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
608 * Check if the size of the memory region is enough, whether bucket sizes
609 * are multiples of quantumn size, and also whether two consecutive buckets
610 * falls within same quanta.
612 lstQnSize = cfg->bktQnSize;
615 for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
617 /* check if bucket size is mutiple of quantum size */
618 if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
620 /* cm_mem_c_001.main_20 Addition */
621 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
623 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
624 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
626 sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
627 \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
633 if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
636 * Two consecutive buckets are not separated by quantum size.
638 /* cm_mem_c_001.main_20 Addition */
639 sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
643 /* cm_mem_c_001.main_20 Addition */
644 if (((cfg->bktCfg[bktIdx].size) /\
645 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
647 /* Error check whether the size of the mapping table is sufficient */
648 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
650 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
651 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
653 sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
654 \n should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
661 regCb->bktSize += (cfg->bktCfg[bktIdx].size *
662 cfg->bktCfg[bktIdx].numBlks);
664 if (regCb->bktSize > cfg->size)
666 /* Size of the memory region is less than the required size */
668 sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
673 lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
678 /* Initialize the region control block */
679 regCb->region = region;
680 regCb->regInfo.regCb = regCb;
681 regCb->regInfo.start = cfg->vAddr;
682 regCb->regInfo.size = cfg->size;
685 avail_size = cfg->size;
686 #endif /* USE_PURE */
688 if ( cfg->chFlag & CMM_REG_OUTBOARD)
690 /* Out_of_board memory */
691 regCb->regInfo.flags = CMM_REG_OUTBOARD;
695 regCb->regInfo.flags = 0;
700 if(region == SS_MAX_REGS - 1)
702 regCb->regInfo.alloc = cmAlloc;
703 regCb->regInfo.free = cmFree;
704 regCb->regInfo.ctl = cmCtl;
708 regCb->regInfo.alloc = cmAllocWL;
709 regCb->regInfo.free = cmFreeWL;
710 regCb->regInfo.ctl = cmCtl;
713 regCb->regInfo.alloc = cmAlloc;
714 regCb->regInfo.free = cmFree;
715 regCb->regInfo.ctl = cmCtl;
718 /* Initialize the physical address */
719 if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
721 regCb->pAddr = cfg->pAddr;
724 /* Initial address of the memory region block */
725 memAddr = cfg->vAddr;
727 /* Initialize the fields related to the bucket pool */
728 regCb->bktMaxBlkSize = 0;
733 /* Last bucket has the maximum size */
734 regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
736 /* Get the power of the bktQnSize */
738 while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
743 /* Initilaize the bktIndex of the map entries to FF */
744 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
746 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
750 for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
752 /* Allocate the lock for the bucket pool */
753 cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx);
756 /* Used while freeing the bktLock in cmMmRegDeInit */
757 regCb->numBkts = cfg->numBkts;
761 * Initialize the heap pool if size the memory region region is more
762 * than the size of the bucket pool
765 regCb->heapFlag = FALSE;
767 /* Align the memory address */
768 memAddr = (Data *)(PTRALIGN(memAddr));
770 regCb->heapSize = cfg->vAddr + cfg->size - memAddr;
773 * Round the heap size so that the heap size is multiple
776 regCb->heapSize -= (regCb->heapSize % CMM_MINBUFSIZE);
780 /* Allocate the lock for the heap pool */
781 regCb->heapFlag = TRUE;
782 cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize);
785 /* Call SRegRegion to register the memory region with SSI */
786 if (SRegRegion(region, ®Cb->regInfo) != ROK)
792 } /* end of cmMmRegInit*/
797 * Fun: cmMmGlobRegInit
799 * Desc: Configure the memory region for allocation. The function
800 * registers the memory region with System Service by calling
804 * Ret: ROK - successful,
805 * RFAILED - unsuccessful.
813 PUBLIC S16 cmMmGlobRegInit
818 PUBLIC S16 cmMmGlobRegInit(regCb)
819 CmMmGlobRegCb *regCb;
828 CmMmBlkSetElement *blkLstElem;
831 #if (ERRCLASS & ERRCLS_INT_PAR)
834 Txt errMsg[256] = {'\0'};
837 TRC2(cmMmGlobRegInit);
839 #ifdef SS_MEM_WL_DEBUG
840 if (cmInitBtInfo() == RFAILED)
845 for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
847 /* Initial address of the memory region block */
848 memAddr = ®Cb->bktTbl[bktIdx].startAddr;
849 bucketSetSize = regCb->bktTbl[bktIdx].bucketSetSize;
850 size = regCb->bktTbl[bktIdx].size;
852 /* Initialize the bucket linked list */
853 cmLListInit(®Cb->bktTbl[bktIdx].listValidBktSet);
854 cmLListInit(®Cb->bktTbl[bktIdx].listFreeBktSet);
855 SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
857 /* Initialize the link list of the memory block */
858 next = &(regCb->bktTbl[bktIdx].next);
860 numBlks = regCb->bktTbl[bktIdx].numBlks;
861 for (cnt = 1; cnt <= numBlks; cnt++)
864 next = (CmMmEntry **)(*memAddr);
865 *memAddr = (*memAddr) + size;
867 /* Maintain the list Cb */
868 if(!(cnt % bucketSetSize))
870 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
871 blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
872 blkLstElem->numFreeBlks = bucketSetSize;
873 blkLstElem->memSetNode.node = (PTR)blkLstElem;
874 cmLListAdd2Tail((®Cb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
875 next = &(regCb->bktTbl[bktIdx].next);
882 } /* end of cmMmGlobRegInit*/
884 #ifdef SS_USE_ICC_MEMORY
887 * Fun: cmIccAllocWithLock
889 * Desc: Allocate a memory block for use by dynamic buffers.
890 * This handler uses the lock to avoid the two thread
891 * trying to allocate the memory at same time. This
892 * handler must be used only for non-data plane thread
893 * it causes delay due to lock.
896 * Ret: ROK - successful
897 * RFAILED - unsuccessful.
904 #ifdef T2K_MEM_LEAK_DBG
906 PRIVATE S16 cmIccAllocWithLock
908 Void *regionCb, /* Pointer to a region */
909 Size *size, /* size needs to be allocated */
910 U32 flags, /* Flags used */
911 Data **ptr, /* Reference to pointer for which need to be allocate */
918 PRIVATE S16 cmIccAllocWithLock
920 Void *regionCb, /* Pointer to a region */
921 Size *size, /* size needs to be allocated */
922 U32 flags, /* Flags used */
923 Data **ptr /* Reference to pointer for which need to be allocate */
926 PRIVATE S16 cmIccAllocWithLock(regionCb, size, flags, ptr)
927 Void *regionCb; /* Pointer to a region */
928 Size *size; /* size needs to be allocated */
929 U32 flags; /* Flags used */
930 Data **ptr; /* Reference to pointer for which need to be allocate */
937 TRC2(cmIccAllocWithLock);
939 regCb = (CmMmDynRegCb *)regionCb;
941 if((SLock(&iccAllocFreeLock)) != ROK)
943 printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
947 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
949 if((SUnlock(&iccAllocFreeLock)) != ROK)
951 printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
955 if ((memPtr) == NULLP)
958 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
959 printf("Exiting...\n");
964 #ifdef T2K_MEM_LEAK_DBG
965 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
967 printf("Address returned is %p size = %ld\n",memPtr,*size);
970 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
976 } /* end of cmIccAllocWithLock */
980 * Fun: cmIccFreeWithLock
982 * Desc: Return the Dynamic memory block for the memory region.
983 * This handler uses the lock to avoid the two thread
984 * trying to free the memory at same time. This
985 * handler must be used only for non-data plane thread
986 * it causes delay due to lock.
988 * Ret: ROK - successful
989 * RFAILED - unsuccessful.
997 #ifdef T2K_MEM_LEAK_DBG
999 PRIVATE S16 cmIccFreeWithLock
1001 Void *regionCb, /* Pointer to region cb */
1002 Data *ptr, /* Memory block needs to be freed */
1003 Size size, /* Size of the block */
1010 PRIVATE S16 cmIccFreeWithLock
1012 Void *regionCb, /* Pointer to region cb */
1013 Data *ptr, /* Memory block needs to be freed */
1014 Size size /* Size of the block */
1017 PRIVATE S16 cmIccFreeWithLock(regionCb, ptr, size)
1018 Void *regionCb; /* Pointer to region cb */
1019 Data *ptr; /* Memory block needs to be freed */
1020 Size size; /* Size of the block */
1024 CmMmDynRegCb *regCb;
1026 TRC2(cmIccFreeWithLock);
1028 regCb = (CmMmDynRegCb *)regionCb;
1030 if((SLock(&iccAllocFreeLock)) != ROK)
1032 printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
1036 #ifdef T2K_MEM_LEAK_DBG
1037 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1040 TL_Free(regCb->iccHdl, ptr);
1042 if((SUnlock(&iccAllocFreeLock)) != ROK)
1044 printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1049 } /* end of cmIccFree */
1055 * Desc: Allocate a memory block for use by dynamic buffers
1058 * Ret: ROK - successful
1059 * RFAILED - unsuccessful.
1066 #ifdef T2K_MEM_LEAK_DBG
1068 PRIVATE S16 cmIccAlloc
1070 Void *regionCb, /* Pointer to a region */
1071 Size *size, /* size needs to be allocated */
1072 U32 flags, /* Flags used */
1073 Data **ptr, /* Reference to pointer for which need to be allocate */
1081 PRIVATE S16 cmIccAlloc
1083 Void *regionCb, /* Pointer to a region */
1084 Size *size, /* size needs to be allocated */
1085 U32 flags, /* Flags used */
1086 Data **ptr /* Reference to pointer for which need to be allocate */
1089 PRIVATE S16 cmIccAlloc(regionCb, size, flags, ptr)
1090 Void *regionCb; /* Pointer to a region */
1091 Size *size; /* size needs to be allocated */
1092 U32 flags; /* Flags used */
1093 Data **ptr; /* Reference to pointer for which need to be allocate */
1098 CmMmDynRegCb *regCb;
1103 regCb = (CmMmDynRegCb *)regionCb;
1105 memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1107 if ((memPtr) == NULLP)
1110 printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1111 printf("Exiting...\n");
1115 #ifdef T2K_MEM_LEAK_DBG
1116 if(((U32)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1118 printf("Address returned is %p size = %ld\n",memPtr,*size);
1121 InsertToT2kMemLeakInfo((U32)memPtr,*size,line,file);
1124 *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1126 *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1131 } /* end of cmIccAlloc */
1137 * Desc: Return the Dynamic memory block for the memory region.
1140 * Ret: ROK - successful
1141 * RFAILED - unsuccessful.
1149 #ifdef T2K_MEM_LEAK_DBG
1150 PRIVATE S16 cmIccFree
1152 Void *regionCb, /* Pointer to region cb */
1153 Data *ptr, /* Memory block needs to be freed */
1154 Size size, /* Size of the block */
1160 PRIVATE S16 cmIccFree
1162 Void *regionCb, /* Pointer to region cb */
1163 Data *ptr, /* Memory block needs to be freed */
1164 Size size /* Size of the block */
1167 PRIVATE S16 cmIccFree(regionCb, ptr, size)
1168 Void *regionCb; /* Pointer to region cb */
1169 Data *ptr; /* Memory block needs to be freed */
1170 Size size; /* Size of the block */
1174 CmMmDynRegCb *regCb;
1177 regCb = (CmMmDynRegCb *)regionCb;
1180 // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1182 #ifdef T2K_MEM_LEAK_DBG
1183 RemoveFromT2kMemLeakInfo((U32)ptr - ((U32)ptr % 512),file,line);
1187 TL_Free(regCb->iccHdl, ptr);
1189 /* memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1191 TL_Free(regCb->iccHdl, memPtr);
1193 /*TL_Free(regCb->iccHdl, ptr);*/
1197 } /* end of cmIccFree */
1201 * Fun: cmMmDynRegInit
1203 * Desc: Configure the memory region for allocation. The function
1204 * registers the memory region with System Service by calling
1208 * Ret: ROK - successful,
1209 * RFAILED - unsuccessful.
1211 * Notes: The memory owner calls this function to initialize the memory
1212 * manager with the information of the memory region. Before
1213 * calling this function, the memory owner should allocate memory
1214 * for the memory region. The memory owner should also provide the
1215 * memory for the control block needed by the memory manager. The
1216 * memory owner should allocate the memory for the region control
1217 * block as cachable memory. This may increase the average
1218 * throughput in allocation and deallocation as the region control
1219 * block is mostly accessed by the CMM.
1225 PUBLIC S16 cmMmDynRegInit
1230 PUBLIC S16 cmMmDynRegInit(regCb)
1231 CmMmDynRegCb *regCb;
1235 #ifdef T2200_2GB_DDR_CHANGES
1236 Txt regIccStr[10] = {'\0'};
1238 Txt regIccStr[64] = {'\0'};
1241 TRC2(cmMmDynRegInit);
1243 /* Register the region/memory with ICC and get the handler for same. The id is starting
1244 * from region+1 as the zero is used by PHY code */
1245 #ifdef T2200_2GB_DDR_CHANGES
1246 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1249 if(clusterMode == RADIO_CLUSTER_MODE)
1251 if(regCb->region == 3)
1252 {/* ICC packet receiver */
1253 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1256 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1257 //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1261 snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1262 //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1263 //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1266 #ifdef T2200_2GB_DDR_CHANGES
1267 sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1269 sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1273 printf(" %s \n",regIccStr);
1274 regCb->iccHdl = TL_Open(regIccStr, 0);
1276 printf("\nICC Region is %d\n",regCb->region);
1278 /* Call SRegRegion to register the memory region with SSI */
1279 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1281 /* Register the lock region for SS_MAX_REGS - 1 region */
1282 if((SS_MAX_REGS - 1) == regCb->region)
1284 regInfo.alloc = cmIccAllocWithLock;
1285 regInfo.free = cmIccFreeWithLock;
1286 regInfo.regCb = regCb;
1287 if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1289 printf("Failed to initialize the lock region lock\n");
1294 regInfo.alloc = cmIccAlloc;
1295 regInfo.free = cmIccFree;
1296 regInfo.regCb = regCb;
1299 if (SRegDynRegion(regCb->region, ®Info) != ROK)
1305 } /* end of cmMmDynRegInit*/
1307 #else /* SS_USE_ICC_MEMORY */
1311 * Fun: cmMmDynRegInit
1313 * Desc: Configure the memory region for allocation. The function
1314 * registers the memory region with System Service by calling
1318 * Ret: ROK - successful,
1319 * RFAILED - unsuccessful.
1321 * Notes: The memory owner calls this function to initialize the memory
1322 * manager with the information of the memory region. Before
1323 * calling this function, the memory owner should allocate memory
1324 * for the memory region. The memory owner should also provide the
1325 * memory for the control block needed by the memory manager. The
1326 * memory owner should allocate the memory for the region control
1327 * block as cachable memory. This may increase the average
1328 * throughput in allocation and deallocation as the region control
1329 * block is mostly accessed by the CMM.
1335 PUBLIC S16 cmMmDynRegInit
1340 PUBLIC S16 cmMmDynRegInit(regCb)
1341 CmMmDynRegCb *regCb;
1348 CmMmBlkSetElement *blkLstElem;
1350 Size bktQnSize = MT_BKTQNSIZE;
1355 TRC2(cmMmDynRegInit);
1357 /* Initialize the region control block */
1358 region = regCb->region;
1359 numBkts = regCb->numBkts;
1361 /* Initilaize the bktIndex of the map entries to FF */
1362 for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1364 regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1369 for(cnt = 0; cnt < numBkts; cnt++)
1371 /* Initialize the Map entry */
1372 size = regCb->bktTbl[cnt].size;
1373 idx = size / bktQnSize;
1376 * Check if the size is multiple of quantum size. If not we need to initialize
1377 * one more map table entry.
1379 if(size % bktQnSize)
1384 while ( lstMapIdx < idx)
1386 regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1391 regCb->bktQnPwr = 0;
1393 while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1398 /* Initialize the bucket structure */
1399 for(idx = 0; idx < numBkts; idx++)
1401 regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1403 for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1405 blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1406 blkLstElem->memSetNode.node = (PTR)blkLstElem;
1407 cmLListAdd2Tail((®Cb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1411 /* Call SRegRegion to register the memory region with SSI */
1412 cmMemset((U8*)®Info, 0, sizeof(regInfo));
1413 if((SS_MAX_REGS - 1) == regCb->region)
1415 regInfo.alloc = cmDynAllocWithLock;
1416 regInfo.free = cmDynFreeWithLock;
1417 if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1419 printf("Failed to initialize the lock region lock\n");
1424 regInfo.alloc = cmDynAlloc;
1425 regInfo.free = cmDynFree;
1428 regInfo.regCb = regCb;
1430 if (SRegDynRegion(region, ®Info) != ROK)
1436 } /* end of cmMmDynRegInit*/
1438 #endif /* SS_USE_ICC_MEMORY */
1443 * Fun: cmMmRegDeInit
1445 * Desc: Deinitialize the memory region. The function call SDeregRegion
1446 * to deregister the memory region with System Service.
1449 * Ret: ROK - successful
1450 * RFAILED - unsuccessful.
1452 * Notes: The memory owner calls this function to deinitialize the region.
1453 * The memory manager does not return the memory to the system.
1454 * Before calling this function, the memory owner must be sure that
1455 * no layer is using any memory block from this region. On
1456 * successful return from the function, any request to the memory
1457 * manager to allocate/deallocate memory will fail. The memory owner
1458 * can reuse the memory for other region or return the memory to the
1459 * system memory pool.
1467 PUBLIC S16 cmMmRegDeInit
1472 PUBLIC S16 cmMmRegDeInit(regCb)
1478 TRC2(cmMmRegDeInit);
1480 #if (ERRCLASS & ERRCLS_INT_PAR)
1482 /* error check on parameters */
1490 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1491 #ifdef SSI_DEBUG_LEVEL1
1492 /* Deinitialize the hash table used for debug info storage at region level */
1493 if (cmMmHashListDeinit(®Cb->hashListCp, regCb->region, 0) != ROK)
1497 #endif /* SSI_DEBUG_LEVEL1 */
1499 /* Call SDeregRegion first to deregister the memory region with SSI */
1500 (Void) SDeregRegion (regCb->region);
1504 /* Bucket pool is configured */
1506 /* Free the initialzed locks of the buckets */
1507 for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1509 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1510 WTDestroyLock for NT */
1511 /* cm_mem_c_001.main_24 fix for memory corruption*/
1514 WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1516 SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1518 /* cm_mem_c_001.main_15:Additions */
1519 #ifdef SS_HISTOGRAM_SUPPORT
1520 /* De-initialise the memory histogram hash list */
1521 cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1522 #endif /* SS_HISTOGRAM_SUPPORT */
1526 if (regCb->heapFlag)
1528 /* Heap pool is configured */
1530 /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1531 WTDestroyLock for NT */
1533 WTDestroyLock(®Cb->heapCb.heapLock);
1535 SDestroyLock(®Cb->heapCb.heapLock);
1541 } /* end of cmMmRegDeInit */
1544 #ifndef SS_USE_ICC_MEMORY
1547 * Fun: cmGetMemBlkSetForAlloc
1549 * Desc: Retruns the pointer to the element which is used for
1550 * allocating the buffer. Also, it does the threshold check
1551 * and get the additional memory block set from the global
1555 * Ret: Pointer to memory block set - successful
1556 * NULL - unsuccessful.
1559 * Current implementation of the is function is made assuming that
1560 * there will maximum two set of nodes only.
1567 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1569 U8 bucketIndex, /* Index to the bucket list */
1570 CmMmDynBktCb *bkt /* Bucket list control block */
1573 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForAlloc(bucketIndex, bkt)
1574 U8 bucketIndex; /* Index to the bucket list */
1575 CmMmDynBktCb *bkt; /* Bucket list control block */
1578 CmMmBlkSetElement *memBlkSetElem;
1579 CmMmBlkSetElement *nextMemBlkSetElem;
1580 CmLList *memSetNode;
1581 CmLList *nextMemSetNode;
1583 /* Check if we are coming here for the first time, if yes get a new
1584 * block set from global region */
1585 if(bkt->crntMemBlkSetElem == NULLP)
1587 /* set the current index to initial one and get the bucket set from
1589 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1591 /* Check if the element exits or not */
1592 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1597 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1598 /* Get the new block set from the gloabl region and return the same */
1599 ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1600 return (bkt->crntMemBlkSetElem);
1602 /* If this is not the first time, take the bucket list CB from the
1604 memBlkSetElem = bkt->crntMemBlkSetElem;
1605 /* If the current index doesnot have any free buckets, it check in
1606 * the next bucket node */
1607 if(memBlkSetElem->numFreeBlks == 0)
1609 /* Get the next element in the list and if it is not present, then
1610 * get the first node */
1611 memSetNode = cmLListNext(&bkt->memBlkSetElem);
1613 if(memSetNode == NULLP)
1615 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1617 memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1619 /* if next node also empty, return failure */
1620 if(memBlkSetElem->numFreeBlks == 0)
1624 /* store the new index in the current node which will be
1625 * used in the next time. */
1626 bkt->crntMemBlkSetElem = memBlkSetElem;
1629 /* If we have reached the threshold value, get the next set of buckets from
1630 * the global region and place it */
1631 if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1633 /* Get the next element for the threshold check. If next is not present,
1634 * get the first one. Here, we are not using the cmLList macros to get
1635 * to the next node or first node as those macros are working on the crnt
1636 * node and will change the crnt. As we dont want to change the crnt node
1637 * at this point, we are directly using the listCp prameter to get next
1639 nextMemSetNode = memBlkSetElem->memSetNode.next;
1641 if(nextMemSetNode == NULLP)
1643 nextMemSetNode = bkt->memBlkSetElem.first;
1646 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1648 if(nextMemBlkSetElem->numFreeBlks == 0)
1650 /* The last parameter is used wheather to block for the block set aquiring
1651 or not. Here, the logic is such that, when the current node number of
1652 free blocks becomes one and the next node has zero free blocks,
1653 we must get the block set from global region.
1654 For example, if acquire threashold is 20 and current node has only one
1655 free block and next node has zero free blocks we block to aquire lock
1656 and get the set from global region else, we try for lock, if we get
1657 the lock, the get the block set else it is get in next go
1659 ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1660 (memBlkSetElem->numFreeBlks - 1));
1664 /* On successful, return the bucket node to calling function */
1665 return (memBlkSetElem);
1666 } /* cmGetMemBlkSetForAlloc */
1671 * Fun: cmGetMemBlkSetForFree
1673 * Desc: Retruns the pointer to the element which is used for
1674 * freeing the buffer. Also, it does the threshold check
1675 * and release the additional memory block set to the global
1679 * Ret: Pointer to memory block set - successful
1680 * NULL - unsuccessful.
1683 * Current implementation of the is function is made assuming that
1684 * there will maximum two set of nodes only.
1691 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree
1693 U8 bucketIndex, /* Index to the bucket list */
1694 CmMmDynBktCb *bkt /* Bucket list control block */
1697 PRIVATE CmMmBlkSetElement* cmGetMemBlkSetForFree(bucketIndex, bkt)
1698 U8 bucketIndex; /* Index to the bucket list */
1699 CmMmDynBktCb *bkt; /* Bucket list control block */
1702 CmMmBlkSetElement *memBlkSetElem;
1703 CmMmBlkSetElement *nextMemBlkSetElem;
1704 CmLList *memSetNode;
1705 CmLList *nextMemSetNode;
1707 /* Check if we are coming here for the first time, if yes get a new
1708 * block set from global region */
1709 if(bkt->crntMemBlkSetElem == NULLP)
1711 /* set the current index to initial one */
1712 memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1714 /* Check if the element exits or not */
1715 if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1719 bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1720 return (bkt->crntMemBlkSetElem);
1722 /* If this is not the first time, take the bucket list CB from the
1724 memBlkSetElem = bkt->crntMemBlkSetElem;
1725 /* If the current index doesnot have any free buckets, it check in
1726 * the next bucket node */
1727 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1729 /* Get the next element in the list and if it is not present, then
1730 * get the first node */
1731 nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1733 if(nextMemSetNode == NULLP)
1735 nextMemSetNode = cmLListFirst(&bkt->memBlkSetElem);
1737 memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1739 /* if next node also empty, return failure */
1740 if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1744 /* store the new index in the current node which will be
1745 * used in the next time. */
1746 bkt->crntMemBlkSetElem = memBlkSetElem;
1749 /* If we have reached the threshold value and have additional block set,
1750 * release the additional block set back to global region */
1751 if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold)
1753 /* Get the next element for the threshold check. If next is not present,
1754 * get the first one. Here, we are not using the cmLList macros to get
1755 * to the next node or first node as those macros are working on the crnt
1756 * node and will change the crnt. As we dont want to change the crnt node
1757 * at this point, we are directly using the listCp prameter to get next
1759 nextMemSetNode = memBlkSetElem->memSetNode.next;
1760 if(nextMemSetNode == NULLP)
1762 nextMemSetNode = bkt->memBlkSetElem.first;
1765 nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1766 if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
1768 /* The last parameter is used wheather to block for the block set aquiring
1769 or not. Here, the logic is such that, when the current node number of
1770 free blocks becomes one less than the bucket set size and the next node
1771 is has full free blocks, we must free the block set back to global region
1772 For example, if bucket set size if 100 and release threashold is 80 and
1773 current node has number of free blocks 99 and next node has 100 free blocks
1774 we block to aquire lock and free it back to global region else, we try for
1775 lock, if we get the lock, the block set is freed else its freed in next go
1777 ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem,
1778 (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
1782 /* On successful, return the bucket node to calling function */
1783 return (memBlkSetElem);
1785 #endif /* SS_USE_ICC_MEMORY */
1786 #endif /* USE_PURE */
1788 #ifdef SS_MEM_WL_DEBUG
1791 * Fun: cmRemoveAllocPtrFromList
1793 * Desc: Remove a node with Free PTR from hashlist. The memory
1794 * of the node is Freed to the same region
1797 * Ret: ROK - successful
1798 * RFAILED - unsuccessful.
1807 PRIVATE S16 cmRemoveAllocPtrFromList
1809 CmMmDynRegCb *regionCb, /* Pointer to a region */
1813 PRIVATE S16 cmRemoveAllocPtrFromList(regionCb, ptr)
1814 CmMmDynRegCb *regionCb; /* Pointer to a region */
1819 CmMemDoubleFree *memNode = NULLP;
1821 SLock(&memDoubleFreeLock);
1822 if((cmHashListFind(&(memDoubleFree), (U8*)&ptr,
1823 sizeof(U32), 0, (PTR *)&memNode)) != ROK)
1830 tmpBtSize = backtrace(tmpBtArr, 10);
1831 strings = backtrace_symbols(tmpBtArr, tmpBtSize);
1832 printf("**** Trying to free non allocated block BT is: \n");
1833 for(idx = 0; idx < tmpBtSize; idx++)
1835 printf("%s\n", strings[idx]);
1837 printf("*****************************************\n");
1838 printf("Analysis from Array storing BT for freeing and allocation\n");
1839 cmAnalyseBtInfo(ptr, regionCb->region);
1840 SUnlock(&memDoubleFreeLock);
1844 if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
1846 SUnlock(&memDoubleFreeLock);
1849 SUnlock(&memDoubleFreeLock);
1850 SPutSBuf(regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
1857 * Fun: cmInsertAllocPtrToList
1859 * Desc: Insert a node with allocated PTR into hashlist. The memory
1860 * for the node is allocated from the same region
1863 * Ret: ROK - successful
1864 * RFAILED - unsuccessful.
1873 PRIVATE S16 cmInsertAllocPtrToList
1875 CmMmDynRegCb *regionCb, /* Pointer to a region */
1879 PRIVATE S16 cmInsertAllocPtrToList(regionCb, ptr)
1880 CmMmDynRegCb *regionCb; /* Pointer to a region */
1885 CmMemDoubleFree *memNode;
1887 SGetSBuf(regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
1888 if(memNode == NULLP)
1893 memNode->memBlkPtr = ptr;
1894 SLock(&memDoubleFreeLock);
1895 if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (U8*)&memNode->memBlkPtr,
1896 sizeof(PTR))) != ROK)
1898 SUnlock(&memDoubleFreeLock);
1901 SUnlock(&memDoubleFreeLock);
1908 #ifndef SS_USE_ICC_MEMORY
1911 * Fun: cmDynAllocWithLock
1913 * Desc: Allocate a memory block for use by dynamic buffers
1916 * Ret: ROK - successful
1917 * RFAILED - unsuccessful.
1924 /* cm_mem_c_001.main_15 : Additions */
1927 PRIVATE S16 cmDynAllocWithLock
1929 Void *regionCb, /* Pointer to a region */
1930 Size *size, /* size needs to be allocated */
1931 U32 flags, /* Flags used */
1932 Data **ptr /* Reference to pointer for which need to be allocate */
1935 PRIVATE S16 cmDynAllocWithLock(regionCb, size, flags, ptr)
1936 Void *regionCb; /* Pointer to a region */
1937 Size *size; /* size needs to be allocated */
1938 U32 flags; /* Flags used */
1939 Data **ptr; /* Reference to pointer for which need to be allocate */
1946 if((SLock(&dynAllocFreeLock)) != ROK)
1948 printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1952 ret = cmDynAlloc (regionCb, size,flags,ptr);
1954 if((SUnlock(&dynAllocFreeLock)) != ROK)
1956 printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1961 } /* end of cmDynAlloc */
1967 * Desc: Allocate a memory block for use by dynamic buffers
1970 * Ret: ROK - successful
1971 * RFAILED - unsuccessful.
1978 /* cm_mem_c_001.main_15 : Additions */
1981 PRIVATE S16 cmDynAlloc
1983 Void *regionCb, /* Pointer to a region */
1984 Size *size, /* size needs to be allocated */
1985 U32 flags, /* Flags used */
1986 Data **ptr /* Reference to pointer for which need to be allocate */
1989 PRIVATE S16 cmDynAlloc(regionCb, size, flags, ptr)
1990 Void *regionCb; /* Pointer to a region */
1991 Size *size; /* size needs to be allocated */
1992 U32 flags; /* Flags used */
1993 Data **ptr; /* Reference to pointer for which need to be allocate */
1996 CmMmDynRegCb *regCb;
2000 regCb = (CmMmDynRegCb *)regionCb;
2002 #ifdef SS_MEM_WL_DEBUG
2003 if((tmpRegTidMap[regCb->region] != (pthread_self())) )
2009 #if (ERRCLASS & ERRCLS_INT_PAR)
2011 /* error check on parameters */
2012 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2021 * Check if the requested size is less than or equal to the maximum block
2022 * size in the bucket.
2025 #ifdef SS_MEM_WL_DEBUG
2026 if ( (*size + 4) <= regCb->bktMaxBlkSize)
2028 if ( (*size) <= regCb->bktMaxBlkSize)
2032 CmMmBlkSetElement *dynMemElem;
2036 /* Get the map to the mapping table */
2037 #ifdef SS_MEM_WL_DEBUG
2038 idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
2040 idx = (((*size) - 1) >> regCb->bktQnPwr);
2043 #if (ERRCLASS & ERRCLS_DEBUG)
2044 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2046 printf("Failed to get the buffer of size %d\n", *size);
2047 /* Some fatal error in the map table initialization. */
2055 /* Dequeue the memory block and return it to the user */
2056 bktIdx = regCb->mapTbl[idx].bktIdx;
2057 bkt = &(regCb->bktTbl[bktIdx]);
2058 #ifdef SS_MEM_WL_DEBUG
2059 if(bkt->size < (*size+4))
2061 if(bkt->size < (*size))
2065 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2068 dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
2070 /* Check if the bucket index, if its not valid, return failure */
2071 if(dynMemElem == NULLP)
2074 printf("Failed to get the buffer of size %ld\n", *size);
2076 printf("Failed to get the buffer of size %d\n", *size);
2081 #ifdef SS_MEM_WL_DEBUG
2082 if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
2088 /* Get the bucket node from the index returned and allocate the memory */
2089 *ptr = dynMemElem->nextBktPtr;
2094 dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
2095 dynMemElem->numFreeBlks--;
2097 #ifdef SS_MEM_WL_DEBUG
2098 prvAllocPtr[regCb->region] = *ptr;
2100 **ptr = (U8) bktIdx;
2104 *ptr += sizeof (U32);
2106 if ((bktIdx == 0) && (!stopBtInfo))
2110 btInfo = &allocBtInfo[regCb->region];
2111 btIdx = btInfo->btInfoIdx;
2112 btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2114 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2116 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2119 btIdx &= (NUM_FREE_BUFFERS - 1);
2121 btInfo->btInfo[btIdx].ptr = (PTR)0;
2122 btInfo->btInfo[btIdx].btSize = 0;
2123 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2124 btInfo->btInfoIdx = btIdx;
2131 /* If the size is not matching, return failure to caller */
2133 printf("Failed to get the buffer of size %ld\n", *size);
2135 printf("Failed to get the buffer of size %d\n", *size);
2139 #else /* use pure is on */
2141 #ifdef SS_4GMX_LCORE
2142 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2143 cmMemset((U8*)ptr, 0, *size);
2145 /* *ptr = (Data*) malloc(*size); */
2147 *ptr = (Data *)malloc(*size);
2149 if ( (*ptr) == NULLP)
2151 /* avail_size -= *size; */
2153 #endif /* USE_PURE */
2155 } /* end of cmDynAlloc */
2156 #endif /* SS_USE_ICC_MEMORY */
2159 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2161 int g_overused[5] = {0};
2168 * Desc: Allocate a memory block for the memory region.
2171 * Ret: ROK - successful
2172 * RFAILED - unsuccessful.
2175 * The function allocates a memory block of size atleast equal to
2176 * the requested size. The size parameter will be updated with the
2177 * actual size of the memory block allocated for the request. The
2178 * CMM tries to allocate the memory block form the bucket pool. If
2179 * there is no memory in the bucket the CMM allocates the memory
2180 * block form the heap pool. This function is always called by the
2181 * System Service module.
2183 * The caller of the function should try to use the out value of
2184 * the size while returning the memory block to the region. However
2185 * the current design of the memory manager does not enforce to pass
2186 * the actual size of the memory block. (Due to the SGetSBuf
2187 * semantics the layer will not able to pass the correct size of the
2188 * memory block while calling SPutSBuf).
2194 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2196 /* cm_mem_c_001.main_15 : Additions */
2197 #ifdef T2K_MEM_LEAK_DBG
2208 #ifdef SS_HISTOGRAM_SUPPORT
2209 #ifdef SSI_DEBUG_LEVEL1
2224 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType, line, fileName, entId, hstReg)
2249 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, line, fileName, entId, hstReg)
2259 #endif /* SSI_DEBUG_LEVEL1 */
2263 #ifdef SSI_DEBUG_LEVEL1
2274 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr, memType)
2291 PRIVATE S16 cmAlloc(regionCb, size, flags, ptr)
2299 #endif /* SSI_DEBUG_LEVEL1 */
2300 /* cm_mem_c_001.main_15: Additions */
2301 #endif /* SS_HISTOGRAM_SUPPORT */
2304 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2311 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2315 /* cm_mem_c_001.main_15 : Additions */
2316 #ifdef SS_MEM_LEAK_STS
2318 #endif /* SS_MEM_LEAK_STS */
2319 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2320 #ifdef SSI_DEBUG_LEVEL1
2321 CmMmBlkHdr *alocBlk;
2322 #endif /* SSI_DEBUG_LEVEL1 */
2323 /* cm_mem_c_001.main_15 : Additions */
2324 #ifdef SS_HISTOGRAM_SUPPORT
2326 #endif /* SS_HISTOGRAM_SUPPORT */
2333 /* cm_mem_c_001.main_15 : Additions */
2334 #ifdef SS_MEM_LEAK_STS
2336 #endif /* SS_MEM_LEAK_STS */
2338 regCb = (CmMmRegCb *)regionCb;
2340 #if (ERRCLASS & ERRCLS_INT_PAR)
2342 /* error check on parameters */
2343 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2349 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2350 #ifdef SSI_DEBUG_LEVEL1
2351 #if (ERRCLASS & ERRCLS_INT_PAR)
2352 if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2356 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2357 #endif /* SSI_DEBUG_LEVEL1 */
2364 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2365 #ifdef SSI_DEBUG_LEVEL1
2366 /* Update the hash list */
2367 if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2369 /* display that, this entry could not be made in the hash list */
2371 /* display an error message here */
2372 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2374 sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2375 *size, regCb->region);
2377 sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2378 *size, regCb->region);
2380 SDisplay(0, dbgPrntBuf);
2383 #endif /* SSI_DEBUG_LEVEL1 */
2386 * Check if the requested size is less than or equal to the maximum block
2387 * size in the bucket.
2389 if ( *size <= regCb->bktMaxBlkSize)
2391 /* Get the map to the mapping table */
2392 idx = ((*size - 1) >> regCb->bktQnPwr);
2394 #if (ERRCLASS & ERRCLS_DEBUG)
2395 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2397 /* Some fatal error in the map table initialization. */
2402 /* Dequeue the memory block and return it to the user */
2403 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2406 /* While loop is introduced to use the "break statement inside */
2410 * Check if the size request is not greater than the size available
2413 if (*size > bkt->size)
2415 /* Try to go to the next bucket if available */
2416 if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2417 (regCb->mapTbl[++idx].bktIdx != 0xFF))
2419 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2423 /* This is the last bucket, try to allocate from heap */
2428 /* Acquire the bucket lock */
2429 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2431 (Void) WTLock(&(bkt->bktLock));
2433 (Void) SLock(&(bkt->bktLock));
2436 #if (ERRCLASS & ERRCLS_DEBUG)
2437 regCb->mapTbl[idx].numReq++;
2438 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2440 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2441 #ifdef SSI_DEBUG_LEVEL1
2442 /* increment the allocation attempt counter at bucket level */
2443 bkt->numAllocAttempts++;
2445 /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2446 the allocation is always from (bkt->nextBlk) */
2449 if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2451 /* detected a trampled memory block in this bucket */
2453 /* display an error message here */
2454 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2456 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2457 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2459 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2460 (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2462 SDisplay(0, dbgPrntBuf);
2465 if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2467 /* Release the lock */
2468 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2470 (Void) WTUnlock(&(bkt->bktLock));
2472 (Void) SUnlock(&(bkt->bktLock));
2474 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2475 return (RTRAMPLINGNOK);
2479 /* Release the lock */
2480 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2482 (Void) WTUnlock(&(bkt->bktLock));
2484 (Void) SUnlock(&(bkt->bktLock));
2486 /* return RFAILED */
2492 if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2494 if ((*ptr = bkt->next))
2495 #endif /* SSI_DEBUG_LEVEL1 */
2497 /* cm_mem_c_001.main_12 - addition for header */
2498 #ifdef SSI_DEBUG_LEVEL1
2499 /* point to next block header */
2500 alocBlk = bkt->nextBlk;
2501 bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2503 bkt->next = *((CmMmEntry **)(bkt->next));
2504 #endif /* SSI_DEBUG_LEVEL1 */
2507 * Increment the statistics variable of number of memory block
2511 if (bkt->numAlloc > bkt->maxAlloc)
2513 bkt->maxAlloc = bkt->numAlloc;
2516 if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2518 g_overused[bktIdx] = 1;
2519 /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2523 /* cm_mem_c_001.main_12 - addition for header manipulation */
2524 #ifdef SSI_DEBUG_LEVEL1
2525 /* update the size for which this memory block has been allocated */
2526 alocBlk->requestedSize = *size;
2527 /* update the memory block header */
2528 CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2529 if (memType == CMM_STATIC_MEM_FLAG)
2531 CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2532 /* add it to the static memory allocated */
2533 bkt->staticMemUsed += bkt->size;
2537 CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2538 /* add it to the dynamic memory allocated */
2539 bkt->dynamicMemUsed += bkt->size;
2541 #endif /* SSI_DEBUG_LEVEL1 */
2543 if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2547 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2550 "[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++);
2553 "[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++);
2555 SDisplay(0, prntBuf);
2563 "SGetSBuf:%08lu:Size Bucket Id:%03d Times:%05lu Pointer: %8p\n",
2564 *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2565 SDisplay(0, prntBuf);
2567 #endif /* MEMCAL_DEBUG */
2568 /* cm_mem_c_001.main_15 : Additions */
2569 #ifdef SS_HISTOGRAM_SUPPORT
2570 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2571 * information into the hash list */
2574 if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2576 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2581 #endif /* SS_HISTOGRAM_SUPPORT */
2583 /* Update the size parameter */
2585 #ifdef SS_MEM_LEAK_STS
2586 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2587 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2588 regCb->mapTbl[idx].bktIdx);
2589 #endif /* SS_MEM_LEAK_STS */
2591 /* cm_mem_c_008.104 - Addition for memory calculator tool */
2593 /* Release the lock */
2594 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2596 (Void) WTUnlock(&(bkt->bktLock));
2598 (Void) SUnlock(&(bkt->bktLock));
2607 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2610 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2613 "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2615 SDisplay(0, prntBuf);
2619 #if (ERRCLASS & ERRCLS_DEBUG)
2620 regCb->mapTbl[idx].numFailure++;
2621 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2623 /* Release the lock */
2624 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2626 (Void) WTUnlock(&(bkt->bktLock));
2628 (Void) SUnlock(&(bkt->bktLock));
2637 regCb->heapCb.heapAllocCnt++;
2639 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
2642 "[MEM_CAL_CNTC] No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2643 regCb->heapCb.heapAllocCnt);
2646 "[MEM_CAL_CNTC] No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2647 regCb->heapCb.heapAllocCnt);
2649 SDisplay(0, prntBuf);
2654 /* Memory not available in the bucket pool */
2655 if (regCb->heapFlag && (*size < regCb->heapSize))
2658 if (flags) tryHeap = 1;
2661 * The heap memory block is available. Allocate the memory block from
2664 /* cm_mem_c_001.main_15: Additions */
2665 #ifdef SS_HISTOGRAM_SUPPORT
2666 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2667 #ifdef SSI_DEBUG_LEVEL1
2668 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2670 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2671 #endif /* SSI_DEBUG_LEVEL1 */
2673 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2674 #ifdef SSI_DEBUG_LEVEL1
2675 return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2677 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2678 #endif /* SSI_DEBUG_LEVEL1 */
2679 #endif /* SS_HISTOGRAM_SUPPORT */
2682 /* No memory available */
2684 #else /* use pure is on */
2685 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
2686 #ifdef SS_4GMX_LCORE
2687 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2688 cmMemset((U8*)ptr, 0, *size);
2690 *ptr = (Data*) malloc(*size);
2692 if ( (*ptr) == NULLP)
2694 avail_size -= *size;
2696 #endif /* USE_PURE */
2698 } /* end of cmAlloc */
2700 #ifdef SS_MEM_WL_DEBUG
2703 * Fun: cmInitDoubleFreeList
2705 * Desc: Initialize the hashlist used for detecting double free
2707 * Ret: ROK - successful
2708 * RFAILED - unsuccessful.
2717 PUBLIC S16 cmInitDoubleFreeList
2722 PUBLIC S16 cmInitDoubleFreeList()
2726 CmMemDoubleFree memNode;
2728 TRC2(cmInitDoubleFreeList);
2730 offset = (U16)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2732 if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2733 CM_HASH_KEYTYPE_U32MOD, 0, 0)) != ROK);
2737 SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2742 #ifdef SS_MEM_WL_DEBUG
2747 * Desc: Return the Dynamic memory block for the memory region.
2750 * Ret: ROK - successful
2751 * RFAILED - unsuccessful.
2760 PRIVATE S16 cmInitBtInfo
2764 PRIVATE S16 cmInitBtInfo (Void)
2767 regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2768 if (regBtInfo == NULLP)
2772 allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2773 if(allocBtInfo == NULLP)
2780 #endif /* SS_MEM_WL_DEBUG */
2783 * Fun: cmAnalyseBtInfo
2785 * Desc: Return the Dynamic memory block for the memory region.
2788 * Ret: ROK - successful
2789 * RFAILED - unsuccessful.
2798 PUBLIC Void cmAnalyseBtInfo
2800 PTR ptr, /* Memory block needs to be freed */
2804 PUBLIC Void cmAnalyseBtInfo (ptr,idx)
2805 PTR ptr; /* Memory block needs to be freed */
2814 /* for(regIdx = 0; regIdx < 8; regIdx++)
2817 btInfo = &allocBtInfo[idx];
2818 btIdx = btInfo->btInfoIdx;
2820 for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)
2822 /* if ((btInfo->btInfo[btIdx].ptr >= ptr) &&
2823 (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr) */
2824 if(btInfo->btInfo[btIdx].btSize != 0)
2828 strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2829 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);
2830 for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2832 printf("%s\n", strings[i]);
2834 printf("*******************************************************\n");
2842 btIdx = NUM_FREE_BUFFERS - 1;
2851 #ifndef SS_USE_ICC_MEMORY
2854 * Fun: cmDynFreeWithLock
2856 * Desc: Return the Dynamic memory block for the memory region.
2859 * Ret: ROK - successful
2860 * RFAILED - unsuccessful.
2869 PRIVATE S16 cmDynFreeWithLock
2871 Void *regionCb, /* Pointer to region cb */
2872 Data *ptr, /* Memory block needs to be freed */
2873 Size size /* Size of the block */
2876 PRIVATE S16 cmDynFreeWithLock(regionCb, ptr, size)
2877 Void *regionCb; /* Pointer to region cb */
2878 Data *ptr; /* Memory block needs to be freed */
2879 Size size; /* Size of the block */
2884 if((SLock(&dynAllocFreeLock)) != ROK)
2886 printf("dynAllocWithLock: Failed to get the DYN lock\n");
2890 ret = cmDynFree(regionCb, ptr,size);
2892 if((SUnlock(&dynAllocFreeLock)) != ROK)
2894 printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2900 } /* end of cmDynFree */
2906 * Desc: Return the Dynamic memory block for the memory region.
2909 * Ret: ROK - successful
2910 * RFAILED - unsuccessful.
2919 PRIVATE S16 cmDynFree
2921 Void *regionCb, /* Pointer to region cb */
2922 Data *ptr, /* Memory block needs to be freed */
2923 Size size /* Size of the block */
2926 PRIVATE S16 cmDynFree(regionCb, ptr, size)
2927 Void *regionCb; /* Pointer to region cb */
2928 Data *ptr; /* Memory block needs to be freed */
2929 Size size; /* Size of the block */
2932 CmMmDynRegCb *regCb;
2936 CmMmDynBktCb *bkt = NULLP;
2937 CmMmBlkSetElement *dynMemElem;
2939 #ifdef SS_MEM_WL_DEBUG
2946 regCb = (CmMmDynRegCb *)regionCb;
2947 #ifdef SS_MEM_WL_DEBUG
2948 if((tmpRegTidMap[regCb->region] != (pthread_self())))
2955 #if (ERRCLASS & ERRCLS_INT_PAR)
2956 /* error check on parameters */
2957 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2962 /* Check if the memory block is from the memory region */
2963 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2964 ((CmMmRegCb *)regCb)->regInfo.size)
2968 /* cm_mem_c_001.main_20 Addition */
2969 if (ptr < regCb->regInfo.start)
2976 #ifdef SS_MEM_WL_DEBUG
2977 ptr -= sizeof (U32);
2980 /* The memory block was allocated from the bucket pool */
2982 /* Get the map to the mapping table */
2983 idx = ((size - 1) >> regCb->bktQnPwr);
2985 #if (ERRCLASS & ERRCLS_DEBUG)
2986 if (regCb->mapTbl[idx].bktIdx == 0xFF)
2988 /* Some fatal error in the map table initialization. */
2993 /* Enqueue the memory block and return it to the user */
2994 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2997 * Check if the size is not greater than the size available
2998 * in the bucket. If so, then the buffer must have been allocated
2999 * from next bucket. We don't need to check the validity of the
3000 * next bucket, otherwise buffer must have been allocated from heap
3003 #ifdef SS_MEM_WL_DEBUG
3004 if (size > bkt->size)
3006 printf("Size = %d bucket size = %d\n", size, bkt->size);
3008 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3010 if(size > bkt->size)
3012 printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
3015 printf("Bucket Size wrong \n");
3020 dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
3022 /* Check if the bucket index, if its not valid, return failure */
3023 if(dynMemElem == NULLP)
3028 #ifdef SS_MEM_WL_DEBUG
3029 tmpBktIdx = (U8)*ptr;
3030 tmpVal = (U8)*(ptr+1);
3032 if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
3035 printf("bktIdx wrong \n");
3039 if ((bktIdx == 0) && (!stopBtInfo))
3043 btInfo = ®BtInfo[regCb->region];
3044 btIdx = btInfo->btInfoIdx;
3045 btInfo->btInfo[btIdx].ptr = (PTR) ptr;
3047 btInfo->btInfo[btIdx].btSize = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
3049 gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
3052 btIdx &= (NUM_FREE_BUFFERS - 1);
3054 btInfo->btInfo[btIdx].ptr = (PTR)0;
3055 btInfo->btInfo[btIdx].btSize = 0;
3056 cmMemset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
3057 btInfo->btInfoIdx = btIdx;
3060 if(prvAllocPtr[regCb->region] == ptr)
3062 prvAllocPtr[regCb->region] = NULLP;
3065 cmMemset(ptr, (regCb->region+1), bkt->size);
3068 /* Get the bucket node from the index returned and allocate the memory */
3069 *((CmMmEntry **)ptr) = dynMemElem->nextBktPtr;
3070 dynMemElem->nextBktPtr = ptr;
3071 dynMemElem->numFreeBlks++;
3075 #else /* use pure is on */
3077 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3078 #ifdef SS_4GMX_LCORE
3079 (Void)MxHeapFree(SsiHeap, ptr);
3081 /* (Void)free(ptr); */
3083 /* avail_size += size; */
3087 #endif /* USE_PURE */
3090 } /* end of cmDynFree */
3091 #endif /* SS_USE_ICC_MEMORY */
3099 * Desc: Return the memory block for the memory region.
3102 * Ret: ROK - successful
3103 * RFAILED - unsuccessful.
3105 * Notes: The user calls this function to return the previously allocated
3106 * memory block to the memory region. The memory manager does not
3107 * check the validity of the state of the memory block(like whether
3108 * it was allocated earlier). The caller must be sure that, the
3109 * address specified in the parameter 'ptr' is valid and was
3110 * allocated previously from same region.
3117 /* cm_mem_c_001.main_15 : Additions */
3118 #ifdef T2K_MEM_LEAK_DBG
3128 #ifdef SS_HISTOGRAM_SUPPORT
3141 PRIVATE S16 cmFree(regionCb, ptr, size, line, fileName, entId, hstReg)
3161 PRIVATE S16 cmFree(regionCb, ptr, size)
3167 /* cm_mem_c_001.main_15 : Additions */
3168 #endif /* SS_HISTOGRAM_SUPPORT */
3171 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
3178 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3179 #ifdef SSI_DEBUG_LEVEL1
3181 #endif /* SSI_DEBUG_LEVEL1 */
3182 /* cm_mem_c_001.main_15 : Additions */
3183 #ifdef SS_HISTOGRAM_SUPPORT
3185 #endif /* SS_HISTOGRAM_SUPPORT */
3189 regCb = (CmMmRegCb *)regionCb;
3192 #if (ERRCLASS & ERRCLS_INT_PAR)
3194 /* error check on parameters */
3195 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3200 /* Check if the memory block is from the memory region */
3201 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3202 ((CmMmRegCb *)regCb)->regInfo.size)
3206 /* cm_mem_c_001.main_20 Addition */
3207 if (ptr < regCb->regInfo.start)
3215 * Check if the memory block was allocated from the bucket pool.
3217 if(ptr < regCb->regInfo.start)
3219 Buffer *tmpBuffer = NULLP;
3220 tmpBuffer->b_cont = NULLP;
3223 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3225 /* The memory block was allocated from the bucket pool */
3227 /* Get the map to the mapping table */
3228 idx = ((size - 1) >> regCb->bktQnPwr);
3230 #if (ERRCLASS & ERRCLS_DEBUG)
3231 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3233 /* Some fatal error in the map table initialization. */
3238 /* Enqueue the memory block and return it to the user */
3239 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3242 * Check if the size is not greater than the size available
3243 * in the bucket. If so, then the buffer must have been allocated
3244 * from next bucket. We don't need to check the validity of the
3245 * next bucket, otherwise buffer must have been allocated from heap
3248 if (size > bkt->size)
3250 bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3253 /* Acquire the bucket lock */
3254 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3256 (Void) WTLock(&(bkt->bktLock));
3258 (Void) SLock(&(bkt->bktLock));
3261 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3262 #ifdef SSI_DEBUG_LEVEL1
3263 /* increment the dealloc attempt counter at bucket level */
3264 bkt->numDeallocAttempts++;
3266 /* Check the memFlags to see whether this block was allocated */
3267 ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3269 /* validate the block to be freed for trampling */
3270 if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3272 /* Handle error case of Memory trampling */
3274 /* display an error message here */
3275 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3277 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3278 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3280 sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3281 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3283 SDisplay(0, dbgPrntBuf);
3286 * if sanity check returns RTRAMPLINGOK then there is nothing to do
3287 * as the memory blk is already invalidated in cmMmBktSanityChk
3289 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3293 /* Release the lock */
3294 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3296 (Void) WTUnlock(&(bkt->bktLock));
3298 (Void) SUnlock(&(bkt->bktLock));
3306 * this is the case where in the entire bucket has been made unusable
3309 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3311 (Void) WTUnlock(&(bkt->bktLock));
3313 (Void) SUnlock(&(bkt->bktLock));
3316 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3317 return (RTRAMPLINGNOK);
3321 /* reset the size */
3322 ptrHdr->requestedSize = 0;
3323 /* check if the block to be freed is already having the state as FREE */
3324 if (CMM_IS_FREE(ptrHdr->memFlags))
3326 /* Handle double deallocation error case */
3328 /* display an error message here */
3329 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3331 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3332 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3334 sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3335 ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3337 SDisplay(0, dbgPrntBuf);
3340 /* Release the lock */
3341 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3343 (Void) WTUnlock(&(bkt->bktLock));
3345 (Void) SUnlock(&(bkt->bktLock));
3348 /* handle RDBLFREE in SFree/SPutSBuf */
3351 if (CMM_IS_STATIC(ptrHdr->memFlags))
3353 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3354 CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3355 /* deduct it from the static memory count */
3356 bkt->staticMemUsed -= bkt->size;
3358 else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3360 CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3361 CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3362 /* deduct it from the dynamic memory count */
3363 bkt->dynamicMemUsed -= bkt->size;
3367 /* This is a case similar to trampled memory */
3369 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
3371 sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3373 sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3375 SDisplay(0, dbgPrntBuf);
3377 if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3379 /* do not add to the free list */
3382 /* Release the lock */
3383 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3385 (Void) WTUnlock(&(bkt->bktLock));
3387 (Void) SUnlock(&(bkt->bktLock));
3394 * this is the case where in the entire bucket has been made unusable
3397 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3399 (Void) WTUnlock(&(bkt->bktLock));
3401 (Void) SUnlock(&(bkt->bktLock));
3404 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3405 return (RTRAMPLINGNOK);
3409 /* Return the block to memory */
3410 ptrHdr->nextBlk = bkt->nextBlk;
3411 bkt->nextBlk = ptrHdr;
3414 *((CmMmEntry **)ptr) = bkt->next;
3415 bkt->next = (CmMmEntry *)ptr;
3416 #endif /* SSI_DEBUG_LEVEL1 */
3419 * Decrement the statistics variable of number of memory block
3427 if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3429 g_overused[bktIdx] = 0;
3430 /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3433 /* cm_mem_c_001.main_15 : Additions */
3434 #ifdef SS_HISTOGRAM_SUPPORT
3435 /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3436 * information into the hash list */
3439 if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3441 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3445 #endif /* SS_HISTOGRAM_SUPPORT */
3447 #ifdef SS_MEM_LEAK_STS
3448 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3449 cmRlsAllocBlk((PTR)ptr);
3450 #endif /* SS_MEM_LEAK_STS */
3452 /* Release the lock */
3453 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3455 (Void) WTUnlock(&(bkt->bktLock));
3457 (Void) SUnlock(&(bkt->bktLock));
3463 /* The memory block was allocated from the heap pool */
3464 /* cm_mem_c_001.main_15 : Additions */
3465 #ifdef SS_HISTOGRAM_SUPPORT
3466 return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3468 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3469 #endif /* SS_HISTOGRAM_SUPPORT */
3470 #else /* use pure is on */
3472 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3473 #ifdef SS_4GMX_LCORE
3474 (Void)MxHeapFree(SsiHeap, ptr);
3480 #endif /* USE_PURE */
3483 } /* end of cmFree */
3490 * Desc: alloc without lock
3493 * Ret: ROK - successful
3494 * RFAILED - unsuccessful.
3500 /*cm_mem_c_001.main_21-added new function*/
3501 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3502 #ifdef T2K_MEM_LEAK_DBG
3503 PRIVATE S16 cmAllocWL
3514 PRIVATE S16 cmAllocWL
3522 PRIVATE S16 cmAllocWL(regionCb, size, flags, ptr)
3532 CmMmBkt *bkt = NULLP;
3535 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3539 /*cm_mem_c_001.main_23 Removed support of USE_MEMCAL and MEMCAL_DEBUG support for SS_FAP*/
3541 regCb = (CmMmRegCb *)regionCb;
3543 #ifdef SS_MEM_WL_DEBUG
3544 if((tmpRegTidMap[regCb->region] != (pthread_self())))
3550 #if (ERRCLASS & ERRCLS_INT_PAR)
3552 /* error check on parameters */
3553 if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3559 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3564 * Check if the requested size is less than or equal to the maximum block
3565 * size in the bucket.
3567 #ifdef MSPD_T2K_TRACK_BUG
3570 /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3571 if ( *size <= regCb->bktMaxBlkSize)
3573 /* Get the map to the mapping table */
3574 idx = ((*size - 1) >> regCb->bktQnPwr);
3576 /* Dequeue the memory block and return it to the user */
3577 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3581 * Check if the size request is not greater than the size available
3584 /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3585 if ((*size <= bkt->size)&&(*ptr = bkt->next))
3587 /* Try to go to the next bucket if available */
3588 bkt->next = *((CmMmEntry **)(bkt->next));
3591 * Increment the statistics variable of number of memory block
3595 if (bkt->numAlloc > bkt->maxAlloc)
3597 bkt->maxAlloc = bkt->numAlloc;
3600 #ifdef MSPD_T2K_TRACK_BUG
3609 /* Update the size parameter */
3617 /* Memory not available in the bucket pool */
3618 if (regCb->heapFlag && (*size < regCb->heapSize))
3620 /*cm_mem_c_001.main_23 Removed support of and MEMCAL_DEBUG support for SS_FAP*/
3622 * The heap memory block is available. Allocate the memory block from
3625 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3626 return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3629 /* No memory available */
3631 #else /* use pure is on */
3632 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3633 #ifdef SS_4GMX_LCORE
3634 *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3635 cmMemset((U8*)ptr, 0, *size);
3637 /* *ptr = (Data*) malloc(*size); */
3639 *ptr = (Data *)malloc(*size);
3641 if ( (*ptr) == NULLP)
3643 /* avail_size -= *size; */
3645 #endif /* USE_PURE */
3647 } /* end of cmAllocWL */
3654 * Desc: free without lock
3657 * Ret: ROK - successful
3658 * RFAILED - unsuccessful.
3665 #ifdef T2K_MEM_LEAK_DBG
3666 PRIVATE S16 cmFreeWL
3676 PRIVATE S16 cmFreeWL
3683 PRIVATE S16 cmFreeWL(regionCb, ptr, size)
3692 CmMmBkt *bkt = NULLP;
3695 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3699 regCb = (CmMmRegCb *)regionCb;
3701 #ifdef SS_MEM_WL_DEBUG
3702 if(tmpRegTidMap[regCb->region] != (pthread_self()))
3709 #if (ERRCLASS & ERRCLS_INT_PAR)
3711 /* error check on parameters */
3712 if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3717 /* Check if the memory block is from the memory region */
3718 if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3719 ((CmMmRegCb *)regCb)->regInfo.size)
3727 * Check if the memory block was allocated from the bucket pool.
3729 #ifdef MSPD_T2K_TRACK_BUG
3733 if (ptr < (regCb->regInfo.start + regCb->bktSize))
3735 /* The memory block was allocated from the bucket pool */
3737 /* Get the map to the mapping table */
3738 idx = ((size - 1) >> regCb->bktQnPwr);
3740 #if (ERRCLASS & ERRCLS_DEBUG)
3741 if (regCb->mapTbl[idx].bktIdx == 0xFF)
3743 /* Some fatal error in the map table initialization. */
3748 /* Enqueue the memory block and return it to the user */
3749 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3751 #ifdef MSPD_T2K_TRACK_BUG
3753 if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3760 * Check if the size is not greater than the size available
3761 * in the bucket. If so, then the buffer must have been allocated
3762 * from next bucket. We don't need to check the validity of the
3763 * next bucket, otherwise buffer must have been allocated from heap
3766 if (size > bkt->size)
3768 bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3771 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3772 *((CmMmEntry **)ptr) = bkt->next;
3773 bkt->next = (CmMmEntry *)ptr;
3776 * Decrement the statistics variable of number of memory block
3784 /* The memory block was allocated from the heap pool */
3785 return (cmHeapFree (&(regCb->heapCb), ptr, size));
3786 #else /* use pure is on */
3788 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
3789 #ifdef SS_4GMX_LCORE
3790 (Void)MxHeapFree(SsiHeap, ptr);
3792 /* (Void)free(ptr); */
3794 /* avail_size += size; */
3798 #endif /* USE_PURE */
3801 } /* end of cmFreeWL */
3808 * Desc: Control request function.
3811 * Ret: ROK - successful
3812 * RFAILED - unsuccessful.
3814 * Notes: The current semantics of the control function is defined for two
3815 * types of events: virtual address to physical address translation
3816 * and memory resource check.
3818 * The physical address translation is valid only for the memory
3819 * region physically contiguous and non pagable.
3835 PRIVATE S16 cmCtl(regionCb, event, memCtl)
3845 regCb = (CmMmRegCb *)regionCb;
3847 #if (ERRCLASS & ERRCLS_INT_PAR)
3849 /* error check on parameters */
3850 if ((regCb == NULLP) || (memCtl == NULLP))
3863 #if (ERRCLASS & ERRCLS_INT_PAR)
3864 if ((memCtl->u.vtop.vaddr == NULLP) ||
3865 (memCtl->u.vtop.paddr == NULLP))
3871 /* Check if the virtual to physical address translation is valid */
3872 if (regCb->chFlag & CMM_REG_PHY_VALID)
3874 offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3875 *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3882 case SS_MEM_CHK_RES:
3885 #if (ERRCLASS & ERRCLS_INT_PAR)
3886 if (!(memCtl->u.chkres.size) ||
3887 (memCtl->u.chkres.status == NULLP))
3893 /* Check if the Bucket pool is configured */
3898 U32 avlSize, totSize;
3900 * The bucket pool is configured. The status value returned
3901 * does reflect on the memory availabilty in the bucket pool.
3902 * The value does not consider the available memory in the
3905 idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3906 bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]);
3907 avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3908 avlSize += regCb->heapCb.avlSize;
3909 totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3910 *(memCtl->u.chkres.status) = (avlSize/(totSize/10));
3914 /* Bucket pool not configured */
3917 * Find the percentage memory available in the heap pool. The value
3918 * does not consider the fragmentation of the heap pool.
3920 *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3921 (regCb->heapSize/10));
3925 #else /* use pure is on */
3926 *(memCtl->u.chkres.status) = ((avail_size) /
3927 (regCb->regInfo.size/10));
3929 #endif /* USE_PURE */
3935 /* No other event is supported currently */
3940 /* shouldn't reach here */
3942 } /* end of cmCtl */
3949 * Desc: Initialize the heap pool.
3952 * Ret: ROK - successful
3953 * RFAILED - unsuccessful.
3955 * Notes: This function is called by the cmMmRegInit.
3961 PRIVATE Void cmMmHeapInit
3968 PRIVATE Void cmMmHeapInit (memAddr, heapCb, size)
3974 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3975 #ifdef SSI_DEBUG_LEVEL1
3977 #endif /* SSI_DEBUG_LEVEL1 */
3980 /* Initialize the heap control block */
3981 heapCb->vStart = memAddr;
3982 heapCb->vEnd = memAddr + size;
3983 heapCb->avlSize = size;
3984 heapCb->minSize = CMM_MINBUFSIZE;
3986 heapCb->next = (CmHEntry *)memAddr;
3987 heapCb->next->next = NULLP;
3988 /* cm_mem_c_001.main_12 - addition for header initialization */
3989 #ifdef SSI_DEBUG_LEVEL1
3990 heapCb->next->size = size - sizeof(CmHEntry);
3991 heapCb->next->requestedSize = 0;
3992 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3994 heapCb->next->trSignature[idx] = 0xAB;
3996 CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3997 heapCb->staticHeapMemUsed = 0;
3998 heapCb->dynamicHeapMemUsed = 0;
3999 heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
4000 sizeof(heapCb->next->memFlags) +
4001 sizeof(heapCb->next->requestedSize);
4002 heapCb->numAllocAttempts = 0;
4003 heapCb->numDeallocAttempts = 0;
4004 heapCb->trampleCount = 0;
4006 heapCb->next->size = size;
4007 #endif /* SSI_DEBUG_LEVEL1 */
4009 #if (ERRCLASS & ERRCLS_DEBUG)
4010 heapCb->numFragBlk = 0;
4012 heapCb->numFailure = 0;
4015 heapCb->heapAllocCnt = 0;
4016 /* cm_mem_c_001.main_15 : Additions */
4017 #ifdef SS_HISTOGRAM_SUPPORT
4018 /* Initialise the memory histogram hash list */
4019 cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
4020 #endif /* SS_HISTOGRAM_SUPPORT */
4023 } /* end of cmMmHeapInit */
4031 * Desc: Allocates the memory block from the heap pool.
4034 * Ret: ROK - successful
4035 * RFAILED - unsuccessful.
4037 * Notes: This function is called by the cmAlloc. cmAlloc calls this
4038 * function when there is no memory block available in the bucket
4039 * and the heap pool is configured.
4046 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
4047 /* cm_mem_c_001.main_15 : Additions */
4048 #ifdef SS_HISTOGRAM_SUPPORT
4049 #ifdef SSI_DEBUG_LEVEL1
4051 PRIVATE S16 cmHeapAlloc
4063 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType, line, fileName, entId, hstReg)
4075 PRIVATE S16 cmHeapAlloc
4086 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, line, fileName, entId, hstReg)
4095 #endif /* SSI_DEBUG_LEVEL1 */
4097 #ifdef SSI_DEBUG_LEVEL1
4099 PRIVATE S16 cmHeapAlloc
4107 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size, memType)
4115 PRIVATE S16 cmHeapAlloc
4122 PRIVATE S16 cmHeapAlloc (heapCb, ptr, size)
4127 #endif /* SSI_DEBUG_LEVEL1 */
4128 /* cm_mem_c_001.main_15 : Additions */
4129 #endif /* SS_HISTOGRAM_SUPPORT */
4131 CmHEntry *prvHBlk; /* Previous heap block */
4132 CmHEntry *curHBlk; /* Current heap block */
4134 /* cm_mem_c_001.main_15 : Additions */
4135 #ifdef SS_MEM_LEAK_STS
4137 #endif /* SS_MEM_LEAK_STS */
4138 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4139 #ifdef SSI_DEBUG_LEVEL1
4140 CmHEntry *alocHeapBlk;
4144 #endif /* SSI_DEBUG_LEVEL1 */
4145 /* cm_mem_c_001.main_15 : Additions */
4146 #ifdef SS_HISTOGRAM_SUPPORT
4148 #endif /* SS_HISTOGRAM_SUPPORT */
4151 /* cm_mem_c_001.main_15 : Additions */
4152 /* Acquire the heap lock */
4153 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4155 (Void) WTLock (&(heapCb->heapLock));
4157 (Void) SLock (&(heapCb->heapLock));
4160 #ifdef SS_MEM_LEAK_STS
4162 #endif /* SS_MEM_LEAK_STS */
4163 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4164 #ifdef SSI_DEBUG_LEVEL1
4165 heapCb->numAllocAttempts++;
4166 requestedSize = *size;
4167 #endif /* SSI_DEBUG_LEVEL1 */
4169 /* Roundup the requested size */
4170 *size = CMM_DATALIGN(*size, (heapCb->minSize));
4172 /* Check if the available total size is adequate. */
4173 if ((*size) >= heapCb->avlSize)
4175 /* cm_mem_c_001.main_15 : Additions */
4177 (Void) WTUnlock (&(heapCb->heapLock));
4179 (Void) SUnlock (&(heapCb->heapLock));
4185 /* cm_mem_c_001.main_12 - addition for aligning the header size */
4186 #ifdef SSI_DEBUG_LEVEL1
4187 hdr = PTRALIGN(sizeof(CmHEntry));
4188 #endif /* SSI_DEBUG_LEVEL1 */
4191 * Search through the heap block list in the heap pool of size
4192 * greater than or equal to the requested size.
4195 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
4196 #ifdef SSI_DEBUG_LEVEL1
4197 prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
4199 prvHBlk = (CmHEntry *)&(heapCb->next);
4200 #endif /* SSI_DEBUG_LEVEL1 */
4201 for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
4202 prvHBlk = prvHBlk->next)
4205 * Since the size of the block is always multiple of CMM_MINBUFSIZE
4206 * and the requested size is rounded to the size multiple of
4207 * CMM_MINBUFSIZE, the difference between the size of the heap block
4208 * and the size to allocate will be either zero or multiple of
4211 if ((*size) <= curHBlk->size)
4213 /* cm_mem_c_001.main_12 - addition for block size calculation */
4214 #ifdef SSI_DEBUG_LEVEL1
4215 tmpSize = curHBlk->size - (*size);
4217 tmpSize = tmpSize - hdr;
4220 if ((tmpSize = (curHBlk->size - (*size))))
4221 #endif /* SSI_DEBUG_LEVEL1 */
4223 /* Heap block of bigger size */
4224 /* cm_mem_c_001.main_12 - addition for allocating memory */
4225 #ifdef SSI_DEBUG_LEVEL1
4226 *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
4227 alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
4229 * No need to look for memory trampling as this is a new block altogether
4230 * Update the header only for this case as it is new block formed
4232 for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
4234 alocHeapBlk->trSignature[idx] = 0xAB;
4236 alocHeapBlk->size = *size;
4238 *ptr = (Data *)curHBlk + tmpSize;
4239 #endif /* SSI_DEBUG_LEVEL1 */
4240 curHBlk->size = tmpSize;
4244 /* Heap block is same size of the requested size */
4245 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4246 #ifdef SSI_DEBUG_LEVEL1
4247 /* look for memory trampling as this is a pure block*/
4250 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4252 /* detected a trampled memory block in this bucket */
4254 /* display an error message here */
4255 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4257 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4259 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4261 SDisplay(0, dbgPrntBuf);
4264 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4266 /* Release the lock */
4267 /* cm_mem_c_001.main_13: Replaced SUnlock with
4270 (Void) WTUnlock (&(heapCb->heapLock));
4272 (Void) SUnlock (&(heapCb->heapLock));
4274 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4275 return (RTRAMPLINGNOK);
4279 /* Release the lock */
4280 /* cm_mem_c_001.main_13: Replaced SUnlock with
4283 (Void) WTUnlock (&(heapCb->heapLock));
4285 (Void) SUnlock (&(heapCb->heapLock));
4292 *ptr = (Data *)curHBlk + hdr;
4293 alocHeapBlk = curHBlk;
4294 *size = curHBlk->size;
4296 *ptr = (Data *)curHBlk;
4297 #endif /* SSI_DEBUG_LEVEL1 */
4298 prvHBlk->next = curHBlk->next;
4301 /* cm_mem_c_001.main_12 - addition for header updation */
4302 #ifdef SSI_DEBUG_LEVEL1
4303 /* update the header fields */
4304 alocHeapBlk->requestedSize = requestedSize;
4305 alocHeapBlk->memFlags = 0;
4306 if (memType == CMM_STATIC_MEM_FLAG)
4308 CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4309 heapCb->staticHeapMemUsed += (*size + hdr);
4313 CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4314 heapCb->dynamicHeapMemUsed += (*size + hdr);
4316 heapCb->avlSize -= ((*size) + hdr);
4318 heapCb->avlSize -= (*size);
4319 #endif /* SSI_DEBUG_LEVEL1 */
4325 "SGetSBuf:%08lu:Size Heap Alloc Times:%05lu Pointer: %8p\n",
4326 *size, num_times, *ptr);
4327 SDisplay(0, prntBuf);
4331 /* cm_mem_c_001.main_15 : Additions */
4332 #ifdef SS_MEM_LEAK_STS
4333 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4334 cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4335 #endif /* SS_MEM_LEAK_STS */
4336 /* Release the lock */
4337 /* cm_mem_c_001.main_16 : cm_mem_c_001.main_18 Additions */
4339 (Void) WTUnlock (&(heapCb->heapLock));
4341 (Void) SUnlock (&(heapCb->heapLock));
4344 #ifdef SS_HISTOGRAM_SUPPORT
4345 /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4346 * information into the hash list */
4349 if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4351 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4356 #endif /* SS_HISTOGRAM_SUPPORT */
4362 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4368 /* Release the lock */
4369 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4371 (Void) WTUnlock (&(heapCb->heapLock));
4373 (Void) SUnlock (&(heapCb->heapLock));
4378 } /* end of cmHeapAlloc */
4385 * Desc: Return the memory block from the heap pool.
4388 * Ret: ROK - successful
4389 * RFAILED - unsuccessful.
4391 * Notes: This function returns the memory block to the heap pool. This
4392 * function is called by cmFree. The function does not check the
4393 * validity of the memory block. The caller must be sure that the
4394 * block was previously allocated and belongs to the heap pool. The
4395 * function maintain the sorting order of the memory block on the
4396 * starting address of the block. This function also do compaction
4397 * if the neighbouring blocks are already in the heap.
4404 /* cm_mem_c_001.main_15 : Additions */
4405 #ifdef SS_HISTOGRAM_SUPPORT
4407 PRIVATE S16 cmHeapFree
4418 PRIVATE S16 cmHeapFree (heapCb, ptr, size, line, fileName, entId, hstReg)
4429 PRIVATE S16 cmHeapFree
4436 PRIVATE S16 cmHeapFree (heapCb, ptr, size)
4441 /* cm_mem_c_001.main_15 : Additions */
4442 #endif /* SS_HISTOGRAM_SUPPORT */
4445 CmHEntry *curHBlk; /* Current heap block */
4446 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4447 #ifdef SSI_DEBUG_LEVEL1
4449 #endif /* SSI_DEBUG_LEVEL1 */
4450 /* cm_mem_c_001.main_15 : Additions */
4451 #ifdef SS_HISTOGRAM_SUPPORT
4452 Size allocSize = size;
4454 #endif /* SS_HISTOGRAM_SUPPORT */
4458 /* Roundup the requested size */
4459 size = CMM_DATALIGN(size, (heapCb->minSize));
4460 /* cm_mem_c_001.main_15: Additions */
4461 #ifdef SS_HISTOGRAM_SUPPORT
4463 #endif /* SS_HISTOGRAM_SUPPORT */
4465 /* Acquire the heap lock */
4466 /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4468 (Void) WTLock (&(heapCb->heapLock));
4470 (Void) SLock (&(heapCb->heapLock));
4473 /* increase the avlSize */
4474 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4475 #ifdef SSI_DEBUG_LEVEL1
4476 hdr = PTRALIGN(sizeof(CmHEntry));
4477 heapCb->avlSize += (size + hdr);
4478 heapCb->numDeallocAttempts++;
4480 heapCb->avlSize += size;
4481 #endif /* SSI_DEBUG_LEVEL1 */
4483 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4484 #ifdef SSI_DEBUG_LEVEL1
4485 p = (CmHEntry *)(ptr - hdr);
4487 p = (CmHEntry *)ptr;
4488 /* cm_mem_c_001.main_15 : Additions */
4489 #ifdef SS_MEM_LEAK_STS
4490 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4491 cmRlsAllocBlk((PTR)ptr);
4492 #endif /* SS_MEM_LEAK_STS */
4493 #endif /* SSI_DEBUG_LEVEL1 */
4496 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4497 #ifdef SSI_DEBUG_LEVEL1
4498 /* look for memory trampling */
4499 if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4501 /* detected a trampled memory block in heap */
4503 /* display an error message here */
4504 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4506 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4508 sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4510 SDisplay(0, dbgPrntBuf);
4513 if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4515 /* Release the lock */
4516 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4518 (Void) WTUnlock (&(heapCb->heapLock));
4520 (Void) SUnlock (&(heapCb->heapLock));
4522 /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4523 return (RTRAMPLINGNOK);
4527 /* do not add to the free heap */
4528 heapCb->avlSize -= (size + hdr);
4529 /* Release the heap lock */
4530 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4532 (Void) WTUnlock (&(heapCb->heapLock));
4534 (Void) SUnlock (&(heapCb->heapLock));
4541 /* look for any double free */
4542 if (CMM_IS_FREE(p->memFlags))
4545 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
4547 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4549 sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4551 SDisplay(0, dbgPrntBuf);
4554 heapCb->avlSize -= (size + hdr);
4555 /* cm_mem_c_001.main_15 : Additions */
4557 (Void) WTUnlock (&(heapCb->heapLock));
4559 (Void) SUnlock (&(heapCb->heapLock));
4564 #endif /* SSI_DEBUG_LEVEL1 */
4566 for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4569 * The block will be inserted to maintain the sorted order on the
4570 * starting address of the block.
4574 if (!(curHBlk->next) ||
4575 (p < (curHBlk->next)))
4577 /* Heap block should be inserted here */
4580 * Check if the block to be returned can be merged with the
4583 /* cm_mem_c_001.main_12 - addition for header consideration */
4584 #ifdef SSI_DEBUG_LEVEL1
4585 if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4587 if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4588 #endif /* SSI_DEBUG_LEVEL1 */
4590 /* Merge the block */
4591 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4592 #ifdef SSI_DEBUG_LEVEL1
4593 /* update the flags */
4594 if (CMM_IS_STATIC(p->memFlags))
4595 heapCb->staticHeapMemUsed -= (size + hdr);
4596 else if (CMM_IS_DYNAMIC(p->memFlags))
4597 heapCb->dynamicHeapMemUsed -= (size + hdr);
4598 size = (curHBlk->size += (size + hdr));
4600 size = (curHBlk->size += size);
4601 #endif /*SSI_DEBUG_LEVEL1*/
4606 /* cm_mem_c_001.main_12 - addition for double-free check */
4607 #ifdef SSI_DEBUG_LEVEL1
4608 /* Check for double deallocation in heap */
4609 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4611 /* Release the lock */
4612 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4614 (Void) WTUnlock (&(heapCb->heapLock));
4616 (Void) SUnlock (&(heapCb->heapLock));
4619 /* This block is already freed in the heap */
4622 /* update the flags as it is a new node */
4623 if (CMM_IS_STATIC(p->memFlags))
4625 heapCb->staticHeapMemUsed -= (size + hdr);
4626 CMM_RESET_STATIC_FLAG(p->memFlags);
4628 else if (CMM_IS_DYNAMIC(p->memFlags))
4630 heapCb->dynamicHeapMemUsed -= (size + hdr);
4631 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4633 CMM_SET_FREE_FLAG(p->memFlags);
4634 p->requestedSize = 0;
4635 #endif /*SSI_DEBUG_LEVEL1*/
4636 /* insert the block */
4637 p->next = curHBlk->next;
4642 /* Try to merge with the next block in the chain */
4643 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4644 #ifdef SSI_DEBUG_LEVEL1
4645 if (((Data *)p + hdr + size) == (Data *)(p->next))
4647 if (((Data *)p + size) == (Data *)(p->next))
4648 #endif /*SSI_DEBUG_LEVEL1*/
4650 /* p->next can not be NULL */
4651 /* cm_mem_c_001.main_12 - addition for header consideration */
4652 #ifdef SSI_DEBUG_LEVEL1
4653 p->size += (p->next->size + hdr);
4655 p->size += p->next->size;
4656 #endif /*SSI_DEBUG_LEVEL1*/
4657 p->next = p->next->next;
4660 /* Release the lock */
4661 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4663 (Void) WTUnlock (&(heapCb->heapLock));
4665 (Void) SUnlock (&(heapCb->heapLock));
4667 /* cm_mem_c_001.main_15 : Additions */
4668 #ifdef SS_HISTOGRAM_SUPPORT
4669 /* If If Tapa task (entId)is registerd for histogram then insert
4670 Memrory Freed information into the hash list */
4673 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4674 fileName, entId) != ROK)
4676 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4680 #endif /* SS_HISTOGRAM_SUPPORT */
4684 else if (p < curHBlk)
4687 * Check if the block to be returned can be merged with the
4690 /* cm_mem_c_001.main_12 - addition for header consideration */
4691 #ifdef SSI_DEBUG_LEVEL1
4692 if (((Data *)p + hdr + size) == (Data *)curHBlk)
4694 if (((Data *)p + size) == (Data *)curHBlk)
4695 #endif /* SSI_DEBUG_LEVEL1 */
4697 /* Merge the block */
4698 /* cm_mem_c_001.main_12 - addition for header consideration */
4699 #ifdef SSI_DEBUG_LEVEL1
4700 p->size = size + (curHBlk->size + hdr);
4702 p->size = size + curHBlk->size;
4703 #endif /* SSI_DEBUG_LEVEL1 */
4704 p->next = curHBlk->next;
4708 /* insert the block */
4712 /* cm_mem_c_001.main_12 - addition for header updation */
4713 #ifdef SSI_DEBUG_LEVEL1
4714 /* update the flags in both cases as they are new start nodes*/
4715 if (CMM_IS_STATIC(p->memFlags))
4717 heapCb->staticHeapMemUsed -= (size + hdr);
4718 CMM_RESET_STATIC_FLAG(p->memFlags);
4720 else if (CMM_IS_DYNAMIC(p->memFlags))
4722 heapCb->dynamicHeapMemUsed -= (size + hdr);
4723 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4725 CMM_SET_FREE_FLAG(p->memFlags);
4726 p->requestedSize = 0;
4727 #endif /* SSI_DEBUG_LEVEL1 */
4731 /* Release the lock */
4732 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4734 (Void) WTUnlock (&(heapCb->heapLock));
4736 (Void) SUnlock (&(heapCb->heapLock));
4738 /* cm_mem_c_001.main_15 : Additions */
4739 #ifdef SS_HISTOGRAM_SUPPORT
4740 /* If If Tapa task (entId)is registerd for histogram then insert
4741 Memrory Freed information into the hash list */
4744 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4745 fileName, entId) != ROK)
4747 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4751 #endif /* SS_HISTOGRAM_SUPPORT */
4757 if (heapCb->next == NULLP)
4759 /* Heap block is empty. Insert the block in the head. */
4764 /* cm_mem_c_001.main_12 - addition for header updation */
4765 #ifdef SSI_DEBUG_LEVEL1
4766 if (CMM_IS_STATIC(p->memFlags))
4768 heapCb->staticHeapMemUsed -= (size + hdr);
4769 CMM_RESET_STATIC_FLAG(p->memFlags);
4771 else if (CMM_IS_DYNAMIC(p->memFlags))
4773 heapCb->dynamicHeapMemUsed -= (size + hdr);
4774 CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4776 CMM_SET_FREE_FLAG(p->memFlags);
4777 p->requestedSize = 0;
4778 #endif /* SSI_DEBUG_LEVEL1 */
4780 /* Release the heap lock */
4781 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4783 (Void) WTUnlock (&(heapCb->heapLock));
4785 (Void) SUnlock (&(heapCb->heapLock));
4787 /* cm_mem_c_001.main_15 : Additions */
4788 #ifdef SS_HISTOGRAM_SUPPORT
4789 /* If If Tapa task (entId)is registerd for histogram then insert
4790 Memrory Freed information into the hash list */
4793 if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line,
4794 fileName, entId) != ROK)
4796 sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4800 #endif /* SS_HISTOGRAM_SUPPORT */
4804 /* Release the lock */
4805 /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4807 (Void) WTUnlock (&(heapCb->heapLock));
4809 (Void) SUnlock (&(heapCb->heapLock));
4813 } /* end of cmHeapFree */
4814 /* cm_mem_c_001.main_15 : Additions */
4816 #ifdef SS_MEM_LEAK_STS
4819 * Fun: cmInitMemLeakMdl
4821 * Desc: Initializes the memory leak detection module
4826 * Notes: This function initializes the memory leak detection module.
4833 PUBLIC Void cmInitMemLeakMdl
4838 PUBLIC Void cmInitMemLeakMdl (Void)
4844 TRC3(cmInitMemLeakMdl);
4846 memLkCb.memLkMdlInit = FALSE;
4847 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4849 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4851 SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4852 cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4853 500, 0, FALSE, CM_HASH_KEYTYPE_U32MOD, 0, 0);
4854 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4857 if(memLkCb.fileLkLog == NULLP)
4859 memLkCb.fileLkLog = (FILE *) stdout;
4861 memLkCb.memLkMdlInit = TRUE;
4864 } /* cmInitMemLeakMdl */
4865 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4868 * Fun: cmDeinitMemLeakMdl
4870 * Desc: De-initializes the memory leak detection module
4875 * Notes: This function de-initializes the memory leak detection module.
4882 PUBLIC Void cmDeinitMemLeakMdl
4887 PUBLIC Void cmDeinitMemLeakMdl (Void)
4893 TRC3(cmDeinitMemLeakMdl);
4895 memLkCb.memLkMdlInit = FALSE;
4896 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4898 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4900 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4901 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4902 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4909 * Fun: cmMemOpenMemLkFile
4911 * Desc: Initializes the memory leak detection module
4916 * Notes: This function initializes the memory leak detection module.
4923 PUBLIC Void cmMemOpenMemLkFile
4928 PUBLIC Void cmMemOpenMemLkFile (arg)
4932 TRC3(cmMemOpenMemLkFile);
4933 memLkCb.fileLkLog = NULLP;
4934 memLkCb.fileLkLog = fopen(arg, "w");
4942 * Desc: Initializes the memory leak detection module
4947 * Notes: This function initializes the memory leak detection module.
4954 PUBLIC Void SLogLkInfo
4959 PUBLIC Void SLogLkInfo (Void)
4963 MemAllocInfo *oldMemInfo;
4964 MemAllocInfo *newMemInfo;
4971 if( memLkCb.memLkMdlInit == FALSE)
4975 sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4976 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4978 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4980 for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4982 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4988 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4989 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4990 (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4992 sprintf(prntBuf, "[LBIS]\n");
4993 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4994 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4996 sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4998 sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
5000 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5001 sprintf(prntBuf, "Module Name: %s\n",
5002 memUsrMdlStr[newMemInfo->moduleId].mdlStr);
5003 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5004 sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
5005 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5006 sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
5007 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5008 sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
5009 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5010 sprintf(prntBuf,"Memory Allocation Path:\n");
5011 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5012 funcNm = (S8 **)newMemInfo->backTrace;
5013 for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
5015 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
5016 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5018 sprintf(prntBuf, "[LBIE]\n\n");
5019 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5020 fflush(memLkCb.fileLkLog);
5021 oldMemInfo = newMemInfo;
5024 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5027 sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
5028 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
5036 * Desc: Initializes the memory leak detection module
5041 * Notes: This function initializes the memory leak detection module.
5048 PUBLIC Void SFlushLkInfo
5053 PUBLIC Void SFlushLkInfo (Void)
5056 MemAllocInfo *newMemInfo;
5060 #ifdef SS_MEM_LEAK_SOL
5062 #endif /* SS_MEM_LEAK_SOL */
5065 if( memLkCb.memLkMdlInit == FALSE)
5070 for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
5072 for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
5074 if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
5079 SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5080 while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
5081 (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
5083 funcNm = (S8 **)newMemInfo->backTrace;
5084 #ifdef SS_MEM_LEAK_SOL
5085 for(i = 0; i < newMemInfo->bTrcSz; i++)
5087 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5088 #ifdef SS_4GMX_LCORE
5089 MxHeapFree(SsiHeap, funcNm[i]);
5093 /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(U32) * CM_MAX_STACK_TRACE); */
5095 #endif /* SS_MEM_LEAK_SOl */
5096 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5097 #ifdef SS_4GMX_LCORE
5098 MxHeapFree(SsiHeap, funcNm);
5099 MxHeapFree(SsiHeap, newMemInfo);
5105 SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
5113 * Fun: cmStorAllocBlk
5115 * Desc: Initializes the memory leak detection module
5120 * Notes: This function initializes the memory leak detection module.
5127 PUBLIC Void cmStorAllocBlk
5135 PUBLIC Void cmStorAllocBlk (addr, reqSz, allocSz, bktIdx)
5142 #ifndef SS_MEM_LEAK_SOL
5143 Ptr trace[CM_MAX_STACK_TRACE];
5144 #endif /* SS_MEM_LEAK_SOL */
5147 MemAllocInfo *allocInfo;
5150 TRC3(cmStorAllocBlk);
5151 if( memLkCb.memLkMdlInit == FALSE)
5156 #ifdef SS_MEM_LEAK_SOL
5157 /* I need to do this for solaris, because it does not implement
5158 * backtrace. Here backtrace is my function. See below for the
5159 * implementation. */
5160 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5161 #ifdef SS_4GMX_LCORE
5162 funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(U32) * CM_MAX_STACK_TRACE));
5163 cmMemset((U8*)funcNm, 0, (sizeof(U32) * CM_MAX_STACK_TRACE));
5165 funcNm = (S8 **)calloc(1, (sizeof(U32) * CM_MAX_STACK_TRACE));
5167 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(U32) * CM_MAX_STACK_TRACE); */
5168 traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
5169 #else /* SS_MEM_LEAK_SOL */
5170 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5171 funcNm = backtrace_symbols(trace, traceSize);
5172 #endif /* SS_MEM_LEAK_SOL */
5174 moduleId = cmMemGetModuleId(funcNm, traceSize);
5176 (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5177 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5178 #ifdef SS_4GMX_LCORE
5179 allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo));
5180 cmMemset((U8*)allocInfo, 0, sizeof(MemAllocInfo));
5182 allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo));
5184 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo, sizeof(MemAllocInfo)); */
5185 allocInfo->memAddr = addr;
5186 allocInfo->reqSz = reqSz;
5187 allocInfo->allocSz = allocSz;
5188 allocInfo->bktIdx = bktIdx;
5189 allocInfo->backTrace = (PTR) funcNm;
5190 allocInfo->moduleId = moduleId;
5191 allocInfo->bTrcSz = traceSize;
5193 cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp,
5194 (PTR)allocInfo, (U8 *)&(allocInfo->memAddr),
5195 sizeof(allocInfo->memAddr));
5196 memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
5198 (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
5200 } /* cmStorAllocBlk */
5204 * Fun: cmMemGetModuleId
5206 * Desc: Initializes the memory leak detection module
5211 * Notes: This function initializes the memory leak detection module.
5218 PUBLIC U8 cmMemGetModuleId
5224 PUBLIC U8 cmMemGetModuleId (funNm, traceSize)
5236 Txt *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
5238 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5239 TRC3(cmMemGetModuleId)
5240 for(idx = 0; idx < traceSize; idx++)
5244 while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
5246 memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx],
5251 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5253 len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5254 memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize,
5255 memUsrMdlStr[mdlFunStrIdx].fPStr,
5259 return (mdlFunStrIdx);
5264 while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
5266 retVal = strcmp((const S8 *)"DEFAULT",
5267 (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
5270 return (mdlFunStrIdx);
5277 } /* cmMemGetModuleId */
5281 * Fun: cmMemGetStrMtchIdx
5283 * Desc: Initializes the memory leak detection module
5288 * Notes: This function initializes the memory leak detection module.
5295 PUBLIC S16 cmMemGetStrMtchIdx
5303 PUBLIC S16 cmMemGetStrMtchIdx(strtIdx, endIdx, str, strLst)
5317 TRC3(cmMemGetStrMtchIdx);
5319 len = strlen((const S8 *)str);
5321 strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
5322 cmpStr[len + 1] = '\0';
5325 for(;strtIdx < endIdx && !found; strtIdx++)
5328 tempLen = strlen((const S8 *)strLst[strtIdx]);
5332 while(*(strLst[strtIdx] + idx + len) != '\0')
5334 retVal = strncmp((const S8 *)cmpStr,
5335 ((const S8 *)strLst[strtIdx] + idx), len);
5351 } /* cmMemGetStrMtchIdx */
5355 * Fun: cmRlsAllocBlk
5357 * Desc: Initializes the memory leak detection module
5362 * Notes: This function initializes the memory leak detection module.
5369 PUBLIC Void cmRlsAllocBlk
5374 PUBLIC Void cmRlsAllocBlk(addr)
5378 Ptr trace[CM_MAX_STACK_TRACE];
5384 MemAllocInfo *memAllocInfo;
5386 TRC3(cmRlsAllocBlk);
5387 if( memLkCb.memLkMdlInit == FALSE)
5393 for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5395 SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5396 retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5397 (U8 *)&addr, sizeof(U32), 0,
5398 (PTR *)&memAllocInfo);
5401 cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5403 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5404 funcNm = (S8 **) memAllocInfo->backTrace;
5405 #ifdef SS_MEM_LEAK_SOL
5406 for(i = 0; i < memAllocInfo->bTrcSz; i++)
5408 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5409 #ifdef SS_4GMX_LCORE
5410 MxHeapFree(SsiHeap, funcNm[i]);
5415 #endif /* SS_MEM_LEAK_SOL */
5416 #ifdef SS_MEM_LEAK_FREE_TRACE
5420 sprintf( prntBuf, "\n==============================\n");
5422 /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5424 sprintf( prntBuf, "Address: [%x]\n", addr);
5426 sprintf( prntBuf, "Address: [%lx]\n", addr);
5429 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5430 funcNm = backtrace_symbols(trace, traceSize);
5431 sprintf( prntBuf, "[bt] Execution path:\n");
5433 for (i=0; i < traceSize; ++i)
5435 sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5438 sprintf( prntBuf, "\n==============================\n");
5441 #endif /* SS_MEM_LEAK_FREE_TRACE */
5442 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5443 #ifdef SS_4GMX_LCORE
5444 MxHeapFree(SsiHeap, funcNm);
5445 MxHeapFree(SsiHeap, memAllocInfo);
5452 SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5455 #ifndef SS_MEM_LEAK_SOL
5456 if(idx == CM_MEM_USR_MDL)
5459 sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5461 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/
5463 sprintf( prntBuf, "Address: [%u]\n", addr);
5465 sprintf( prntBuf, "Address: [%lu]\n", addr);
5468 traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5469 funcNm = backtrace_symbols(trace, traceSize);
5470 sprintf( prntBuf,"[bt] Execution path:\n");
5472 for (i=0; i < traceSize; ++i)
5474 sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5477 printf("\n==============================\n");
5478 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5479 #ifdef SS_4GMX_LCORE
5480 MxHeapFree(SsiHeap, funcNm);
5485 #endif /* SS_MEM_LEAK_SOL */
5487 /*cm_mem_c_001.main_25 : */
5489 } /* cmRlsAllocBlk */
5492 #ifdef SS_MEM_LEAK_SOL
5495 * Fun: cmAddrToSymStr
5497 * Desc: Initializes the memory leak detection module
5502 * Notes: This function initializes the memory leak detection module.
5509 PUBLIC S32 cmAddrToSymStr
5516 PUBLIC S32 cmAddrToSymStr(pc, buffer, size)
5526 TRC3(cmAddrToSymStr);
5528 if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5530 return (snprintf(buffer, size, "[0x%p]", pc));
5533 if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5534 ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5536 return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5539 (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5543 return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5545 (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5548 } /* cmAddrToSymStr */
5552 * Fun: cmLeakCallBack
5554 * Desc: Initializes the memory leak detection module
5559 * Notes: This function initializes the memory leak detection module.
5566 PUBLIC S32 cmLeakCallBack
5573 PUBLIC S32 cmLeakCallBack(pc, sigNo, arg)
5580 TRC3(cmLeakCallBack);
5582 Backtrace_t *bt = (Backtrace_t *)arg;
5583 if (bt->bt_actcount >= bt->bt_maxcount)
5585 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/
5586 #ifdef SS_4GMX_LCORE
5587 buffer = (S8 *)MxHeapAlloc(SsiHeap, 510);
5588 cmMemset((U8*)buffer, 0, 510);
5590 buffer = (S8 *)calloc(1, 510);
5592 /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
5593 (void) cmAddrToSymStr((void *)pc, buffer, 505);
5594 bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5597 } /* cmLeakCallBack */
5603 * Desc: Initializes the memory leak detection module
5608 * Notes: This function initializes the memory leak detection module.
5615 PUBLIC S32 backtrace
5621 PUBLIC S32 backtrace(buffer, count)
5631 bt.bt_buffer = buffer;
5632 bt.bt_maxcount = count;
5635 if (getcontext(&u) < 0)
5637 (Void) walkcontext(&u, cmLeakCallBack, &bt);
5638 return (bt.bt_actcount);
5642 #endif /* SS_MEM_LEAK_SOL */
5644 #endif /* SS_MEM_LEAK_STS */
5645 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5646 * These include sanity check functions for bucket and heap,
5647 * for printing several memory related statistics
5649 #ifdef SSI_DEBUG_LEVEL1
5652 * Fun: cmMmBktSanityChk
5654 * Desc: Performs the sanity check for the memory blocks in a memory bucket.
5655 * This API gets called when trampling is detected in a memory block.
5657 * Ret: RTRAMPLINGNOK - Trampling, serious error
5658 * RTRAMPLINGOK - Trampling, but OK to proceed
5660 * Notes: This function performs the memory block sanity in a bucket. This
5661 * function is called by cmAlloc and cmFree as part of error handling mechanism.
5662 * Performs sanity check for the whole bucket by traversing each
5663 * of the memory blocks using the pointer bktStartPtr.
5664 * Keeps track of number of tramplings happened. If the count
5665 * exceeds the threshold decided, then invalidates this bucket.
5671 PRIVATE S16 cmMmBktSanityChk
5676 PRIVATE S16 cmMmBktSanityChk(bkt)
5683 TRC2(cmMmBktSanityChk);
5685 bkt->trampleCount = 0;
5687 /* scan the entire memory list of the bucket */
5688 for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5689 blkCnt < (bkt->numBlks); blkCnt++)
5691 if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5693 bkt->trampleCount++;
5694 if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5696 /* Take action to invalidate the entire bucket */
5697 return (RTRAMPLINGNOK);
5700 /* reach next memory block in this bucket manually */
5701 ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5705 /* display an error message here */
5706 sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5707 SDisplay(0, dbgPrntBuf);
5710 return (RTRAMPLINGOK);
5715 * Fun: cmMmHeapSanityChk
5717 * Desc: Performs the sanity check for the memory blocks in the memory heap.
5718 * This API gets called when trampling is detected in heap(Alloc/Free).
5720 * Ret: RTRAMPLINGNOK - Trampling, serious error
5721 * RTRAMPLINGOK - Trampling, but OK to proceed
5723 * Notes: This function performs the memory block sanity in the heap. This
5724 * function is called by cmHeapAlloc and cmHeapFree as part of error
5725 * handling mechanism. Keeps track of number of tramplings happened.
5726 * If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5727 * count is less than threshold, then return RTRAMPLINGOK.
5733 PRIVATE S16 cmMmHeapSanityChk
5738 PRIVATE S16 cmMmHeapSanityChk(heapCb)
5743 TRC2(cmMmHeapSanityChk);
5745 /* increment the trample count */
5746 heapCb->trampleCount++;
5748 if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5750 return (RTRAMPLINGNOK);
5753 return (RTRAMPLINGOK);
5758 * Fun: cmMmRegIsBlkSane
5760 * Desc: Performs the sanity check for the memory block by checking its header.
5762 * Ret: ROK - If no trampling is detected in the block
5763 * RFAILED - If trampling is detected in the block
5765 * Notes: This function performs the memory block sanity in a block.
5771 PUBLIC S16 cmMmRegIsBlkSane
5776 PUBLIC S16 cmMmRegIsBlkSane(blkPtr)
5782 TRC2(cmMmRegIsBlkSane);
5784 for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5786 if (blkPtr->trSignature[sigCnt] != 0xAB)
5799 * Desc: Computes the hash list index (bin number) for a specified
5800 * key of type (x % 101).
5802 * return (idx % hash_table_size);
5804 * Ret: ROK - successful, *idx contains computed index
5812 PRIVATE S16 cmMmHashFunc
5814 CmMmHashListCp *hashListCp,
5819 PRIVATE S16 cmMmHashFunc (hashListCp, key, idx)
5820 CmMmHashListCp *hashListCp; /* hash list control point */
5821 U32 key; /* key string */
5822 U16 *idx; /* idx to return */
5827 *idx = (U16)(key % hashListCp->numOfbins);
5831 } /* end of cmMmHashFunc () */
5835 * Fun: cmMmHashListInit
5837 * Desc: Initializes a hash list. Parameters are:
5839 * hashListCp control point for hash list
5840 * nmbBins number of bins in the hash list. Storage will
5841 * be allocated for them from the indicated memory
5844 * pool for allocating storage for bins.
5846 * Ret: ROK - initialization successful
5847 * RFAILED - initialization failed, lack of memory
5855 PRIVATE S16 cmMmHashListInit
5857 CmMmHashListCp *hashListCp, /* hash list to initialize */
5858 U16 nmbBins, /* number of hash list bins */
5859 Region region, /* memory region to allocate bins */
5860 Pool pool /* memory pool to allocate bins */
5863 PRIVATE S16 cmMmHashListInit(hashListCp, nmbBins, region, pool)
5864 CmMmHashListCp *hashListCp; /* hash list to initialize */
5865 U16 nmbBins; /* number of hash list bins */
5866 Region region; /* memory region to allocate bins */
5867 Pool pool; /* memory pool to allocate bins */
5871 CmMmHashListEnt *hl;
5873 TRC2(cmMmHashListInit);
5875 /* initialize control point fields */
5876 hashListCp->hashList = NULLP;
5877 hashListCp->numOfbins = 0;
5878 hashListCp->numOfEntries = 0;
5880 /* allocate memory for bins */
5883 if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
5884 (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5887 /* initialize bin pointers */
5888 hl = hashListCp->hashList;
5889 for(i = 0; i < nmbBins; i++)
5891 hl[i].size = hl[i].numAttempts = 0;
5894 /* initialize bin size */
5895 hashListCp->numOfbins = nmbBins;
5903 * Fun: cmMmHashListDeinit
5905 * Desc: Deinitializes a hash list. Deallocates memory for bins
5906 * and resets header fields. Parameters are:
5908 * hashListCp control point for hash list
5910 * pool for allocating storage for bins.
5912 * Ret: ROK - successful
5913 * RFAILED - failure, invalid parameters
5921 PRIVATE S16 cmMmHashListDeinit
5923 CmMmHashListCp *hashListCp, /* hash list to deinitialize */
5924 Region region, /* memory region to allocate bins */
5925 Pool pool /* memory pool to allocate bins */
5928 PRIVATE S16 cmMmHashListDeinit(hashListCp, region, pool)
5929 CmMmHashListCp *hashListCp; /* hash list to deinitialize */
5930 Region region; /* memory region to allocate bins */
5931 Pool pool; /* memory pool to allocate bins */
5934 TRC2(cmMmHashListDeinit);
5936 /* deallocate memory for bins */
5937 if (hashListCp->numOfbins)
5938 (Void) SPutSBuf(region, pool,
5939 (Data *) hashListCp->hashList,
5940 (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5942 /* deinitialize control point fields */
5943 hashListCp->hashList = NULLP;
5944 hashListCp->numOfbins = 0;
5945 hashListCp->numOfEntries = 0;
5948 } /* end of cmMmHashListDeinit */
5952 * Fun: cmMmHashListInsert
5954 * Desc: Inserts a new entry in the hash list. Parameters are:
5956 * hashListCp control point for hash list
5957 * key pointer to key string in the new entry
5959 * Ret: ROK - insertion successful
5960 * RFAILED - insertion failed (incorrect parameter values)
5968 PRIVATE S16 cmMmHashListInsert
5970 CmMmHashListCp *hashListCp, /* hash list to add to */
5971 U32 key /* pointer to key */
5974 PRIVATE S16 cmMmHashListInsert(hashListCp, key)
5975 CmMmHashListCp *hashListCp; /* hash list to add to */
5976 U32 key; /* pointer to key */
5979 CmMmHashListEnt *hashListEnt; /* pointer to hash list entry header */
5980 U16 idx; /* index for insertion into hash list */
5983 TRC2(cmMmHashListInsert);
5985 /* check if hashListCp is initialised yet */
5986 if ( hashListCp->numOfbins == 0)
5989 /* compute index for insertion */
5990 if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5993 hashListEnt = hashListCp->hashList;
5995 if (hashListEnt[idx].numAttempts == 0)
5997 /* new entry, insert here */
5998 hashListEnt[idx].size = key;
5999 hashListEnt[idx].numAttempts++;
6000 /* increment count of entries in hash list */
6001 hashListCp->numOfEntries++;
6005 /* this hash is occupied, re-hash it using linear probing */
6006 for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
6008 if (hashListEnt[i].size == key)
6010 hashListEnt[i].numAttempts++;
6014 if (hashListEnt[i].numAttempts == 0)
6016 hashListEnt[i].size = key;
6017 hashListEnt[i].numAttempts++;
6018 /* increment count of entries in hash list */
6019 hashListCp->numOfEntries++;
6024 if (i == CMM_STAT_HASH_TBL_LEN)
6026 /* there is no free slot for this key */
6032 } /* end of cmMmHashListInsert */
6034 #endif /* SSI_DEBUG_LEVEL1 */
6035 /* cm_mem_c_001.main_15 : Additions */
6036 #ifdef SS_HISTOGRAM_SUPPORT
6039 * Fun: cmHstGrmHashListInit
6041 * Desc: Initializes a hash list. Parameters are:
6043 * hashListCp control point for hash list
6044 * Ret: ROK - initialization successful
6045 * RFAILED - initialization failed, lack of memory
6053 PRIVATE S16 cmHstGrmHashListInit
6055 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6058 PRIVATE S16 cmHstGrmHashListInit(hashListCp)
6059 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6062 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6063 TRC2(cmHstGrmHashListInit)
6065 /* display an error message here */
6066 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6068 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6070 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6072 SDisplay(0, dbgPrntBuf);
6074 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6080 * Fun: cmHstGrmHashListDeInit
6082 * Desc: De-initializes a hash list. Parameters are:
6084 * hashListCp control point for hash list
6085 * Ret: ROK - initialization successful
6086 * RFAILED - initialization failed, lack of memory
6094 PRIVATE S16 cmHstGrmHashListDeInit
6096 CmHstGrmHashListCp *hashListCp /* hash list to initialize */
6099 PRIVATE S16 cmHstGrmHashListDeInit(hashListCp)
6100 CmHstGrmHashListCp *hashListCp; /* hash list to initialize */
6103 /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
6104 TRC2(cmHstGrmHashListDeInit)
6106 /* display an error message here */
6107 /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/
6109 sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6111 sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
6113 SDisplay(0, dbgPrntBuf);
6115 memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
6121 * Fun: cmHstGrmFreeInsert
6123 * Desc: Inserts a Freed information in into the hash list. Parameters are:
6125 * bkt : pointer to bucket for which memory is freed.
6126 * line : Line where memory is freed.
6127 * file : file where memory is freed.
6128 * entId : Tapa task which releases the memory.
6130 * Ret: ROK - insertion successful
6131 * RFAILED - insertion failed (incorrect parameter values)
6139 PRIVATE S16 cmHstGrmFreeInsert
6141 CmHstGrmHashListCp* hashListCp, /* hash list cp */
6142 U32 blkSz, /* size of the block freed */
6143 U32 line, /* Line number */
6144 U8 *fileName, /* file name */
6145 U8 entId /* Tapa task which free the memory */
6148 PRIVATE S16 cmHstGrmFreeInsert(hashListCp, blkSz, line, fileName, entId)
6149 CmHstGrmHashListCp* hashListCp; /* hash list cp */
6150 U32 blkSz; /* size of the block freed */
6151 U32 line; /* line number */
6152 U8 *fileName; /* file Name */
6153 U8 entId; /* Tapa task which frees the memory */
6156 U32 binIdx = 0; /* Bin index to insert the entry into the hash list */
6157 U32 key = 0; /* Key to fine the bin index */
6158 U32 ret = 0; /* Return value */
6159 CmMemEntries *entry = NULLP; /* Entry which contains the information */
6162 TRC2(cmHstGrmFreeInsert);
6164 /* check for the total number of entries in the hash list. *
6165 * If there is no place for new entry return failure */
6166 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6168 /* After comuting the hash bind and key, check the entity already *
6169 existing or not. if we found the entry then update the information */
6170 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6173 entry->freedBytes += blkSz;
6174 entry->bucketFreeReq++;
6178 /* If hash list is full then print the error tna continue */
6179 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6181 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");
6185 /* Take the address of next free entry in the hash bin */
6186 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6188 /* Increase the number of time frees called */
6189 entry->bucketFreeReq++;
6190 entry->freedBytes += blkSz;
6192 /* Fill the information into the entry structure */
6193 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6194 /* Increase the total numbet of entries in the bin */
6195 hashListCp->hashList[binIdx].numOfEntries++;
6197 /* Increase the total number of entries in the hash list */
6198 hashListCp->totalNumEntries++;
6201 } /* end of cmHstGrmFreeInsert */
6206 * Fun: ret = cmHstGrmAllocInsert
6208 * Desc: Inserts a memory allocated information in the hash list. Parameters are:
6210 * hashListCp control point for hash list
6211 * key pointer to key string in the new entry
6213 * Ret: ROK - insertion successful
6214 * RFAILED - insertion failed (incorrect parameter values)
6222 PRIVATE S16 cmHstGrmAllocInsert
6224 CmHstGrmHashListCp *hashListCp,
6232 PRIVATE S16 cmHstGrmAllocInsert(hashListCp, blkSz, reqSz, line, fileName, entId)
6233 CmHstGrmHashListCp *hashListCp;
6244 CmMemEntries *entry = NULLP;
6246 TRC2(cmHstGrmAllocInsert);
6248 /* check for the total number of entries in the hash list. *
6249 * If there is no place for new entry return failure */
6250 cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
6252 /* After comuting the hash bind and key, check the entity already *
6253 existing or not. if we found the entry then update the information */
6254 ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
6258 entry->allocBytes += blkSz;
6259 entry->bucketAllocReq++;
6260 entry->wastedBytes += (blkSz - *reqSz);
6264 if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
6266 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");
6270 /* Take the address of next free entry in the hash bin */
6271 entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
6273 /* Clauculae the wasted bytes */
6274 /* Here wasted byte is differnce between the byte user
6275 * has requested and the byte the ssi allocated */
6276 entry->wastedBytes += (blkSz - *reqSz);
6277 entry->bucketAllocReq++;
6278 entry->allocBytes += blkSz;
6280 /* Fill the information into the entry structure */
6281 cmHstGrmFillEntry(entry, key, line, fileName, entId);
6282 /* Increase the total numbet of entries in the bin */
6283 hashListCp->hashList[binIdx].numOfEntries++;
6285 /* Increase the total number of entries in the hash list */
6286 hashListCp->totalNumEntries++;
6289 } /* end of cmHstGrmAllocInsert */
6294 * Fun: cmHstGrmGetHashIdxAndKey
6296 * Desc: Finds an entry in the hash list. Parameters are:
6298 * hashListCp control point for hash list
6299 * key pointer to key string in the new entry
6301 * Ret: ROK - insertion successful
6302 * RFAILED - insertion failed (incorrect parameter values)
6310 PRIVATE S16 cmHstGrmGetHashIdxAndKey
6318 PRIVATE S16 cmHstGrmGetHashIdxAndKey(fileName, line, binIdx, key)
6327 TRC2(cmHstGrmGetHashIdxAndKey);
6329 /* Calculate the key using file name and line number */
6330 for(i = 0 ; fileName[i] != '\0'; i++)
6332 *key += fileName[i];
6335 *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
6337 } /* end of cmHstGrmFillEntry */
6341 * Fun: cmHstGrmFillEntry
6343 * Desc: Insert the entry into the hash list.
6345 * entry : Infornation which will be inserted into the hash list
6346 * key : Which will be used ti find the entry.
6347 * line : Line number
6348 * fileName : File name
6349 * entId : Tapa task Id
6351 * Ret: ROK - insertion successful
6352 * RFAILED - insertion failed (incorrect parameter values)
6360 PRIVATE S16 cmHstGrmFillEntry
6362 CmMemEntries *entry,
6369 PRIVATE S16 cmHstGrmFillEntry(entry, key, line, fileName, entId)
6370 CmMemEntries *entry;
6379 TRC2(cmHstGrmFillEntry);
6382 entry->entId = entId;
6383 for(idx = 0; fileName[idx] != '\0'; idx++)
6385 entry->fileName[idx] = fileName[idx];
6387 entry->fileName[idx] = '\0';
6389 } /* end of cmHstGrmFillEntry */
6393 * Fun: cmHstGrmFindEntry
6395 * Desc: Finds an entry in the hash list. Parameters are:
6397 * hashListCp control point for hash list
6398 * key pointer to key string in the new entry
6400 * Ret: ROK - insertion successful
6401 * RFAILED - insertion failed (incorrect parameter values)
6409 PRIVATE S16 cmHstGrmFindEntry
6411 CmHstGrmHashListCp *hashListCp,
6414 CmMemEntries **entry
6417 PRIVATE S16 cmHstGrmFindEntry(hashListCp, key, binIdx, entry)
6418 CmHstGrmHashListCp *hashListCp;
6421 CmMemEntries **entry;
6427 CmHstGrmHashListEnt *tmpBin = NULLP;
6429 TRC2(cmHstGrmFindEntry);
6432 for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
6434 /* find for the entry in the bin */
6435 tmpBin = &(hashListCp->hashList[*binIdx]);
6436 for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
6438 /* If key supplied is matched with the stored key then
6439 * return that entity */
6440 if(tmpBin->entries[numEnt].key == key)
6442 *entry = &(tmpBin->entries[numEnt]);
6444 }/* End of if (tmpBin->entries[numEnt].key) */
6445 }/* end of for (numEnt = 0) */
6447 /* Here we are checking for any room left in the bin. If the room *
6448 exists its mean that there is no entry with the Key. so return *
6450 If there is no room in the bin, then check the other bins to find *
6452 if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
6454 if(*binIdx == CMM_HIST_MAX_MEM_BIN)
6457 }/* End of if (binIdx) */
6461 }/* End of else (binIdx) */
6462 } /* End of if (numEnt) */
6465 printf ("Unable to find the entry in hash list\n");
6467 }/* End of else (numEnt) */
6468 }/* end of for (numBin = 0) */
6470 printf("Unable to find the entry in the hash list\n");
6472 } /* end of cmHstGrmFindEntry */
6474 #endif /* SS_HISTOGRAM_SUPPORT */
6475 #ifdef T2K_MEM_LEAK_DBG
6476 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
6477 U32 getT2kMemLeakIndex(U32 address)
6479 return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6482 static U32 t2kMemAllocTick;
6483 static U32 smallTick;
6485 void InsertToT2kMemLeakInfo(U32 address, U32 size, U32 lineNo, char* fileName)
6487 U32 idx = getT2kMemLeakIndex(address);
6489 if(((U32)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6491 printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6492 "line is %ld \n", address, size, fileName, lineNo);
6495 if(gMemLeakInfo[idx].address == 0)
6497 gMemLeakInfo[idx].address = address;
6498 gMemLeakInfo[idx].size = size;
6499 gMemLeakInfo[idx].lineNo = lineNo;
6500 gMemLeakInfo[idx].fileName = fileName;
6501 gMemLeakInfo[idx].age = t2kMemAllocTick;
6502 gMemLeakInfo[idx].prevRemLineNo = 0;
6503 gMemLeakInfo[idx].prevRemFileName = '\0';
6505 if(smallTick++ == 4096)
6508 gMemLeakInfo[idx].age = (++t2kMemAllocTick);
6513 printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
6514 "line is %ld \n",address, idx, fileName, lineNo);
6515 printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
6516 "Age:%ld, differnce in Age:%ld",
6517 gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
6518 gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
6519 gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
6524 void RemoveFromT2kMemLeakInfo(U32 address, char *file, U32 line)
6526 U32 idx = getT2kMemLeakIndex(address);
6528 if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
6530 printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
6536 if(gMemLeakInfo[idx].address == address)
6538 gMemLeakInfo[idx].address = 0;
6539 gMemLeakInfo[idx].age = 0;
6540 gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6541 gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName;
6543 gMemLeakInfo[idx].lastDelLineNum = line;
6544 gMemLeakInfo[idx].lastDelFileName = file;
6545 /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6549 printf("Something is wrong, trying to remove %lx idx = %ld from"
6550 "File=%s, line=%ld address present is %lx\n",address, idx, file,line,
6551 gMemLeakInfo[idx].address);
6554 printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6555 gMemLeakInfo[idx].lastDelLineNum);
6557 if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6559 printf("Previous File:%s, Previous Line:%ld\n",
6560 gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6565 PUBLIC void DumpT2kMemLeakInfoToFile()
6569 FILE *fp = fopen("memLeakInfo.txt","wb");
6573 printf("Could not open file for dumping mem leak info\n");
6577 for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6579 if(gMemLeakInfo[i].address != 0)
6581 char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6582 if(onlyFileName == NULL)
6584 onlyFileName = gMemLeakInfo[i].fileName;
6587 fprintf(fp, "%ld s=%ld a=%ld l=%ld f=%s\n",gMemLeakInfo[i].address,
6588 gMemLeakInfo[i].size,
6589 gMemLeakInfo[i].age,
6590 gMemLeakInfo[i].lineNo,
6595 fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6601 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6603 /* For Updating SOC Specific Memory Information */
6605 PUBLIC S16 UpdateSocMemInfo
6611 PUBLIC S16 UpdateSocMemInfo(areaIndex,mInfo)
6613 CmLteMemInfo *mInfo;
6619 void *iccHdl = NULLP;
6623 U32 poolTotAvail[4];
6625 idxReg = mInfo->numRegions;
6626 mInfo->numRegions = mInfo->numRegions + 1;
6627 /* Calling Soc specific API to get shared memory status */
6628 numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6629 iccHdl = ssGetIccHdl(areaIndex);
6631 /* Populating global memory information */
6632 mInfo->regInfo[idxReg].numPools = numPool;
6633 mInfo->regInfo[idxReg].regionId = areaIndex;
6634 mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6636 /* Calling INTEL API's to Get Free MEM BLOCKS */
6637 poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6638 poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6639 poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6640 poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6642 poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6643 poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6644 poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6645 poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6647 poolSize[0] = ICC_POOL_ZERO_SIZE;
6648 poolSize[1] = ICC_POOL_ONE_SIZE;
6649 poolSize[2] = ICC_POOL_TWO_SIZE;
6650 poolSize[3] = ICC_POOL_THREE_SIZE;
6652 poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6653 poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6654 poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6655 poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6657 for(idxPool=0; idxPool<numPool;idxPool++)
6659 mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6660 mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable =
6661 poolTotAvail[idxPool];
6662 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6663 if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed >
6664 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6666 mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed =
6667 mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6676 * Fun: isL2MemUsageBelowLowerThreshold
6678 * Desc: Checks for the Lower threshold of ICC memory.
6680 * region region for obtaining the ICC handle
6682 * Ret: TRUE - Threshold has reached
6683 * FALSE - Threshold has not reached
6691 PUBLIC U32 isL2MemUsageBelowLowerThreshold(
6695 PUBLIC U32 isL2MemUsageBelowLowerThreshold(region)
6699 void * iccHdl = ssGetIccHdl(region);
6701 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6702 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6704 /* We are below the threshold if free count in BOTH of the pools
6705 * is above the ICC_MEM_LOWER_THRESHOLD % */
6706 if(((poolZeroFreeCnt * 100) >
6707 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6708 ((poolOneFreeCnt * 100) >
6709 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6720 * Fun: isMemUsageBelowLowerThreshold
6722 * Desc: Checks for the Lower threshold of ICC memory.
6724 * region region for obtaining the ICC handle
6726 * Ret: TRUE - Threshold has reached
6727 * FALSE - Threshold has not reached
6735 PUBLIC U32 isMemUsageBelowLowerThreshold(
6739 PUBLIC U32 isMemUsageBelowLowerThreshold(region)
6743 void * iccHdl = ssGetIccHdl(region);
6745 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6746 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6747 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6748 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6750 /* We are below the threshold if free count in BOTH of the pools
6751 * is above the ICC_MEM_LOWER_THRESHOLD % */
6752 if(((poolZeroFreeCnt * 100) >
6753 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6754 ((poolOneFreeCnt * 100) >
6755 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6756 ((poolTwoFreeCnt * 100) >
6757 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6758 ((poolThreeFreeCnt * 100) >
6759 (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6769 * Fun: isMemUsageAboveUpperThreshold
6771 * Desc: Checks for the Upper threshold of ICC memory.
6773 * region region for obtaining the ICC handle
6775 * Ret: TRUE - Threshold has reached
6776 * FALSE - Threshold has not reached
6784 PRIVATE U32 isMemUsageAboveUpperThreshold(
6788 PRIVATE U32 isMemUsageAboveUpperThreshold(region)
6792 void * iccHdl = ssGetIccHdl(region);
6794 U32 poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6795 U32 poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6796 U32 poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6797 U32 poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6799 /* We are above the threshold if free count in either of the pools
6800 * is below the ICC_MEM_UPPER_THRESHOLD % */
6801 if(((poolZeroFreeCnt * 100) <
6802 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6803 ((poolOneFreeCnt * 100) <
6804 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6805 ((poolTwoFreeCnt * 100) <
6806 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6807 ((poolThreeFreeCnt * 100) <
6808 (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6816 /* ccpu00142274- Function to check if we have reached the
6817 * Threshold for dropping UL packets at the RLC. This function
6818 * measures the free count of the ICC memory and based on the
6819 * volume of packets it sets an alarm to drop packets.
6820 * In DL, the PDCP packets are dropped at Admission Control, but
6821 * at UL we need to check if its an AM(Data only and
6822 * not Status PDU) or UM packet and free the PDU
6823 * Note: With the current design, we have PDCP DL and RLC UL
6824 * running in the same thread and the below function will be
6825 * accessed in tandem. But if PDCP DL and RLC UL are made to run
6826 * in different threads then there might be a race condition.
6827 * Please revisit this function in such a case.
6831 * Fun: isMemThreshReached
6833 * Desc: Checks whether the system has reached the
6834 * designated threshold of ICC memory.
6836 * region region for obtaining the ICC handle
6838 * Ret: ROK - Threshold has not reached
6839 * RFAILED - Threshold has reached
6847 PUBLIC U32 isMemThreshReached(
6851 PUBLIC U32 isMemThreshReached(reg)
6855 TRC3(isMemThreshReached)
6858 gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6863 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6865 gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6866 memoryCheckCounter = 0;
6872 #endif /* SS_LOCKLESS_MEMORY */
6873 /**********************************************************************
6875 **********************************************************************/