Memory handling fixes
[o-du/l2.git] / src / cm / cm_mem_wl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 \f
20 /********************************************************************20**
21  
22      Name:     Common Memory Manager 
23  
24      Type:     C source file
25  
26      Desc:     C source code for the Commom Memory Manager module. 
27  
28      File:     cm_mem_wl.c
29  
30 *********************************************************************21*/
31
32 \f
33 /************************************************************************
34
35 The following functions are provided in this file.
36  
37     cmMmRegInit     Memory Region Initialization.
38     cmMmRegDeInit   Memory Region Deinitialization.
39
40 ************************************************************************/
41
42 #ifndef SS_RBUF
43 \f
44 /* header include files (.h) */
45 #include "envopt.h"        /* environment options */
46 #include "envdep.h"        /* environment dependent */
47 #include "envind.h"        /* environment independent */
48  
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 */ 
52 #include <stdlib.h>
53 #ifdef SS_MEM_LEAK_STS
54 #include <stdio.h>
55 #include <string.h>
56 #ifdef SS_MEM_LEAK_SOL
57 #include <ucontext.h>
58 #include <dlfcn.h>
59 #include <sys/machelf.h>
60 #else /* SS_MEM_LEAK_SOL */
61 #include <execinfo.h>
62 #endif /* SS_MEM_LEAK_SOL */
63 #include <sys/types.h>
64 #endif /* SS_MEM_LEAK_STS */
65 #include "cm_hash.h" 
66
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 */
71 #endif 
72 #ifdef SS_MULTICORE_SUPPORT
73 #include "ss_dep.h"        /* implementation-specific */
74 #include "ss_queue.h"      /* queues */
75 #include "ss_task.h"       /* tasking */
76 #endif
77 #include "cm_llist.h"
78
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 */
86 #endif
87 #include "cm_hash.x"       /* common hash functions */
88 #include "cm_llist.x"
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 */
92
93
94 #ifdef USE_PURE
95 #include <stdlib.h>
96 #endif /* USE_PURE */
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 */
101 #endif
102
103 #ifdef USE_PURE
104 #include <stdlib.h>
105 #endif /* USE_PURE */
106
107 #include <execinfo.h>
108 #include <stdio.h>
109 #include <stdlib.h>
110 #include <sys/time.h>
111
112 #ifdef SS_USE_ICC_MEMORY
113 #include "icc_lib.h"
114 #endif /* SS_USE_ICC_MEMORY */
115
116 #ifdef L2_L3_SPLIT     
117 #include "mt_plat_t33.h"
118 S32 clusterMode;
119 #endif
120
121 #include "cm_lte.x"
122 #include "du_log.h"
123 \f
124 /* local defines */
125 /*ccpu00142274 - UL mem based flow control changes */
126 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
127 /* selva */
128 uint32_t gMemoryAlarm;
129 static uint32_t memoryCheckCounter;
130
131 #define NUM_CALLS_TO_CHECK_MEM_AGAIN      80 /* Number of calls after which need to check mem */
132 #ifndef L2_L3_SPLIT
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 */
136 #else
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 */
139 #endif
140 #else
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 */
143 #endif
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
149 #else
150 #define ICC_POOL_THREE_SIZE  8064
151 #endif
152 #ifndef L2_L3_SPLIT
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 
158 #else
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 
163 #endif
164 #else
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*/
167 #ifndef LTE_ADV
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
172 #else
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
177 #endif
178 #endif
179 #endif
180
181 /* local typedefs */
182  
183 /* local externs */
184  
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*/
189 #ifdef __cplusplus
190  extern "C" {
191 #endif
192
193 CmHashListCp    memDoubleFree;           /* Added to find the double free */
194 SLockId         memDoubleFreeLock;
195 #define NUM_BT_TRACES 12
196 typedef struct cmMemFreeInfo
197 {
198   PTR             ptr;
199   size_t          btSize;
200   void           *btArr[NUM_BT_TRACES]; 
201   struct timeval  timeStamp;
202   
203 } CmMemFreeInfo;
204
205 #define NUM_FREE_BUFFERS    128
206 typedef struct cmBtInfo
207 {
208   uint32_t btInfoIdx;
209   CmMemFreeInfo  btInfo[NUM_FREE_BUFFERS];
210 } CmBtInfo;
211
212 CmBtInfo    *regBtInfo;
213 CmBtInfo    *allocBtInfo;
214
215 typedef struct cmMemDoubleFree
216 {
217    CmHashListEnt  tmpListEnt;
218    CmMemFreeInfo  traceInfo;
219    PTR            memBlkPtr;
220 }CmMemDoubleFree;
221
222 PTR prvAllocPtr[8];
223 uint8_t stopBtInfo = FALSE;
224 Buffer *palBuffer;
225 Buffer *mtTskBuffer1;
226 Buffer *mtTskBuffer2;
227
228 #ifdef SS_USE_ICC_MEMORY
229 static pthread_mutex_t iccAllocFreeLock;
230 #else
231 static pthread_mutex_t dynAllocFreeLock;
232 #endif /* SS_USE_ICC_MEMORY */
233
234 #ifdef SS_MEM_WL_DEBUG 
235 static S16  cmInitBtInfo ARGS((void));
236 #endif
237
238 #ifdef SS_USE_ICC_MEMORY
239 #ifdef T2K_MEM_LEAK_DBG
240 static S16  cmIccAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, char*, uint32_t));
241 static S16  cmIccFree ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
242 static S16  cmIccAllocWithLock ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr, char*, uint32_t));
243 static S16  cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
244 void InsertToT2kMemLeakInfo ARGS((uint32_t address, uint32_t size, uint32_t lineNo, char* fileName));
245 void RemoveFromT2kMemLeakInfo ARGS((uint32_t address, char *file, uint32_t line));
246 static uint32_t getT2kMemLeakIndex ARGS((uint32_t address));
247 #else
248 static S16  cmIccAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
249 static S16  cmIccFree ARGS((Void *regionCb, Data *ptr, Size size));
250 static S16  cmIccAllocWithLock ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
251 static S16  cmIccFreeWithLock ARGS((Void *regionCb, Data *ptr, Size size));
252 #endif
253 #else  /* SS_USE_ICC_MEMORY */
254 static S16  cmDynAllocWithLock ARGS((Void   *regionCb,Size   *size,uint32_t     flags,Data  **ptr));
255 static S16  cmDynFreeWithLock ARGS((Void   *regionCb,Data   *ptr, Size    size));
256 static S16  cmDynAlloc ARGS((Void   *regionCb,Size   *size,uint32_t     flags,Data  **ptr));
257 static S16  cmDynFree ARGS((Void   *regionCb,Data   *ptr, Size    size));
258 #endif /* SS_USE_ICC_MEMORY */
259
260
261 #ifdef T2K_MEM_LEAK_DBG
262 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t));
263 static S16 cmFreeWL  ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
264
265 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t));
266 static S16 cmFree  ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t));
267 #else
268 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
269 static S16 cmFreeWL  ARGS((Void *regionCb, Data *ptr, Size size));
270
271 static S16 cmAlloc ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
272 static S16 cmFree  ARGS((Void *regionCb, Data *ptr, Size size));
273 #endif
274 #ifdef T2K_MEM_LEAK_DBG
275 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr,char*,uint32_t);
276 static S16 cmFreeWL  ARGS((Void *regionCb, Data *ptr, Size size,char*, uint32_t);
277 #else
278 static S16 cmAllocWL ARGS((Void *regionCb, Size *size, uint32_t flags, Data **ptr));
279 static S16 cmFreeWL  ARGS((Void *regionCb, Data *ptr, Size size));
280 #endif
281 #ifndef USE_PURE
282 static S16 cmHeapAlloc ARGS((CmMmHeapCb *heapCb, Data **ptr, Size *size));
283 static S16 cmHeapFree  ARGS((CmMmHeapCb *heapCb, Data *ptr, Size size));
284 #endif
285 static S16 cmCtl   ARGS((Void *regionCb, Event event, SMemCtl *memCtl));
286 static Void cmMmHeapInit ARGS((Data *memAddr, CmMmHeapCb *heapCb, Size size));
287
288 /* cm_mem_c_001.main_22: Fixing warnings on GCC compiler */
289 #ifdef __cplusplus
290 }
291 #endif
292
293 /* public variable declarations */
294 #ifdef USE_PURE
295 Size avail_size;
296 #endif /* USE_PURE */
297 /*  cm_mem_c_001.main_15:Additions */
298 #ifdef SS_MEM_LEAK_STS 
299 MemUsrMdlStr   memUsrMdlStr[]=
300 {
301    MEMRAW2STR(DEFAULT, STACK),
302    MEMRAW2STR(tc, PDCP_LAYER),
303    MEMRAW2STR(Tc, PDCP_LAYER),
304    MEMRAW2STR(mg, GCP_LAYER),
305    MEMRAW2STR(Mg, GCP_LAYER),
306    {NULLP, NULLP}
307 };
308
309 MemLkCb memLkCb;
310 #endif /* SS_MEM_LEAK_STS */
311
312 /* cm_mem_c_008.104 - Addition for memory calculator tool */
313 #ifdef MEMCAL_DEBUG
314 static Txt prntBuf[200];        /* print buffer */
315 static uint8_t tryHeap=0;
316 #endif 
317
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))
321 #ifdef DEBUGP
322 static Txt dbgPrntBuf[200];        /* print buffer */
323 #endif /* DEBUGP */
324 #endif /*SSI_DEBUG_LEVEL1 || SS_HISTOGRAM_SUPPORT */
325
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*/
334 #endif
335
336 uint32_t num_times = 0;
337 pthread_t tmpRegTidMap[20];
338 Bool g_usettitmr;
339 void DumpLayersDebugInformation()
340 {
341    DumpSSIDemandQDebugInformation();
342    /* dump layers information only after we start receiving the TTIs */
343    if(g_usettitmr)
344    {
345 #ifdef L2_L3_SPLIT     
346       if (clusterMode == RADIO_CLUSTER_MODE)
347       {
348          DumpRLCDlDebugInformation();
349
350 #ifndef UL_RLC_NET_CLUSTER
351          DumpRLCUlDebugInformation();
352 #endif
353          printSchCellInfo();
354       }
355       else
356       {
357 #ifdef UL_RLC_NET_CLUSTER
358          DumpRLCUlDebugInformation();
359 #endif
360          DumpPDCPDlDebugInformation();
361          DumpPDCPUlDebugInformation();   
362       }
363 #else
364       //DumpPDCPDlDebugInformation();
365       //DumpPDCPUlDebugInformation();   
366 #ifndef ODU_TEST_STUB
367       DumpRLCDlDebugInformation();
368       DumpRLCUlDebugInformation();
369 #endif
370       //printSchCellInfo();
371 #endif      
372    }
373 }
374
375 /* private variable declarations */
376 /*
377 *
378 *       Fun:   cmMmStatBktInit
379 *
380 *       Desc:  Initialize the bucket and the map table.
381 *
382 *
383 *       Ret:   ROK     - successful, 
384 *              RFAILED - unsuccessful.
385 *
386 *       Notes: This function is called by the cmMmRegInit. 
387 *
388 *       File:  cm_mem_wl.c
389 *
390 */
391 static Void cmMmStatBktInit
392 (
393 Data      **memAddr,
394 CmMmRegCb  *regCb,
395 CmMmRegCfg *cfg,
396 uint16_t         bktIdx,
397 uint16_t        *lstMapIdx
398 )
399 {
400    uint32_t   cnt;
401    uint16_t   idx;
402    uint32_t   numBlks;
403    Size  size;
404 /* cm_mem_c_001.main_12 - addition for temporary variables */
405 #ifdef SSI_DEBUG_LEVEL1
406    CmMmBlkHdr **nextBlk;
407    uint32_t sigCnt;
408 #else
409    Data **next;
410 #endif /* SSI_DEBUG_LEVEL1 */
411
412
413
414    size = cfg->bktCfg[bktIdx].size; 
415    numBlks = cfg->bktCfg[bktIdx].numBlks; 
416
417 /* cm_mem_c_001.main_12 - addition for header initialization */
418 #ifdef SSI_DEBUG_LEVEL1
419    /* Reset the next block pointer */
420    regCb->bktTbl[bktIdx].nextBlk = NULLP;
421
422    /* Initialize the link list of the memory block */
423    nextBlk = &(regCb->bktTbl[bktIdx].nextBlk);
424
425    for (cnt = 0; cnt < numBlks; cnt++)
426    {
427       *nextBlk = (CmMmBlkHdr *)*memAddr;
428
429       /* initialize the memory block header */
430       for (sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
431       {
432          (*nextBlk)->trSignature[sigCnt] = 0xAB;
433       }
434
435       CMM_SET_FREE_FLAG((*nextBlk)->memFlags);
436       (*nextBlk)->requestedSize = 0;
437       *memAddr = (Data *)((*memAddr) + ((sizeof(CmMmBlkHdr)) + size));
438       nextBlk = &((*nextBlk)->nextBlk);
439    }
440
441    *nextBlk = NULLP;
442
443 #else
444    /* Initialize the bucket linked list */
445
446    /* Reset the next pointer */
447    regCb->bktTbl[bktIdx].next = NULLP; 
448
449    /* Initialize the link list of the memory block */
450    next = &(regCb->bktTbl[bktIdx].next); 
451    for (cnt = 0; cnt < numBlks; cnt++)
452    {
453       *next     = *memAddr;
454       next      = (CmMmEntry **)(*memAddr);
455       *memAddr  = (*memAddr) + size;
456
457    }
458    *next = NULLP;
459
460 #endif /* SSI_DEBUG_LEVEL1 */
461
462    /* Initialize the Map entry */
463    idx = size / cfg->bktQnSize;
464
465    /* 
466     * Check if the size is multiple of quantum size. If not we need to initialize
467     * one more map table entry.
468     */ 
469    if(size % cfg->bktQnSize)
470    {
471       idx++;
472    }
473    
474    while ( *lstMapIdx < idx)
475    {
476       regCb->mapTbl[*lstMapIdx].bktIdx = bktIdx;
477
478 #if (ERRCLASS & ERRCLS_DEBUG)
479       regCb->mapTbl[*lstMapIdx].numReq     = 0;
480       regCb->mapTbl[*lstMapIdx].numFailure = 0;
481 #endif
482
483       (*lstMapIdx)++;
484    } 
485
486    /* Initialize the bucket structure */
487    regCb->bktTbl[bktIdx].size     = size; 
488    regCb->bktTbl[bktIdx].numBlks  = numBlks; 
489    regCb->bktTbl[bktIdx].numAlloc = 0;
490    regCb->bktTbl[bktIdx].maxAlloc = 0;
491
492    /* Update the total bucket size */
493 /* cm_mem_c_001.main_12 - addition for considering the header size */
494 #ifdef SSI_DEBUG_LEVEL1
495    regCb->bktSize += ((size + sizeof(CmMmBlkHdr)) * numBlks);
496 #else
497    regCb->bktSize += (size * numBlks); 
498 #endif /* SSI_DEBUG_LEVEL1 */
499
500    regCb->bktTbl[bktIdx].bktFailCnt = 0;
501    regCb->bktTbl[bktIdx].bktNoFitCnt = 0;
502
503 /* cm_mem_c_001.main_12 - addition for statistics related variable initialization */
504 #ifdef SSI_DEBUG_LEVEL1
505    /* Initialize other required pointers */
506    regCb->bktTbl[bktIdx].bktStartPtr = (Data *)(regCb->bktTbl[bktIdx].nextBlk);
507    regCb->bktTbl[bktIdx].numAllocAttempts = 0;
508    regCb->bktTbl[bktIdx].numDeallocAttempts = 0;
509    regCb->bktTbl[bktIdx].staticMemUsed = 0;
510    regCb->bktTbl[bktIdx].dynamicMemUsed = 0;
511    regCb->bktTbl[bktIdx].trampleCount = 0;
512 #endif /*SSI_DEBUG_LEVEL1*/
513 /*  cm_mem_c_001.main_15 : Additions */
514 #ifdef SS_HISTOGRAM_SUPPORT 
515    /* Initialise the memory histogram hash list */
516    cmHstGrmHashListInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
517 #endif /* SS_HISTOGRAM_SUPPORT */
518
519    return;
520 } /* end of cmMmStatBktInit */
521
522 /*
523 *
524 *       Fun:   cmMmStatRegInit
525 *
526 *       Desc:  Configure the memory region for allocation. The function 
527 *              registers the memory region with System Service by calling
528 *              SRegRegion.
529 *
530 *
531 *       Ret:   ROK     - successful, 
532 *              RFAILED - unsuccessful.
533 *
534 *       Notes: The memory owner calls this function to initialize the memory 
535 *              manager with the information of the memory region. Before 
536 *              calling this function, the memory owner should allocate memory 
537 *              for the memory region. The memory owner should also provide the 
538 *              memory for the control block needed by the memory manager. The 
539 *              memory owner should allocate the memory for the region control 
540 *              block as cachable memory. This may increase the average 
541 *              throughput in allocation and deallocation as the region control
542 *              block is mostly accessed by the CMM.
543 *
544 *       File:  cm_mem_wl.c
545 *
546 */
547 S16 cmMmStatRegInit
548 (
549 Region       region,
550 CmMmRegCb   *regCb,
551 CmMmRegCfg  *cfg
552 )
553 {
554    Data *memAddr;
555    uint16_t   bktIdx;
556    uint16_t   lstMapIdx;
557
558 #if (ERRCLASS & ERRCLS_INT_PAR)
559    Size  lstQnSize;
560    Size  bktBlkSize;
561         Txt   errMsg[256] = {'\0'};
562 #endif
563
564
565 #if (ERRCLASS & ERRCLS_INT_PAR)
566
567    /* error check on parameters */
568    if ((regCb == NULLP) || (cfg == NULLP)) 
569    {
570       return RFAILED;
571    }
572    
573    /* Error check on the configuration fields */
574    if ((!cfg->size) || (cfg->vAddr == NULLP) || 
575         (cfg->numBkts > CMM_MAX_BKT_ENT)) 
576    {
577       return RFAILED;
578    }
579    /* Check if the quantum size is power of 2 */
580    if ((cfg->numBkts) &&
581        ((cfg->bktQnSize - 1) & (cfg->bktQnSize)))
582    {
583       /* cm_mem_c_001.main_20 Addition */
584                 sprintf(errMsg,"\n cmMmRegInit() failed, check if BktQuantum size might not be power of 2 \n");
585                 SPrint(errMsg);
586       return RFAILED;
587    }
588
589    /* 
590     * Check if the size of the memory region is enough, whether bucket sizes
591     * are multiples of quantumn size, and also whether two consecutive buckets
592     *  falls within same quanta.
593     */
594    lstQnSize      = cfg->bktQnSize;
595    regCb->bktSize = 0;
596
597    for ( bktIdx =0; bktIdx < cfg->numBkts; bktIdx++)
598    {
599       /* check if bucket size is mutiple of quantum size */
600       if (cfg->bktCfg[bktIdx].size % cfg->bktQnSize)
601       {
602           /* cm_mem_c_001.main_20 Addition */
603 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
604 #ifdef ALIGN_64BIT          
605                          sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%u not multiple of quantum size:%u\
606                                                         \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
607 #else                     
608                          sprintf(errMsg,"\n cmMmRegInit() failed, Bkt:%d size:%lu not multiple of quantum size:%lu\
609                                                         \n",bktIdx,cfg->bktCfg[bktIdx].size,cfg->bktQnSize);
610 #endif                     
611                          SPrint(errMsg);
612           return RFAILED;
613       }
614
615       if ((bktBlkSize = cfg->bktCfg[bktIdx].size) < lstQnSize)
616       {
617          /* 
618           * Two consecutive buckets are not separated by quantum size.
619           */
620           /* cm_mem_c_001.main_20 Addition */
621                          sprintf(errMsg,"\n cmMmRegInit() failed, Two consecutive buckets are not separated by quantum size \n");
622                          SPrint(errMsg);
623           return RFAILED;
624       }
625       /* cm_mem_c_001.main_20 Addition */
626                 if (((cfg->bktCfg[bktIdx].size) /\
627                                 cfg->bktQnSize) > CMM_MAX_MAP_ENT)
628                 {
629                   /* Error check whether the size of the mapping table is sufficient */
630 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
631 #ifdef ALIGN_64BIT          
632                           sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%u)\
633                                 \n      should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
634 #else                     
635                           sprintf(errMsg,"\n cmMmRegInit() failed, check maxBucketSize/BktQuantumSize(%lu)\
636                                 \n      should be less than CMM_MAX_MAP_ENT:%d \n",cfg->bktQnSize,CMM_MAX_MAP_ENT);
637 #endif                     
638                                 SPrint(errMsg);
639                           return RFAILED;
640                 }
641
642
643       regCb->bktSize += (cfg->bktCfg[bktIdx].size * 
644                          cfg->bktCfg[bktIdx].numBlks); 
645     
646       if (regCb->bktSize > cfg->size)
647       {
648          /* Size of the memory region is less than the required size */
649                 
650                         sprintf(errMsg,"\n cmMmRegInit() failed, Size of the memory region is less than the required size \n");
651                         SPrint(errMsg);
652          return RFAILED;
653       }
654
655       lstQnSize = ((bktBlkSize / cfg->bktQnSize) + 1) * cfg->bktQnSize;
656    }
657
658 #endif
659
660    /* Initialize the region control block */
661    regCb->region = region;
662    regCb->regInfo.regCb = regCb;
663    regCb->regInfo.start = cfg->vAddr;
664    regCb->regInfo.size  = cfg->size;
665
666 #ifdef USE_PURE
667    avail_size = cfg->size;
668 #endif /* USE_PURE */
669
670    if ( cfg->chFlag & CMM_REG_OUTBOARD)
671    {
672       /* Out_of_board memory */
673       regCb->regInfo.flags = CMM_REG_OUTBOARD;
674    } 
675   else
676    {
677       regCb->regInfo.flags = 0;
678    }
679
680
681 #if 1
682    if(region == SS_MAX_REGS - 1)
683    {
684       regCb->regInfo.alloc = cmAlloc;
685       regCb->regInfo.free  = cmFree;
686       regCb->regInfo.ctl   = cmCtl;   
687    }
688    else
689    {
690       regCb->regInfo.alloc = cmAllocWL;
691       regCb->regInfo.free  = cmFreeWL;
692       regCb->regInfo.ctl   = cmCtl;   
693    }
694 #else
695    regCb->regInfo.alloc = cmAlloc;
696    regCb->regInfo.free  = cmFree;
697    regCb->regInfo.ctl   = cmCtl;
698 #endif
699
700    /* Initialize the physical address */
701    if ((regCb->chFlag = cfg->chFlag) & CMM_REG_PHY_VALID)
702    {
703       regCb->pAddr = cfg->pAddr;
704    }
705
706    /* Initial address of the memory region block */
707    memAddr    = cfg->vAddr;
708
709    /* Initialize the fields related to the bucket pool */
710    regCb->bktMaxBlkSize = 0;
711    regCb->bktSize       = 0; 
712
713    if (cfg->numBkts)
714    {
715       /* Last bucket has the maximum size */
716       regCb->bktMaxBlkSize = cfg->bktCfg[cfg->numBkts - 1].size;
717    
718       /* Get the power of the bktQnSize */
719       regCb->bktQnPwr = 0; 
720       while( !((cfg->bktQnSize >> regCb->bktQnPwr) & 0x01))
721       {
722          regCb->bktQnPwr++;
723       }
724     
725       /* Initilaize the bktIndex of the map entries to FF */
726       for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
727       {
728          regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
729       }
730   
731       lstMapIdx = 0;
732       for ( bktIdx = 0; bktIdx < cfg->numBkts; bktIdx++)
733       {
734          /* Allocate the lock for the bucket pool */
735          cmMmStatBktInit( &memAddr, regCb, cfg, bktIdx, &lstMapIdx); 
736       }
737
738       /* Used while freeing the bktLock in cmMmRegDeInit */
739       regCb->numBkts = cfg->numBkts;
740    }
741
742    /* 
743     * Initialize the heap pool if size the memory region region is more
744     * than the size of the bucket pool 
745     */
746     regCb->heapSize = 0;
747     regCb->heapFlag = FALSE;
748
749     /* Align the memory address */
750     memAddr = (Data *)(PTRALIGN(memAddr));
751
752     regCb->heapSize = cfg->vAddr + cfg->size - memAddr;  
753
754     /* 
755      * Round the heap size so that the heap size is multiple 
756      * of CMM_MINBUFSIZE 
757      */
758     regCb->heapSize -= (regCb->heapSize %  CMM_MINBUFSIZE);
759
760     if (regCb->heapSize)
761     {
762        /* Allocate the lock for the heap pool */
763        regCb->heapFlag = TRUE;
764        cmMmHeapInit(memAddr, &(regCb->heapCb), regCb->heapSize); 
765     }
766
767     /* Call SRegRegion to register the memory region with SSI */
768     if (SRegRegion(region, &regCb->regInfo) != ROK)
769     {
770        return RFAILED;
771     }
772
773     return ROK;
774 } /* end of cmMmRegInit*/
775
776
777 /*
778 *
779 *       Fun:   cmMmGlobRegInit
780 *
781 *       Desc:  Configure the memory region for allocation. The function 
782 *              registers the memory region with System Service by calling
783 *              SRegRegion.
784 *
785 *
786 *       Ret:   ROK     - successful, 
787 *              RFAILED - unsuccessful.
788 *
789 *       Notes: 
790 *
791 *       File:  cm_mem_wl.c
792 *
793 */
794 S16 cmMmGlobRegInit
795 (
796 CmMmGlobRegCb   *regCb
797 )
798 {
799    Data **memAddr;
800    Data **next;
801    uint16_t   bktIdx;
802    uint16_t   bucketSetSize;
803    uint16_t   cnt;
804    Size  size;
805    CmMmBlkSetElement *blkLstElem;
806    uint16_t   numBlks;
807
808 #if (ERRCLASS & ERRCLS_INT_PAR)
809    Size  lstQnSize;
810    Size  bktBlkSize;
811         Txt   errMsg[256] = {'\0'};
812 #endif
813
814
815 #ifdef SS_MEM_WL_DEBUG 
816    if (cmInitBtInfo() == RFAILED)
817    {
818      return RFAILED;
819    }
820 #endif
821    for ( bktIdx = 0; bktIdx < regCb->numBkts; bktIdx++)
822    {
823       /* Initial address of the memory region block */
824       memAddr    = &regCb->bktTbl[bktIdx].startAddr;
825       bucketSetSize  = regCb->bktTbl[bktIdx].bucketSetSize;
826       size = regCb->bktTbl[bktIdx].size;
827
828       /* Initialize the bucket linked list */
829       cmLListInit(&regCb->bktTbl[bktIdx].listValidBktSet);
830       cmLListInit(&regCb->bktTbl[bktIdx].listFreeBktSet);
831       SInitLock(&(regCb->bktTbl[bktIdx].bucketLock), SS_LOCK_MUTEX);
832
833       /* Initialize the link list of the memory block */
834       next = &(regCb->bktTbl[bktIdx].next); 
835
836       numBlks = regCb->bktTbl[bktIdx].numBlks;
837       for (cnt = 1; cnt <= numBlks; cnt++)
838       {
839          *next     = *memAddr;
840          next      = (CmMmEntry **)(*memAddr);
841          *memAddr  = (*memAddr) + size;
842
843          /* Maintain the list Cb */
844          if(!(cnt % bucketSetSize))
845          {
846             blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
847             blkLstElem->nextBktPtr = (CmMmEntry *)regCb->bktTbl[bktIdx].next;
848             blkLstElem->numFreeBlks = bucketSetSize;
849             blkLstElem->memSetNode.node = (PTR)blkLstElem;
850             cmLListAdd2Tail((&regCb->bktTbl[bktIdx].listValidBktSet), (&blkLstElem->memSetNode));
851             next = &(regCb->bktTbl[bktIdx].next);
852          }
853       }
854       *next = NULLP;
855    }
856
857     return ROK;
858 } /* end of cmMmGlobRegInit*/
859
860 #ifdef SS_USE_ICC_MEMORY
861 /*
862 *
863 *       Fun:   cmIccAllocWithLock
864 *
865 *       Desc:  Allocate a memory block for use by dynamic buffers.
866 *              This handler uses the lock to avoid the two thread
867 *              trying to allocate the memory at same time. This
868 *              handler must be used only for non-data plane thread
869 *              it causes delay due to lock.
870 *
871 *
872 *       Ret:   ROK     - successful
873 *              RFAILED - unsuccessful.
874 *
875 *       Notes: 
876 *
877 *       File:  cm_mem_wl.c
878 *
879 */
880 #ifdef T2K_MEM_LEAK_DBG
881 static S16  cmIccAllocWithLock
882 (
883 Void   *regionCb,    /* Pointer to a region */
884 Size   *size,        /* size needs to be allocated */
885 uint32_t     flags,       /* Flags used */
886 Data  **ptr,          /* Reference to pointer for which need to be allocate */
887 char *file,
888 uint32_t line
889 )
890 #else
891 static S16  cmIccAllocWithLock
892 (
893 Void   *regionCb,    /* Pointer to a region */
894 Size   *size,        /* size needs to be allocated */
895 uint32_t     flags,       /* Flags used */
896 Data  **ptr          /* Reference to pointer for which need to be allocate */
897 )
898 #endif
899 {
900    CmMmDynRegCb        *regCb;
901    Data                *memPtr;
902
903
904    regCb = (CmMmDynRegCb *)regionCb;
905
906    if((SLock(&iccAllocFreeLock)) != ROK)
907    {
908       printf("cmIccAllocWithLock: Failed to get the ICC lock\n");
909       return RFAILED;
910    }
911
912    memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
913
914    if((SUnlock(&iccAllocFreeLock)) != ROK)
915    {
916       printf("cmIccAllocWithLock: Failed to unlock the ICC lock\n");
917       return RFAILED;
918    }
919
920    if ((memPtr) == NULLP)
921    {
922       int *p = 0;
923       printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
924       printf("Exiting...\n");
925       /* crash here */
926       *p = 10;
927    }
928
929 #ifdef T2K_MEM_LEAK_DBG
930    if(((uint32_t)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
931    {
932       printf("Address returned is %p size = %ld\n",memPtr,*size);
933    }
934
935    InsertToT2kMemLeakInfo((uint32_t)memPtr,*size,line,file);
936 #endif
937    *ptr = memPtr;
938
939    return ROK;
940
941 } /* end of cmIccAllocWithLock */
942
943 /*
944 *
945 *       Fun:   cmIccFreeWithLock
946 *
947 *       Desc:  Return the Dynamic memory block for the memory region.
948 *              This handler uses the lock to avoid the two thread
949 *              trying to free the memory at same time. This
950 *              handler must be used only for non-data plane thread
951 *              it causes delay due to lock.
952 *
953 *       Ret:   ROK     - successful
954 *              RFAILED - unsuccessful.
955 *
956 *       Notes:
957 *
958 *
959 *       File:  cm_mem_wl.c
960 *
961 */
962 #ifdef T2K_MEM_LEAK_DBG
963 static S16  cmIccFreeWithLock
964 (
965 Void   *regionCb,   /* Pointer to region cb */
966 Data   *ptr,        /* Memory block needs to be freed */
967 Size    size,        /* Size of the block */
968 char *file,
969 uint32_t line
970 )
971 #else
972 static S16  cmIccFreeWithLock
973 (
974 Void   *regionCb,   /* Pointer to region cb */
975 Data   *ptr,        /* Memory block needs to be freed */
976 Size    size        /* Size of the block */
977 )
978 #endif
979 {
980    CmMmDynRegCb       *regCb;
981
982
983    regCb = (CmMmDynRegCb *)regionCb;
984
985    if((SLock(&iccAllocFreeLock)) != ROK)
986    {
987       printf("cmIccFreeWithLock: Failed to get the ICC lock\n");
988       return RFAILED;
989    }
990
991 #ifdef T2K_MEM_LEAK_DBG
992    RemoveFromT2kMemLeakInfo((uint32_t)ptr - ((uint32_t)ptr % 512),file,line);
993
994 #endif
995    TL_Free(regCb->iccHdl, ptr);
996
997    if((SUnlock(&iccAllocFreeLock)) != ROK)
998    {
999       printf("cmIccFreeWithLock: Failed to unlock the ICC lock\n");
1000       return RFAILED;
1001    }
1002
1003    return ROK;
1004 } /* end of cmIccFree */
1005
1006 /*
1007 *
1008 *       Fun:   cmIccAlloc
1009 *
1010 *       Desc:  Allocate a memory block for use by dynamic buffers
1011 *
1012 *
1013 *       Ret:   ROK     - successful
1014 *              RFAILED - unsuccessful.
1015 *
1016 *       Notes: 
1017 *
1018 *       File:  cm_mem_wl.c
1019 *
1020 */
1021 #ifdef T2K_MEM_LEAK_DBG
1022 static S16  cmIccAlloc
1023 (
1024 Void   *regionCb,    /* Pointer to a region */
1025 Size   *size,        /* size needs to be allocated */
1026 uint32_t     flags,       /* Flags used */
1027 Data  **ptr,          /* Reference to pointer for which need to be allocate */
1028 char *file,
1029 uint32_t line
1030 )
1031 #else
1032 static S16  cmIccAlloc
1033 (
1034 Void   *regionCb,    /* Pointer to a region */
1035 Size   *size,        /* size needs to be allocated */
1036 uint32_t     flags,       /* Flags used */
1037 Data  **ptr          /* Reference to pointer for which need to be allocate */
1038 )
1039
1040 #endif
1041 {
1042    CmMmDynRegCb        *regCb;
1043    Data                *memPtr;
1044
1045
1046    regCb = (CmMmDynRegCb *)regionCb;
1047
1048    memPtr = (Data *)TL_Alloc(regCb->iccHdl, *size);
1049
1050    if ((memPtr) == NULLP)
1051    {
1052       int *p = 0;
1053       printf("\n*****************Region(%d) is out of memory size = %ld******************\n",regCb->region, *size);
1054       printf("Exiting...\n");
1055       /* crash here */
1056       *p = 10;
1057    }
1058 #ifdef T2K_MEM_LEAK_DBG
1059    if(((uint32_t)(memPtr - T2K_MEM_LEAK_START_ADDR) & 0xff) != 0)
1060    {
1061       printf("Address returned is %p size = %ld\n",memPtr,*size);
1062    }
1063   
1064    InsertToT2kMemLeakInfo((uint32_t)memPtr,*size,line,file);
1065 #endif
1066 #ifdef YS_PHY_3_8_2
1067    *ptr = memPtr;/*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1068 #else
1069    *ptr = memPtr; /*TL_VA2TRUEVA(regCb->iccHdl, memPtr); */
1070 #endif
1071
1072    return ROK;
1073
1074 } /* end of cmIccAlloc */
1075
1076 /*
1077 *
1078 *       Fun:   cmIccFree
1079 *
1080 *       Desc:  Return the Dynamic memory block for the memory region.
1081 *
1082 *
1083 *       Ret:   ROK     - successful
1084 *              RFAILED - unsuccessful.
1085 *
1086 *       Notes:
1087 *
1088 *
1089 *       File:  cm_mem_wl.c
1090 *
1091 */
1092 #ifdef T2K_MEM_LEAK_DBG
1093 static S16  cmIccFree
1094 (
1095 Void   *regionCb,   /* Pointer to region cb */
1096 Data   *ptr,        /* Memory block needs to be freed */
1097 Size    size,        /* Size of the block */
1098 char* file,
1099 uint32_t line
1100 )
1101 #else
1102 static S16  cmIccFree
1103 (
1104 Void   *regionCb,   /* Pointer to region cb */
1105 Data   *ptr,        /* Memory block needs to be freed */
1106 Size    size        /* Size of the block */
1107 )
1108 #endif
1109 {
1110    CmMmDynRegCb       *regCb;
1111
1112    regCb = (CmMmDynRegCb *)regionCb;
1113
1114 #ifdef YS_PHY_3_8_2
1115    // memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr);
1116    {
1117 #ifdef T2K_MEM_LEAK_DBG
1118       RemoveFromT2kMemLeakInfo((uint32_t)ptr - ((uint32_t)ptr % 512),file,line);
1119 #endif
1120    }
1121
1122    TL_Free(regCb->iccHdl, ptr);
1123 #else
1124 /*   memPtr = TL_TRUEVA2VA(regCb->iccHdl, ptr); */
1125    memPtr = ptr;
1126    TL_Free(regCb->iccHdl, memPtr); 
1127 #endif
1128    /*TL_Free(regCb->iccHdl, ptr);*/
1129
1130
1131    return ROK;
1132 } /* end of cmIccFree */
1133
1134 /*
1135 *
1136 *       Fun:   cmMmDynRegInit
1137 *
1138 *       Desc:  Configure the memory region for allocation. The function 
1139 *              registers the memory region with System Service by calling
1140 *              SRegRegion.
1141 *
1142 *
1143 *       Ret:   ROK     - successful, 
1144 *              RFAILED - unsuccessful.
1145 *
1146 *       Notes: The memory owner calls this function to initialize the memory 
1147 *              manager with the information of the memory region. Before 
1148 *              calling this function, the memory owner should allocate memory 
1149 *              for the memory region. The memory owner should also provide the 
1150 *              memory for the control block needed by the memory manager. The 
1151 *              memory owner should allocate the memory for the region control 
1152 *              block as cachable memory. This may increase the average 
1153 *              throughput in allocation and deallocation as the region control
1154 *              block is mostly accessed by the CMM.
1155 *
1156 *       File:  cm_mem_wl.c
1157 *
1158 */
1159 S16 cmMmDynRegInit
1160 (
1161 CmMmDynRegCb   *regCb
1162 )
1163 {
1164    SRegInfo regInfo;
1165 #ifdef T2200_2GB_DDR_CHANGES
1166    Txt      regIccStr[10] = {'\0'};
1167 #else
1168    Txt      regIccStr[64] = {'\0'};
1169 #endif
1170
1171
1172    /* Register the region/memory with ICC and get the handler for same. The id is starting
1173     * from region+1 as the zero is used by PHY code */
1174 #ifdef T2200_2GB_DDR_CHANGES
1175    sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1176 #else
1177 #ifdef L2_L3_SPLIT     
1178   if(clusterMode == RADIO_CLUSTER_MODE)  
1179   {
1180      if(regCb->region == 3)
1181      {/* ICC packet receiver */
1182          snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 4096, (regCb->region + 1));
1183      }else
1184      {
1185          snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1186         //sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1187      }
1188   }else
1189   {/* NET CLUSTER */
1190      snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 2048, (regCb->region + 1));
1191      //snprintf(regIccStr, sizeof(regIccStr), "QueueSize=%u RxID=%u", 1024, (regCb->region + 1));
1192      //snprintf(regIccStr, sizeof(regIccStr), "RXID=%u", (regCb->region + 1));
1193   }
1194 #else
1195 #ifdef T2200_2GB_DDR_CHANGES
1196   sprintf(regIccStr, "RxID=%d", (regCb->region + 1));
1197 #else
1198   sprintf (regIccStr, "queuesize=%d rxid=%d", 512, (regCb->region) + 1);
1199 #endif
1200 #endif
1201 #endif
1202    printf(" %s \n",regIccStr);
1203    regCb->iccHdl = TL_Open(regIccStr, 0);
1204
1205    printf("\nICC Region is %d\n",regCb->region);
1206
1207    /* Call SRegRegion to register the memory region with SSI */
1208    memset(&regInfo, 0, sizeof(regInfo));
1209
1210    /* Register the lock region for SS_MAX_REGS - 1 region */
1211    if((SS_MAX_REGS - 1) == regCb->region)
1212    {
1213       regInfo.alloc = cmIccAllocWithLock;
1214       regInfo.free  = cmIccFreeWithLock;
1215       regInfo.regCb = regCb;
1216       if((SInitLock((&iccAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1217       {
1218          printf("Failed to initialize the lock region lock\n");
1219       }
1220    }
1221    else
1222    {
1223       regInfo.alloc = cmIccAlloc;
1224       regInfo.free  = cmIccFree;
1225       regInfo.regCb = regCb;
1226    }
1227
1228    if (SRegDynRegion(regCb->region, &regInfo) != ROK)
1229    {
1230       return RFAILED;
1231    }
1232
1233     return ROK;
1234 } /* end of cmMmDynRegInit*/
1235
1236 #else /* SS_USE_ICC_MEMORY */
1237
1238 /*
1239 *
1240 *       Fun:   cmMmDynRegInit
1241 *
1242 *       Desc:  Configure the memory region for allocation. The function 
1243 *              registers the memory region with System Service by calling
1244 *              SRegRegion.
1245 *
1246 *
1247 *       Ret:   ROK     - successful, 
1248 *              RFAILED - unsuccessful.
1249 *
1250 *       Notes: The memory owner calls this function to initialize the memory 
1251 *              manager with the information of the memory region. Before 
1252 *              calling this function, the memory owner should allocate memory 
1253 *              for the memory region. The memory owner should also provide the 
1254 *              memory for the control block needed by the memory manager. The 
1255 *              memory owner should allocate the memory for the region control 
1256 *              block as cachable memory. This may increase the average 
1257 *              throughput in allocation and deallocation as the region control
1258 *              block is mostly accessed by the CMM.
1259 *
1260 *       File:  cm_mem_wl.c
1261 *
1262 */
1263 S16 cmMmDynRegInit
1264 (
1265 CmMmDynRegCb   *regCb
1266 )
1267 {
1268    Region region;
1269    uint16_t    lstMapIdx;
1270    uint16_t   cnt;
1271    Size  size;
1272    CmMmBlkSetElement *blkLstElem;
1273    SRegInfo regInfo;
1274    Size   bktQnSize = MT_BKTQNSIZE;
1275    uint16_t    idx;
1276    uint16_t    idx1;
1277    uint16_t    numBkts;
1278
1279
1280    /* Initialize the region control block */
1281    region = regCb->region;
1282    numBkts = regCb->numBkts;
1283
1284    /* Initilaize the bktIndex of the map entries to FF */
1285    for ( lstMapIdx = 0; lstMapIdx < CMM_MAX_MAP_ENT; lstMapIdx++)
1286    {
1287       regCb->mapTbl[lstMapIdx].bktIdx = 0xFF;
1288    }
1289
1290    lstMapIdx = 0;
1291
1292    for(cnt = 0; cnt < numBkts; cnt++)
1293    {
1294       /* Initialize the Map entry */
1295       size = regCb->bktTbl[cnt].size;
1296       idx = size / bktQnSize;
1297    
1298       /* 
1299        * Check if the size is multiple of quantum size. If not we need to initialize
1300        * one more map table entry.
1301        */ 
1302       if(size % bktQnSize)
1303       {
1304          idx++;
1305       }
1306    
1307       while ( lstMapIdx < idx)
1308       {
1309          regCb->mapTbl[lstMapIdx].bktIdx = cnt;
1310          lstMapIdx++;
1311       } 
1312    }
1313
1314    regCb->bktQnPwr = 0; 
1315
1316    while( !((bktQnSize >> regCb->bktQnPwr) & 0x01))
1317    {
1318       regCb->bktQnPwr++;
1319    }
1320
1321    /* Initialize the bucket structure */
1322    for(idx = 0; idx < numBkts; idx++)
1323    {
1324       regCb->bktTbl[idx].crntMemBlkSetElem = NULLP;
1325
1326       for(idx1 = 0; idx1 < CMM_MAX_NUMBER_BKT_NODE; idx1++)
1327       {
1328           blkLstElem = calloc(1, sizeof(CmMmBlkSetElement));
1329           blkLstElem->memSetNode.node = (PTR)blkLstElem;
1330           cmLListAdd2Tail((&regCb->bktTbl[idx].memBlkSetElem), (&blkLstElem->memSetNode));
1331       }
1332    }
1333
1334    /* Call SRegRegion to register the memory region with SSI */
1335    memset(&regInfo, 0, sizeof(regInfo));
1336    if((SS_MAX_REGS - 1) == regCb->region)
1337    {
1338       regInfo.alloc = cmDynAllocWithLock;
1339       regInfo.free  = cmDynFreeWithLock;
1340       if((SInitLock((&dynAllocFreeLock), SS_LOCK_MUTEX)) != ROK)
1341       {
1342          printf("Failed to initialize the lock region lock\n");
1343       }
1344    }
1345    else
1346    {
1347        regInfo.alloc = cmDynAlloc;
1348        regInfo.free = cmDynFree;
1349    }
1350
1351    regInfo.regCb = regCb;
1352
1353    if (SRegDynRegion(region, &regInfo) != ROK)
1354    {
1355       return RFAILED;
1356    }
1357
1358     return ROK;
1359 } /* end of cmMmDynRegInit*/
1360
1361 #endif /* SS_USE_ICC_MEMORY */
1362
1363 \f
1364 /*
1365 *
1366 *       Fun:   cmMmRegDeInit
1367 *
1368 *       Desc:  Deinitialize the memory region. The function call SDeregRegion
1369 *              to deregister the memory region with System Service.
1370 *
1371 *
1372 *       Ret:   ROK     - successful
1373 *              RFAILED - unsuccessful.
1374 *
1375 *       Notes: The memory owner calls this function to deinitialize the region.
1376 *              The memory manager does not return the memory to the system. 
1377 *              Before calling this function, the memory owner must be sure that 
1378 *              no layer is using any memory block from this region. On 
1379 *              successful return from the function, any request to the memory 
1380 *              manager to allocate/deallocate memory will fail. The memory owner
1381 *              can reuse the memory for other region or return the memory to the
1382 *              system memory pool.
1383 *
1384 *
1385 *
1386 *       File:  cm_mem_wl.c
1387 *
1388 */
1389 S16 cmMmRegDeInit(CmMmRegCb   *regCb)
1390 {
1391    uint16_t  bktIdx; 
1392
1393
1394 #if (ERRCLASS & ERRCLS_INT_PAR)
1395   
1396    /* error check on parameters */
1397    if (regCb == NULLP)
1398    {
1399       return RFAILED;
1400    }
1401
1402 #endif
1403
1404 /* cm_mem_c_001.main_12 - addition for deinitializing the hash table */
1405 #ifdef SSI_DEBUG_LEVEL1
1406     /* Deinitialize the hash table used for debug info storage at region level */
1407     if (cmMmHashListDeinit(&regCb->hashListCp, regCb->region, 0) != ROK)
1408     {
1409         return RFAILED;
1410     }
1411 #endif /* SSI_DEBUG_LEVEL1 */
1412
1413    /* Call SDeregRegion first to deregister the memory region with SSI */
1414    (Void) SDeregRegion (regCb->region);
1415
1416    if (regCb->bktSize)
1417    {
1418       /* Bucket pool is configured */
1419
1420       /* Free the initialzed locks of the buckets */
1421       for ( bktIdx = regCb->numBkts; bktIdx > 0;)
1422       {
1423           /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1424              WTDestroyLock for NT */
1425           /*  cm_mem_c_001.main_24 fix for memory corruption*/
1426           --bktIdx;
1427 #ifdef SS_WIN
1428           WTDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1429 #else
1430           SDestroyLock(&(regCb->bktTbl[bktIdx].bktLock));
1431 #endif
1432 /*  cm_mem_c_001.main_15:Additions */
1433 #ifdef SS_HISTOGRAM_SUPPORT 
1434    /* De-initialise the memory histogram hash list */
1435    cmHstGrmHashListDeInit(&(regCb->bktTbl[bktIdx].hstGrmHashListCp));
1436 #endif /* SS_HISTOGRAM_SUPPORT */
1437       }
1438    }
1439
1440    if (regCb->heapFlag)
1441    {
1442       /* Heap pool is configured */
1443
1444       /* cm_mem_c_001.main_13: Replaced SDestroyLock with
1445          WTDestroyLock for NT */
1446 #ifdef SS_WIN
1447       WTDestroyLock(&regCb->heapCb.heapLock);
1448 #else
1449       SDestroyLock(&regCb->heapCb.heapLock);
1450 #endif
1451    }
1452
1453    return ROK;
1454
1455 } /* end of cmMmRegDeInit */
1456
1457 #ifndef USE_PURE 
1458 #ifndef SS_USE_ICC_MEMORY
1459 /*
1460 *
1461 *       Fun:   cmGetMemBlkSetForAlloc
1462 *
1463 *       Desc:  Retruns the pointer to the element which is used for 
1464 *              allocating the buffer. Also, it does the threshold check
1465 *              and get the additional memory block set from the global
1466 *              region
1467 *
1468 *
1469 *       Ret:   Pointer to memory block set     - successful
1470 *              NULL                            - unsuccessful.
1471 *
1472 *       Notes: 
1473 *       Current implementation of the is function is made assuming that
1474 *       there will maximum two set of nodes only.
1475 *
1476 *       File:  cm_mem_wl.c
1477 *
1478 */
1479
1480 static CmMmBlkSetElement* cmGetMemBlkSetForAlloc
1481 (
1482 uint8_t       bucketIndex, /* Index to the bucket list */
1483 CmMmDynBktCb  *bkt        /* Bucket list control block */
1484 )
1485 {
1486    CmMmBlkSetElement  *memBlkSetElem;
1487    CmMmBlkSetElement  *nextMemBlkSetElem;
1488    CmLList            *memSetNode;
1489    CmLList            *nextMemSetNode;
1490
1491    /* Check if we are coming here for the first time, if yes get a new
1492     * block set from global region */
1493    if(bkt->crntMemBlkSetElem == NULLP)
1494    {
1495       /* set the current index to initial one and get the bucket set from
1496        * global region */
1497       memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1498
1499       /* Check if the element exits or not */
1500       if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1501       {
1502          return (NULLP);
1503       }
1504
1505       bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1506       /* Get the new block set from the gloabl region and return the same */
1507       ssGetDynMemBlkSet(bucketIndex, bkt->crntMemBlkSetElem, 0);
1508       return (bkt->crntMemBlkSetElem);
1509    }
1510    /* If this is not the first time, take the bucket list CB from the 
1511     * current index */
1512    memBlkSetElem = bkt->crntMemBlkSetElem;
1513    /* If the current index doesnot have any free buckets, it check in
1514     * the next bucket node */
1515    if(memBlkSetElem->numFreeBlks == 0)
1516    {
1517       /* Get the next element in the list and if it is not present, then 
1518        * get the first node */
1519       memSetNode = cmLListNext(&bkt->memBlkSetElem);
1520
1521       if(memSetNode == NULLP)
1522       {
1523          memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1524       }
1525       memBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1526
1527       /* if next node also empty, return failure */
1528       if(memBlkSetElem->numFreeBlks == 0)
1529       {
1530          return (NULLP);
1531       }
1532       /* store the new index in the current node which will be
1533        * used in the next time. */
1534       bkt->crntMemBlkSetElem = memBlkSetElem;
1535    }
1536
1537    /* If we have reached the threshold value, get the next set of buckets from
1538     * the global region and place it */
1539    if(memBlkSetElem->numFreeBlks < bkt->blkSetAcquireThreshold)
1540    {
1541       /* Get the next element for the threshold check. If next is not present, 
1542        * get the first one. Here, we are not using the cmLList macros to get
1543        * to the next node or first node as those macros are working on the crnt
1544        * node and will change the crnt. As we dont want to change the crnt node
1545        * at this point, we are directly using the listCp prameter to get next
1546        * first nodes */
1547       nextMemSetNode = memBlkSetElem->memSetNode.next;
1548
1549       if(nextMemSetNode == NULLP)
1550       {
1551          nextMemSetNode =  bkt->memBlkSetElem.first;
1552       }
1553
1554       nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1555
1556       if(nextMemBlkSetElem->numFreeBlks == 0)
1557       {
1558          /* The last parameter is used wheather to block for the block set aquiring
1559             or not. Here, the logic is such that, when the current node number of 
1560             free blocks becomes one and the next node has zero free blocks, 
1561             we must get the block set from global region.
1562             For example, if acquire threashold is 20 and current node has only one 
1563             free block and next node has zero free blocks we block to aquire lock 
1564             and get the set from global region else, we try for lock, if we get 
1565             the lock, the get the block set else it is get in next go
1566          */
1567          ssGetDynMemBlkSet(bucketIndex, nextMemBlkSetElem, 
1568                            (memBlkSetElem->numFreeBlks - 1));
1569       }
1570    }
1571    
1572    /* On successful, return the bucket node to calling function */
1573    return (memBlkSetElem);
1574 } /* cmGetMemBlkSetForAlloc */
1575
1576
1577 /*
1578 *
1579 *       Fun:   cmGetMemBlkSetForFree
1580 *
1581 *       Desc:  Retruns the pointer to the element which is used for 
1582 *              freeing the buffer. Also, it does the threshold check
1583 *              and release the additional memory block set to the global
1584 *              region
1585 *
1586 *
1587 *       Ret:   Pointer to memory block set     - successful
1588 *              NULL                            - unsuccessful.
1589 *
1590 *       Notes: 
1591 *       Current implementation of the is function is made assuming that
1592 *       there will maximum two set of nodes only.
1593 *
1594 *       File:  cm_mem_wl.c
1595 *
1596 */
1597
1598 static CmMmBlkSetElement* cmGetMemBlkSetForFree
1599 (
1600 uint8_t       bucketIndex, /* Index to the bucket list */
1601 CmMmDynBktCb  *bkt        /* Bucket list control block */
1602 )
1603 {
1604    CmMmBlkSetElement  *memBlkSetElem;
1605    CmMmBlkSetElement  *nextMemBlkSetElem;
1606    CmLList            *memSetNode;
1607    CmLList            *nextMemSetNode;
1608
1609    /* Check if we are coming here for the first time, if yes get a new
1610     * block set from global region */
1611    if(bkt->crntMemBlkSetElem == NULLP)
1612    {
1613       /* set the current index to initial one */
1614       memSetNode = cmLListFirst(&bkt->memBlkSetElem);
1615
1616       /* Check if the element exits or not */
1617       if((memSetNode == NULLP) || (memSetNode->node == NULLP))
1618       {
1619          return (NULLP);
1620       }
1621       bkt->crntMemBlkSetElem = (CmMmBlkSetElement *)memSetNode->node;
1622       return (bkt->crntMemBlkSetElem);
1623    }
1624    /* If this is not the first time, take the bucket list CB from the 
1625     * current index */
1626    memBlkSetElem = bkt->crntMemBlkSetElem;
1627    /* If the current index doesnot have any free buckets, it check in
1628     * the next bucket node */
1629    if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1630    {
1631       /* Get the next element in the list and if it is not present, then 
1632        * get the first node */
1633       nextMemSetNode = cmLListNext(&bkt->memBlkSetElem);
1634
1635       if(nextMemSetNode == NULLP)
1636       {
1637          nextMemSetNode =  cmLListFirst(&bkt->memBlkSetElem);
1638       }
1639       memBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1640
1641       /* if next node also empty, return failure */
1642       if(memBlkSetElem->numFreeBlks >= bkt->bucketSetSize)
1643       {
1644          return (NULLP);
1645       }
1646       /* store the new index in the current node which will be
1647        * used in the next time. */
1648       bkt->crntMemBlkSetElem = memBlkSetElem;
1649    }
1650
1651    /* If we have reached the threshold value and have additional block set,
1652     * release the additional block set back to global region */
1653    if(memBlkSetElem->numFreeBlks > bkt->blkSetRelThreshold) 
1654    {
1655       /* Get the next element for the threshold check. If next is not present, 
1656        * get the first one. Here, we are not using the cmLList macros to get
1657        * to the next node or first node as those macros are working on the crnt
1658        * node and will change the crnt. As we dont want to change the crnt node
1659        * at this point, we are directly using the listCp prameter to get next
1660        * first nodes */
1661       nextMemSetNode = memBlkSetElem->memSetNode.next;
1662       if(nextMemSetNode == NULLP)
1663       {
1664          nextMemSetNode =  bkt->memBlkSetElem.first;
1665       }
1666
1667       nextMemBlkSetElem = (CmMmBlkSetElement *)nextMemSetNode->node;
1668       if(nextMemBlkSetElem->numFreeBlks == bkt->bucketSetSize)
1669       {
1670          /* The last parameter is used wheather to block for the block set aquiring
1671             or not. Here, the logic is such that, when the current node number of 
1672             free blocks becomes one less than the bucket set size and the next node
1673             is has full free blocks, we must free the block set back to global region
1674             For example, if bucket set size if 100 and release threashold is 80 and
1675             current node has number of free blocks 99 and next node has 100 free blocks
1676             we block to aquire lock and free it back to global region else, we try for
1677             lock, if we get the lock, the block set is freed else its freed in next go 
1678            */
1679          ssPutDynMemBlkSet(bucketIndex, nextMemBlkSetElem, 
1680                            (bkt->bucketSetSize - memBlkSetElem->numFreeBlks - 1));
1681       }
1682    }
1683    
1684    /* On successful, return the bucket node to calling function */
1685    return (memBlkSetElem);
1686 }
1687 #endif /* SS_USE_ICC_MEMORY */
1688 #endif /* USE_PURE */
1689
1690 #ifdef SS_MEM_WL_DEBUG
1691 /*
1692 *
1693 *       Fun:   cmRemoveAllocPtrFromList
1694 *
1695 *       Desc:  Remove a node with Free PTR from hashlist. The memory
1696 *              of the node is Freed to the same region
1697 *
1698 *
1699 *       Ret:   ROK     - successful
1700 *              RFAILED - unsuccessful.
1701 *
1702 *       Notes: 
1703 *
1704 *       File:  cm_mem_wl.c
1705 *
1706 */
1707
1708 static S16  cmRemoveAllocPtrFromList
1709 (
1710 CmMmDynRegCb    *regionCb,    /* Pointer to a region */
1711 PTR              ptr
1712 )
1713 {
1714
1715    CmMemDoubleFree   *memNode = NULLP;
1716
1717    SLock(&memDoubleFreeLock);
1718    if((cmHashListFind(&(memDoubleFree), (uint8_t*)&ptr,
1719        sizeof(uint32_t), 0, (PTR *)&memNode)) != ROK)
1720    {
1721       Void    *tmpBtArr[10];
1722       uint16_t     tmpBtSize;
1723       S8      **strings;
1724       uint16_t     idx;
1725
1726       tmpBtSize = backtrace(tmpBtArr, 10);
1727       strings = backtrace_symbols(tmpBtArr, tmpBtSize);
1728       printf("**** Trying to free non allocated block BT is: \n");
1729       for(idx = 0; idx < tmpBtSize; idx++)
1730       {
1731            printf("%s\n", strings[idx]);
1732       }
1733       printf("*****************************************\n");
1734       printf("Analysis from Array storing BT for freeing and allocation\n");
1735       cmAnalyseBtInfo(ptr, regionCb->region);
1736       SUnlock(&memDoubleFreeLock);
1737       return RFAILED;
1738    }
1739
1740    if((cmHashListDelete(&(memDoubleFree), (PTR)memNode)) != ROK)
1741    {
1742       SUnlock(&memDoubleFreeLock);
1743       return RFAILED;
1744    }
1745    SUnlock(&memDoubleFreeLock);
1746    SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,regionCb->region, 0, (Data *)memNode, sizeof(CmMemDoubleFree));
1747
1748    return ROK;
1749 }
1750
1751 /*
1752 *
1753 *       Fun:   cmInsertAllocPtrToList
1754 *
1755 *       Desc:  Insert a node with allocated PTR into hashlist. The memory
1756 *              for the node is allocated from the same region
1757 *
1758 *
1759 *       Ret:   ROK     - successful
1760 *              RFAILED - unsuccessful.
1761 *
1762 *       Notes: 
1763 *
1764 *       File:  cm_mem_wl.c
1765 *
1766 */
1767
1768 static S16  cmInsertAllocPtrToList
1769 (
1770 CmMmDynRegCb    *regionCb,    /* Pointer to a region */
1771 PTR              ptr
1772 )
1773 {
1774
1775    CmMemDoubleFree   *memNode;
1776
1777    SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,regionCb->region, 0, (Data **)&memNode, sizeof(CmMemDoubleFree));
1778    if(memNode == NULLP)
1779    {
1780        return RFAILED;
1781    }
1782
1783    memNode->memBlkPtr = ptr;
1784    SLock(&memDoubleFreeLock);
1785    if((cmHashListInsert(&(memDoubleFree), (PTR)memNode, (uint8_t*)&memNode->memBlkPtr,
1786        sizeof(PTR))) != ROK)
1787    {
1788        SUnlock(&memDoubleFreeLock);
1789        return RFAILED;
1790    }
1791    SUnlock(&memDoubleFreeLock);
1792
1793    return ROK;
1794 }
1795 #endif
1796
1797
1798 #ifndef SS_USE_ICC_MEMORY
1799 /*
1800 *
1801 *       Fun:   cmDynAllocWithLock
1802 *
1803 *       Desc:  Allocate a memory block for use by dynamic buffers
1804 *
1805 *
1806 *       Ret:   ROK     - successful
1807 *              RFAILED - unsuccessful.
1808 *
1809 *       Notes: 
1810 *
1811 *       File:  cm_mem_wl.c
1812 *
1813 */
1814 /* cm_mem_c_001.main_15 : Additions */
1815
1816 static S16  cmDynAllocWithLock
1817 (
1818 Void   *regionCb,    /* Pointer to a region */
1819 Size   *size,        /* size needs to be allocated */
1820 uint32_t     flags,       /* Flags used */
1821 Data  **ptr          /* Reference to pointer for which need to be allocate */
1822 )
1823 {
1824    S16 ret;
1825
1826    if((SLock(&dynAllocFreeLock)) != ROK)
1827    {
1828       printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1829       return RFAILED;
1830    }
1831
1832    ret =  cmDynAlloc (regionCb, size,flags,ptr);
1833
1834    if((SUnlock(&dynAllocFreeLock)) != ROK)
1835    {
1836       printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1837       return RFAILED;
1838    }
1839  
1840    return (ret);
1841 } /* end of cmDynAlloc */
1842
1843 /*
1844 *
1845 *       Fun:   cmDynAlloc
1846 *
1847 *       Desc:  Allocate a memory block for use by dynamic buffers
1848 *
1849 *
1850 *       Ret:   ROK     - successful
1851 *              RFAILED - unsuccessful.
1852 *
1853 *       Notes: 
1854 *
1855 *       File:  cm_mem_wl.c
1856 *
1857 */
1858 /* cm_mem_c_001.main_15 : Additions */
1859
1860 static S16  cmDynAlloc
1861 (
1862 Void   *regionCb,    /* Pointer to a region */
1863 Size   *size,        /* size needs to be allocated */
1864 uint32_t flags,       /* Flags used */
1865 Data  **ptr          /* Reference to pointer for which need to be allocate */
1866 )
1867 {
1868    CmMmDynRegCb        *regCb;
1869
1870
1871    regCb = (CmMmDynRegCb *)regionCb;
1872
1873 #ifdef SS_MEM_WL_DEBUG
1874       if((tmpRegTidMap[regCb->region] != (pthread_self())) )
1875       {
1876          **ptr = 10;
1877       }
1878 #endif
1879
1880 #if (ERRCLASS & ERRCLS_INT_PAR)
1881
1882    /* error check on parameters */
1883    if(regCb == NULLP)
1884    {
1885       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory region pointer is null");
1886       return RFAILED;
1887    }
1888    
1889    if(ptr == NULLP)
1890    {
1891       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory block pointer is null");
1892       return RFAILED;
1893    }
1894    
1895    if(size == NULLP)
1896    {
1897       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory size pointer null");
1898       return RFAILED;  
1899    }
1900    
1901    if(!(*size))
1902    {
1903       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory block size is 0");
1904       return RFAILED;
1905    }
1906 #endif
1907   
1908 #ifndef USE_PURE
1909
1910    /* 
1911     * Check if the requested size is less than or equal to the maximum block 
1912     * size in the bucket. 
1913     */
1914    
1915 #ifdef SS_MEM_WL_DEBUG
1916    if ( (*size + 4) <= regCb->bktMaxBlkSize)
1917 #else
1918    if ( (*size) <= regCb->bktMaxBlkSize)
1919 #endif
1920    {
1921       uint32_t                  idx;
1922       CmMmBlkSetElement   *dynMemElem;
1923       uint32_t                  bktIdx;
1924       CmMmDynBktCb        *bkt;
1925
1926       /* Get the map to the mapping table */
1927 #ifdef SS_MEM_WL_DEBUG
1928       idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
1929 #else
1930       idx = (((*size) - 1) >> regCb->bktQnPwr);
1931 #endif
1932
1933 #if (ERRCLASS & ERRCLS_DEBUG)
1934       if (regCb->mapTbl[idx].bktIdx == 0xFF)
1935       {
1936          DU_LOG("\nERROR  --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
1937          /* Some fatal error in the map table initialization. */
1938          return RFAILED;
1939       }
1940 #endif
1941      if (idx > 512)
1942      {
1943          DU_LOG("\nERROR  --> CM: cmDynAlloc(): idx value is greater than 512");
1944          return RFAILED;
1945      }
1946       /* Dequeue the memory block and return it to the user */
1947       bktIdx = regCb->mapTbl[idx].bktIdx;
1948       bkt = &(regCb->bktTbl[bktIdx]);
1949 #ifdef SS_MEM_WL_DEBUG
1950       if(bkt->size < (*size+4))
1951 #else
1952       if(bkt->size < (*size))
1953 #endif
1954       {
1955          idx++;
1956          bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
1957       }
1958
1959       dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
1960
1961       /* Check if the bucket index, if its not valid, return failure */
1962       if(dynMemElem == NULLP)
1963       {
1964 #ifndef ALIGN_64BIT
1965          DU_LOG("\nERROR  --> CM: cmDynAlloc(): Failed to get the buffer of size %ld\n", *size);
1966 #else
1967          printf("\nERROR  --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
1968 #endif
1969          return RFAILED;
1970       }
1971
1972 #ifdef SS_MEM_WL_DEBUG
1973       if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
1974       {
1975           uint32_t    *tmpDump;
1976           *tmpDump = 100;
1977       }
1978 #endif
1979       /* Get the bucket node from the index returned and allocate the memory */
1980       *ptr = dynMemElem->nextBktPtr;
1981       if (*ptr == NULLP)
1982       {
1983         DU_LOG("\nERROR  --> CM: cmDynAlloc(): nextBktPtr is null");
1984         return RFAILED;
1985       }
1986       dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
1987       dynMemElem->numFreeBlks--;
1988
1989 #ifdef SS_MEM_WL_DEBUG
1990       prvAllocPtr[regCb->region] = *ptr;
1991
1992       **ptr = (uint8_t) bktIdx;
1993       *(*ptr+1) = 0xde;
1994       *(*ptr+2) = 0xad;
1995       *(*ptr+3) = 0xbe;
1996       *ptr += sizeof (uint32_t);
1997
1998       if ((bktIdx == 0) && (!stopBtInfo))
1999       {
2000          CmBtInfo *btInfo;
2001          uint32_t      btIdx;
2002          btInfo  = &allocBtInfo[regCb->region];
2003          btIdx = btInfo->btInfoIdx;
2004          btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
2005          {
2006             btInfo->btInfo[btIdx].btSize  = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2007          }
2008          gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2009    
2010          btIdx++;
2011          btIdx &= (NUM_FREE_BUFFERS - 1); 
2012    
2013          btInfo->btInfo[btIdx].ptr = (PTR)0;
2014          btInfo->btInfo[btIdx].btSize = 0;
2015          memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2016          btInfo->btInfoIdx = btIdx;
2017       }
2018 #endif
2019
2020       return ROK;
2021    }
2022
2023    /* If the size is not matching, return failure to caller */
2024 #ifndef ALIGN_64BIT
2025    DU_LOG("\nERROR  --> CM : cmDynAlloc(): Failed to get the buffer of size %ld\n", *size);
2026 #else
2027    DU_LOG("\nERROR  --> CM: cmDynAlloc(): Failed to get the buffer of size %d\n", *size);
2028 #endif
2029    return RFAILED;
2030    
2031 #else /* use pure is on */
2032
2033 #ifdef SS_4GMX_LCORE
2034    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2035    memset(ptr, 0, *size);
2036 #else
2037 /*   *ptr = (Data*) malloc(*size); */
2038 #endif
2039    *ptr = (Data *)malloc(*size);
2040
2041    if ( (*ptr) == NULLP)
2042    {
2043        DU_LOG("\nERROR  --> CM : cmDynAlloc(): Data ptr is null");
2044        return RFAILED; 
2045    }
2046    /* avail_size -= *size; */
2047    return ROK;
2048 #endif /* USE_PURE */
2049
2050 } /* end of cmDynAlloc */
2051 #endif /* SS_USE_ICC_MEMORY */
2052
2053
2054 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2055
2056 int g_overused[5] = {0};
2057
2058 \f
2059 /*
2060 *
2061 *       Fun:   cmAlloc
2062 *
2063 *       Desc:  Allocate a memory block for the memory region.
2064 *
2065 *
2066 *       Ret:   ROK     - successful
2067 *              RFAILED - unsuccessful.
2068 *
2069 *       Notes: 
2070 *              The function allocates a memory block of size atleast equal to 
2071 *              the requested size. The size parameter will be updated with the 
2072 *              actual size of the memory block allocated for the request. The 
2073 *              CMM tries to allocate the memory block form the bucket pool. If
2074 *              there is no memory in the bucket the CMM allocates the memory 
2075 *              block form the heap pool. This function is always called by the
2076 *              System Service module.
2077 *    
2078 *              The caller of the function should try to use the out value of 
2079 *              the size while returning the memory block to the region. However 
2080 *              the current design of the memory manager does not enforce to pass
2081 *              the actual size of the memory block.  (Due to the SGetSBuf 
2082 *              semantics the layer will not able to pass the correct size of the
2083 *              memory block while calling SPutSBuf).
2084 *
2085 *
2086 *       File:  cm_mem_wl.c
2087 *
2088 */
2089 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2090
2091 /* cm_mem_c_001.main_15 : Additions */
2092 #ifdef T2K_MEM_LEAK_DBG
2093 static S16  cmAlloc
2094 (
2095  Void   *regionCb,
2096  Size   *size,
2097  uint32_t     flags,
2098  Data  **ptr ,
2099  char* file,
2100  uint32_t line
2101  )
2102 #else
2103 #ifdef SS_HISTOGRAM_SUPPORT
2104 #ifdef SSI_DEBUG_LEVEL1
2105 static S16  cmAlloc
2106 (
2107 Void   *regionCb,
2108 Size   *size,
2109 uint32_t     flags,
2110 Data  **ptr,
2111 uint32_t     memType,
2112 uint32_t     line,
2113 uint8_t     *fileName,
2114 uint8_t      entId,
2115 Bool    hstReg
2116 )
2117 #else
2118 static S16  cmAlloc
2119 (
2120 Void   *regionCb,
2121 Size   *size,
2122 uint32_t     flags,
2123 Data  **ptr,
2124 uint32_t     line,
2125 uint8_t     *fileName,
2126 uint8_t      entId,
2127 Bool    hstReg
2128 )
2129 #endif /* SSI_DEBUG_LEVEL1 */
2130
2131 #else
2132
2133 #ifdef SSI_DEBUG_LEVEL1
2134 static S16  cmAlloc
2135 (
2136 Void   *regionCb,
2137 Size   *size,
2138 uint32_t     flags,
2139 Data  **ptr,
2140 uint32_t     memType
2141 )
2142 #else
2143 static S16  cmAlloc
2144 (
2145 Void   *regionCb,
2146 Size   *size,
2147 uint32_t     flags,
2148 Data  **ptr 
2149 )
2150
2151 #endif
2152 #endif /* SSI_DEBUG_LEVEL1 */
2153 /* cm_mem_c_001.main_15: Additions */
2154 #endif /* SS_HISTOGRAM_SUPPORT */
2155
2156 {
2157 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2158 #ifndef USE_PURE
2159    uint16_t        idx;
2160    CmMmBkt   *bkt;
2161    uint16_t   bktIdx;
2162 #endif
2163    CmMmRegCb *regCb;
2164 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2165 #ifndef USE_PURE
2166    uint16_t        cnt;
2167 #endif
2168 /*   cm_mem_c_001.main_15 : Additions */
2169 #ifdef SS_MEM_LEAK_STS
2170    Size       reqSz;
2171 #endif /* SS_MEM_LEAK_STS */
2172 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2173 #ifdef SSI_DEBUG_LEVEL1
2174    CmMmBlkHdr *alocBlk;
2175 #endif /* SSI_DEBUG_LEVEL1 */
2176 /*   cm_mem_c_001.main_15 : Additions */
2177 #ifdef SS_HISTOGRAM_SUPPORT
2178         S8 hstGrmBuf[256];
2179 #endif /* SS_HISTOGRAM_SUPPORT */
2180
2181
2182 #ifndef USE_MEMCAL
2183    UNUSED(flags);
2184 #endif
2185 /*  cm_mem_c_001.main_15 : Additions */
2186 #ifdef SS_MEM_LEAK_STS 
2187    reqSz = *size;
2188 #endif /* SS_MEM_LEAK_STS */
2189
2190    regCb = (CmMmRegCb *)regionCb;
2191
2192 #if (ERRCLASS & ERRCLS_INT_PAR)
2193
2194    /* error check on parameters */
2195    if(regCb == NULL)
2196    {
2197       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory region pointer is null");
2198       return RFAILED;
2199    }
2200
2201    if(ptr == NULLP)
2202    {
2203       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory block pointer is null");
2204       return RFAILED;
2205    }
2206
2207    if(size == NULLP)
2208    {
2209       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory size pointer null");
2210       return RFAILED;
2211    }
2212
2213    if(!(*size))
2214    {
2215       DU_LOG("\nERROR  --> CM: cmDynAlloc(): Received memory block size is 0");
2216       return RFAILED;
2217    }
2218 #endif
2219   
2220 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2221 #ifdef SSI_DEBUG_LEVEL1
2222 #if (ERRCLASS & ERRCLS_INT_PAR)
2223       if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2224       {
2225          DU_LOG("\nERROR  --> CM : cmAlloc(): memType[%d] is invalid",memType);
2226          return RFAILED;
2227       }
2228 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2229 #endif /* SSI_DEBUG_LEVEL1 */
2230
2231 #ifndef USE_PURE
2232
2233    if (flags)
2234       num_times++;
2235
2236 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2237 #ifdef SSI_DEBUG_LEVEL1
2238    /* Update the hash list */
2239    if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2240    {
2241       /* display that, this entry could not be made in the hash list */
2242 #ifdef DEBUGP
2243       /* display an error message here */
2244 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2245 #ifdef ALIGN_64BIT          
2246       sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2247                            *size, regCb->region);
2248 #else                           
2249       sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2250                            *size, regCb->region);
2251 #endif                           
2252       SDisplay(0, dbgPrntBuf);
2253 #endif /* DEBUGP */
2254    }
2255 #endif /* SSI_DEBUG_LEVEL1 */
2256
2257    /* 
2258     * Check if the requested size is less than or equal to the maximum block 
2259     * size in the bucket. 
2260     */
2261    if ( *size <= regCb->bktMaxBlkSize)
2262    {
2263       /* Get the map to the mapping table */
2264       idx = ((*size - 1) >> regCb->bktQnPwr);
2265
2266 #if (ERRCLASS & ERRCLS_DEBUG)
2267       if (regCb->mapTbl[idx].bktIdx == 0xFF)
2268       { 
2269          /* Some fatal error in the map table initialization. */
2270          DU_LOG("\nERROR  --> CM : cmAlloc(): bktIdx is invalid");
2271          return RFAILED;
2272       }
2273 #endif
2274
2275       /* Dequeue the memory block and return it to the user */
2276       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2277
2278       cnt = 0;
2279       /* While loop is introduced to use the "break statement inside */
2280       while (cnt < 1)
2281       {
2282          /*
2283           * Check if the size request is not greater than the size available
2284           * in the bucket
2285           */
2286          if (*size > bkt->size)
2287          {
2288             /* Try to go to the next bucket if available */
2289             if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2290                (regCb->mapTbl[++idx].bktIdx != 0xFF))
2291             {
2292                bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2293             }
2294             else
2295             {
2296                /* This is the last bucket, try to allocate from heap */
2297                break;
2298             }
2299          }
2300
2301          /* Acquire the bucket lock */
2302          /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2303 #ifdef SS_WIN
2304          (Void) WTLock(&(bkt->bktLock));
2305 #else
2306          (Void) SLock(&(bkt->bktLock));
2307 #endif
2308
2309 #if (ERRCLASS & ERRCLS_DEBUG)
2310          regCb->mapTbl[idx].numReq++;
2311 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2312
2313 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2314 #ifdef SSI_DEBUG_LEVEL1
2315       /* increment the allocation attempt counter at bucket level */
2316       bkt->numAllocAttempts++;
2317
2318       /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2319          the allocation is always from (bkt->nextBlk) */
2320       if (bkt->nextBlk)
2321       {
2322          if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2323          {
2324                /* detected a trampled memory block in this bucket */
2325             #ifdef DEBUGP
2326                /* display an error message here */
2327 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2328 #ifdef ALIGN_64BIT          
2329                sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2330                                     (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2331 #else                                    
2332                sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2333                                     (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2334 #endif                                    
2335                SDisplay(0, dbgPrntBuf);
2336             #endif /* DEBUGP */
2337
2338                if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2339                {
2340                   /* Release the lock */
2341                   /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2342 #ifdef SS_WIN
2343                   (Void) WTUnlock(&(bkt->bktLock));
2344 #else
2345                   (Void) SUnlock(&(bkt->bktLock));
2346 #endif
2347                   /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2348                   return (RTRAMPLINGNOK);
2349                }
2350                else
2351                {
2352                   /* Release the lock */
2353                   /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2354 #ifdef SS_WIN
2355                   (Void) WTUnlock(&(bkt->bktLock));
2356 #else
2357                   (Void) SUnlock(&(bkt->bktLock));
2358 #endif
2359                   DU_LOG("\nERROR  --> CM : cmAlloc(): Sanity check returns failure");
2360                   /* return RFAILED */
2361                   return RFAILED;
2362                }
2363          }
2364       }
2365
2366       if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2367 #else
2368          if ((*ptr = bkt->next))
2369 #endif /* SSI_DEBUG_LEVEL1 */
2370          {
2371 /* cm_mem_c_001.main_12 - addition for header */
2372 #ifdef SSI_DEBUG_LEVEL1
2373       /* point to next block header */
2374          alocBlk = bkt->nextBlk;
2375          bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2376 #else
2377             bkt->next = *((CmMmEntry **)(bkt->next));
2378 #endif /* SSI_DEBUG_LEVEL1 */
2379
2380             /* 
2381              * Increment the statistics variable of number of memory block 
2382              * allocated 
2383              */
2384             bkt->numAlloc++;
2385             if (bkt->numAlloc > bkt->maxAlloc)
2386             {
2387                bkt->maxAlloc = bkt->numAlloc;
2388             }
2389             {
2390                if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2391                {
2392                   g_overused[bktIdx] = 1;
2393                   /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2394                }
2395             }
2396
2397 /* cm_mem_c_001.main_12 - addition for header manipulation */
2398 #ifdef SSI_DEBUG_LEVEL1
2399       /* update the size for which this memory block has been allocated */
2400       alocBlk->requestedSize = *size;
2401       /* update the memory block header */
2402       CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2403       if (memType == CMM_STATIC_MEM_FLAG)
2404       {
2405          CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2406          /* add it to the static memory allocated */
2407          bkt->staticMemUsed += bkt->size;
2408       }
2409       else
2410       {
2411          CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2412          /* add it to the dynamic memory allocated */
2413          bkt->dynamicMemUsed += bkt->size;
2414       }
2415 #endif /* SSI_DEBUG_LEVEL1 */
2416
2417             if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2418             {
2419                bkt->bktNoFitCnt++;
2420 #ifdef MEMCAL_DEBUG
2421 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2422 #ifdef ALIGN_64BIT          
2423                sprintf(prntBuf,
2424    "[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++);
2425 #else   
2426                sprintf(prntBuf,
2427    "[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++);
2428 #endif   
2429                SDisplay(0, prntBuf);
2430 #endif
2431             }
2432
2433 #ifdef MEMCAL_DEBUG
2434             if (flags)
2435             {
2436                sprintf(prntBuf,
2437     "SGetSBuf:%08lu:Size Bucket Id:%03d  Times:%05lu  Pointer: %8p\n",
2438                     *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2439                SDisplay(0, prntBuf);
2440             }
2441 #endif /* MEMCAL_DEBUG */
2442  /*  cm_mem_c_001.main_15 : Additions */
2443 #ifdef SS_HISTOGRAM_SUPPORT
2444             /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2445              * information into the hash list */
2446             if(hstReg)
2447             {
2448                if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2449                {
2450                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2451                                           SPrint(hstGrmBuf);
2452                }
2453             }/* End of if */
2454
2455 #endif /* SS_HISTOGRAM_SUPPORT */
2456         
2457             /* Update the size parameter */
2458             *size = bkt->size;
2459 #ifdef SS_MEM_LEAK_STS
2460         /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2461          cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2462                           regCb->mapTbl[idx].bktIdx);
2463 #endif /* SS_MEM_LEAK_STS */
2464
2465       /* cm_mem_c_008.104 - Addition for memory calculator tool */
2466
2467             /* Release the lock */
2468             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2469 #ifdef SS_WIN
2470             (Void) WTUnlock(&(bkt->bktLock));
2471 #else
2472             (Void) SUnlock(&(bkt->bktLock));
2473 #endif
2474
2475             return ROK;
2476          }
2477          else if (flags)
2478          {
2479             bkt->bktFailCnt++;
2480 #ifdef MEMCAL_DEBUG
2481 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2482 #ifdef ALIGN_64BIT          
2483  sprintf(prntBuf,
2484             "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2485 #else            
2486  sprintf(prntBuf,
2487             "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2488 #endif            
2489             SDisplay(0, prntBuf);
2490 #endif
2491          }
2492
2493 #if (ERRCLASS & ERRCLS_DEBUG)
2494          regCb->mapTbl[idx].numFailure++;
2495 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2496
2497          /* Release the lock */
2498          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2499 #ifdef SS_WIN
2500             (Void) WTUnlock(&(bkt->bktLock));
2501 #else
2502             (Void) SUnlock(&(bkt->bktLock));
2503 #endif
2504          cnt = cnt + 1;
2505       }
2506    }
2507    else
2508    {
2509       if (flags)
2510       {
2511          regCb->heapCb.heapAllocCnt++;
2512 #ifdef MEMCAL_DEBUG
2513 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2514 #ifdef ALIGN_64BIT          
2515          sprintf(prntBuf,
2516                  "[MEM_CAL_CNTC]  No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2517                  regCb->heapCb.heapAllocCnt);
2518 #else                 
2519          sprintf(prntBuf,
2520                  "[MEM_CAL_CNTC]  No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2521                  regCb->heapCb.heapAllocCnt);
2522 #endif                 
2523          SDisplay(0, prntBuf);
2524 #endif
2525       }
2526    }
2527
2528    /* Memory not available in the bucket pool */
2529    if (regCb->heapFlag &&  (*size < regCb->heapSize))
2530    {
2531 #ifdef MEMCAL_DEBUG
2532       if (flags) tryHeap = 1;
2533 #endif
2534       /* 
2535        * The heap memory block is available. Allocate the memory block from
2536        * heap pool.
2537        */ 
2538 /* cm_mem_c_001.main_15: Additions */
2539 #ifdef SS_HISTOGRAM_SUPPORT  
2540 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2541 #ifdef SSI_DEBUG_LEVEL1
2542        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2543 #else
2544        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2545 #endif /* SSI_DEBUG_LEVEL1 */
2546 #else
2547 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2548 #ifdef SSI_DEBUG_LEVEL1
2549        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2550 #else
2551        return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2552 #endif /* SSI_DEBUG_LEVEL1 */
2553 #endif /* SS_HISTOGRAM_SUPPORT */
2554    }
2555
2556    /* No memory available */
2557    DU_LOG("\nERROR  --> CM : cmAlloc(): No memory available in heap");
2558    return RFAILED;
2559 #else /* use pure is on */
2560 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
2561 #ifdef SS_4GMX_LCORE
2562    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2563    memset(ptr, 0, *size);
2564 #else
2565    *ptr = (Data*) malloc(*size);
2566 #endif
2567    if ( (*ptr) == NULLP)
2568    {
2569        DU_LOG("\nERROR  --> CM : cmAlloc(): ptr is null");
2570        return RFAILED;
2571    }
2572    avail_size -= *size;
2573    return ROK;
2574 #endif /* USE_PURE */
2575
2576 } /* end of cmAlloc */
2577
2578 #ifdef SS_MEM_WL_DEBUG
2579 /*
2580 *
2581 *       Fun:   cmInitDoubleFreeList
2582 *
2583 *       Desc:  Initialize the hashlist used for detecting double free
2584 *
2585 *       Ret:   ROK     - successful
2586 *              RFAILED - unsuccessful.
2587 *
2588 *       Notes:
2589 *
2590 *
2591 *       File:  cm_mem_wl.c
2592 *
2593 */
2594 S16  cmInitDoubleFreeList(void)
2595 {
2596     uint16_t offset;
2597     CmMemDoubleFree  memNode;
2598
2599     offset = (uint16_t)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2600
2601     if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2602         CM_HASH_KEYTYPE_UINT32_MOD, 0, 0)) != ROK);
2603     {
2604         return RFAILED;
2605     }
2606     SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2607
2608     return ROK;
2609 }
2610
2611 #ifdef SS_MEM_WL_DEBUG 
2612 /*
2613 *
2614 *       Fun:   cmInitBtInfo
2615 *
2616 *       Desc:  Return the Dynamic memory block for the memory region.
2617 *
2618 *
2619 *       Ret:   ROK     - successful
2620 *              RFAILED - unsuccessful.
2621 *
2622 *       Notes:
2623 *
2624 *
2625 *       File:  cm_mem_wl.c
2626 *
2627 */
2628 static S16  cmInitBtInfo()
2629 {
2630    regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2631    if (regBtInfo == NULLP)
2632    {
2633       return RFAILED;
2634    }
2635    allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2636    if(allocBtInfo == NULLP)
2637    {
2638       return RFAILED;
2639    }
2640
2641    return ROK;
2642 }
2643 #endif /* SS_MEM_WL_DEBUG */
2644 /*
2645 *
2646 *       Fun:   cmAnalyseBtInfo
2647 *
2648 *       Desc:  Return the Dynamic memory block for the memory region.
2649 *
2650 *
2651 *       Ret:   ROK     - successful
2652 *              RFAILED - unsuccessful.
2653 *
2654 *       Notes:
2655 *
2656 *
2657 *       File:  cm_mem_wl.c
2658 *
2659 */
2660 Void  cmAnalyseBtInfo
2661 (
2662 PTR   ptr,       /* Memory block needs to be freed */
2663 uint32_t   idx
2664 )
2665 {
2666    uint32_t  tmpCnt;
2667    uint32_t  btIdx;
2668    CmBtInfo  *btInfo;
2669    uint8_t    regIdx;
2670
2671 /*   for(regIdx = 0; regIdx < 8; regIdx++)
2672    { */
2673    idx = 2;
2674       btInfo = &allocBtInfo[idx];
2675       btIdx = btInfo->btInfoIdx;
2676    
2677       for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)  
2678       {
2679 /*         if ((btInfo->btInfo[btIdx].ptr >= ptr) &&   
2680              (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr)    */
2681          if(btInfo->btInfo[btIdx].btSize != 0)
2682          {
2683            uint32_t i;
2684            char **strings;
2685            strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2686            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);
2687            for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2688            {
2689               printf("%s\n", strings[i]); 
2690            }
2691            printf("*******************************************************\n");
2692            
2693            free(strings);
2694          }
2695    
2696          btIdx--; 
2697          if (btIdx == 0)
2698          {
2699             btIdx = NUM_FREE_BUFFERS - 1;
2700          }
2701       }
2702 /*    } */
2703
2704    return;
2705 }
2706 #endif
2707
2708 #ifndef SS_USE_ICC_MEMORY
2709 /*
2710 *
2711 *       Fun:   cmDynFreeWithLock
2712 *
2713 *       Desc:  Return the Dynamic memory block for the memory region.
2714 *
2715 *
2716 *       Ret:   ROK     - successful
2717 *              RFAILED - unsuccessful.
2718 *
2719 *       Notes:
2720 *
2721 *
2722 *       File:  cm_mem_wl.c
2723 *
2724 */
2725 static S16  cmDynFreeWithLock
2726 (
2727 Void   *regionCb,   /* Pointer to region cb */
2728 Data   *ptr,        /* Memory block needs to be freed */
2729 Size    size        /* Size of the block */
2730 )
2731 {
2732    S16 ret;
2733    
2734    if((SLock(&dynAllocFreeLock)) != ROK)
2735    {
2736       printf("dynAllocWithLock: Failed to get the DYN lock\n");
2737       return RFAILED;
2738    }
2739
2740    ret = cmDynFree(regionCb, ptr,size);
2741
2742    if((SUnlock(&dynAllocFreeLock)) != ROK)
2743    {
2744       printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2745       return RFAILED;
2746    }
2747
2748    return (ret);
2749
2750 } /* end of cmDynFree */
2751
2752 /*
2753 *
2754 *       Fun:   cmDynFree
2755 *
2756 *       Desc:  Return the Dynamic memory block for the memory region.
2757 *
2758 *
2759 *       Ret:   ROK     - successful
2760 *              RFAILED - unsuccessful.
2761 *
2762 *       Notes:
2763 *
2764 *
2765 *       File:  cm_mem_wl.c
2766 *
2767 */
2768 static S16  cmDynFree
2769 (
2770 Void   *regionCb,   /* Pointer to region cb */
2771 Data   *ptr,        /* Memory block needs to be freed */
2772 Size    size        /* Size of the block */
2773 )
2774 {
2775    CmMmDynRegCb       *regCb;
2776 #ifndef USE_PURE
2777    uint32_t                 idx;
2778    uint32_t                 bktIdx;
2779    CmMmDynBktCb       *bkt = NULLP;
2780    CmMmBlkSetElement  *dynMemElem;
2781 #endif
2782 #ifdef SS_MEM_WL_DEBUG
2783    uint8_t                 tmpBktIdx;
2784    uint8_t                 tmpVal;
2785 #endif
2786
2787
2788    regCb = (CmMmDynRegCb *)regionCb;
2789 #ifdef SS_MEM_WL_DEBUG
2790    if((tmpRegTidMap[regCb->region] != (pthread_self())))
2791    {
2792       bkt->size = 10;
2793    }
2794 #endif
2795
2796 #ifndef USE_PURE
2797 #if (ERRCLASS & ERRCLS_INT_PAR)
2798    /* error check on parameters */
2799    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2800    {
2801       DU_LOG("\nERROR --> CM : cmDynFree(): Received memory region[%p] or size[%p] or block[%p] is invalid",regCb,size,ptr);
2802       return RFAILED;
2803    }
2804
2805    /* Check if the memory block is from the memory region */
2806    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2807                ((CmMmRegCb *)regCb)->regInfo.size) 
2808    {
2809       DU_LOG("\nERROR --> CM : cmDynFree(): Memory block[%p] not from region[%d]", ptr, ((CmMmRegCb *)regCb)->region);
2810       return RFAILED;
2811    }
2812         /* cm_mem_c_001.main_20 Addition */
2813         if (ptr < regCb->regInfo.start)
2814         {
2815            DU_LOG("\nERROR --> CM : cmDynFree(): Memory block[%p] not from region[%d]", ptr, ((CmMmRegCb *)regCb)->region);
2816       return RFAILED;
2817         }
2818
2819 #endif
2820
2821 #ifdef SS_MEM_WL_DEBUG
2822    ptr -= sizeof (uint32_t);
2823    size += 4;
2824 #endif
2825    /* The memory block was allocated from the bucket pool */
2826
2827    /* Get the map to the mapping table */
2828    idx = ((size - 1) >> regCb->bktQnPwr);
2829
2830 #if (ERRCLASS & ERRCLS_DEBUG)
2831    if (regCb->mapTbl[idx].bktIdx == 0xFF)
2832    { 
2833       DU_LOG("\nERROR --> CM : cmDynFree(): bktIdx is not valid");
2834       /* Some fatal error in the map table initialization. */
2835       return RFAILED;
2836    }
2837 #endif
2838
2839    /* Enqueue the memory block and return it to the user */
2840    bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2841
2842    /*
2843     * Check if the size is not greater than the size available
2844     * in the bucket. If so, then the buffer must have been allocated
2845     * from next bucket.  We don't need to check the validity of the
2846     * next bucket, otherwise buffer must have been allocated from heap
2847     * pool.
2848     */
2849 #ifdef SS_MEM_WL_DEBUG
2850    if (size > bkt->size)
2851    {
2852       DU_LOG("Size = %d bucket size = %d\n", size, bkt->size);
2853       exit(-1);
2854       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
2855    }
2856    if(size > bkt->size)
2857    {
2858       DU_LOG("2nd time Size = %d bucket size = %d\n", size, bkt->size);
2859       exit(-1);
2860       uint8_t *tmpptr = NULLP;
2861       printf("Bucket Size wrong \n");
2862       *tmpptr =  10;
2863    }
2864 #endif
2865
2866    dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
2867
2868    /* Check if the bucket index, if its not valid, return failure */
2869    if(dynMemElem == NULLP)
2870    {
2871       DU_LOG("\nERROR --> CM : cmDynFree(): dynMemElem is null");
2872       return RFAILED;
2873    }
2874
2875 #ifdef SS_MEM_WL_DEBUG
2876    tmpBktIdx = (uint8_t)*ptr;
2877    tmpVal  =  (uint8_t)*(ptr+1);
2878
2879    if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
2880    {
2881       uint8_t *tmpptr = NULLP;
2882       printf("bktIdx wrong \n");
2883       *tmpptr =  10;
2884    }
2885
2886    if ((bktIdx == 0) && (!stopBtInfo))
2887    {
2888       CmBtInfo *btInfo;
2889       uint32_t      btIdx;
2890       btInfo  = &regBtInfo[regCb->region];
2891       btIdx = btInfo->btInfoIdx;
2892       btInfo->btInfo[btIdx].ptr = (PTR) ptr;
2893       {
2894          btInfo->btInfo[btIdx].btSize  = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2895       }
2896       gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2897
2898       btIdx++;
2899       btIdx &= (NUM_FREE_BUFFERS - 1); 
2900
2901       btInfo->btInfo[btIdx].ptr = (PTR)0;
2902       btInfo->btInfo[btIdx].btSize = 0;
2903       memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2904       btInfo->btInfoIdx = btIdx;
2905    }
2906    
2907    if(prvAllocPtr[regCb->region] == ptr)
2908    {
2909       prvAllocPtr[regCb->region] = NULLP;
2910    }
2911
2912    memset(ptr, (regCb->region+1), bkt->size); 
2913 #endif
2914    /* Get the bucket node from the index returned and allocate the memory */
2915    *((CmMmEntry **)ptr) =  dynMemElem->nextBktPtr;
2916    dynMemElem->nextBktPtr = ptr;
2917    dynMemElem->numFreeBlks++;
2918
2919    return ROK;
2920
2921 #else /* use pure is on */
2922 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
2923 #ifdef SS_4GMX_LCORE
2924    (Void)MxHeapFree(SsiHeap, ptr);
2925 #else
2926    /* (Void)free(ptr); */
2927 #endif
2928 /*   avail_size += size; */
2929    free(ptr);
2930
2931    return ROK;
2932 #endif /* USE_PURE */
2933
2934
2935 } /* end of cmDynFree */
2936 #endif /* SS_USE_ICC_MEMORY */
2937
2938 \f
2939
2940 /*
2941 *
2942 *       Fun:   cmFree
2943 *
2944 *       Desc:  Return the memory block for the memory region.
2945 *
2946 *
2947 *       Ret:   ROK     - successful
2948 *              RFAILED - unsuccessful.
2949 *
2950 *       Notes: The user calls this function to return the previously allocated 
2951 *              memory block to the memory region. The memory manager does not 
2952 *              check the validity of the state of the memory block(like whether 
2953 *              it was allocated earlier). The caller must be sure that, the 
2954 *              address specified in the parameter 'ptr' is valid and was 
2955 *              allocated previously from same region.
2956 *
2957 *
2958 *       File:  cm_mem_wl.c
2959 *
2960 */
2961
2962 /*  cm_mem_c_001.main_15 : Additions */
2963 #ifdef T2K_MEM_LEAK_DBG
2964 static S16  cmFree
2965 (
2966  Void   *regionCb,
2967  Data   *ptr,
2968  Size    size,
2969  char* file,
2970  uint32_t line
2971 )
2972 #else
2973 #ifdef SS_HISTOGRAM_SUPPORT
2974 static S16  cmFree
2975 (
2976 Void   *regionCb,
2977 Data   *ptr,
2978 Size    size,
2979 uint32_t     line,
2980 uint8_t     *fileName,
2981 uint8_t      entId,
2982 Bool    hstReg
2983 )
2984 #else
2985 static S16  cmFree
2986 (
2987 Void   *regionCb,
2988 Data   *ptr, 
2989 Size    size
2990 )
2991 #endif
2992 /*  cm_mem_c_001.main_15 : Additions */
2993 #endif /* SS_HISTOGRAM_SUPPORT */ 
2994
2995 {
2996 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2997 #ifndef USE_PURE
2998    uint16_t        idx;
2999    CmMmBkt   *bkt;
3000    uint16_t   bktIdx;
3001 #endif
3002    CmMmRegCb *regCb;
3003 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
3004 #ifdef SSI_DEBUG_LEVEL1
3005    CmMmBlkHdr *ptrHdr;
3006 #endif /* SSI_DEBUG_LEVEL1 */
3007 /*  cm_mem_c_001.main_15 : Additions */
3008 #ifdef SS_HISTOGRAM_SUPPORT 
3009         S8 hstGrmBuf[256];
3010 #endif /* SS_HISTOGRAM_SUPPORT */
3011
3012
3013    regCb = (CmMmRegCb *)regionCb;
3014
3015 #ifndef USE_PURE
3016 #if (ERRCLASS & ERRCLS_INT_PAR)
3017
3018    /* error check on parameters */
3019    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3020    {
3021       DU_LOG("\nERROR --> CM : cmFree(): Received memory region[%p] or size[%p] or block[%p] is invalid",regCb,size,ptr);
3022       return RFAILED;
3023    }
3024
3025    /* Check if the memory block is from the memory region */
3026    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3027                ((CmMmRegCb *)regCb)->regInfo.size) 
3028    {
3029       DU_LOG("\nERROR --> CM : cmFree(): Memory block[%p] not from region[%d]",ptr,regCb.region);
3030       return RFAILED;
3031    }
3032         /* cm_mem_c_001.main_20 Addition */
3033         if (ptr < regCb->regInfo.start)
3034         {
3035      DU_LOG("\nERROR --> CM : cmFree(): Memory block[%p] not from region[%d]",ptr,regCb.region);
3036           return RFAILED;
3037         }
3038
3039 #endif
3040
3041    /* 
3042     * Check if the memory block was allocated from the bucket pool. 
3043     */
3044    if(ptr < regCb->regInfo.start)
3045    {
3046       Buffer *tmpBuffer = NULLP;
3047       tmpBuffer->b_cont = NULLP;
3048    }
3049
3050    if (ptr < (regCb->regInfo.start + regCb->bktSize))
3051    {
3052       /* The memory block was allocated from the bucket pool */
3053
3054       /* Get the map to the mapping table */
3055       idx = ((size - 1) >> regCb->bktQnPwr);
3056
3057 #if (ERRCLASS & ERRCLS_DEBUG)
3058       if (regCb->mapTbl[idx].bktIdx == 0xFF)
3059       { 
3060          /* Some fatal error in the map table initialization. */
3061          DU_LOG("\nERROR --> CM : cmFree(): Invalid bktIdx");
3062          return RFAILED;
3063       }
3064 #endif
3065
3066       /* Enqueue the memory block and return it to the user */
3067       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3068
3069       /*
3070        * Check if the size is not greater than the size available
3071        * in the bucket. If so, then the buffer must have been allocated
3072        * from next bucket.  We don't need to check the validity of the
3073        * next bucket, otherwise buffer must have been allocated from heap
3074        * pool.
3075        */
3076        if (size > bkt->size)
3077        {
3078           bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3079        }
3080
3081       /* Acquire the bucket lock */
3082       /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3083 #ifdef SS_WIN
3084       (Void) WTLock(&(bkt->bktLock));
3085 #else
3086       (Void) SLock(&(bkt->bktLock));
3087 #endif
3088
3089 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3090 #ifdef SSI_DEBUG_LEVEL1
3091       /* increment the dealloc attempt counter at bucket level */
3092       bkt->numDeallocAttempts++;
3093
3094       /* Check the memFlags to see whether this block was allocated */
3095       ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3096
3097       /* validate the block to be freed for trampling */
3098       if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3099       {
3100           /* Handle error case of Memory trampling */
3101       #ifdef  DEBUGP
3102           /* display an error message here */
3103 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3104 #ifdef ALIGN_64BIT          
3105           sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3106                                ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3107 #else                               
3108           sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3109                                ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3110 #endif                               
3111           SDisplay(0, dbgPrntBuf);
3112       #endif /* DEBUGP */
3113            /* 
3114            * if sanity check returns RTRAMPLINGOK then there is nothing to do
3115            * as the memory blk is already invalidated in cmMmBktSanityChk
3116            */
3117            if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3118            {
3119               bkt->numAlloc--;
3120
3121               /* Release the lock */
3122               /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3123 #ifdef SS_WIN
3124               (Void) WTUnlock(&(bkt->bktLock));
3125 #else
3126               (Void) SUnlock(&(bkt->bktLock));
3127 #endif
3128
3129               return ROK;
3130            }
3131            else
3132            {
3133                /* 
3134                * this is the case where in the entire bucket has been made unusable
3135                * Release the lock 
3136                */
3137                /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3138 #ifdef SS_WIN
3139                (Void) WTUnlock(&(bkt->bktLock));
3140 #else
3141                (Void) SUnlock(&(bkt->bktLock));
3142 #endif
3143
3144                 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3145                 DU_LOG("\nERROR  --> CM : cmFree(): Sanity check returns failure");    
3146                 return (RTRAMPLINGNOK);
3147            }
3148       }
3149
3150       /* reset the size */
3151       ptrHdr->requestedSize = 0;
3152       /* check if the block to be freed is already having the state as FREE */
3153       if (CMM_IS_FREE(ptrHdr->memFlags))
3154       {
3155             /* Handle double deallocation error case */
3156       #ifdef DEBUGP
3157             /* display an error message here */
3158 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3159 #ifdef ALIGN_64BIT          
3160          sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3161                               ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3162 #else                              
3163          sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3164                               ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3165 #endif                              
3166          SDisplay(0, dbgPrntBuf);
3167       #endif /* DEBUGP */
3168
3169           /* Release the lock */
3170           /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3171 #ifdef SS_WIN
3172           (Void) WTUnlock(&(bkt->bktLock));
3173 #else
3174           (Void) SUnlock(&(bkt->bktLock));
3175 #endif
3176
3177           /* handle RDBLFREE in SFree/SPutSBuf */
3178           DU_LOG("\nERROR  --> CM : cmFree(): Memory block is already freed");    
3179           return (RDBLFREE);
3180       }
3181       if (CMM_IS_STATIC(ptrHdr->memFlags))
3182       {
3183          CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3184          CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3185          /* deduct it from the static memory count */
3186          bkt->staticMemUsed -= bkt->size;
3187       }
3188       else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3189       {
3190          CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3191          CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3192          /* deduct it from the dynamic memory count */
3193          bkt->dynamicMemUsed -= bkt->size;
3194       }
3195       else
3196       {
3197          /* This is a case similar to trampled memory */
3198       #ifdef  DEBUGP
3199 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3200 #ifdef ALIGN_64BIT          
3201          sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3202 #else         
3203          sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3204 #endif         
3205          SDisplay(0, dbgPrntBuf);
3206       #endif /* DEBUGP */
3207          if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3208          {
3209             /* do not add to the free list */
3210             bkt->numAlloc--;
3211
3212             /* Release the lock */
3213             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3214 #ifdef SS_WIN
3215             (Void) WTUnlock(&(bkt->bktLock));
3216 #else
3217             (Void) SUnlock(&(bkt->bktLock));
3218 #endif
3219             return ROK;
3220          }
3221          else
3222          {
3223             /* 
3224             * this is the case where in the entire bucket has been made unusable
3225             * Release the lock 
3226             */
3227             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3228 #ifdef SS_WIN
3229             (Void) WTUnlock(&(bkt->bktLock));
3230 #else
3231             (Void) SUnlock(&(bkt->bktLock));
3232 #endif
3233
3234             /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3235             DU_LOG("\nERROR  --> CM : cmFree(): Sanity check returns failure");    
3236             return (RTRAMPLINGNOK);
3237          }
3238       }
3239
3240       /* Return the block to memory */
3241       ptrHdr->nextBlk = bkt->nextBlk;
3242       bkt->nextBlk = ptrHdr;
3243 #else
3244       /* MS_REMOVE */
3245       *((CmMmEntry **)ptr) =  bkt->next; 
3246       bkt->next = (CmMmEntry *)ptr;
3247 #endif /* SSI_DEBUG_LEVEL1 */
3248
3249       /* 
3250       * Decrement the statistics variable of number of memory block 
3251       * allocated 
3252       */
3253       if(bkt->numAlloc)
3254       {
3255          bkt->numAlloc--;
3256       }
3257       {
3258         if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3259         {
3260            g_overused[bktIdx] = 0;
3261            /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3262         }
3263       }
3264 /*  cm_mem_c_001.main_15 : Additions */
3265 #ifdef SS_HISTOGRAM_SUPPORT
3266         /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3267          * information into the hash list */
3268         if(hstReg)
3269         {
3270             if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3271             {
3272                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3273                                           SPrint(hstGrmBuf);
3274             }
3275          }/* End of if */
3276 #endif /* SS_HISTOGRAM_SUPPORT */
3277
3278 #ifdef SS_MEM_LEAK_STS
3279       /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3280       cmRlsAllocBlk((PTR)ptr);
3281 #endif /* SS_MEM_LEAK_STS */
3282
3283       /* Release the lock */
3284       /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3285 #ifdef SS_WIN
3286       (Void) WTUnlock(&(bkt->bktLock));
3287 #else
3288       (Void) SUnlock(&(bkt->bktLock));
3289 #endif
3290
3291       return ROK;
3292    }
3293
3294    /* The memory block was allocated from the heap pool */ 
3295 /*  cm_mem_c_001.main_15 : Additions */
3296 #ifdef SS_HISTOGRAM_SUPPORT 
3297    return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3298 #else
3299    return (cmHeapFree (&(regCb->heapCb), ptr, size));
3300 #endif /* SS_HISTOGRAM_SUPPORT */
3301 #else /* use pure is on */
3302 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3303 #ifdef SS_4GMX_LCORE
3304    (Void)MxHeapFree(SsiHeap, ptr);
3305 #else
3306    (Void)free(ptr);
3307 #endif
3308    avail_size += size;
3309    return ROK;
3310 #endif /* USE_PURE */
3311
3312
3313 } /* end of cmFree */
3314
3315 \f
3316 /*
3317 *
3318 *       Fun:   cmAllocWL
3319 *
3320 *       Desc: alloc without lock 
3321 *
3322 *
3323 *       Ret:   ROK     - successful
3324 *              RFAILED - unsuccessful.
3325 *
3326 *
3327 *       File:  cm_mem_wl.c
3328 *
3329 */
3330 /*cm_mem_c_001.main_21-added new function*/
3331 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3332 #ifdef T2K_MEM_LEAK_DBG
3333 static S16  cmAllocWL
3334 (
3335 Void   *regionCb,
3336 Size   *size,
3337 uint32_t     flags,
3338 Data  **ptr ,
3339 char* file,
3340 uint32_t line
3341 )
3342 #else
3343 static S16  cmAllocWL
3344 (
3345 Void   *regionCb,
3346 Size   *size,
3347 uint32_t     flags,
3348 Data  **ptr 
3349 )
3350 #endif
3351 {
3352 #ifndef USE_PURE
3353    uint16_t        idx;
3354    CmMmBkt   *bkt = NULLP;
3355 #endif
3356    CmMmRegCb *regCb;
3357    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3358
3359
3360    /*cm_mem_c_001.main_23 Removed support of  USE_MEMCAL and MEMCAL_DEBUG support for  SS_FAP*/
3361
3362    regCb = (CmMmRegCb *)regionCb;
3363
3364 #ifdef SS_MEM_WL_DEBUG
3365    if((tmpRegTidMap[regCb->region] != (pthread_self())))
3366    {
3367       bkt->size = 10;
3368    }
3369 #endif
3370
3371 #if (ERRCLASS & ERRCLS_INT_PAR)
3372
3373    /* error check on parameters */
3374    if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3375    {
3376       return RFAILED;
3377    }
3378 #endif
3379   
3380    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3381
3382 #ifndef USE_PURE 
3383
3384    /* 
3385     * Check if the requested size is less than or equal to the maximum block 
3386     * size in the bucket. 
3387     */
3388 #ifdef MSPD_T2K_TRACK_BUG
3389    *size += 4;
3390 #endif
3391    /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3392    if ( *size <= regCb->bktMaxBlkSize)
3393    {
3394       /* Get the map to the mapping table */
3395       idx = ((*size - 1) >> regCb->bktQnPwr);
3396
3397       /* Dequeue the memory block and return it to the user */
3398       bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3399
3400       {
3401          /*
3402           * Check if the size request is not greater than the size available
3403           * in the bucket
3404           */
3405          /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3406          if ((*size <= bkt->size)&&(*ptr = bkt->next))
3407          {
3408             /* Try to go to the next bucket if available */
3409             bkt->next = *((CmMmEntry **)(bkt->next));
3410
3411             /* 
3412              * Increment the statistics variable of number of memory block 
3413              * allocated 
3414              */
3415             bkt->numAlloc++;
3416             if (bkt->numAlloc > bkt->maxAlloc)
3417             {
3418                bkt->maxAlloc = bkt->numAlloc;
3419             }
3420
3421 #ifdef MSPD_T2K_TRACK_BUG
3422             *(*ptr + 0) = 0xDE;
3423             *(*ptr + 1) = 0xAD;
3424             *(*ptr + 2) = 0xBE;
3425             *(*ptr + 3) = 0xEF;
3426
3427             (*ptr) += 4;
3428 #endif
3429
3430             /* Update the size parameter */
3431             *size = bkt->size;
3432
3433             return ROK;
3434          }
3435       }
3436    }
3437
3438    /* Memory not available in the bucket pool */
3439    if (regCb->heapFlag &&  (*size < regCb->heapSize))
3440    {
3441       /*cm_mem_c_001.main_23 Removed support of  and MEMCAL_DEBUG support for  SS_FAP*/
3442       /* 
3443        * The heap memory block is available. Allocate the memory block from
3444        * heap pool.
3445        */ 
3446        /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3447        return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3448    }
3449
3450    /* No memory available */
3451    return RFAILED;
3452 #else /* use pure is on */
3453 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3454 #ifdef SS_4GMX_LCORE
3455    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3456    memset(ptr, 0, *size);
3457 #else
3458 /*   *ptr = (Data*) malloc(*size); */
3459 #endif
3460    *ptr = (Data *)malloc(*size);
3461
3462    if ( (*ptr) == NULLP)
3463        return RFAILED;
3464 /*   avail_size -= *size; */
3465    return ROK;
3466 #endif /* USE_PURE */
3467
3468 } /* end of cmAllocWL */
3469
3470 \f
3471 /*
3472 *
3473 *       Fun:   cmfree
3474 *
3475 *       Desc: free without lock 
3476 *
3477 *
3478 *       Ret:   ROK     - successful
3479 *              RFAILED - unsuccessful.
3480 *
3481 *
3482 *       File:  cm_mem_wl.c
3483 *
3484 */
3485
3486 #ifdef T2K_MEM_LEAK_DBG
3487 static S16  cmFreeWL
3488 (
3489 Void   *regionCb,
3490 Data   *ptr, 
3491 Size    size,
3492 char* file,
3493 uint32_t line
3494 )
3495 #else
3496 static S16  cmFreeWL
3497 (
3498 Void   *regionCb,
3499 Data   *ptr, 
3500 Size    size
3501 )
3502 #endif
3503 {
3504 #ifndef USE_PURE
3505    uint16_t        idx;
3506    CmMmBkt   *bkt = NULLP;
3507 #endif
3508    CmMmRegCb *regCb;
3509    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3510
3511
3512    regCb = (CmMmRegCb *)regionCb;
3513
3514 #ifdef SS_MEM_WL_DEBUG
3515    if(tmpRegTidMap[regCb->region] != (pthread_self()))
3516    {
3517       bkt->size = 10;
3518    }
3519 #endif
3520
3521 #ifndef USE_PURE
3522 #if (ERRCLASS & ERRCLS_INT_PAR)
3523
3524    /* error check on parameters */
3525    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3526    {
3527       return RFAILED;
3528    }
3529
3530    /* Check if the memory block is from the memory region */
3531    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3532                ((CmMmRegCb *)regCb)->regInfo.size) 
3533    {
3534       return RFAILED;
3535    }
3536
3537 #endif
3538
3539    /* 
3540     * Check if the memory block was allocated from the bucket pool. 
3541     */
3542 #ifdef MSPD_T2K_TRACK_BUG
3543    size += 4;
3544 #endif
3545
3546    if (ptr < (regCb->regInfo.start + regCb->bktSize))
3547    {
3548       /* The memory block was allocated from the bucket pool */
3549
3550       /* Get the map to the mapping table */
3551       idx = ((size - 1) >> regCb->bktQnPwr);
3552
3553 #if (ERRCLASS & ERRCLS_DEBUG)
3554       if (regCb->mapTbl[idx].bktIdx == 0xFF)
3555       { 
3556          /* Some fatal error in the map table initialization. */
3557          return RFAILED;
3558       }
3559 #endif
3560
3561       /* Enqueue the memory block and return it to the user */
3562       bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3563
3564 #ifdef MSPD_T2K_TRACK_BUG
3565       ptr -= 4;
3566       if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3567       {
3568           char *abc = NULLP;
3569           *abc = 100;
3570       }
3571 #endif
3572       /*
3573        * Check if the size is not greater than the size available
3574        * in the bucket. If so, then the buffer must have been allocated
3575        * from next bucket.  We don't need to check the validity of the
3576        * next bucket, otherwise buffer must have been allocated from heap
3577        * pool.
3578        */
3579        if (size > bkt->size)
3580        {
3581           bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3582        }
3583
3584       /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3585       *((CmMmEntry **)ptr) =  bkt->next; 
3586       bkt->next = (CmMmEntry *)ptr;
3587
3588       /* 
3589       * Decrement the statistics variable of number of memory block 
3590       * allocated 
3591       */
3592       bkt->numAlloc--;
3593
3594       return ROK;
3595    }
3596
3597    /* The memory block was allocated from the heap pool */ 
3598    return (cmHeapFree (&(regCb->heapCb), ptr, size));
3599 #else /* use pure is on */
3600 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3601 #ifdef SS_4GMX_LCORE
3602    (Void)MxHeapFree(SsiHeap, ptr);
3603 #else
3604 /*   (Void)free(ptr); */
3605 #endif
3606 /*   avail_size += size; */
3607    free(ptr);
3608
3609    return ROK;
3610 #endif /* USE_PURE */
3611
3612
3613 } /* end of cmFreeWL */
3614
3615 \f
3616 /*
3617 *
3618 *       Fun:   cmCtl
3619 *
3620 *       Desc:  Control request function. 
3621 *
3622 *
3623 *       Ret:   ROK     - successful
3624 *              RFAILED - unsuccessful.
3625 *
3626 *       Notes: The current semantics of the control function is defined for two 
3627 *              types of events: virtual address to physical address translation 
3628 *              and memory resource check. 
3629 *
3630 *              The physical address translation is valid only for the memory 
3631 *              region physically contiguous and non pagable.
3632 *
3633 *
3634 *
3635 *       File:  cm_mem_wl.c
3636 *
3637 */
3638
3639 static S16  cmCtl
3640 (
3641 Void    *regionCb,
3642 Event    event, 
3643 SMemCtl *memCtl
3644 )
3645 {
3646    CmMmRegCb *regCb;
3647
3648
3649    regCb = (CmMmRegCb *)regionCb;
3650
3651 #if (ERRCLASS & ERRCLS_INT_PAR)
3652
3653    /* error check on parameters */
3654    if ((regCb == NULLP) || (memCtl == NULLP))
3655    {
3656       return RFAILED;
3657    }
3658
3659 #endif
3660
3661    switch (event)
3662    {
3663       case SS_MEM_V_TO_P:
3664       {
3665          Size       offset;
3666   
3667 #if (ERRCLASS & ERRCLS_INT_PAR)
3668          if ((memCtl->u.vtop.vaddr == NULLP) || 
3669              (memCtl->u.vtop.paddr == NULLP))
3670          {
3671             return RFAILED;
3672          }
3673 #endif
3674    
3675          /* Check if the virtual to physical address translation is valid */
3676          if (regCb->chFlag & CMM_REG_PHY_VALID) 
3677          {
3678             offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3679             *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3680    
3681             return ROK;
3682          }
3683          break;
3684       }
3685
3686       case SS_MEM_CHK_RES:
3687       {
3688
3689 #if (ERRCLASS & ERRCLS_INT_PAR)
3690          if (!(memCtl->u.chkres.size) || 
3691             (memCtl->u.chkres.status == NULLP))
3692          {
3693             return RFAILED;
3694          }
3695 #endif
3696 #ifndef USE_PURE
3697          /* Check if the Bucket pool is configured */
3698          if (regCb->bktSize)
3699          {
3700             uint16_t        idx;
3701             CmMmBkt   *bkt;
3702             uint32_t        avlSize, totSize;
3703             /* 
3704              * The bucket pool is configured. The status value returned
3705              * does reflect on the memory availabilty in the bucket pool. 
3706              * The value does not consider the available memory in the
3707              * heap pool. 
3708              */
3709              idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3710              bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3711              avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3712              avlSize += regCb->heapCb.avlSize;
3713              totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3714              *(memCtl->u.chkres.status) = (avlSize/(totSize/10)); 
3715          }
3716          else
3717          {
3718             /* Bucket pool not configured */
3719
3720             /* 
3721              * Find the percentage memory available in the heap pool. The value
3722              * does not consider the fragmentation of the heap pool.
3723              */
3724             *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3725                                           (regCb->heapSize/10)); 
3726          }
3727
3728          return ROK;
3729 #else /* use pure is on */
3730             *(memCtl->u.chkres.status) = ((avail_size) /
3731                                           (regCb->regInfo.size/10));
3732          return ROK;
3733 #endif /* USE_PURE */
3734
3735       }
3736
3737       default:
3738       {
3739          /* No other event is supported currently */
3740          return RFAILED;
3741       }
3742    }
3743
3744    /* shouldn't reach here */
3745    return RFAILED;
3746 } /* end of cmCtl */
3747
3748 \f
3749 /*
3750 *
3751 *       Fun:   cmMmHeapInit
3752 *
3753 *       Desc:  Initialize the heap pool. 
3754 *
3755 *
3756 *       Ret:   ROK     - successful
3757 *              RFAILED - unsuccessful.
3758 *
3759 *       Notes: This function is called by the cmMmRegInit. 
3760 *
3761 *       File:  cm_mem_wl.c
3762 *
3763 */
3764 static Void  cmMmHeapInit 
3765 (
3766 Data        *memAddr,
3767 CmMmHeapCb  *heapCb,
3768 Size         size 
3769 )
3770 {
3771 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3772 #ifdef SSI_DEBUG_LEVEL1
3773    uint16_t idx;
3774 #endif /* SSI_DEBUG_LEVEL1 */
3775
3776    /* Initialize the heap control block */
3777    heapCb->vStart      = memAddr;
3778    heapCb->vEnd        = memAddr + size;
3779    heapCb->avlSize    = size; 
3780    heapCb->minSize    = CMM_MINBUFSIZE; 
3781
3782    heapCb->next       = (CmHEntry *)memAddr;
3783    heapCb->next->next = NULLP;
3784 /* cm_mem_c_001.main_12 - addition for header initialization */
3785 #ifdef SSI_DEBUG_LEVEL1
3786    heapCb->next->size = size - sizeof(CmHEntry);
3787    heapCb->next->requestedSize = 0;
3788    for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3789    {
3790       heapCb->next->trSignature[idx] = 0xAB;
3791    }
3792    CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3793    heapCb->staticHeapMemUsed = 0;
3794    heapCb->dynamicHeapMemUsed = 0;
3795    heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3796                         sizeof(heapCb->next->memFlags) +
3797                         sizeof(heapCb->next->requestedSize);
3798    heapCb->numAllocAttempts = 0;
3799    heapCb->numDeallocAttempts = 0;
3800    heapCb->trampleCount = 0;
3801 #else
3802    heapCb->next->size = size; 
3803 #endif /* SSI_DEBUG_LEVEL1 */
3804
3805 #if (ERRCLASS & ERRCLS_DEBUG)
3806    heapCb->numFragBlk  = 0;
3807    heapCb->numReq      = 0;
3808    heapCb->numFailure  = 0;
3809 #endif
3810
3811    heapCb->heapAllocCnt = 0;
3812 /*  cm_mem_c_001.main_15 : Additions */
3813 #ifdef SS_HISTOGRAM_SUPPORT 
3814    /* Initialise the memory histogram hash list */
3815    cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3816 #endif /* SS_HISTOGRAM_SUPPORT */
3817    return;
3818
3819 } /* end of cmMmHeapInit */
3820
3821 #ifndef USE_PURE
3822 \f
3823 /*
3824 *
3825 *       Fun:   cmHeapAlloc
3826 *
3827 *       Desc:  Allocates the memory block from the heap pool. 
3828 *
3829 *
3830 *       Ret:   ROK     - successful
3831 *              RFAILED - unsuccessful.
3832 *
3833 *       Notes: This function is called by the cmAlloc. cmAlloc calls this
3834 *              function when there is no memory block available in the bucket 
3835 *              and the  heap pool is configured.
3836 *
3837 *
3838 *
3839 *       File:  cm_mem_wl.c
3840 *
3841 */
3842 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
3843 /*  cm_mem_c_001.main_15 : Additions */
3844 #ifdef SS_HISTOGRAM_SUPPORT 
3845 #ifdef SSI_DEBUG_LEVEL1
3846 static S16  cmHeapAlloc
3847 (
3848 CmMmHeapCb  *heapCb,
3849 Data       **ptr,
3850 Size        *size,
3851 uint32_t        memType,
3852 uint32_t     line,
3853 uint8_t     *fileName,
3854 uint8_t      entId,
3855 Bool    hstReg
3856 )
3857 #else
3858 static S16  cmHeapAlloc 
3859 (
3860 CmMmHeapCb  *heapCb,
3861 Data       **ptr,
3862 Size        *size,
3863 uint32_t     line,
3864 uint8_t     *fileName,
3865 uint8_t      entId,
3866 Bool    hstReg
3867 )
3868 #endif /* SSI_DEBUG_LEVEL1 */
3869 #else
3870 #ifdef SSI_DEBUG_LEVEL1
3871 static S16  cmHeapAlloc
3872 (
3873 CmMmHeapCb  *heapCb,
3874 Data       **ptr,
3875 Size        *size,
3876 uint32_t        memType
3877 )
3878 #else
3879 static S16  cmHeapAlloc 
3880 (
3881 CmMmHeapCb  *heapCb,
3882 Data       **ptr,
3883 Size        *size 
3884 )
3885 #endif /* SSI_DEBUG_LEVEL1 */
3886 /*  cm_mem_c_001.main_15 : Additions */
3887 #endif /* SS_HISTOGRAM_SUPPORT */ 
3888 {
3889    CmHEntry  *prvHBlk;    /* Previous heap block */
3890    CmHEntry  *curHBlk;    /* Current heap block */ 
3891    Size       tmpSize;
3892 /*  cm_mem_c_001.main_15 : Additions */
3893 #ifdef SS_MEM_LEAK_STS 
3894    Size       reqSz;
3895 #endif /* SS_MEM_LEAK_STS */
3896 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3897 #ifdef SSI_DEBUG_LEVEL1
3898    CmHEntry *alocHeapBlk;
3899    Size requestedSize;
3900    Size hdr;
3901    uint16_t idx;
3902 #endif /* SSI_DEBUG_LEVEL1 */
3903 /*  cm_mem_c_001.main_15 : Additions */
3904 #ifdef SS_HISTOGRAM_SUPPORT 
3905         S8 hstGrmBuf[256];
3906 #endif /* SS_HISTOGRAM_SUPPORT */
3907
3908 /*  cm_mem_c_001.main_15 : Additions */
3909    /* Acquire the heap lock */ 
3910    /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3911 #ifdef SS_WIN
3912    (Void) WTLock (&(heapCb->heapLock));
3913 #else
3914    (Void) SLock (&(heapCb->heapLock));
3915 #endif
3916
3917 #ifdef SS_MEM_LEAK_STS
3918    reqSz = *size;
3919 #endif /* SS_MEM_LEAK_STS */
3920 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
3921 #ifdef SSI_DEBUG_LEVEL1
3922    heapCb->numAllocAttempts++;
3923    requestedSize = *size;
3924 #endif /* SSI_DEBUG_LEVEL1 */
3925
3926    /* Roundup the requested size */
3927    *size = CMM_DATALIGN(*size, (heapCb->minSize));
3928    
3929    /* Check if the available total size is adequate. */
3930    if ((*size) >= heapCb->avlSize)
3931    {
3932 /*  cm_mem_c_001.main_15 : Additions */
3933 #ifdef SS_WIN
3934                         (Void) WTUnlock (&(heapCb->heapLock));
3935 #else
3936                         (Void) SUnlock (&(heapCb->heapLock));
3937 #endif
3938       return (ROUTRES);
3939    }
3940
3941
3942 /* cm_mem_c_001.main_12 - addition for aligning the header size */
3943 #ifdef SSI_DEBUG_LEVEL1
3944    hdr = PTRALIGN(sizeof(CmHEntry));
3945 #endif /* SSI_DEBUG_LEVEL1 */
3946
3947    /* 
3948     * Search through the heap block list in the heap pool of size 
3949     * greater than or equal to the requested size.
3950     *
3951     */ 
3952 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
3953 #ifdef SSI_DEBUG_LEVEL1
3954    prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
3955 #else
3956    prvHBlk = (CmHEntry *)&(heapCb->next);
3957 #endif /* SSI_DEBUG_LEVEL1 */
3958    for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
3959                                                    prvHBlk = prvHBlk->next)
3960    {
3961       /*
3962        * Since the size of the block is always multiple of CMM_MINBUFSIZE 
3963        * and the requested size is rounded to the size multiple of
3964        * CMM_MINBUFSIZE, the difference between the size of the heap block
3965        * and the size to allocate will be either zero or multiple of
3966        * CMM_MINBUFSIZE. 
3967        */
3968       if ((*size) <= curHBlk->size) 
3969       {
3970 /* cm_mem_c_001.main_12 - addition for block size calculation */
3971 #ifdef SSI_DEBUG_LEVEL1
3972       tmpSize = curHBlk->size - (*size);
3973       if (tmpSize != 0)
3974          tmpSize = tmpSize - hdr;
3975       if (tmpSize)
3976 #else
3977          if ((tmpSize = (curHBlk->size - (*size))))
3978 #endif /* SSI_DEBUG_LEVEL1 */
3979          {
3980             /* Heap block of bigger size */
3981 /* cm_mem_c_001.main_12 - addition for allocating memory */
3982 #ifdef SSI_DEBUG_LEVEL1
3983             *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
3984             alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
3985             /*
3986             * No need to look for memory trampling as this is a new block altogether
3987             * Update the header only for this case as it is new block formed 
3988             */
3989             for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3990             {
3991                alocHeapBlk->trSignature[idx] = 0xAB;
3992             }
3993             alocHeapBlk->size = *size;
3994 #else
3995             *ptr = (Data *)curHBlk + tmpSize;             
3996 #endif /* SSI_DEBUG_LEVEL1 */
3997              curHBlk->size = tmpSize;
3998          } 
3999          else
4000          {
4001             /* Heap block is same size of the requested size */
4002 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
4003 #ifdef SSI_DEBUG_LEVEL1
4004             /* look for memory trampling as this is a pure block*/
4005             if (curHBlk)
4006             {
4007                if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
4008                {
4009                      /* detected a trampled memory block in this bucket */
4010                   #ifdef DEBUGP
4011                      /* display an error message here */
4012 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
4013 #ifdef ALIGN_64BIT          
4014                      sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
4015 #else                     
4016                      sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
4017 #endif                     
4018                      SDisplay(0, dbgPrntBuf);
4019                   #endif /* DEBUGP */
4020
4021                      if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4022                      {
4023                         /* Release the lock */
4024                         /* cm_mem_c_001.main_13: Replaced SUnlock with
4025                            WTUnlock for NT */
4026 #ifdef SS_WIN
4027                         (Void) WTUnlock (&(heapCb->heapLock));
4028 #else
4029                         (Void) SUnlock (&(heapCb->heapLock));
4030 #endif
4031                         /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4032                         return (RTRAMPLINGNOK);
4033                      }
4034                      else
4035                      {
4036                         /* Release the lock */
4037                         /* cm_mem_c_001.main_13: Replaced SUnlock with
4038                            WTUnlock for NT */
4039 #ifdef SS_WIN
4040                         (Void) WTUnlock (&(heapCb->heapLock));
4041 #else
4042                         (Void) SUnlock (&(heapCb->heapLock));
4043 #endif
4044                         return RFAILED;
4045                      }
4046                }
4047             }
4048
4049             *ptr = (Data *)curHBlk + hdr;
4050             alocHeapBlk =  curHBlk;
4051             *size = curHBlk->size;
4052 #else
4053             *ptr = (Data *)curHBlk;
4054 #endif /* SSI_DEBUG_LEVEL1 */
4055              prvHBlk->next = curHBlk->next;
4056          }
4057
4058 /* cm_mem_c_001.main_12 - addition for header updation */
4059 #ifdef SSI_DEBUG_LEVEL1
4060          /* update the header fields */
4061          alocHeapBlk->requestedSize = requestedSize;
4062          alocHeapBlk->memFlags = 0;
4063          if (memType == CMM_STATIC_MEM_FLAG)
4064          {
4065             CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4066             heapCb->staticHeapMemUsed += (*size + hdr);
4067          }
4068          else
4069          {
4070             CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4071             heapCb->dynamicHeapMemUsed += (*size + hdr);
4072          }
4073          heapCb->avlSize -= ((*size) + hdr);
4074 #else
4075          heapCb->avlSize -= (*size); 
4076 #endif /* SSI_DEBUG_LEVEL1 */
4077
4078 #ifdef MEMCAL_DEBUG
4079         if (tryHeap)
4080         {
4081             sprintf(prntBuf,
4082                  "SGetSBuf:%08lu:Size  Heap Alloc Times:%05lu  Pointer: %8p\n",
4083                  *size, num_times, *ptr);
4084             SDisplay(0, prntBuf);
4085             tryHeap = 0;
4086         }
4087 #endif
4088 /*  cm_mem_c_001.main_15 : Additions */
4089 #ifdef SS_MEM_LEAK_STS 
4090         /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4091          cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4092 #endif /* SS_MEM_LEAK_STS */
4093          /* Release the lock */
4094 /*  cm_mem_c_001.main_16 : cm_mem_c_001.main_18  Additions */
4095 #ifdef SS_WIN
4096    (Void) WTUnlock (&(heapCb->heapLock));
4097 #else
4098    (Void) SUnlock (&(heapCb->heapLock));
4099 #endif
4100
4101 #ifdef SS_HISTOGRAM_SUPPORT
4102             /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4103              * information into the hash list */
4104             if(hstReg)
4105             {
4106                if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4107                {
4108                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4109                                           SPrint(hstGrmBuf);
4110                }
4111             }/* End of if */
4112
4113 #endif /* SS_HISTOGRAM_SUPPORT */
4114
4115          return ROK;
4116       }
4117    }
4118
4119 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4120 #ifdef MEMCAL_DEBUG
4121         tryHeap = 0;
4122 #endif
4123    
4124
4125    /* Release the lock */
4126    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4127 #ifdef SS_WIN
4128    (Void) WTUnlock (&(heapCb->heapLock));
4129 #else
4130    (Void) SUnlock (&(heapCb->heapLock));
4131 #endif
4132
4133    return (ROUTRES);
4134
4135 } /* end of cmHeapAlloc */
4136
4137 \f
4138 /*
4139 *
4140 *       Fun:   cmHeapFree
4141 *
4142 *       Desc:  Return the memory block from the heap pool. 
4143 *
4144 *
4145 *       Ret:   ROK     - successful
4146 *              RFAILED - unsuccessful.
4147 *
4148 *       Notes: This function returns the memory block to the heap  pool. This 
4149 *              function is called by cmFree. The function does not check the 
4150 *              validity of the memory block. The caller must be sure that the 
4151 *              block was previously allocated and belongs to the heap pool. The 
4152 *              function maintain the sorting order of the memory block on the
4153 *              starting address of the block. This function also do compaction 
4154 *              if the neighbouring blocks are already in the heap. 
4155 *
4156 *
4157 *
4158 *       File:  cm_mem_wl.c
4159 *
4160 */
4161 /*  cm_mem_c_001.main_15 : Additions */
4162 #ifdef SS_HISTOGRAM_SUPPORT  
4163 static S16  cmHeapFree 
4164 (
4165 CmMmHeapCb  *heapCb,
4166 Data        *ptr,
4167 Size         size,
4168 uint32_t     line,
4169 uint8_t     *fileName,
4170 uint8_t      entId,
4171 Bool    hstReg
4172 )
4173 #else
4174 static S16  cmHeapFree 
4175 (
4176 CmMmHeapCb  *heapCb,
4177 Data        *ptr,
4178 Size         size 
4179 )
4180 /*  cm_mem_c_001.main_15 : Additions */
4181 #endif /* SS_HISTOGRAM_SUPPORT */ 
4182 {
4183    CmHEntry  *p;    
4184    CmHEntry  *curHBlk;    /* Current heap block */ 
4185 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4186 #ifdef SSI_DEBUG_LEVEL1
4187    Size  hdr;
4188 #endif /* SSI_DEBUG_LEVEL1 */
4189 /*  cm_mem_c_001.main_15 : Additions */
4190 #ifdef SS_HISTOGRAM_SUPPORT 
4191    Size allocSize = size;
4192         S8 hstGrmBuf[256];
4193 #endif /* SS_HISTOGRAM_SUPPORT */
4194
4195
4196    /* Roundup the requested size */
4197    size = CMM_DATALIGN(size, (heapCb->minSize));
4198 /*  cm_mem_c_001.main_15: Additions */
4199 #ifdef SS_HISTOGRAM_SUPPORT  
4200    allocSize = size;
4201 #endif /* SS_HISTOGRAM_SUPPORT */
4202
4203    /* Acquire the heap lock */
4204    /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4205 #ifdef SS_WIN
4206    (Void) WTLock (&(heapCb->heapLock));
4207 #else
4208    (Void) SLock (&(heapCb->heapLock));
4209 #endif
4210
4211    /* increase the avlSize */
4212 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4213 #ifdef SSI_DEBUG_LEVEL1
4214    hdr = PTRALIGN(sizeof(CmHEntry));
4215    heapCb->avlSize += (size + hdr);
4216    heapCb->numDeallocAttempts++;
4217 #else
4218    heapCb->avlSize += size;
4219 #endif /* SSI_DEBUG_LEVEL1 */
4220    
4221 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4222 #ifdef SSI_DEBUG_LEVEL1
4223    p = (CmHEntry *)(ptr - hdr);
4224 #else
4225    p = (CmHEntry *)ptr; 
4226 /*  cm_mem_c_001.main_15 : Additions */
4227 #ifdef SS_MEM_LEAK_STS
4228    /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4229    cmRlsAllocBlk((PTR)ptr);
4230 #endif /* SS_MEM_LEAK_STS */
4231 #endif /* SSI_DEBUG_LEVEL1 */
4232
4233
4234 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4235 #ifdef SSI_DEBUG_LEVEL1
4236    /* look for memory trampling */
4237    if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4238    {
4239       /* detected a trampled memory block in heap */
4240    #ifdef DEBUGP
4241       /* display an error message here */
4242 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
4243 #ifdef ALIGN_64BIT          
4244       sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4245 #else      
4246       sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4247 #endif      
4248       SDisplay(0, dbgPrntBuf);
4249    #endif /* DEBUGP */
4250
4251       if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4252       {
4253          /* Release the lock */
4254          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4255 #ifdef SS_WIN
4256          (Void) WTUnlock (&(heapCb->heapLock));
4257 #else
4258          (Void) SUnlock (&(heapCb->heapLock));
4259 #endif
4260          /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4261          return (RTRAMPLINGNOK);
4262       }
4263       else
4264       {
4265          /* do not add to the free heap */
4266          heapCb->avlSize -= (size + hdr);
4267          /* Release the heap lock */
4268          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4269 #ifdef SS_WIN
4270          (Void) WTUnlock (&(heapCb->heapLock));
4271 #else
4272          (Void) SUnlock (&(heapCb->heapLock));
4273 #endif
4274
4275          return ROK;
4276       }
4277    }
4278
4279    /* look for any double free */
4280    if (CMM_IS_FREE(p->memFlags))
4281    {
4282    #ifdef DEBUGP
4283 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
4284 #ifdef ALIGN_64BIT          
4285       sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4286 #else
4287       sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4288 #endif      
4289       SDisplay(0, dbgPrntBuf);
4290    #endif /* DEBUGP */
4291
4292       heapCb->avlSize -= (size + hdr);
4293 /*  cm_mem_c_001.main_15 : Additions */
4294 #ifdef SS_WIN 
4295          (Void) WTUnlock (&(heapCb->heapLock));
4296 #else
4297          (Void) SUnlock (&(heapCb->heapLock));
4298 #endif
4299
4300       return (RDBLFREE);
4301    }
4302 #endif /* SSI_DEBUG_LEVEL1 */
4303
4304    for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4305    {
4306       /* 
4307        * The block will be inserted to maintain the sorted order on the
4308        * starting address of the block.
4309        */
4310       if (p > curHBlk)
4311       {
4312          if (!(curHBlk->next) || 
4313              (p < (curHBlk->next)))
4314          {
4315             /* Heap block should be inserted here */
4316
4317             /* 
4318              * Check if the block to be returned can be merged with the
4319              * current block.
4320              */
4321 /* cm_mem_c_001.main_12 - addition for header consideration */
4322 #ifdef SSI_DEBUG_LEVEL1
4323              if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4324 #else
4325              if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4326 #endif /* SSI_DEBUG_LEVEL1 */
4327              {
4328                  /* Merge the block */
4329 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4330 #ifdef SSI_DEBUG_LEVEL1
4331                   /* update the flags */
4332                   if (CMM_IS_STATIC(p->memFlags))
4333                      heapCb->staticHeapMemUsed -= (size + hdr);
4334                   else if (CMM_IS_DYNAMIC(p->memFlags))
4335                      heapCb->dynamicHeapMemUsed -= (size + hdr);
4336                   size = (curHBlk->size += (size + hdr));
4337 #else
4338                   size = (curHBlk->size += size);
4339 #endif /*SSI_DEBUG_LEVEL1*/
4340                   p = curHBlk;
4341              }
4342              else
4343              {
4344 /* cm_mem_c_001.main_12 - addition for double-free check */
4345 #ifdef SSI_DEBUG_LEVEL1
4346                 /* Check for double deallocation in heap */
4347                 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4348                 {
4349                    /* Release the lock */
4350                    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4351 #ifdef SS_WIN
4352                    (Void) WTUnlock (&(heapCb->heapLock));
4353 #else
4354                    (Void) SUnlock (&(heapCb->heapLock));
4355 #endif
4356
4357                    /* This block is already freed in the heap */
4358                    return (RDBLFREE);
4359                 }
4360                 /* update the flags as it is a new node */
4361                 if (CMM_IS_STATIC(p->memFlags))
4362                 {
4363                    heapCb->staticHeapMemUsed -= (size + hdr);
4364                    CMM_RESET_STATIC_FLAG(p->memFlags);
4365                 }
4366                 else if (CMM_IS_DYNAMIC(p->memFlags))
4367                 {
4368                    heapCb->dynamicHeapMemUsed -= (size + hdr);
4369                    CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4370                 }
4371                 CMM_SET_FREE_FLAG(p->memFlags);
4372                 p->requestedSize = 0;
4373 #endif /*SSI_DEBUG_LEVEL1*/
4374                 /* insert the block */
4375                 p->next = curHBlk->next;
4376                 p->size = size; 
4377                 curHBlk->next = p;
4378              }
4379
4380             /* Try to merge with the next block in the chain */
4381 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4382 #ifdef SSI_DEBUG_LEVEL1
4383             if (((Data *)p + hdr + size) == (Data *)(p->next))
4384 #else
4385             if (((Data *)p + size) == (Data *)(p->next))
4386 #endif /*SSI_DEBUG_LEVEL1*/
4387             {
4388                /* p->next can not be NULL */
4389 /* cm_mem_c_001.main_12 - addition for header consideration */
4390 #ifdef SSI_DEBUG_LEVEL1
4391                p->size += (p->next->size + hdr);
4392 #else
4393                p->size += p->next->size; 
4394 #endif /*SSI_DEBUG_LEVEL1*/
4395                p->next  = p->next->next;
4396             }
4397
4398             /* Release the lock */
4399             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4400 #ifdef SS_WIN
4401             (Void) WTUnlock (&(heapCb->heapLock));
4402 #else
4403             (Void) SUnlock (&(heapCb->heapLock));
4404 #endif
4405 /*  cm_mem_c_001.main_15 : Additions */             
4406 #ifdef SS_HISTOGRAM_SUPPORT 
4407         /* If If Tapa task (entId)is registerd for histogram then insert 
4408                    Memrory Freed information into the hash list */
4409         if(hstReg)
4410         {
4411             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4412                                            fileName, entId) != ROK)
4413             {
4414                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4415                                         SPrint(hstGrmBuf);
4416             }
4417          }/* End of if */
4418 #endif /* SS_HISTOGRAM_SUPPORT */
4419             return ROK;
4420          }
4421       }
4422       else if (p < curHBlk)
4423       {
4424          /*
4425          * Check if the block to be returned can be merged with the
4426          * current block.
4427          */
4428 /* cm_mem_c_001.main_12 - addition for header consideration */
4429 #ifdef SSI_DEBUG_LEVEL1
4430          if (((Data *)p + hdr + size) == (Data *)curHBlk)
4431 #else
4432          if (((Data *)p + size) == (Data *)curHBlk)
4433 #endif /* SSI_DEBUG_LEVEL1 */
4434          {
4435             /* Merge the block */
4436 /* cm_mem_c_001.main_12 - addition for header consideration */
4437 #ifdef SSI_DEBUG_LEVEL1
4438             p->size = size + (curHBlk->size + hdr);
4439 #else
4440             p->size = size + curHBlk->size;
4441 #endif /* SSI_DEBUG_LEVEL1 */
4442             p->next = curHBlk->next;
4443          }
4444          else
4445          {
4446             /* insert the block */
4447             p->next = curHBlk;
4448             p->size = size;
4449          }
4450 /* cm_mem_c_001.main_12 - addition for header updation */
4451 #ifdef SSI_DEBUG_LEVEL1
4452          /* update the flags in both cases as they are new start nodes*/
4453          if (CMM_IS_STATIC(p->memFlags))
4454          {
4455             heapCb->staticHeapMemUsed -= (size + hdr);
4456             CMM_RESET_STATIC_FLAG(p->memFlags);
4457          }
4458          else if (CMM_IS_DYNAMIC(p->memFlags))
4459          {
4460             heapCb->dynamicHeapMemUsed -= (size + hdr);
4461             CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4462          }
4463          CMM_SET_FREE_FLAG(p->memFlags);
4464          p->requestedSize = 0;
4465 #endif /* SSI_DEBUG_LEVEL1 */
4466
4467          heapCb->next = p;
4468
4469          /* Release the lock */
4470          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4471 #ifdef SS_WIN
4472          (Void) WTUnlock (&(heapCb->heapLock));
4473 #else
4474          (Void) SUnlock (&(heapCb->heapLock));
4475 #endif
4476 /*  cm_mem_c_001.main_15 : Additions */
4477 #ifdef SS_HISTOGRAM_SUPPORT  
4478         /* If If Tapa task (entId)is registerd for histogram then insert 
4479                    Memrory Freed information into the hash list */
4480         if(hstReg)
4481         {
4482             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4483                                            fileName, entId) != ROK)
4484             {
4485                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4486                                         SPrint(hstGrmBuf);
4487             }
4488          }/* End of if */
4489 #endif /* SS_HISTOGRAM_SUPPORT */
4490          return ROK;
4491       }
4492
4493    }
4494
4495    if (heapCb->next == NULLP)
4496    {
4497       /* Heap block is empty. Insert the block in the head. */
4498       heapCb->next = p;
4499       p->next = NULLP;
4500       p->size = size;
4501
4502 /* cm_mem_c_001.main_12 - addition for header updation */
4503 #ifdef SSI_DEBUG_LEVEL1
4504       if (CMM_IS_STATIC(p->memFlags))
4505       {
4506          heapCb->staticHeapMemUsed -= (size + hdr);
4507          CMM_RESET_STATIC_FLAG(p->memFlags);
4508       }
4509       else if (CMM_IS_DYNAMIC(p->memFlags))
4510       {
4511          heapCb->dynamicHeapMemUsed -= (size + hdr);
4512          CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4513       }
4514       CMM_SET_FREE_FLAG(p->memFlags);
4515       p->requestedSize = 0;
4516 #endif /* SSI_DEBUG_LEVEL1 */
4517
4518       /* Release the heap lock */
4519       /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4520 #ifdef SS_WIN
4521       (Void) WTUnlock (&(heapCb->heapLock));
4522 #else
4523       (Void) SUnlock (&(heapCb->heapLock));
4524 #endif
4525 /*  cm_mem_c_001.main_15 : Additions */
4526 #ifdef SS_HISTOGRAM_SUPPORT 
4527         /* If If Tapa task (entId)is registerd for histogram then insert 
4528                    Memrory Freed information into the hash list */
4529         if(hstReg)
4530         {
4531             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4532                                            fileName, entId) != ROK)
4533             {
4534                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4535                                         SPrint(hstGrmBuf);
4536             }
4537          }/* End of if */
4538 #endif /* SS_HISTOGRAM_SUPPORT */
4539       return ROK;
4540    }
4541
4542    /* Release the lock */
4543    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4544 #ifdef SS_WIN
4545    (Void) WTUnlock (&(heapCb->heapLock));
4546 #else
4547    (Void) SUnlock (&(heapCb->heapLock));
4548 #endif
4549
4550    return RFAILED;
4551 } /* end of cmHeapFree */
4552 /*  cm_mem_c_001.main_15 : Additions */
4553 #endif
4554 #ifdef SS_MEM_LEAK_STS 
4555 /*
4556 *
4557 *       Fun:   cmInitMemLeakMdl
4558 *
4559 *       Desc:  Initializes the memory leak detection module
4560 *
4561 *
4562 *       Ret:   void
4563 *
4564 *       Notes: This function initializes the memory leak detection module.
4565 *
4566 *
4567 *       File:  cm_mem_wl.c
4568 *
4569 */
4570 Void cmInitMemLeakMdl(Void)
4571 {
4572    uint8_t   memMdl;
4573    uint8_t   hashIdx;
4574
4575
4576    memLkCb.memLkMdlInit = FALSE;
4577    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4578    {
4579            for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4580                 {
4581        SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4582        cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4583                       500, 0, FALSE, CM_HASH_KEYTYPE_UINT32_MOD, 0, 0);
4584        memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4585                 }
4586    }
4587    if(memLkCb.fileLkLog == NULLP)
4588    {
4589       memLkCb.fileLkLog = (FILE *) stdout;
4590    }
4591    memLkCb.memLkMdlInit = TRUE;
4592
4593    return;
4594 } /* cmInitMemLeakMdl */
4595 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4596 /*
4597  *
4598  * Fun:   cmDeinitMemLeakMdl
4599  * 
4600  * Desc:  De-initializes the memory leak detection module
4601  * 
4602  * 
4603  * Ret:   void
4604  * 
4605  * Notes: This function de-initializes the memory leak detection module.
4606  * 
4607  * 
4608  * File:  cm_mem_wl.c
4609  * 
4610  **/
4611 Void cmDeinitMemLeakMdl (Void)
4612 {
4613   uint8_t   memMdl;
4614   uint8_t   hashIdx;
4615
4616
4617   memLkCb.memLkMdlInit = FALSE;
4618   for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4619   {
4620          for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4621          {
4622                 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4623                 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4624                 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4625          }
4626   }
4627   return;
4628 }
4629 /*
4630 *
4631 *       Fun:   cmMemOpenMemLkFile
4632 *
4633 *       Desc:  Initializes the memory leak detection module
4634 *
4635 *
4636 *       Ret:   void
4637 *
4638 *       Notes: This function initializes the memory leak detection module.
4639 *
4640 *
4641 *       File:  cm_mem_wl.c
4642 *
4643 */
4644 Void cmMemOpenMemLkFile(S8 *arg)
4645 {
4646    memLkCb.fileLkLog = NULLP;
4647    memLkCb.fileLkLog = fopen(arg, "w");
4648    return;
4649 }
4650
4651 /*
4652 *
4653 *       Fun:   SLogLkInfo
4654 *
4655 *       Desc:  Initializes the memory leak detection module
4656 *
4657 *
4658 *       Ret:   void
4659 *
4660 *       Notes: This function initializes the memory leak detection module.
4661 *
4662 *
4663 *       File:  cm_mem_wl.c
4664 *
4665 */
4666 Void SLogLkInfo (Void)
4667 {
4668
4669    MemAllocInfo  *oldMemInfo;
4670    MemAllocInfo  *newMemInfo;
4671    uint8_t       memMdl;  
4672    uint8_t       hashIdx;  
4673    uint8_t       idx;
4674    Txt           prntBuf[255];
4675    S8            **funcNm;
4676    if( memLkCb.memLkMdlInit == FALSE)
4677    {
4678      return;
4679    }
4680    sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4681    fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4682
4683    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4684    {
4685            for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4686                 {
4687          if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4688          {
4689             continue;
4690          }
4691          oldMemInfo = NULLP;
4692          newMemInfo = NULLP;
4693          SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4694          while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4695                                  (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4696          {
4697              sprintf(prntBuf, "[LBIS]\n");
4698              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4699              /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4700 #ifdef ALIGN_64BIT
4701              sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4702 #else
4703              sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
4704 #endif
4705              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4706              sprintf(prntBuf, "Module Name: %s\n", 
4707                      memUsrMdlStr[newMemInfo->moduleId].mdlStr);
4708              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4709              sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
4710              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4711              sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
4712              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4713              sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
4714              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4715              sprintf(prntBuf,"Memory Allocation Path:\n");
4716              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4717              funcNm = (S8 **)newMemInfo->backTrace;
4718              for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
4719              {
4720                 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
4721                 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4722              }
4723              sprintf(prntBuf, "[LBIE]\n\n");
4724              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4725              fflush(memLkCb.fileLkLog);
4726              oldMemInfo = newMemInfo;
4727              newMemInfo = NULLP;
4728          } 
4729          SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4730                 }
4731    }
4732    sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
4733    fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4734    return;
4735 }
4736
4737 /*
4738 *
4739 *       Fun:   SFlushLkInfo
4740 *
4741 *       Desc:  Initializes the memory leak detection module
4742 *
4743 *
4744 *       Ret:   void
4745 *
4746 *       Notes: This function initializes the memory leak detection module.
4747 *
4748 *
4749 *       File:  cm_mem_wl.c
4750 *
4751 */
4752 Void SFlushLkInfo (Void)
4753 {
4754    MemAllocInfo *newMemInfo;
4755    uint8_t      memMdl;
4756    uint8_t      hashIdx;
4757    S8           **funcNm;
4758 #ifdef SS_MEM_LEAK_SOL
4759    uint8_t      i;
4760 #endif /* SS_MEM_LEAK_SOL */
4761
4762    if( memLkCb.memLkMdlInit == FALSE)
4763    {
4764      return;
4765    }
4766
4767    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4768    {
4769            for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4770                 {
4771          if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4772          {
4773             continue;
4774          }
4775          newMemInfo = NULLP;
4776          SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4777          while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4778                                  (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
4779          {
4780              funcNm = (S8 **)newMemInfo->backTrace;
4781 #ifdef SS_MEM_LEAK_SOL
4782              for(i = 0; i < newMemInfo->bTrcSz; i++)
4783              {
4784 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4785 #ifdef SS_4GMX_LCORE
4786                 MxHeapFree(SsiHeap, funcNm[i]); 
4787 #else
4788                 free(funcNm[i]); 
4789 #endif
4790                                     /* SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4791              }
4792 #endif /* SS_MEM_LEAK_SOl */
4793 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4794 #ifdef SS_4GMX_LCORE
4795              MxHeapFree(SsiHeap, funcNm);
4796              MxHeapFree(SsiHeap, newMemInfo);
4797 #else
4798              free(funcNm);
4799              free(newMemInfo);
4800 #endif
4801          }
4802          SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4803                 }
4804     }
4805     return;
4806 }
4807
4808 /*
4809 *
4810 *       Fun:   cmStorAllocBlk
4811 *
4812 *       Desc:  Initializes the memory leak detection module
4813 *
4814 *
4815 *       Ret:   void
4816 *
4817 *       Notes: This function initializes the memory leak detection module.
4818 *
4819 *
4820 *       File:  cm_mem_wl.c
4821 *
4822 */
4823 Void cmStorAllocBlk
4824 (
4825 uint32_t    addr,
4826 Size   reqSz,
4827 Size   allocSz,
4828 uint16_t    bktIdx
4829 )
4830 {
4831 #ifndef SS_MEM_LEAK_SOL
4832    Ptr           trace[CM_MAX_STACK_TRACE];
4833 #endif  /* SS_MEM_LEAK_SOL */
4834    S8            **funcNm;
4835    S32           traceSize;
4836    MemAllocInfo  *allocInfo;
4837    uint8_t            moduleId;
4838
4839    if( memLkCb.memLkMdlInit == FALSE)
4840    {
4841      return;
4842    }
4843
4844 #ifdef SS_MEM_LEAK_SOL
4845    /* I need to do this for solaris, because it does not implement 
4846     * backtrace. Here backtrace is my function. See below for the 
4847     * implementation. */
4848 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4849 #ifdef SS_4GMX_LCORE
4850    funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4851    memset(funcNm, 0, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4852 #else
4853    funcNm = (S8 **)calloc(1, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4854 #endif
4855         /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &funcNm, sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4856    traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
4857 #else /* SS_MEM_LEAK_SOL */
4858    traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4859    funcNm = backtrace_symbols(trace, traceSize); 
4860 #endif /* SS_MEM_LEAK_SOL */
4861    
4862    moduleId = cmMemGetModuleId(funcNm, traceSize);
4863
4864    (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4865 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4866 #ifdef SS_4GMX_LCORE
4867    allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo)); 
4868    memset(allocInfo, 0, sizeof(MemAllocInfo));
4869 #else
4870    allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo)); 
4871 #endif
4872         /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &allocInfo,  sizeof(MemAllocInfo)); */
4873    allocInfo->memAddr    = addr;
4874    allocInfo->reqSz      = reqSz;
4875    allocInfo->allocSz    = allocSz;
4876    allocInfo->bktIdx     = bktIdx;
4877    allocInfo->backTrace  = (PTR) funcNm;
4878    allocInfo->moduleId   = moduleId;
4879    allocInfo->bTrcSz     = traceSize;
4880
4881    cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp, 
4882                     (PTR)allocInfo, (uint8_t *)&(allocInfo->memAddr),
4883                     sizeof(allocInfo->memAddr));
4884    memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
4885
4886    (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4887    return;
4888 } /* cmStorAllocBlk */
4889
4890 /*
4891 *
4892 *       Fun:   cmMemGetModuleId
4893 *
4894 *       Desc:  Initializes the memory leak detection module
4895 *
4896 *
4897 *       Ret:   void
4898 *
4899 *       Notes: This function initializes the memory leak detection module.
4900 *
4901 *
4902 *       File:  cm_mem_wl.c
4903 *
4904 */
4905 uint8_t cmMemGetModuleId
4906 (
4907 S8     **funNm,
4908 S32    traceSize
4909 )
4910 {
4911    uint8_t    idx;
4912    uint8_t    memStrIdx;
4913    uint32_t   len;
4914    S32   retVal;
4915    S16   memReqIdx;
4916    S16   mdlFunStrIdx;
4917
4918    Txt   *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
4919                  
4920    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
4921    for(idx = 0; idx < traceSize; idx++)
4922    {
4923       memReqIdx = -1;
4924       memStrIdx = 0;
4925       while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
4926       {
4927          memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx], 
4928                                         funNm);
4929          memStrIdx++;
4930       }
4931       mdlFunStrIdx = 0;
4932       while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4933       {
4934          len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4935          memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize, 
4936                                         memUsrMdlStr[mdlFunStrIdx].fPStr,
4937                                         funNm);
4938          if(memReqIdx >= 0)
4939          {
4940             return (mdlFunStrIdx);
4941          }
4942          mdlFunStrIdx++;
4943       }
4944       mdlFunStrIdx = 0;
4945       while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4946       {
4947           retVal = strcmp((const S8 *)"DEFAULT", 
4948                                (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4949          if(retVal == NULLD)
4950          {
4951             return (mdlFunStrIdx);
4952          } 
4953          mdlFunStrIdx++;
4954       }
4955    }
4956
4957    return (0);
4958 } /* cmMemGetModuleId */
4959
4960 /*
4961 *
4962 *       Fun:   cmMemGetStrMtchIdx
4963 *
4964 *       Desc:  Initializes the memory leak detection module
4965 *
4966 *
4967 *       Ret:   void
4968 *
4969 *       Notes: This function initializes the memory leak detection module.
4970 *
4971 *
4972 *       File:  cm_mem_wl.c
4973 *
4974 */
4975 S16 cmMemGetStrMtchIdx  
4976 (
4977 uint8_t strtIdx, 
4978 uint8_t endIdx,
4979 S8 *str, 
4980 S8 **strLst
4981 )
4982 {
4983
4984    S8   cmpStr[255];
4985    uint32_t  len;
4986    Bool found;
4987    uint32_t  tempLen;
4988    uint8_t   idx;
4989    S32  retVal;
4990
4991    len = strlen((const S8 *)str);
4992    cmpStr[0] = '(';
4993    strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
4994    cmpStr[len + 1] = '\0';
4995    len++;
4996    found = FALSE;
4997    for(;strtIdx < endIdx && !found; strtIdx++)
4998    {
4999        idx = 0;
5000        tempLen = strlen((const S8 *)strLst[strtIdx]);
5001        if(tempLen < len)
5002          continue;
5003
5004        while(*(strLst[strtIdx] + idx + len) != '\0')
5005        {
5006          retVal = strncmp((const S8 *)cmpStr, 
5007                          ((const S8 *)strLst[strtIdx] + idx), len);
5008          if(0 == retVal)
5009          {
5010            found = TRUE;
5011            break;
5012          }
5013          idx++;
5014        }
5015    }
5016
5017    if(!found)
5018    {
5019      return (-1); 
5020    }
5021    return (strtIdx);
5022
5023 }  /* cmMemGetStrMtchIdx */
5024
5025 /*
5026 *
5027 *       Fun:   cmRlsAllocBlk
5028 *
5029 *       Desc:  Initializes the memory leak detection module
5030 *
5031 *
5032 *       Ret:   void
5033 *
5034 *       Notes: This function initializes the memory leak detection module.
5035 *
5036 *
5037 *       File:  cm_mem_wl.c
5038 *
5039 */
5040 Void cmRlsAllocBlk
5041 (
5042 uint32_t    addr
5043 )
5044 {
5045     Ptr           trace[CM_MAX_STACK_TRACE];
5046     S8            **funcNm;
5047     uint8_t       idx;
5048     uint8_t       i;
5049     S16           retVal;
5050     S32           traceSize;
5051     MemAllocInfo  *memAllocInfo;
5052
5053     if( memLkCb.memLkMdlInit == FALSE)
5054     {
5055       return;
5056     }
5057
5058
5059     for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5060     {
5061        SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5062        retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5063                                (uint8_t *)&addr, sizeof(uint32_t), 0,
5064                                (PTR *)&memAllocInfo);                              
5065        if(retVal == ROK)
5066        {
5067          cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5068                           (PTR)memAllocInfo);
5069          SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5070          funcNm = (S8 **) memAllocInfo->backTrace;
5071 #ifdef SS_MEM_LEAK_SOL
5072          for(i = 0; i < memAllocInfo->bTrcSz; i++)
5073          {
5074 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5075 #ifdef SS_4GMX_LCORE
5076             MxHeapFree(SsiHeap, funcNm[i]);
5077 #else
5078             free(funcNm[i]);
5079 #endif
5080          }
5081 #endif /* SS_MEM_LEAK_SOL */
5082 #ifdef SS_MEM_LEAK_FREE_TRACE
5083          {
5084
5085             Txt   prntBuf[255];
5086             sprintf( prntBuf, "\n==============================\n");
5087             SPrint(prntBuf);
5088             /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5089 #ifdef ALIGN_64BIT
5090             sprintf( prntBuf, "Address: [%x]\n", addr);
5091 #else
5092             sprintf( prntBuf, "Address: [%lx]\n", addr);
5093 #endif
5094             SPrint(prntBuf);
5095             traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5096             funcNm    = backtrace_symbols(trace, traceSize);
5097             sprintf( prntBuf, "[bt] Execution path:\n");
5098             SPrint(prntBuf);
5099             for (i=0; i < traceSize; ++i)
5100             {
5101               sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5102               SPrint(prntBuf);
5103             }
5104             sprintf( prntBuf, "\n==============================\n");
5105             SPrint(prntBuf);
5106          }
5107 #endif   /* SS_MEM_LEAK_FREE_TRACE */
5108 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5109 #ifdef SS_4GMX_LCORE
5110          MxHeapFree(SsiHeap, funcNm);
5111          MxHeapFree(SsiHeap, memAllocInfo);
5112 #else
5113          free(funcNm);
5114          free(memAllocInfo);
5115 #endif
5116          break;
5117        }
5118        SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5119     }
5120
5121 #ifndef SS_MEM_LEAK_SOL
5122      if(idx == CM_MEM_USR_MDL)
5123      {
5124        Txt   prntBuf[255];
5125        sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5126        SPrint(prntBuf);
5127 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
5128 #ifdef ALIGN_64BIT          
5129        sprintf( prntBuf, "Address: [%u]\n", addr);
5130 #else       
5131        sprintf( prntBuf, "Address: [%lu]\n", addr);
5132 #endif       
5133        SPrint(prntBuf);
5134        traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5135        funcNm    = backtrace_symbols(trace, traceSize);
5136        sprintf( prntBuf,"[bt] Execution path:\n");
5137        SPrint(prntBuf);
5138        for (i=0; i < traceSize; ++i)
5139        {
5140              sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5141              SPrint(prntBuf);
5142        }
5143        printf("\n==============================\n");
5144 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5145 #ifdef SS_4GMX_LCORE
5146        MxHeapFree(SsiHeap, funcNm);
5147 #else
5148        free(funcNm);
5149 #endif
5150      }
5151 #endif /* SS_MEM_LEAK_SOL */
5152
5153    /*cm_mem_c_001.main_25 : */
5154    return;
5155 } /* cmRlsAllocBlk */
5156
5157
5158 #ifdef SS_MEM_LEAK_SOL
5159 /*
5160 *
5161 *       Fun:   cmAddrToSymStr
5162 *
5163 *       Desc:  Initializes the memory leak detection module
5164 *
5165 *
5166 *       Ret:   void
5167 *
5168 *       Notes: This function initializes the memory leak detection module.
5169 *
5170 *
5171 *       File:  cm_mem_wl.c
5172 *
5173 */
5174 S32 cmAddrToSymStr
5175 (
5176 Void   *pc, 
5177 S8     *buffer, 
5178 S32    size
5179 )
5180 {
5181
5182    Dl_info info;
5183    Sym *sym;
5184
5185
5186    if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5187    {
5188        return (snprintf(buffer, size, "[0x%p]", pc));
5189    }
5190
5191    if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5192        ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5193    {
5194       return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5195                        info.dli_fname,
5196                        info.dli_sname,
5197                        (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5198    }
5199    else
5200    {
5201       return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5202                       info.dli_fname,
5203                       (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5204    }
5205
5206 } /* cmAddrToSymStr */
5207
5208 /*
5209 *
5210 *       Fun:   cmLeakCallBack
5211 *
5212 *       Desc:  Initializes the memory leak detection module
5213 *
5214 *
5215 *       Ret:   void
5216 *
5217 *       Notes: This function initializes the memory leak detection module.
5218 *
5219 *
5220 *       File:  cm_mem_wl.c
5221 *
5222 */
5223 S32 cmLeakCallBack
5224 (
5225 uintptr_t pc,
5226 S32       sigNo, 
5227 Void      *arg
5228 )
5229 {
5230     S8   *buffer;
5231
5232     Backtrace_t *bt = (Backtrace_t *)arg;
5233     if (bt->bt_actcount >= bt->bt_maxcount)
5234          return (-1);
5235 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5236 #ifdef SS_4GMX_LCORE
5237     buffer = (S8 *)MxHeapAlloc(SsiHeap, 510); 
5238     memset(buffer, 0, 510);
5239 #else
5240     buffer = (S8 *)calloc(1, 510); 
5241 #endif
5242          /* SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,DFLT_REGION, DFLT_POOL, &buffer, 510); */
5243     (void) cmAddrToSymStr((void *)pc, buffer, 505);
5244     bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5245
5246     return (0);
5247 } /* cmLeakCallBack */
5248
5249 /*
5250 *
5251 *       Fun:   backtrace
5252 *
5253 *       Desc:  Initializes the memory leak detection module
5254 *
5255 *
5256 *       Ret:   void
5257 *
5258 *       Notes: This function initializes the memory leak detection module.
5259 *
5260 *
5261 *       File:  cm_mem_wl.c
5262 *
5263 */
5264 S32 backtrace
5265 (
5266 Void  **buffer,
5267 S32   count
5268 )
5269 {
5270
5271     Backtrace_t  bt;
5272     ucontext_t   u;
5273
5274     bt.bt_buffer = buffer;
5275     bt.bt_maxcount = count;
5276     bt.bt_actcount = 0;
5277
5278     if (getcontext(&u) < 0)
5279        return (0);
5280     (Void) walkcontext(&u, cmLeakCallBack, &bt);
5281     return (bt.bt_actcount);
5282
5283 } /* backtrace */
5284
5285 #endif /* SS_MEM_LEAK_SOL */
5286
5287 #endif /* SS_MEM_LEAK_STS */
5288 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5289 * These include sanity check functions for bucket and heap,
5290 * for printing several memory related statistics 
5291 */
5292 #ifdef SSI_DEBUG_LEVEL1
5293 /*
5294 *
5295 *       Fun:   cmMmBktSanityChk
5296 *
5297 *       Desc:  Performs the sanity check for the memory blocks in a memory bucket.
5298 *              This API gets called when trampling is detected in a memory block.
5299 *
5300 *       Ret:   RTRAMPLINGNOK - Trampling, serious error
5301 *              RTRAMPLINGOK  - Trampling, but OK to proceed
5302 *
5303 *       Notes: This function performs the memory block sanity in a bucket. This
5304 *              function is called by cmAlloc and cmFree as part of error handling mechanism.
5305 *              Performs sanity check for the whole bucket by traversing each
5306 *              of the memory blocks using the pointer bktStartPtr.
5307 *              Keeps track of number of tramplings happened. If the count
5308 *              exceeds the threshold decided, then invalidates this bucket.
5309 *
5310 *       File:  cm_mem_wl.c
5311 *
5312 */
5313 static S16  cmMmBktSanityChk(CmMmBkt  *bkt)
5314 {
5315    CmMmBlkHdr *ptrBlk;
5316    uint32_t blkCnt;
5317
5318
5319    bkt->trampleCount = 0;
5320
5321    /* scan the entire memory list of the bucket */
5322    for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5323          blkCnt < (bkt->numBlks); blkCnt++)
5324    {
5325       if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5326       {
5327          bkt->trampleCount++;
5328          if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5329          {
5330             /* Take action to invalidate the entire bucket */
5331             return (RTRAMPLINGNOK);
5332          }
5333       }
5334       /* reach next memory block in this bucket manually */
5335       ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5336    }
5337
5338  #ifdef  DEBUGP
5339    /* display an error message here */
5340    sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5341    SDisplay(0, dbgPrntBuf);
5342  #endif /* DEBUGP */
5343
5344    return (RTRAMPLINGOK);
5345 }
5346
5347 /*
5348 *
5349 *       Fun:   cmMmHeapSanityChk
5350 *
5351 *       Desc:  Performs the sanity check for the memory blocks in the memory heap.
5352 *              This API gets called when trampling is detected in heap(Alloc/Free).
5353 *
5354 *       Ret:   RTRAMPLINGNOK - Trampling, serious error
5355 *              RTRAMPLINGOK  - Trampling, but OK to proceed
5356 *
5357 *       Notes: This function performs the memory block sanity in the heap. This
5358 *              function is called by cmHeapAlloc and cmHeapFree as part of error
5359 *              handling mechanism. Keeps track of number of tramplings happened.
5360 *              If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5361 *              count is less than threshold, then return RTRAMPLINGOK.
5362 *
5363 *       File:  cm_mem_wl.c
5364 *
5365 */
5366 static S16  cmMmHeapSanityChk(CmMmHeapCb  *heapCb)
5367 {
5368
5369    /* increment the trample count */
5370    heapCb->trampleCount++;
5371
5372    if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5373    {
5374       return (RTRAMPLINGNOK);
5375    }
5376
5377    return (RTRAMPLINGOK);
5378 }
5379
5380 /*
5381 *
5382 *       Fun:   cmMmRegIsBlkSane
5383 *
5384 *       Desc:  Performs the sanity check for the memory block by checking its header.
5385 *
5386 *       Ret:   ROK - If no trampling is detected in the block
5387 *              RFAILED  - If trampling is detected in the block
5388 *
5389 *       Notes: This function performs the memory block sanity in a block.
5390 *
5391 *       File:  cm_mem_wl.c
5392 *
5393 */
5394 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr)
5395 {
5396    uint32_t sigCnt;
5397
5398
5399    for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5400    {
5401       if (blkPtr->trSignature[sigCnt] != 0xAB)
5402       {
5403          return RFAILED;
5404       }
5405    }
5406
5407    return ROK;
5408 }
5409
5410 /*
5411 *
5412 *       Fun:   cmMmHashFunc
5413 *
5414 *       Desc:  Computes the hash list index (bin number) for a specified
5415 *              key of type (x % 101).
5416 *
5417 *       return (idx % hash_table_size);
5418 *
5419 *       Ret:   ROK     - successful, *idx contains computed index
5420 *
5421 *       Notes: None.
5422 *
5423 *       File:  cm_mem_wl.c
5424 *
5425 */
5426 static S16 cmMmHashFunc
5427 (
5428 CmMmHashListCp *hashListCp,
5429 uint32_t key,
5430 uint16_t *idx
5431 )
5432 {
5433
5434    *idx = (uint16_t)(key % hashListCp->numOfbins);
5435
5436    return ROK;
5437
5438 } /* end of cmMmHashFunc () */
5439
5440 /*
5441 *
5442 *       Fun:   cmMmHashListInit
5443 *
5444 *       Desc:  Initializes a hash list. Parameters are:
5445 *
5446 *              hashListCp   control point for hash list
5447 *              nmbBins      number of bins in the hash list. Storage will
5448 *                           be allocated for them from the indicated memory
5449 *                           region and pool.
5450 *              region
5451 *              pool         for allocating storage for bins.
5452 *
5453 *       Ret:   ROK      - initialization successful
5454 *              RFAILED  - initialization failed, lack of memory
5455 *
5456 *       Notes: None
5457 *
5458 *       File:  cm_mem_wl.c
5459 *
5460 */
5461 static S16 cmMmHashListInit
5462 (
5463 CmMmHashListCp *hashListCp,  /* hash list to initialize */
5464 uint16_t     nmbBins,      /* number of hash list bins */
5465 Region       region,       /* memory region to allocate bins */
5466 Pool         pool          /* memory pool to allocate bins */
5467 )
5468 {
5469    uint16_t i;
5470    CmMmHashListEnt *hl;
5471
5472
5473    /* initialize control point fields */
5474    hashListCp->hashList = NULLP;
5475    hashListCp->numOfbins = 0;
5476    hashListCp->numOfEntries  = 0;
5477
5478    /* allocate memory for bins */
5479    if (nmbBins)
5480    {
5481       if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool, (Data **) &hashListCp->hashList,
5482                (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5483       return RFAILED;
5484
5485       /* initialize bin pointers */
5486       hl = hashListCp->hashList;
5487       for(i = 0; i < nmbBins; i++)
5488       {
5489          hl[i].size = hl[i].numAttempts = 0;
5490       }
5491
5492       /* initialize bin size */
5493       hashListCp->numOfbins = nmbBins;
5494    }
5495
5496    return ROK;
5497 }
5498
5499 /*
5500 *
5501 *       Fun:   cmMmHashListDeinit
5502 *
5503 *       Desc:  Deinitializes a hash list. Deallocates memory for bins
5504 *              and resets header fields. Parameters are:
5505 *
5506 *              hashListCp   control point for hash list
5507 *              region
5508 *              pool         for allocating storage for bins.
5509 *
5510 *       Ret:   ROK      - successful
5511 *              RFAILED - failure, invalid parameters
5512 *
5513 *       Notes: None
5514 *
5515 *       File:  cm_mem_wl.c
5516 *
5517 */
5518 static S16 cmMmHashListDeinit
5519 (
5520 CmMmHashListCp *hashListCp,   /* hash list to deinitialize */
5521 Region       region,       /* memory region to allocate bins */
5522 Pool         pool          /* memory pool to allocate bins */
5523 )
5524 {
5525
5526    /* deallocate memory for bins */
5527    if (hashListCp->numOfbins)
5528       (Void) SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool,
5529                       (Data *) hashListCp->hashList,
5530                       (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5531
5532    /* deinitialize control point fields */
5533    hashListCp->hashList = NULLP;
5534    hashListCp->numOfbins = 0;
5535    hashListCp->numOfEntries = 0;
5536
5537    return ROK;
5538 } /* end of cmMmHashListDeinit */
5539
5540 /*
5541 *
5542 *       Fun:   cmMmHashListInsert
5543 *
5544 *       Desc:  Inserts a new entry in the hash list. Parameters are:
5545 *
5546 *              hashListCp   control point for hash list
5547 *              key          pointer to key string in the new entry
5548 *
5549 *       Ret:   ROK      - insertion successful
5550 *              RFAILED  - insertion failed (incorrect parameter values)
5551 *
5552 *       Notes: None
5553 *
5554 *       File:  cm_mem_wl.c
5555 *
5556 */
5557 static S16 cmMmHashListInsert
5558 (
5559 CmMmHashListCp *hashListCp,  /* hash list to add to */
5560 uint32_t       key         /* pointer to key */
5561 )
5562 {
5563    CmMmHashListEnt *hashListEnt;    /* pointer to hash list entry header */
5564    uint16_t idx;                       /* index for insertion into hash list */
5565    uint16_t i;
5566
5567
5568    /* check if hashListCp is initialised yet */
5569    if ( hashListCp->numOfbins == 0)
5570       return ROK;
5571
5572    /* compute index for insertion */
5573    if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5574       return RFAILED;
5575
5576    hashListEnt = hashListCp->hashList;
5577
5578    if (hashListEnt[idx].numAttempts == 0)
5579    {
5580       /* new entry, insert here */
5581       hashListEnt[idx].size = key;
5582       hashListEnt[idx].numAttempts++;
5583       /* increment count of entries in hash list */
5584       hashListCp->numOfEntries++;
5585    }
5586    else
5587    {
5588       /* this hash is occupied, re-hash it using linear probing */
5589       for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5590       {
5591          if (hashListEnt[i].size == key)
5592          {
5593             hashListEnt[i].numAttempts++;
5594             break;
5595          }
5596
5597          if (hashListEnt[i].numAttempts == 0)
5598          {
5599             hashListEnt[i].size = key;
5600             hashListEnt[i].numAttempts++;
5601             /* increment count of entries in hash list */
5602             hashListCp->numOfEntries++;
5603             break;
5604          }
5605    }
5606
5607    if (i == CMM_STAT_HASH_TBL_LEN)
5608    {
5609       /* there is no free slot for this key */
5610       return RFAILED;
5611    }
5612    }
5613
5614    return ROK;
5615 } /* end of cmMmHashListInsert */
5616
5617 #endif /* SSI_DEBUG_LEVEL1 */
5618 /*  cm_mem_c_001.main_15 : Additions */
5619 #ifdef SS_HISTOGRAM_SUPPORT  
5620 /*
5621 *
5622 *       Fun:   cmHstGrmHashListInit
5623 *
5624 *       Desc:  Initializes a hash list. Parameters are:
5625 *
5626 *              hashListCp   control point for hash list
5627 *       Ret:   ROK      - initialization successful
5628 *              RFAILED  - initialization failed, lack of memory
5629 *
5630 *       Notes: None
5631 *
5632 *       File:  cm_mem_wl.c
5633 *
5634 */
5635 static S16 cmHstGrmHashListInit
5636 (
5637 CmHstGrmHashListCp *hashListCp  /* hash list to initialize */
5638 )
5639 {
5640    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5641 #ifdef  DEBUGP
5642    /* display an error message here */
5643    /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/ 
5644 #ifdef ALIGN_64BIT
5645     sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5646 #else
5647     sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5648 #endif
5649     SDisplay(0, dbgPrntBuf);
5650 #endif /* DEBUGP */
5651     memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5652     return ROK;
5653 }
5654
5655 /*
5656 *
5657 *       Fun:   cmHstGrmHashListDeInit
5658 *
5659 *       Desc:  De-initializes a hash list. Parameters are:
5660 *
5661 *              hashListCp   control point for hash list
5662 *       Ret:   ROK      - initialization successful
5663 *              RFAILED  - initialization failed, lack of memory
5664 *
5665 *       Notes: None
5666 *
5667 *       File:  cm_mem_wl.c
5668 *
5669 */
5670 static S16 cmHstGrmHashListDeInit
5671 (
5672 CmHstGrmHashListCp *hashListCp  /* hash list to initialize */
5673 )
5674 {
5675    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5676 #ifdef  DEBUGP
5677    /* display an error message here */
5678    /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/ 
5679 #ifdef ALIGN_64BIT
5680     sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5681 #else
5682     sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5683 #endif
5684     SDisplay(0, dbgPrntBuf);
5685 #endif /* DEBUGP */
5686     memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5687     return ROK;
5688 }
5689
5690 /*
5691 *
5692 *       Fun:   cmHstGrmFreeInsert
5693 *
5694 *       Desc:  Inserts a Freed information in into the hash list. Parameters are:
5695 *
5696 *              bkt : pointer to bucket for which memory is freed.
5697 *              line : Line where memory is freed.
5698 *              file : file where memory is freed.
5699 *              entId : Tapa task which releases the memory.
5700 *
5701 *       Ret:   ROK      - insertion successful
5702 *              RFAILED  - insertion failed (incorrect parameter values)
5703 *
5704 *       Notes: None
5705 *
5706 *       File:  cm_mem_wl.c
5707 *
5708 */
5709 static S16 cmHstGrmFreeInsert
5710 (
5711 CmHstGrmHashListCp* hashListCp, /* hash list cp */
5712 uint32_t blkSz, /* size of the block freed */
5713 uint32_t line, /* Line number */
5714 uint8_t  *fileName, /* file name */
5715 uint8_t  entId    /* Tapa task which free the memory */
5716 )
5717 {
5718    uint32_t      binIdx = 0; /* Bin index to insert the entry into the hash list */
5719    uint32_t      key = 0; /* Key to fine the bin index */
5720    uint32_t      ret = 0; /* Return value */
5721    CmMemEntries  *entry = NULLP; /* Entry which contains the information */
5722
5723
5724
5725    /* check for the total number of entries in the hash list. *
5726     * If there is no place for new entry return failure */
5727     cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5728
5729    /* After comuting the hash bind and key, check the entity already *
5730       existing or not. if we found the entry then update the information */
5731    ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5732    if(ret == ROK)
5733    {
5734                 entry->freedBytes += blkSz;
5735       entry->bucketFreeReq++;
5736       return ROK;
5737    } /* End of if */
5738
5739    /* If hash list is full then print the error tna continue */
5740    if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5741    {
5742         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");
5743         return RFAILED;
5744    } /* End of if */
5745
5746    /* Take the address of next free entry in the hash bin */
5747    entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5748
5749    /* Increase the number of time frees called */
5750    entry->bucketFreeReq++;
5751         entry->freedBytes += blkSz;
5752
5753    /* Fill the information into the entry structure */
5754    cmHstGrmFillEntry(entry, key, line, fileName, entId);
5755    /* Increase the total numbet of entries in the bin */
5756    hashListCp->hashList[binIdx].numOfEntries++;
5757
5758    /* Increase the total number of entries in the hash list */
5759    hashListCp->totalNumEntries++;
5760
5761    return ROK;
5762 } /* end of cmHstGrmFreeInsert */
5763
5764
5765 /*
5766 *
5767 *       Fun:  ret = cmHstGrmAllocInsert
5768 *
5769 *       Desc:  Inserts a memory allocated information in the hash list. Parameters are:
5770 *
5771 *              hashListCp   control point for hash list
5772 *              key          pointer to key string in the new entry
5773 *
5774 *       Ret:   ROK      - insertion successful
5775 *              RFAILED  - insertion failed (incorrect parameter values)
5776 *
5777 *       Notes: None
5778 *
5779 *       File:  cm_mem_wl.c
5780 *
5781 */
5782 static S16 cmHstGrmAllocInsert
5783 (
5784 CmHstGrmHashListCp     *hashListCp,
5785 uint32_t blkSz,
5786 uint32_t *reqSz,
5787 uint32_t line,
5788 uint8_t  *fileName,
5789 uint8_t  entId
5790 )
5791 {
5792    uint32_t      binIdx = 0;
5793    uint32_t      key = 0;
5794    uint32_t      ret = 0;
5795    CmMemEntries  *entry = NULLP;
5796
5797
5798    /* check for the total number of entries in the hash list. *
5799     * If there is no place for new entry return failure */
5800    cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5801
5802    /* After comuting the hash bind and key, check the entity already *
5803       existing or not. if we found the entry then update the information */
5804    ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5805
5806    if(ret == ROK)
5807    {
5808            entry->allocBytes += blkSz;
5809       entry->bucketAllocReq++;
5810       entry->wastedBytes += (blkSz - *reqSz);
5811       return ROK;
5812    } /* End of if */
5813
5814    if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5815    {
5816         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");
5817         return RFAILED;
5818    } /* End of if */
5819
5820    /* Take the address of next free entry in the hash bin */
5821    entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5822
5823    /* Clauculae the wasted bytes */
5824    /* Here wasted byte is differnce between the byte user
5825     * has requested and the byte the ssi allocated */
5826    entry->wastedBytes += (blkSz - *reqSz);
5827    entry->bucketAllocReq++;
5828         entry->allocBytes += blkSz;
5829
5830    /* Fill the information into the entry structure */
5831    cmHstGrmFillEntry(entry, key, line, fileName, entId);
5832    /* Increase the total numbet of entries in the bin */
5833    hashListCp->hashList[binIdx].numOfEntries++;
5834
5835    /* Increase the total number of entries in the hash list */
5836    hashListCp->totalNumEntries++;
5837
5838    return ROK;
5839 } /* end of cmHstGrmAllocInsert */
5840
5841
5842 /*
5843 *
5844 *       Fun:   cmHstGrmGetHashIdxAndKey
5845 *
5846 *       Desc:  Finds an entry in the hash list. Parameters are:
5847 *
5848 *              hashListCp   control point for hash list
5849 *              key          pointer to key string in the new entry
5850 *
5851 *       Ret:   ROK      - insertion successful
5852 *              RFAILED  - insertion failed (incorrect parameter values)
5853 *
5854 *       Notes: None
5855 *
5856 *       File:  cm_mem_wl.c
5857 *
5858 */
5859 static S16 cmHstGrmGetHashIdxAndKey
5860 (
5861 uint8_t   *fileName,
5862 uint32_t  line,
5863 uint32_t  *binIdx,
5864 uint32_t  *key
5865 )
5866 {
5867
5868    uint32_t  i = 0;
5869
5870    /* Calculate the key using file name and line number */
5871    for(i = 0 ; fileName[i] != '\0'; i++)
5872    {
5873        *key += fileName[i];
5874    }/* End of for */
5875        *key += line;
5876    *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
5877    return ROK;
5878 } /* end of cmHstGrmFillEntry */
5879
5880 /*
5881 *
5882 *       Fun:   cmHstGrmFillEntry
5883 *
5884 *       Desc:  Insert the entry into the hash list.
5885 *
5886 *              entry : Infornation which will be inserted into the hash list
5887 *              key   : Which will be used ti find the entry.
5888 *              line  : Line number
5889 *              fileName : File name
5890 *              entId   : Tapa task Id
5891 *
5892 *       Ret:   ROK      - insertion successful
5893 *              RFAILED  - insertion failed (incorrect parameter values)
5894 *
5895 *       Notes: None
5896 *
5897 *       File:  cm_mem_wl.c
5898 *
5899 */
5900 static S16 cmHstGrmFillEntry
5901 (
5902 CmMemEntries       *entry,
5903 uint32_t key,
5904 uint32_t line,
5905 uint8_t  *fileName,
5906 uint8_t  entId
5907 )
5908 {
5909
5910    uint32_t       idx = 0;
5911    entry->key = key;
5912    entry->line = line;
5913    entry->entId = entId;
5914    for(idx = 0; fileName[idx] != '\0'; idx++)
5915    {
5916       entry->fileName[idx] = fileName[idx];
5917    }
5918    entry->fileName[idx] = '\0';
5919    return ROK;
5920 } /* end of cmHstGrmFillEntry */
5921
5922 /*
5923 *
5924 *       Fun:  cmHstGrmFindEntry
5925 *
5926 *       Desc:  Finds an entry in the hash list. Parameters are:
5927 *
5928 *              hashListCp   control point for hash list
5929 *              key          pointer to key string in the new entry
5930 *
5931 *       Ret:   ROK      - insertion successful
5932 *              RFAILED  - insertion failed (incorrect parameter values)
5933 *
5934 *       Notes: None
5935 *
5936 *       File:  cm_mem_wl.c
5937 *
5938 */
5939 static S16 cmHstGrmFindEntry
5940 (
5941 CmHstGrmHashListCp  *hashListCp,
5942 uint32_t            key,
5943 uint32_t            *binIdx,
5944 CmMemEntries        **entry
5945 )
5946 {
5947
5948    uint32_t             numEnt = 0;
5949    uint32_t             numBin = 0;
5950    CmHstGrmHashListEnt  *tmpBin = NULLP;
5951
5952
5953    for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
5954    {
5955       /* find for the entry in the bin */
5956       tmpBin = &(hashListCp->hashList[*binIdx]);
5957       for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
5958       {
5959          /* If key supplied is matched with the stored key then
5960           * return that entity */
5961          if(tmpBin->entries[numEnt].key == key)
5962          {
5963             *entry = &(tmpBin->entries[numEnt]);
5964             return ROK;
5965          }/* End of if (tmpBin->entries[numEnt].key) */
5966       }/* end of for (numEnt = 0) */
5967
5968       /* Here we are checking for any room left in the bin. If the room *
5969          exists its mean that there is no entry with the Key. so return *
5970          failure.
5971          If there is no room in the bin, then check the other bins to find *
5972          the entry */
5973       if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
5974       {
5975         if(*binIdx == CMM_HIST_MAX_MEM_BIN)
5976         {
5977             *binIdx = 0;
5978         }/* End of if (binIdx) */
5979         else
5980         {
5981             *binIdx++;
5982         }/* End of else (binIdx) */
5983       } /* End of if (numEnt) */
5984       else
5985       {
5986          printf ("Unable to find the entry in hash list\n");
5987          return RFAILED;
5988       }/* End of else (numEnt) */
5989    }/* end of for (numBin = 0) */
5990
5991    printf("Unable to find the entry in the hash list\n");
5992    return RFAILED;
5993 } /* end of cmHstGrmFindEntry */
5994
5995 #endif /* SS_HISTOGRAM_SUPPORT */
5996 #ifdef T2K_MEM_LEAK_DBG
5997 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
5998 uint32_t getT2kMemLeakIndex(uint32_t address)
5999 {
6000    return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
6001 }
6002
6003 static uint32_t t2kMemAllocTick;
6004 static uint32_t smallTick;
6005
6006 void InsertToT2kMemLeakInfo(uint32_t address, uint32_t size, uint32_t lineNo, char* fileName)
6007 {
6008    uint32_t idx = getT2kMemLeakIndex(address);
6009
6010    if(((uint32_t)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
6011    {
6012      printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
6013            "line is %ld \n", address, size, fileName, lineNo);
6014    }
6015
6016    if(gMemLeakInfo[idx].address == 0)
6017    {
6018       gMemLeakInfo[idx].address = address;
6019       gMemLeakInfo[idx].size = size;
6020       gMemLeakInfo[idx].lineNo = lineNo;
6021       gMemLeakInfo[idx].fileName = fileName;
6022       gMemLeakInfo[idx].age = t2kMemAllocTick; 
6023       gMemLeakInfo[idx].prevRemLineNo = 0;
6024       gMemLeakInfo[idx].prevRemFileName = '\0';
6025
6026       if(smallTick++ == 4096)
6027       {
6028          smallTick = 0;
6029               gMemLeakInfo[idx].age = (++t2kMemAllocTick); 
6030       }
6031    }
6032    else
6033    {
6034          printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
6035                "line is %ld \n",address, idx, fileName, lineNo);
6036          printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
6037                "Age:%ld, differnce in Age:%ld",
6038                gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
6039                gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
6040                gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
6041    }
6042 }
6043
6044
6045 void RemoveFromT2kMemLeakInfo(uint32_t address, char *file, uint32_t line)
6046 {
6047    uint32_t idx = getT2kMemLeakIndex(address);
6048
6049    if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
6050    {
6051       printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
6052               idx,
6053               address,
6054               file,
6055               line);
6056    }
6057    if(gMemLeakInfo[idx].address == address)
6058    {
6059       gMemLeakInfo[idx].address = 0;
6060       gMemLeakInfo[idx].age = 0; 
6061       gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6062       gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName; 
6063
6064       gMemLeakInfo[idx].lastDelLineNum = line;
6065       gMemLeakInfo[idx].lastDelFileName = file; 
6066       /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6067    }
6068    else
6069    {
6070          printf("Something is wrong, trying to remove %lx idx = %ld  from"
6071                "File=%s, line=%ld address present is %lx\n",address, idx, file,line, 
6072                    gMemLeakInfo[idx].address);
6073
6074
6075          printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6076                  gMemLeakInfo[idx].lastDelLineNum);
6077
6078          if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6079          {
6080             printf("Previous File:%s, Previous Line:%ld\n",
6081                   gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6082          }
6083    }
6084 }
6085
6086 void DumpT2kMemLeakInfoToFile()
6087 {
6088    int i;
6089   
6090    FILE *fp = fopen("memLeakInfo.txt","wb");
6091
6092    if(fp == NULL)
6093    {
6094       printf("Could not open file for dumping mem leak info\n");
6095       return;
6096    }
6097
6098    for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6099    {
6100       if(gMemLeakInfo[i].address != 0)
6101       {
6102          char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6103          if(onlyFileName == NULL)
6104          {
6105             onlyFileName = gMemLeakInfo[i].fileName;
6106          }
6107
6108          fprintf(fp, "%ld  s=%ld  a=%ld  l=%ld  f=%s\n",gMemLeakInfo[i].address,
6109                                             gMemLeakInfo[i].size,
6110                                             gMemLeakInfo[i].age,
6111                                             gMemLeakInfo[i].lineNo,
6112                                             onlyFileName);
6113       }
6114    }
6115
6116    fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6117
6118    fclose(fp);
6119 }
6120 #endif
6121
6122 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6123
6124 /* For Updating SOC Specific Memory Information */
6125 S16 UpdateSocMemInfo
6126 (
6127 uint8_t areaIndex,
6128 CmLteMemInfo *mInfo
6129 )
6130 {
6131    uint8_t  idxReg;
6132    uint8_t  idxPool;
6133    uint16_t  numPool;
6134    void *iccHdl = NULLP;
6135    uint32_t poolFreeCnt[4];
6136    uint32_t poolUsedCnt[4];
6137    uint32_t poolSize[4];
6138    uint32_t poolTotAvail[4];
6139
6140    idxReg = mInfo->numRegions;
6141    mInfo->numRegions = mInfo->numRegions + 1;
6142    /* Calling Soc specific API to get shared memory status */
6143    numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6144    iccHdl = ssGetIccHdl(areaIndex);
6145
6146    /* Populating global memory information */
6147    mInfo->regInfo[idxReg].numPools = numPool;
6148    mInfo->regInfo[idxReg].regionId = areaIndex;
6149    mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6150
6151    /* Calling INTEL API's to Get Free MEM BLOCKS */
6152    poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6153    poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6154    poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6155    poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6156
6157    poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6158    poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6159    poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6160    poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6161      
6162    poolSize[0] = ICC_POOL_ZERO_SIZE;
6163    poolSize[1] = ICC_POOL_ONE_SIZE;
6164    poolSize[2] = ICC_POOL_TWO_SIZE;
6165    poolSize[3] = ICC_POOL_THREE_SIZE;
6166
6167    poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6168    poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6169    poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6170    poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6171
6172    for(idxPool=0; idxPool<numPool;idxPool++)
6173    {
6174       mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6175       mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable = 
6176                                                 poolTotAvail[idxPool];
6177       mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6178       if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed > 
6179                    mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6180       {
6181          mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed = 
6182                          mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6183       }
6184    }
6185
6186    return ROK;
6187 }
6188
6189 /*
6190 *
6191 *       Fun:   isL2MemUsageBelowLowerThreshold
6192 *
6193 *       Desc:  Checks for the Lower threshold of ICC memory.
6194 *
6195 *              region       region for obtaining the ICC handle
6196 *
6197 *       Ret:   TRUE      - Threshold has reached
6198 *              FALSE     - Threshold has not reached
6199 *
6200 *       Notes: None
6201 *
6202 *       File:  cm_mem_wl.c
6203 *
6204 */
6205 uint32_t isL2MemUsageBelowLowerThreshold(
6206 Region region
6207 )
6208 {
6209    void * iccHdl = ssGetIccHdl(region);
6210
6211    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6212    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6213
6214    /* We are below the threshold if free count in BOTH of the pools
6215     * is above the ICC_MEM_LOWER_THRESHOLD % */
6216    if(((poolZeroFreeCnt * 100) > 
6217       (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6218       ((poolOneFreeCnt * 100) >
6219        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6220      {
6221         return (TRUE);
6222      }
6223
6224    return (FALSE);
6225 }
6226
6227
6228 /*
6229 *
6230 *       Fun:   isMemUsageBelowLowerThreshold
6231 *
6232 *       Desc:  Checks for the Lower threshold of ICC memory.
6233 *
6234 *              region       region for obtaining the ICC handle
6235 *
6236 *       Ret:   TRUE      - Threshold has reached
6237 *              FALSE     - Threshold has not reached
6238 *
6239 *       Notes: None
6240 *
6241 *       File:  cm_mem_wl.c
6242 *
6243 */
6244 uint32_t isMemUsageBelowLowerThreshold(
6245 Region region
6246 )
6247 {
6248    void * iccHdl = ssGetIccHdl(region);
6249
6250    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6251    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6252    uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6253    uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6254
6255    /* We are below the threshold if free count in BOTH of the pools
6256     * is above the ICC_MEM_LOWER_THRESHOLD % */
6257    if(((poolZeroFreeCnt * 100) > 
6258       (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6259       ((poolOneFreeCnt * 100) >
6260        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6261       ((poolTwoFreeCnt * 100) >
6262        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6263       ((poolThreeFreeCnt * 100) >
6264        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6265      {
6266         return (TRUE);
6267      }
6268
6269    return (FALSE);
6270 }
6271
6272 /*
6273 *
6274 *       Fun:   isMemUsageAboveUpperThreshold
6275 *
6276 *       Desc:  Checks for the Upper threshold of ICC memory.
6277 *
6278 *              region       region for obtaining the ICC handle
6279 *
6280 *       Ret:   TRUE      - Threshold has reached
6281 *              FALSE     - Threshold has not reached
6282 *
6283 *       Notes: None
6284 *
6285 *       File:  cm_mem_wl.c
6286 *
6287 */
6288 static uint32_t isMemUsageAboveUpperThreshold(
6289 Region region
6290 )
6291 {
6292    void * iccHdl = ssGetIccHdl(region);
6293
6294    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6295    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6296    uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6297    uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6298
6299    /* We are above the threshold if free count in either of the pools
6300     * is below the ICC_MEM_UPPER_THRESHOLD % */
6301    if(((poolZeroFreeCnt * 100) < 
6302       (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6303       ((poolOneFreeCnt * 100) <
6304        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6305       ((poolTwoFreeCnt * 100) <
6306        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6307       ((poolThreeFreeCnt * 100) <
6308        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6309      {
6310         return (TRUE);
6311      }
6312
6313    return (FALSE);
6314 }
6315
6316 /* ccpu00142274- Function to check if we have reached the 
6317  * Threshold for dropping UL packets at the RLC. This function
6318  * measures the free count of the ICC memory and based on the 
6319  * volume of packets it sets an alarm to drop packets. 
6320  * In DL, the PDCP packets are dropped at Admission Control, but 
6321  * at UL we need to check if its an AM(Data only and 
6322  * not Status PDU) or UM packet and free the PDU 
6323  * Note: With the current design, we have PDCP DL and RLC UL
6324  * running in the same thread and the below function will be 
6325  * accessed in tandem. But if PDCP DL and RLC UL are made to run 
6326  * in different threads then there might be a race condition.
6327  * Please revisit this function in such a case.
6328  * */
6329 /*
6330 *
6331 *       Fun:   isMemThreshReached
6332 *
6333 *       Desc:  Checks whether the system has reached the 
6334 *              designated threshold of ICC memory.
6335 *
6336 *              region       region for obtaining the ICC handle
6337 *
6338 *       Ret:   ROK         - Threshold has not reached
6339 *              RFAILED     - Threshold has reached
6340 *
6341 *       Notes: None
6342 *
6343 *       File:  cm_mem_wl.c
6344 *
6345 */
6346 uint32_t isMemThreshReached(
6347 Region reg
6348 )
6349 {
6350    if(gMemoryAlarm)
6351    {
6352       gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6353       return RFAILED;
6354    }
6355    else
6356    {
6357       if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6358       {
6359          gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6360          memoryCheckCounter = 0;
6361       }
6362    }
6363    return ROK;
6364 }
6365 #endif
6366 #endif /* SS_LOCKLESS_MEMORY */
6367 /**********************************************************************
6368          End of file
6369  **********************************************************************/
6370