31c073b08b8bf91ff8da159918b61fdb4c7be7d4
[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
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    SPutSBuf(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    SGetSBuf(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
1827    if((SLock(&dynAllocFreeLock)) != ROK)
1828    {
1829       printf("cmDynAllocWithLock: Failed to get the dyn lock\n");
1830       return RFAILED;
1831    }
1832
1833    ret =  cmDynAlloc (regionCb, size,flags,ptr);
1834
1835    if((SUnlock(&dynAllocFreeLock)) != ROK)
1836    {
1837       printf("cmDynAllocWithLock: Failed to unlock the Dyn lock\n");
1838       return RFAILED;
1839    }
1840  
1841    return (ret);
1842 } /* end of cmDynAlloc */
1843
1844 /*
1845 *
1846 *       Fun:   cmDynAlloc
1847 *
1848 *       Desc:  Allocate a memory block for use by dynamic buffers
1849 *
1850 *
1851 *       Ret:   ROK     - successful
1852 *              RFAILED - unsuccessful.
1853 *
1854 *       Notes: 
1855 *
1856 *       File:  cm_mem_wl.c
1857 *
1858 */
1859 /* cm_mem_c_001.main_15 : Additions */
1860
1861 static S16  cmDynAlloc
1862 (
1863 Void   *regionCb,    /* Pointer to a region */
1864 Size   *size,        /* size needs to be allocated */
1865 uint32_t flags,       /* Flags used */
1866 Data  **ptr          /* Reference to pointer for which need to be allocate */
1867 )
1868 {
1869    CmMmDynRegCb        *regCb;
1870
1871
1872    regCb = (CmMmDynRegCb *)regionCb;
1873
1874 #ifdef SS_MEM_WL_DEBUG
1875       if((tmpRegTidMap[regCb->region] != (pthread_self())) )
1876       {
1877          **ptr = 10;
1878       }
1879 #endif
1880
1881 #if (ERRCLASS & ERRCLS_INT_PAR)
1882
1883    /* error check on parameters */
1884    if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
1885    {
1886       return RFAILED;
1887    }
1888 #endif
1889   
1890 #ifndef USE_PURE
1891
1892    /* 
1893     * Check if the requested size is less than or equal to the maximum block 
1894     * size in the bucket. 
1895     */
1896    
1897 #ifdef SS_MEM_WL_DEBUG
1898    if ( (*size + 4) <= regCb->bktMaxBlkSize)
1899 #else
1900    if ( (*size) <= regCb->bktMaxBlkSize)
1901 #endif
1902    {
1903       uint32_t                  idx;
1904       CmMmBlkSetElement   *dynMemElem;
1905       uint32_t                  bktIdx;
1906       CmMmDynBktCb        *bkt;
1907
1908       /* Get the map to the mapping table */
1909 #ifdef SS_MEM_WL_DEBUG
1910       idx = (((*size + 4) - 1) >> regCb->bktQnPwr);
1911 #else
1912       idx = (((*size) - 1) >> regCb->bktQnPwr);
1913 #endif
1914
1915 #if (ERRCLASS & ERRCLS_DEBUG)
1916       if (regCb->mapTbl[idx].bktIdx == 0xFF)
1917       { 
1918          printf("Failed to get the buffer of size %d\n", *size);
1919          /* Some fatal error in the map table initialization. */
1920          return RFAILED;
1921       }
1922 #endif
1923      if (idx > 512)
1924      {
1925          return RFAILED;
1926      }
1927       /* Dequeue the memory block and return it to the user */
1928       bktIdx = regCb->mapTbl[idx].bktIdx;
1929       bkt = &(regCb->bktTbl[bktIdx]);
1930 #ifdef SS_MEM_WL_DEBUG
1931       if(bkt->size < (*size+4))
1932 #else
1933       if(bkt->size < (*size))
1934 #endif
1935       {
1936          idx++;
1937          bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
1938       }
1939
1940       dynMemElem = cmGetMemBlkSetForAlloc(bktIdx, bkt);
1941
1942       /* Check if the bucket index, if its not valid, return failure */
1943       if(dynMemElem == NULLP)
1944       {
1945 #ifndef ALIGN_64BIT
1946          printf("Failed to get the buffer of size %ld\n", *size);
1947 #else
1948          printf("Failed to get the buffer of size %d\n", *size);
1949 #endif
1950          return RFAILED;
1951       }
1952
1953 #ifdef SS_MEM_WL_DEBUG
1954       if(dynMemElem->nextBktPtr == prvAllocPtr[regCb->region])
1955       {
1956           uint32_t    *tmpDump;
1957           *tmpDump = 100;
1958       }
1959 #endif
1960       /* Get the bucket node from the index returned and allocate the memory */
1961       *ptr = dynMemElem->nextBktPtr;
1962       if (*ptr == NULLP)
1963       {
1964         return RFAILED;
1965       }
1966       dynMemElem->nextBktPtr = *((CmMmEntry **)(*ptr));
1967       dynMemElem->numFreeBlks--;
1968
1969 #ifdef SS_MEM_WL_DEBUG
1970       prvAllocPtr[regCb->region] = *ptr;
1971
1972       **ptr = (uint8_t) bktIdx;
1973       *(*ptr+1) = 0xde;
1974       *(*ptr+2) = 0xad;
1975       *(*ptr+3) = 0xbe;
1976       *ptr += sizeof (uint32_t);
1977
1978       if ((bktIdx == 0) && (!stopBtInfo))
1979       {
1980          CmBtInfo *btInfo;
1981          uint32_t      btIdx;
1982          btInfo  = &allocBtInfo[regCb->region];
1983          btIdx = btInfo->btInfoIdx;
1984          btInfo->btInfo[btIdx].ptr = (PTR) *ptr;
1985          {
1986             btInfo->btInfo[btIdx].btSize  = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
1987          }
1988          gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
1989    
1990          btIdx++;
1991          btIdx &= (NUM_FREE_BUFFERS - 1); 
1992    
1993          btInfo->btInfo[btIdx].ptr = (PTR)0;
1994          btInfo->btInfo[btIdx].btSize = 0;
1995          memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
1996          btInfo->btInfoIdx = btIdx;
1997       }
1998 #endif
1999
2000       return ROK;
2001    }
2002
2003    /* If the size is not matching, return failure to caller */
2004 #ifndef ALIGN_64BIT
2005    printf("Failed to get the buffer of size %ld\n", *size);
2006 #else
2007    printf("Failed to get the buffer of size %d\n", *size);
2008 #endif
2009    return RFAILED;
2010    
2011 #else /* use pure is on */
2012
2013 #ifdef SS_4GMX_LCORE
2014    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2015    memset(ptr, 0, *size);
2016 #else
2017 /*   *ptr = (Data*) malloc(*size); */
2018 #endif
2019    *ptr = (Data *)malloc(*size);
2020
2021    if ( (*ptr) == NULLP)
2022        return RFAILED;
2023    /* avail_size -= *size; */
2024    return ROK;
2025 #endif /* USE_PURE */
2026
2027 } /* end of cmDynAlloc */
2028 #endif /* SS_USE_ICC_MEMORY */
2029
2030
2031 #define OVERUSED(_bkt) (((_bkt)->numAlloc * 100) / (_bkt)->numBlks > 80)
2032
2033 int g_overused[5] = {0};
2034
2035 \f
2036 /*
2037 *
2038 *       Fun:   cmAlloc
2039 *
2040 *       Desc:  Allocate a memory block for the memory region.
2041 *
2042 *
2043 *       Ret:   ROK     - successful
2044 *              RFAILED - unsuccessful.
2045 *
2046 *       Notes: 
2047 *              The function allocates a memory block of size atleast equal to 
2048 *              the requested size. The size parameter will be updated with the 
2049 *              actual size of the memory block allocated for the request. The 
2050 *              CMM tries to allocate the memory block form the bucket pool. If
2051 *              there is no memory in the bucket the CMM allocates the memory 
2052 *              block form the heap pool. This function is always called by the
2053 *              System Service module.
2054 *    
2055 *              The caller of the function should try to use the out value of 
2056 *              the size while returning the memory block to the region. However 
2057 *              the current design of the memory manager does not enforce to pass
2058 *              the actual size of the memory block.  (Due to the SGetSBuf 
2059 *              semantics the layer will not able to pass the correct size of the
2060 *              memory block while calling SPutSBuf).
2061 *
2062 *
2063 *       File:  cm_mem_wl.c
2064 *
2065 */
2066 /* cm_mem_c_001.main_12 - addition to accept new parameter memType(static/dynamic) */
2067
2068 /* cm_mem_c_001.main_15 : Additions */
2069 #ifdef T2K_MEM_LEAK_DBG
2070 static S16  cmAlloc
2071 (
2072  Void   *regionCb,
2073  Size   *size,
2074  uint32_t     flags,
2075  Data  **ptr ,
2076  char* file,
2077  uint32_t line
2078  )
2079 #else
2080 #ifdef SS_HISTOGRAM_SUPPORT
2081 #ifdef SSI_DEBUG_LEVEL1
2082 static S16  cmAlloc
2083 (
2084 Void   *regionCb,
2085 Size   *size,
2086 uint32_t     flags,
2087 Data  **ptr,
2088 uint32_t     memType,
2089 uint32_t     line,
2090 uint8_t     *fileName,
2091 uint8_t      entId,
2092 Bool    hstReg
2093 )
2094 #else
2095 static S16  cmAlloc
2096 (
2097 Void   *regionCb,
2098 Size   *size,
2099 uint32_t     flags,
2100 Data  **ptr,
2101 uint32_t     line,
2102 uint8_t     *fileName,
2103 uint8_t      entId,
2104 Bool    hstReg
2105 )
2106 #endif /* SSI_DEBUG_LEVEL1 */
2107
2108 #else
2109
2110 #ifdef SSI_DEBUG_LEVEL1
2111 static S16  cmAlloc
2112 (
2113 Void   *regionCb,
2114 Size   *size,
2115 uint32_t     flags,
2116 Data  **ptr,
2117 uint32_t     memType
2118 )
2119 #else
2120 static S16  cmAlloc
2121 (
2122 Void   *regionCb,
2123 Size   *size,
2124 uint32_t     flags,
2125 Data  **ptr 
2126 )
2127
2128 #endif
2129 #endif /* SSI_DEBUG_LEVEL1 */
2130 /* cm_mem_c_001.main_15: Additions */
2131 #endif /* SS_HISTOGRAM_SUPPORT */
2132
2133 {
2134 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2135 #ifndef USE_PURE
2136    uint16_t        idx;
2137    CmMmBkt   *bkt;
2138    uint16_t   bktIdx;
2139 #endif
2140    CmMmRegCb *regCb;
2141 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2142 #ifndef USE_PURE
2143    uint16_t        cnt;
2144 #endif
2145 /*   cm_mem_c_001.main_15 : Additions */
2146 #ifdef SS_MEM_LEAK_STS
2147    Size       reqSz;
2148 #endif /* SS_MEM_LEAK_STS */
2149 /* cm_mem_c_001.main_12 - addition to hold the allocated block */
2150 #ifdef SSI_DEBUG_LEVEL1
2151    CmMmBlkHdr *alocBlk;
2152 #endif /* SSI_DEBUG_LEVEL1 */
2153 /*   cm_mem_c_001.main_15 : Additions */
2154 #ifdef SS_HISTOGRAM_SUPPORT
2155         S8 hstGrmBuf[256];
2156 #endif /* SS_HISTOGRAM_SUPPORT */
2157
2158
2159 #ifndef USE_MEMCAL
2160    UNUSED(flags);
2161 #endif
2162 /*  cm_mem_c_001.main_15 : Additions */
2163 #ifdef SS_MEM_LEAK_STS 
2164    reqSz = *size;
2165 #endif /* SS_MEM_LEAK_STS */
2166
2167    regCb = (CmMmRegCb *)regionCb;
2168
2169 #if (ERRCLASS & ERRCLS_INT_PAR)
2170
2171    /* error check on parameters */
2172    if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
2173    {
2174       return RFAILED;
2175    }
2176 #endif
2177   
2178 /* cm_mem_c_001.main_12 - addition for checking memType parameter */
2179 #ifdef SSI_DEBUG_LEVEL1
2180 #if (ERRCLASS & ERRCLS_INT_PAR)
2181       if ((memType != CMM_STATIC_MEM_FLAG) && (memType != CMM_DYNAMIC_MEM_FLAG))
2182       {
2183          return RFAILED;
2184       }
2185 #endif /* (ERRCLASS & ERRCLS_INT_PAR) */
2186 #endif /* SSI_DEBUG_LEVEL1 */
2187
2188 #ifndef USE_PURE
2189
2190    if (flags)
2191       num_times++;
2192
2193 /* cm_mem_c_001.main_12 - addition to insert the size into hash list */
2194 #ifdef SSI_DEBUG_LEVEL1
2195    /* Update the hash list */
2196    if (cmMmHashListInsert(&(regCb->hashListCp), *size) != ROK)
2197    {
2198       /* display that, this entry could not be made in the hash list */
2199 #ifdef DEBUGP
2200       /* display an error message here */
2201 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2202 #ifdef ALIGN_64BIT          
2203       sprintf(dbgPrntBuf, "\n Could not make an entry for size %u in hash table of region %d \n",
2204                            *size, regCb->region);
2205 #else                           
2206       sprintf(dbgPrntBuf, "\n Could not make an entry for size %lu in hash table of region %d \n",
2207                            *size, regCb->region);
2208 #endif                           
2209       SDisplay(0, dbgPrntBuf);
2210 #endif /* DEBUGP */
2211    }
2212 #endif /* SSI_DEBUG_LEVEL1 */
2213
2214    /* 
2215     * Check if the requested size is less than or equal to the maximum block 
2216     * size in the bucket. 
2217     */
2218    if ( *size <= regCb->bktMaxBlkSize)
2219    {
2220       /* Get the map to the mapping table */
2221       idx = ((*size - 1) >> regCb->bktQnPwr);
2222
2223 #if (ERRCLASS & ERRCLS_DEBUG)
2224       if (regCb->mapTbl[idx].bktIdx == 0xFF)
2225       { 
2226          /* Some fatal error in the map table initialization. */
2227          return RFAILED;
2228       }
2229 #endif
2230
2231       /* Dequeue the memory block and return it to the user */
2232       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2233
2234       cnt = 0;
2235       /* While loop is introduced to use the "break statement inside */
2236       while (cnt < 1)
2237       {
2238          /*
2239           * Check if the size request is not greater than the size available
2240           * in the bucket
2241           */
2242          if (*size > bkt->size)
2243          {
2244             /* Try to go to the next bucket if available */
2245             if((idx < (CMM_MAX_MAP_ENT - 1)) &&
2246                (regCb->mapTbl[++idx].bktIdx != 0xFF))
2247             {
2248                bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2249             }
2250             else
2251             {
2252                /* This is the last bucket, try to allocate from heap */
2253                break;
2254             }
2255          }
2256
2257          /* Acquire the bucket lock */
2258          /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
2259 #ifdef SS_WIN
2260          (Void) WTLock(&(bkt->bktLock));
2261 #else
2262          (Void) SLock(&(bkt->bktLock));
2263 #endif
2264
2265 #if (ERRCLASS & ERRCLS_DEBUG)
2266          regCb->mapTbl[idx].numReq++;
2267 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2268
2269 /* cm_mem_c_001.main_12 - addition for sanity check before allocation */
2270 #ifdef SSI_DEBUG_LEVEL1
2271       /* increment the allocation attempt counter at bucket level */
2272       bkt->numAllocAttempts++;
2273
2274       /* detect trampling if any and call sanity check. This is done for (bkt->nextBlk) as
2275          the allocation is always from (bkt->nextBlk) */
2276       if (bkt->nextBlk)
2277       {
2278          if (cmMmRegIsBlkSane(bkt->nextBlk) != ROK)
2279          {
2280                /* detected a trampled memory block in this bucket */
2281             #ifdef DEBUGP
2282                /* display an error message here */
2283 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2284 #ifdef ALIGN_64BIT          
2285                sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
2286                                     (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2287 #else                                    
2288                sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
2289                                     (void *)bkt->nextBlk, regCb->mapTbl[idx].bktIdx, *size);
2290 #endif                                    
2291                SDisplay(0, dbgPrntBuf);
2292             #endif /* DEBUGP */
2293
2294                if (cmMmBktSanityChk(bkt) == RTRAMPLINGNOK)
2295                {
2296                   /* Release the lock */
2297                   /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2298 #ifdef SS_WIN
2299                   (Void) WTUnlock(&(bkt->bktLock));
2300 #else
2301                   (Void) SUnlock(&(bkt->bktLock));
2302 #endif
2303                   /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
2304                   return (RTRAMPLINGNOK);
2305                }
2306                else
2307                {
2308                   /* Release the lock */
2309                   /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2310 #ifdef SS_WIN
2311                   (Void) WTUnlock(&(bkt->bktLock));
2312 #else
2313                   (Void) SUnlock(&(bkt->bktLock));
2314 #endif
2315                   /* return RFAILED */
2316                   return RFAILED;
2317                }
2318          }
2319       }
2320
2321       if ((bkt->nextBlk) && (*ptr = (Data *)(bkt->nextBlk) + (sizeof(CmMmBlkHdr))))
2322 #else
2323          if ((*ptr = bkt->next))
2324 #endif /* SSI_DEBUG_LEVEL1 */
2325          {
2326 /* cm_mem_c_001.main_12 - addition for header */
2327 #ifdef SSI_DEBUG_LEVEL1
2328       /* point to next block header */
2329          alocBlk = bkt->nextBlk;
2330          bkt->nextBlk = (CmMmBlkHdr *)(bkt->nextBlk->nextBlk);
2331 #else
2332             bkt->next = *((CmMmEntry **)(bkt->next));
2333 #endif /* SSI_DEBUG_LEVEL1 */
2334
2335             /* 
2336              * Increment the statistics variable of number of memory block 
2337              * allocated 
2338              */
2339             bkt->numAlloc++;
2340             if (bkt->numAlloc > bkt->maxAlloc)
2341             {
2342                bkt->maxAlloc = bkt->numAlloc;
2343             }
2344             {
2345                if (g_overused[bktIdx] == 0 && OVERUSED(bkt))
2346                {
2347                   g_overused[bktIdx] = 1;
2348                   /*printf("cmAlloc: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
2349                }
2350             }
2351
2352 /* cm_mem_c_001.main_12 - addition for header manipulation */
2353 #ifdef SSI_DEBUG_LEVEL1
2354       /* update the size for which this memory block has been allocated */
2355       alocBlk->requestedSize = *size;
2356       /* update the memory block header */
2357       CMM_RESET_FREE_FLAG(alocBlk->memFlags);
2358       if (memType == CMM_STATIC_MEM_FLAG)
2359       {
2360          CMM_SET_STATIC_FLAG(alocBlk->memFlags);
2361          /* add it to the static memory allocated */
2362          bkt->staticMemUsed += bkt->size;
2363       }
2364       else
2365       {
2366          CMM_SET_DYNAMIC_FLAG(alocBlk->memFlags);
2367          /* add it to the dynamic memory allocated */
2368          bkt->dynamicMemUsed += bkt->size;
2369       }
2370 #endif /* SSI_DEBUG_LEVEL1 */
2371
2372             if (((bkt->size - (*size)) >> regCb->bktQnPwr) && flags)
2373             {
2374                bkt->bktNoFitCnt++;
2375 #ifdef MEMCAL_DEBUG
2376 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2377 #ifdef ALIGN_64BIT          
2378                sprintf(prntBuf,
2379    "[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++);
2380 #else   
2381                sprintf(prntBuf,
2382    "[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++);
2383 #endif   
2384                SDisplay(0, prntBuf);
2385 #endif
2386             }
2387
2388 #ifdef MEMCAL_DEBUG
2389             if (flags)
2390             {
2391                sprintf(prntBuf,
2392     "SGetSBuf:%08lu:Size Bucket Id:%03d  Times:%05lu  Pointer: %8p\n",
2393                     *size, regCb->mapTbl[idx].bktIdx, num_times, *ptr);
2394                SDisplay(0, prntBuf);
2395             }
2396 #endif /* MEMCAL_DEBUG */
2397  /*  cm_mem_c_001.main_15 : Additions */
2398 #ifdef SS_HISTOGRAM_SUPPORT
2399             /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
2400              * information into the hash list */
2401             if(hstReg)
2402             {
2403                if (cmHstGrmAllocInsert(&(bkt->hstGrmHashListCp), bkt->size, size, line, fileName, entId) != ROK)
2404                {
2405                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
2406                                           SPrint(hstGrmBuf);
2407                }
2408             }/* End of if */
2409
2410 #endif /* SS_HISTOGRAM_SUPPORT */
2411         
2412             /* Update the size parameter */
2413             *size = bkt->size;
2414 #ifdef SS_MEM_LEAK_STS
2415         /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
2416          cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size,
2417                           regCb->mapTbl[idx].bktIdx);
2418 #endif /* SS_MEM_LEAK_STS */
2419
2420       /* cm_mem_c_008.104 - Addition for memory calculator tool */
2421
2422             /* Release the lock */
2423             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2424 #ifdef SS_WIN
2425             (Void) WTUnlock(&(bkt->bktLock));
2426 #else
2427             (Void) SUnlock(&(bkt->bktLock));
2428 #endif
2429
2430             return ROK;
2431          }
2432          else if (flags)
2433          {
2434             bkt->bktFailCnt++;
2435 #ifdef MEMCAL_DEBUG
2436 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2437 #ifdef ALIGN_64BIT          
2438  sprintf(prntBuf,
2439             "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %u bytes], %u times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2440 #else            
2441  sprintf(prntBuf,
2442             "[MEM_CAL_CNTB] Allocation failed in bucket %d [ size %lu bytes], %lu times\n", regCb->mapTbl[idx].bktIdx, bkt->size, bkt->bktFailCnt);
2443 #endif            
2444             SDisplay(0, prntBuf);
2445 #endif
2446          }
2447
2448 #if (ERRCLASS & ERRCLS_DEBUG)
2449          regCb->mapTbl[idx].numFailure++;
2450 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
2451
2452          /* Release the lock */
2453          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
2454 #ifdef SS_WIN
2455             (Void) WTUnlock(&(bkt->bktLock));
2456 #else
2457             (Void) SUnlock(&(bkt->bktLock));
2458 #endif
2459          cnt = cnt + 1;
2460       }
2461    }
2462    else
2463    {
2464       if (flags)
2465       {
2466          regCb->heapCb.heapAllocCnt++;
2467 #ifdef MEMCAL_DEBUG
2468 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
2469 #ifdef ALIGN_64BIT          
2470          sprintf(prntBuf,
2471                  "[MEM_CAL_CNTC]  No bucket block configured for %u bytes \n Number of blocks allocated from heap = %u\n",*size,
2472                  regCb->heapCb.heapAllocCnt);
2473 #else                 
2474          sprintf(prntBuf,
2475                  "[MEM_CAL_CNTC]  No bucket block configured for %lu bytes \n Number of blocks allocated from heap = %lu\n",*size,
2476                  regCb->heapCb.heapAllocCnt);
2477 #endif                 
2478          SDisplay(0, prntBuf);
2479 #endif
2480       }
2481    }
2482
2483    /* Memory not available in the bucket pool */
2484    if (regCb->heapFlag &&  (*size < regCb->heapSize))
2485    {
2486 #ifdef MEMCAL_DEBUG
2487       if (flags) tryHeap = 1;
2488 #endif
2489       /* 
2490        * The heap memory block is available. Allocate the memory block from
2491        * heap pool.
2492        */ 
2493 /* cm_mem_c_001.main_15: Additions */
2494 #ifdef SS_HISTOGRAM_SUPPORT  
2495 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2496 #ifdef SSI_DEBUG_LEVEL1
2497        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType, line, fileName, entId, hstReg));
2498 #else
2499        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
2500 #endif /* SSI_DEBUG_LEVEL1 */
2501 #else
2502 /* cm_mem_c_001.main_12 - addition for passing an extra parameter */
2503 #ifdef SSI_DEBUG_LEVEL1
2504        return (cmHeapAlloc(&(regCb->heapCb), ptr, size, memType));
2505 #else
2506        return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
2507 #endif /* SSI_DEBUG_LEVEL1 */
2508 #endif /* SS_HISTOGRAM_SUPPORT */
2509    }
2510
2511    /* No memory available */
2512    return RFAILED;
2513 #else /* use pure is on */
2514 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
2515 #ifdef SS_4GMX_LCORE
2516    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
2517    memset(ptr, 0, *size);
2518 #else
2519    *ptr = (Data*) malloc(*size);
2520 #endif
2521    if ( (*ptr) == NULLP)
2522        return RFAILED;
2523    avail_size -= *size;
2524    return ROK;
2525 #endif /* USE_PURE */
2526
2527 } /* end of cmAlloc */
2528
2529 #ifdef SS_MEM_WL_DEBUG
2530 /*
2531 *
2532 *       Fun:   cmInitDoubleFreeList
2533 *
2534 *       Desc:  Initialize the hashlist used for detecting double free
2535 *
2536 *       Ret:   ROK     - successful
2537 *              RFAILED - unsuccessful.
2538 *
2539 *       Notes:
2540 *
2541 *
2542 *       File:  cm_mem_wl.c
2543 *
2544 */
2545 S16  cmInitDoubleFreeList(void)
2546 {
2547     uint16_t offset;
2548     CmMemDoubleFree  memNode;
2549
2550     offset = (uint16_t)((PTR)(&memNode.tmpListEnt) - (PTR)&memNode);
2551
2552     if((cmHashListInit(&(memDoubleFree), 1000, offset, 0,
2553         CM_HASH_KEYTYPE_UINT32_MOD, 0, 0)) != ROK);
2554     {
2555         return RFAILED;
2556     }
2557     SInitLock(&memDoubleFreeLock, SS_LOCK_MUTEX);
2558
2559     return ROK;
2560 }
2561
2562 #ifdef SS_MEM_WL_DEBUG 
2563 /*
2564 *
2565 *       Fun:   cmInitBtInfo
2566 *
2567 *       Desc:  Return the Dynamic memory block for the memory region.
2568 *
2569 *
2570 *       Ret:   ROK     - successful
2571 *              RFAILED - unsuccessful.
2572 *
2573 *       Notes:
2574 *
2575 *
2576 *       File:  cm_mem_wl.c
2577 *
2578 */
2579 static S16  cmInitBtInfo()
2580 {
2581    regBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2582    if (regBtInfo == NULLP)
2583    {
2584       return RFAILED;
2585    }
2586    allocBtInfo = (CmBtInfo *)calloc(1, 8 * sizeof (CmBtInfo));
2587    if(allocBtInfo == NULLP)
2588    {
2589       return RFAILED;
2590    }
2591
2592    return ROK;
2593 }
2594 #endif /* SS_MEM_WL_DEBUG */
2595 /*
2596 *
2597 *       Fun:   cmAnalyseBtInfo
2598 *
2599 *       Desc:  Return the Dynamic memory block for the memory region.
2600 *
2601 *
2602 *       Ret:   ROK     - successful
2603 *              RFAILED - unsuccessful.
2604 *
2605 *       Notes:
2606 *
2607 *
2608 *       File:  cm_mem_wl.c
2609 *
2610 */
2611 Void  cmAnalyseBtInfo
2612 (
2613 PTR   ptr,       /* Memory block needs to be freed */
2614 uint32_t   idx
2615 )
2616 {
2617    uint32_t  tmpCnt;
2618    uint32_t  btIdx;
2619    CmBtInfo  *btInfo;
2620    uint8_t    regIdx;
2621
2622 /*   for(regIdx = 0; regIdx < 8; regIdx++)
2623    { */
2624    idx = 2;
2625       btInfo = &allocBtInfo[idx];
2626       btIdx = btInfo->btInfoIdx;
2627    
2628       for (tmpCnt = 0; tmpCnt < NUM_FREE_BUFFERS; tmpCnt++)  
2629       {
2630 /*         if ((btInfo->btInfo[btIdx].ptr >= ptr) &&   
2631              (btInfo->btInfo[btIdx].ptr + 128 ) >= ptr)    */
2632          if(btInfo->btInfo[btIdx].btSize != 0)
2633          {
2634            uint32_t i;
2635            char **strings;
2636            strings = backtrace_symbols( btInfo->btInfo[btIdx].btArr,btInfo->btInfo[btIdx].btSize);
2637            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);
2638            for (i=0; i < btInfo->btInfo[btIdx].btSize; i++)
2639            {
2640               printf("%s\n", strings[i]); 
2641            }
2642            printf("*******************************************************\n");
2643            
2644            free(strings);
2645          }
2646    
2647          btIdx--; 
2648          if (btIdx == 0)
2649          {
2650             btIdx = NUM_FREE_BUFFERS - 1;
2651          }
2652       }
2653 /*    } */
2654
2655    return;
2656 }
2657 #endif
2658
2659 #ifndef SS_USE_ICC_MEMORY
2660 /*
2661 *
2662 *       Fun:   cmDynFreeWithLock
2663 *
2664 *       Desc:  Return the Dynamic memory block for the memory region.
2665 *
2666 *
2667 *       Ret:   ROK     - successful
2668 *              RFAILED - unsuccessful.
2669 *
2670 *       Notes:
2671 *
2672 *
2673 *       File:  cm_mem_wl.c
2674 *
2675 */
2676 static S16  cmDynFreeWithLock
2677 (
2678 Void   *regionCb,   /* Pointer to region cb */
2679 Data   *ptr,        /* Memory block needs to be freed */
2680 Size    size        /* Size of the block */
2681 )
2682 {
2683    S16 ret;
2684
2685    if((SLock(&dynAllocFreeLock)) != ROK)
2686    {
2687       printf("dynAllocWithLock: Failed to get the DYN lock\n");
2688       return RFAILED;
2689    }
2690
2691    ret = cmDynFree(regionCb, ptr,size);
2692
2693    if((SUnlock(&dynAllocFreeLock)) != ROK)
2694    {
2695       printf("dynAllocWithLock: Failed to unlock the dyn lock\n");
2696       return RFAILED;
2697    }
2698
2699    return (ret);
2700
2701 } /* end of cmDynFree */
2702
2703 /*
2704 *
2705 *       Fun:   cmDynFree
2706 *
2707 *       Desc:  Return the Dynamic memory block for the memory region.
2708 *
2709 *
2710 *       Ret:   ROK     - successful
2711 *              RFAILED - unsuccessful.
2712 *
2713 *       Notes:
2714 *
2715 *
2716 *       File:  cm_mem_wl.c
2717 *
2718 */
2719 static S16  cmDynFree
2720 (
2721 Void   *regionCb,   /* Pointer to region cb */
2722 Data   *ptr,        /* Memory block needs to be freed */
2723 Size    size        /* Size of the block */
2724 )
2725 {
2726    CmMmDynRegCb       *regCb;
2727 #ifndef USE_PURE
2728    uint32_t                 idx;
2729    uint32_t                 bktIdx;
2730    CmMmDynBktCb       *bkt = NULLP;
2731    CmMmBlkSetElement  *dynMemElem;
2732 #endif
2733 #ifdef SS_MEM_WL_DEBUG
2734    uint8_t                 tmpBktIdx;
2735    uint8_t                 tmpVal;
2736 #endif
2737
2738
2739    regCb = (CmMmDynRegCb *)regionCb;
2740 #ifdef SS_MEM_WL_DEBUG
2741    if((tmpRegTidMap[regCb->region] != (pthread_self())))
2742    {
2743       bkt->size = 10;
2744    }
2745 #endif
2746
2747 #ifndef USE_PURE
2748 #if (ERRCLASS & ERRCLS_INT_PAR)
2749    /* error check on parameters */
2750    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2751    {
2752       return RFAILED;
2753    }
2754
2755    /* Check if the memory block is from the memory region */
2756    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2757                ((CmMmRegCb *)regCb)->regInfo.size) 
2758    {
2759       return RFAILED;
2760    }
2761         /* cm_mem_c_001.main_20 Addition */
2762         if (ptr < regCb->regInfo.start)
2763         {
2764           return RFAILED;
2765         }
2766
2767 #endif
2768
2769 #ifdef SS_MEM_WL_DEBUG
2770    ptr -= sizeof (uint32_t);
2771    size += 4;
2772 #endif
2773    /* The memory block was allocated from the bucket pool */
2774
2775    /* Get the map to the mapping table */
2776    idx = ((size - 1) >> regCb->bktQnPwr);
2777
2778 #if (ERRCLASS & ERRCLS_DEBUG)
2779    if (regCb->mapTbl[idx].bktIdx == 0xFF)
2780    { 
2781       /* Some fatal error in the map table initialization. */
2782       return RFAILED;
2783    }
2784 #endif
2785
2786    /* Enqueue the memory block and return it to the user */
2787    bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
2788
2789    /*
2790     * Check if the size is not greater than the size available
2791     * in the bucket. If so, then the buffer must have been allocated
2792     * from next bucket.  We don't need to check the validity of the
2793     * next bucket, otherwise buffer must have been allocated from heap
2794     * pool.
2795     */
2796 #ifdef SS_MEM_WL_DEBUG
2797    if (size > bkt->size)
2798    {
2799       printf("Size = %d bucket size = %d\n", size, bkt->size);
2800       exit(-1);
2801       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
2802    }
2803    if(size > bkt->size)
2804    {
2805       printf("2nd time Size = %d bucket size = %d\n", size, bkt->size);
2806       exit(-1);
2807       uint8_t *tmpptr = NULLP;
2808       printf("Bucket Size wrong \n");
2809       *tmpptr =  10;
2810    }
2811 #endif
2812
2813    dynMemElem = cmGetMemBlkSetForFree(bktIdx, bkt);
2814
2815    /* Check if the bucket index, if its not valid, return failure */
2816    if(dynMemElem == NULLP)
2817    {
2818       return RFAILED;
2819    }
2820
2821 #ifdef SS_MEM_WL_DEBUG
2822    tmpBktIdx = (uint8_t)*ptr;
2823    tmpVal  =  (uint8_t)*(ptr+1);
2824
2825    if ((tmpBktIdx != bktIdx) || (tmpVal != 0xde))
2826    {
2827       uint8_t *tmpptr = NULLP;
2828       printf("bktIdx wrong \n");
2829       *tmpptr =  10;
2830    }
2831
2832    if ((bktIdx == 0) && (!stopBtInfo))
2833    {
2834       CmBtInfo *btInfo;
2835       uint32_t      btIdx;
2836       btInfo  = &regBtInfo[regCb->region];
2837       btIdx = btInfo->btInfoIdx;
2838       btInfo->btInfo[btIdx].ptr = (PTR) ptr;
2839       {
2840          btInfo->btInfo[btIdx].btSize  = backtrace(btInfo->btInfo[btIdx].btArr, NUM_BT_TRACES);
2841       }
2842       gettimeofday(&(btInfo->btInfo[btIdx].timeStamp), NULLP);
2843
2844       btIdx++;
2845       btIdx &= (NUM_FREE_BUFFERS - 1); 
2846
2847       btInfo->btInfo[btIdx].ptr = (PTR)0;
2848       btInfo->btInfo[btIdx].btSize = 0;
2849       memset(btInfo->btInfo[bktIdx].btArr, 0, sizeof (btInfo->btInfo[bktIdx].btArr));
2850       btInfo->btInfoIdx = btIdx;
2851    }
2852    
2853    if(prvAllocPtr[regCb->region] == ptr)
2854    {
2855       prvAllocPtr[regCb->region] = NULLP;
2856    }
2857
2858    memset(ptr, (regCb->region+1), bkt->size); 
2859 #endif
2860
2861    /* Get the bucket node from the index returned and allocate the memory */
2862    *((CmMmEntry **)ptr) =  dynMemElem->nextBktPtr;
2863    dynMemElem->nextBktPtr = ptr;
2864    dynMemElem->numFreeBlks++;
2865
2866    return ROK;
2867
2868 #else /* use pure is on */
2869 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
2870 #ifdef SS_4GMX_LCORE
2871    (Void)MxHeapFree(SsiHeap, ptr);
2872 #else
2873    /* (Void)free(ptr); */
2874 #endif
2875 /*   avail_size += size; */
2876    free(ptr);
2877
2878    return ROK;
2879 #endif /* USE_PURE */
2880
2881
2882 } /* end of cmDynFree */
2883 #endif /* SS_USE_ICC_MEMORY */
2884
2885 \f
2886
2887 /*
2888 *
2889 *       Fun:   cmFree
2890 *
2891 *       Desc:  Return the memory block for the memory region.
2892 *
2893 *
2894 *       Ret:   ROK     - successful
2895 *              RFAILED - unsuccessful.
2896 *
2897 *       Notes: The user calls this function to return the previously allocated 
2898 *              memory block to the memory region. The memory manager does not 
2899 *              check the validity of the state of the memory block(like whether 
2900 *              it was allocated earlier). The caller must be sure that, the 
2901 *              address specified in the parameter 'ptr' is valid and was 
2902 *              allocated previously from same region.
2903 *
2904 *
2905 *       File:  cm_mem_wl.c
2906 *
2907 */
2908
2909 /*  cm_mem_c_001.main_15 : Additions */
2910 #ifdef T2K_MEM_LEAK_DBG
2911 static S16  cmFree
2912 (
2913  Void   *regionCb,
2914  Data   *ptr,
2915  Size    size,
2916  char* file,
2917  uint32_t line
2918 )
2919 #else
2920 #ifdef SS_HISTOGRAM_SUPPORT
2921 static S16  cmFree
2922 (
2923 Void   *regionCb,
2924 Data   *ptr,
2925 Size    size,
2926 uint32_t     line,
2927 uint8_t     *fileName,
2928 uint8_t      entId,
2929 Bool    hstReg
2930 )
2931 #else
2932 static S16  cmFree
2933 (
2934 Void   *regionCb,
2935 Data   *ptr, 
2936 Size    size
2937 )
2938 #endif
2939 /*  cm_mem_c_001.main_15 : Additions */
2940 #endif /* SS_HISTOGRAM_SUPPORT */ 
2941
2942 {
2943 /* cm_mem_c_001.main_26 : Fixes for Compilation Warnings */
2944 #ifndef USE_PURE
2945    uint16_t        idx;
2946    CmMmBkt   *bkt;
2947    uint16_t   bktIdx;
2948 #endif
2949    CmMmRegCb *regCb;
2950 /* cm_mem_c_001.main_12 - addition for holding the free pointer */
2951 #ifdef SSI_DEBUG_LEVEL1
2952    CmMmBlkHdr *ptrHdr;
2953 #endif /* SSI_DEBUG_LEVEL1 */
2954 /*  cm_mem_c_001.main_15 : Additions */
2955 #ifdef SS_HISTOGRAM_SUPPORT 
2956         S8 hstGrmBuf[256];
2957 #endif /* SS_HISTOGRAM_SUPPORT */
2958
2959
2960    regCb = (CmMmRegCb *)regionCb;
2961
2962 #ifndef USE_PURE
2963 #if (ERRCLASS & ERRCLS_INT_PAR)
2964
2965    /* error check on parameters */
2966    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
2967    {
2968       return RFAILED;
2969    }
2970
2971    /* Check if the memory block is from the memory region */
2972    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
2973                ((CmMmRegCb *)regCb)->regInfo.size) 
2974    {
2975       return RFAILED;
2976    }
2977         /* cm_mem_c_001.main_20 Addition */
2978         if (ptr < regCb->regInfo.start)
2979         {
2980           return RFAILED;
2981         }
2982
2983 #endif
2984
2985    /* 
2986     * Check if the memory block was allocated from the bucket pool. 
2987     */
2988    if(ptr < regCb->regInfo.start)
2989    {
2990       Buffer *tmpBuffer = NULLP;
2991       tmpBuffer->b_cont = NULLP;
2992    }
2993
2994    if (ptr < (regCb->regInfo.start + regCb->bktSize))
2995    {
2996       /* The memory block was allocated from the bucket pool */
2997
2998       /* Get the map to the mapping table */
2999       idx = ((size - 1) >> regCb->bktQnPwr);
3000
3001 #if (ERRCLASS & ERRCLS_DEBUG)
3002       if (regCb->mapTbl[idx].bktIdx == 0xFF)
3003       { 
3004          /* Some fatal error in the map table initialization. */
3005          return RFAILED;
3006       }
3007 #endif
3008
3009       /* Enqueue the memory block and return it to the user */
3010       bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[idx].bktIdx]);
3011
3012       /*
3013        * Check if the size is not greater than the size available
3014        * in the bucket. If so, then the buffer must have been allocated
3015        * from next bucket.  We don't need to check the validity of the
3016        * next bucket, otherwise buffer must have been allocated from heap
3017        * pool.
3018        */
3019        if (size > bkt->size)
3020        {
3021           bkt = &(regCb->bktTbl[bktIdx = regCb->mapTbl[++idx].bktIdx]);
3022        }
3023
3024       /* Acquire the bucket lock */
3025       /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3026 #ifdef SS_WIN
3027       (Void) WTLock(&(bkt->bktLock));
3028 #else
3029       (Void) SLock(&(bkt->bktLock));
3030 #endif
3031
3032 /* cm_mem_c_001.main_12 - addition for sanity check and free */
3033 #ifdef SSI_DEBUG_LEVEL1
3034       /* increment the dealloc attempt counter at bucket level */
3035       bkt->numDeallocAttempts++;
3036
3037       /* Check the memFlags to see whether this block was allocated */
3038       ptrHdr = (CmMmBlkHdr *) (ptr - sizeof(CmMmBlkHdr));
3039
3040       /* validate the block to be freed for trampling */
3041       if (cmMmRegIsBlkSane(ptrHdr) != ROK)
3042       {
3043           /* Handle error case of Memory trampling */
3044       #ifdef  DEBUGP
3045           /* display an error message here */
3046 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3047 #ifdef ALIGN_64BIT          
3048           sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %u bytes \n",
3049                                ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3050 #else                               
3051           sprintf(dbgPrntBuf, "Memory Trampling at: %8p, Bucket Id:%03d, size %lu bytes \n",
3052                                ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3053 #endif                               
3054           SDisplay(0, dbgPrntBuf);
3055       #endif /* DEBUGP */
3056            /* 
3057            * if sanity check returns RTRAMPLINGOK then there is nothing to do
3058            * as the memory blk is already invalidated in cmMmBktSanityChk
3059            */
3060            if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3061            {
3062               bkt->numAlloc--;
3063
3064               /* Release the lock */
3065               /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3066 #ifdef SS_WIN
3067               (Void) WTUnlock(&(bkt->bktLock));
3068 #else
3069               (Void) SUnlock(&(bkt->bktLock));
3070 #endif
3071
3072               return ROK;
3073            }
3074            else
3075            {
3076                /* 
3077                * this is the case where in the entire bucket has been made unusable
3078                * Release the lock 
3079                */
3080                /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3081 #ifdef SS_WIN
3082                (Void) WTUnlock(&(bkt->bktLock));
3083 #else
3084                (Void) SUnlock(&(bkt->bktLock));
3085 #endif
3086
3087                 /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3088                 return (RTRAMPLINGNOK);
3089            }
3090       }
3091
3092       /* reset the size */
3093       ptrHdr->requestedSize = 0;
3094       /* check if the block to be freed is already having the state as FREE */
3095       if (CMM_IS_FREE(ptrHdr->memFlags))
3096       {
3097             /* Handle double deallocation error case */
3098       #ifdef DEBUGP
3099             /* display an error message here */
3100 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3101 #ifdef ALIGN_64BIT          
3102          sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %u bytes \n",
3103                               ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3104 #else                              
3105          sprintf(dbgPrntBuf, "Attempt to double deallocate memory at: %8p, Bucket Id:%03d, size %lu bytes \n",
3106                               ptr, regCb->mapTbl[idx].bktIdx, bkt->size);
3107 #endif                              
3108          SDisplay(0, dbgPrntBuf);
3109       #endif /* DEBUGP */
3110
3111           /* Release the lock */
3112           /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3113 #ifdef SS_WIN
3114           (Void) WTUnlock(&(bkt->bktLock));
3115 #else
3116           (Void) SUnlock(&(bkt->bktLock));
3117 #endif
3118
3119           /* handle RDBLFREE in SFree/SPutSBuf */
3120           return (RDBLFREE);
3121       }
3122       if (CMM_IS_STATIC(ptrHdr->memFlags))
3123       {
3124          CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3125          CMM_RESET_STATIC_FLAG(ptrHdr->memFlags);
3126          /* deduct it from the static memory count */
3127          bkt->staticMemUsed -= bkt->size;
3128       }
3129       else if (CMM_IS_DYNAMIC(ptrHdr->memFlags))
3130       {
3131          CMM_SET_FREE_FLAG(ptrHdr->memFlags);
3132          CMM_RESET_DYNAMIC_FLAG(ptrHdr->memFlags);
3133          /* deduct it from the dynamic memory count */
3134          bkt->dynamicMemUsed -= bkt->size;
3135       }
3136       else
3137       {
3138          /* This is a case similar to trampled memory */
3139       #ifdef  DEBUGP
3140 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3141 #ifdef ALIGN_64BIT          
3142          sprintf(dbgPrntBuf, "Invalid memory flag: %u !!!\n", ptrHdr->memFlags);
3143 #else         
3144          sprintf(dbgPrntBuf, "Invalid memory flag: %lu !!!\n", ptrHdr->memFlags);
3145 #endif         
3146          SDisplay(0, dbgPrntBuf);
3147       #endif /* DEBUGP */
3148          if (cmMmBktSanityChk(bkt) == RTRAMPLINGOK)
3149          {
3150             /* do not add to the free list */
3151             bkt->numAlloc--;
3152
3153             /* Release the lock */
3154             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3155 #ifdef SS_WIN
3156             (Void) WTUnlock(&(bkt->bktLock));
3157 #else
3158             (Void) SUnlock(&(bkt->bktLock));
3159 #endif
3160             return ROK;
3161          }
3162          else
3163          {
3164             /* 
3165             * this is the case where in the entire bucket has been made unusable
3166             * Release the lock 
3167             */
3168             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3169 #ifdef SS_WIN
3170             (Void) WTUnlock(&(bkt->bktLock));
3171 #else
3172             (Void) SUnlock(&(bkt->bktLock));
3173 #endif
3174
3175             /* handle RTRAMPLINGNOK in SFree/SPutSBuf */
3176             return (RTRAMPLINGNOK);
3177          }
3178       }
3179
3180       /* Return the block to memory */
3181       ptrHdr->nextBlk = bkt->nextBlk;
3182       bkt->nextBlk = ptrHdr;
3183 #else
3184       /* MS_REMOVE */
3185       *((CmMmEntry **)ptr) =  bkt->next; 
3186       bkt->next = (CmMmEntry *)ptr;
3187 #endif /* SSI_DEBUG_LEVEL1 */
3188
3189       /* 
3190       * Decrement the statistics variable of number of memory block 
3191       * allocated 
3192       */
3193       if(bkt->numAlloc)
3194       {
3195          bkt->numAlloc--;
3196       }
3197       {
3198         if (g_overused[bktIdx] == 1 && !OVERUSED(bkt))
3199         {
3200            g_overused[bktIdx] = 0;
3201            /*printf("cmFree: bktIdx %u overused %u numAlloc %u\n", bktIdx, g_overused[bktIdx], bkt->numAlloc); */
3202         }
3203       }
3204 /*  cm_mem_c_001.main_15 : Additions */
3205 #ifdef SS_HISTOGRAM_SUPPORT
3206         /* If If Tapa task (entId)is registerd for histogram then insert Memrory Freed
3207          * information into the hash list */
3208         if(hstReg)
3209         {
3210             if (cmHstGrmFreeInsert(&bkt->hstGrmHashListCp, bkt->size, line, fileName, entId) != ROK)
3211             {
3212                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
3213                                           SPrint(hstGrmBuf);
3214             }
3215          }/* End of if */
3216 #endif /* SS_HISTOGRAM_SUPPORT */
3217
3218 #ifdef SS_MEM_LEAK_STS
3219       /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
3220       cmRlsAllocBlk((PTR)ptr);
3221 #endif /* SS_MEM_LEAK_STS */
3222
3223       /* Release the lock */
3224       /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
3225 #ifdef SS_WIN
3226       (Void) WTUnlock(&(bkt->bktLock));
3227 #else
3228       (Void) SUnlock(&(bkt->bktLock));
3229 #endif
3230
3231       return ROK;
3232    }
3233
3234    /* The memory block was allocated from the heap pool */ 
3235 /*  cm_mem_c_001.main_15 : Additions */
3236 #ifdef SS_HISTOGRAM_SUPPORT 
3237    return (cmHeapFree (&(regCb->heapCb), ptr, size, line, fileName, entId, hstReg));
3238 #else
3239    return (cmHeapFree (&(regCb->heapCb), ptr, size));
3240 #endif /* SS_HISTOGRAM_SUPPORT */
3241 #else /* use pure is on */
3242 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3243 #ifdef SS_4GMX_LCORE
3244    (Void)MxHeapFree(SsiHeap, ptr);
3245 #else
3246    (Void)free(ptr);
3247 #endif
3248    avail_size += size;
3249    return ROK;
3250 #endif /* USE_PURE */
3251
3252
3253 } /* end of cmFree */
3254
3255 \f
3256 /*
3257 *
3258 *       Fun:   cmAllocWL
3259 *
3260 *       Desc: alloc without lock 
3261 *
3262 *
3263 *       Ret:   ROK     - successful
3264 *              RFAILED - unsuccessful.
3265 *
3266 *
3267 *       File:  cm_mem_wl.c
3268 *
3269 */
3270 /*cm_mem_c_001.main_21-added new function*/
3271 /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3272 #ifdef T2K_MEM_LEAK_DBG
3273 static S16  cmAllocWL
3274 (
3275 Void   *regionCb,
3276 Size   *size,
3277 uint32_t     flags,
3278 Data  **ptr ,
3279 char* file,
3280 uint32_t line
3281 )
3282 #else
3283 static S16  cmAllocWL
3284 (
3285 Void   *regionCb,
3286 Size   *size,
3287 uint32_t     flags,
3288 Data  **ptr 
3289 )
3290 #endif
3291 {
3292 #ifndef USE_PURE
3293    uint16_t        idx;
3294    CmMmBkt   *bkt = NULLP;
3295 #endif
3296    CmMmRegCb *regCb;
3297    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3298
3299
3300    /*cm_mem_c_001.main_23 Removed support of  USE_MEMCAL and MEMCAL_DEBUG support for  SS_FAP*/
3301
3302    regCb = (CmMmRegCb *)regionCb;
3303
3304 #ifdef SS_MEM_WL_DEBUG
3305    if((tmpRegTidMap[regCb->region] != (pthread_self())))
3306    {
3307       bkt->size = 10;
3308    }
3309 #endif
3310
3311 #if (ERRCLASS & ERRCLS_INT_PAR)
3312
3313    /* error check on parameters */
3314    if ((regCb == NULLP) || (size == NULLP) || !(*size) || (ptr == NULLP))
3315    {
3316       return RFAILED;
3317    }
3318 #endif
3319   
3320    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3321
3322 #ifndef USE_PURE 
3323
3324    /* 
3325     * Check if the requested size is less than or equal to the maximum block 
3326     * size in the bucket. 
3327     */
3328 #ifdef MSPD_T2K_TRACK_BUG
3329    *size += 4;
3330 #endif
3331    /* cm_mem_c_001.main_23 Adding check to compair size with Maximum block size*/
3332    if ( *size <= regCb->bktMaxBlkSize)
3333    {
3334       /* Get the map to the mapping table */
3335       idx = ((*size - 1) >> regCb->bktQnPwr);
3336
3337       /* Dequeue the memory block and return it to the user */
3338       bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3339
3340       {
3341          /*
3342           * Check if the size request is not greater than the size available
3343           * in the bucket
3344           */
3345          /* cm_mem_c_001.main_23 combined If(*size <= bkt->size) and if(*ptr = bkt->next)*/
3346          if ((*size <= bkt->size)&&(*ptr = bkt->next))
3347          {
3348             /* Try to go to the next bucket if available */
3349             bkt->next = *((CmMmEntry **)(bkt->next));
3350
3351             /* 
3352              * Increment the statistics variable of number of memory block 
3353              * allocated 
3354              */
3355             bkt->numAlloc++;
3356             if (bkt->numAlloc > bkt->maxAlloc)
3357             {
3358                bkt->maxAlloc = bkt->numAlloc;
3359             }
3360
3361 #ifdef MSPD_T2K_TRACK_BUG
3362             *(*ptr + 0) = 0xDE;
3363             *(*ptr + 1) = 0xAD;
3364             *(*ptr + 2) = 0xBE;
3365             *(*ptr + 3) = 0xEF;
3366
3367             (*ptr) += 4;
3368 #endif
3369
3370             /* Update the size parameter */
3371             *size = bkt->size;
3372
3373             return ROK;
3374          }
3375       }
3376    }
3377
3378    /* Memory not available in the bucket pool */
3379    if (regCb->heapFlag &&  (*size < regCb->heapSize))
3380    {
3381       /*cm_mem_c_001.main_23 Removed support of  and MEMCAL_DEBUG support for  SS_FAP*/
3382       /* 
3383        * The heap memory block is available. Allocate the memory block from
3384        * heap pool.
3385        */ 
3386        /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3387        return (cmHeapAlloc(&(regCb->heapCb), ptr, size));
3388    }
3389
3390    /* No memory available */
3391    return RFAILED;
3392 #else /* use pure is on */
3393 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3394 #ifdef SS_4GMX_LCORE
3395    *ptr = (Data*) MxHeapAlloc(SsiHeap, *size);
3396    memset(ptr, 0, *size);
3397 #else
3398 /*   *ptr = (Data*) malloc(*size); */
3399 #endif
3400    *ptr = (Data *)malloc(*size);
3401
3402    if ( (*ptr) == NULLP)
3403        return RFAILED;
3404 /*   avail_size -= *size; */
3405    return ROK;
3406 #endif /* USE_PURE */
3407
3408 } /* end of cmAllocWL */
3409
3410 \f
3411 /*
3412 *
3413 *       Fun:   cmfree
3414 *
3415 *       Desc: free without lock 
3416 *
3417 *
3418 *       Ret:   ROK     - successful
3419 *              RFAILED - unsuccessful.
3420 *
3421 *
3422 *       File:  cm_mem_wl.c
3423 *
3424 */
3425
3426 #ifdef T2K_MEM_LEAK_DBG
3427 static S16  cmFreeWL
3428 (
3429 Void   *regionCb,
3430 Data   *ptr, 
3431 Size    size,
3432 char* file,
3433 uint32_t line
3434 )
3435 #else
3436 static S16  cmFreeWL
3437 (
3438 Void   *regionCb,
3439 Data   *ptr, 
3440 Size    size
3441 )
3442 #endif
3443 {
3444 #ifndef USE_PURE
3445    uint16_t        idx;
3446    CmMmBkt   *bkt = NULLP;
3447 #endif
3448    CmMmRegCb *regCb;
3449    /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3450
3451
3452    regCb = (CmMmRegCb *)regionCb;
3453
3454 #ifdef SS_MEM_WL_DEBUG
3455    if(tmpRegTidMap[regCb->region] != (pthread_self()))
3456    {
3457       bkt->size = 10;
3458    }
3459 #endif
3460
3461 #ifndef USE_PURE
3462 #if (ERRCLASS & ERRCLS_INT_PAR)
3463
3464    /* error check on parameters */
3465    if ((regCb == NULLP) || (!size) || (ptr == NULLP))
3466    {
3467       return RFAILED;
3468    }
3469
3470    /* Check if the memory block is from the memory region */
3471    if (ptr >= ((CmMmRegCb *)regCb)->regInfo.start +
3472                ((CmMmRegCb *)regCb)->regInfo.size) 
3473    {
3474       return RFAILED;
3475    }
3476
3477 #endif
3478
3479    /* 
3480     * Check if the memory block was allocated from the bucket pool. 
3481     */
3482 #ifdef MSPD_T2K_TRACK_BUG
3483    size += 4;
3484 #endif
3485
3486    if (ptr < (regCb->regInfo.start + regCb->bktSize))
3487    {
3488       /* The memory block was allocated from the bucket pool */
3489
3490       /* Get the map to the mapping table */
3491       idx = ((size - 1) >> regCb->bktQnPwr);
3492
3493 #if (ERRCLASS & ERRCLS_DEBUG)
3494       if (regCb->mapTbl[idx].bktIdx == 0xFF)
3495       { 
3496          /* Some fatal error in the map table initialization. */
3497          return RFAILED;
3498       }
3499 #endif
3500
3501       /* Enqueue the memory block and return it to the user */
3502       bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3503
3504 #ifdef MSPD_T2K_TRACK_BUG
3505       ptr -= 4;
3506       if((ptr[0] != 0xDE) || (ptr[1] != 0xAD) || (ptr[2] != 0xBE) || (ptr[3] != 0xEF))
3507       {
3508           char *abc = NULLP;
3509           *abc = 100;
3510       }
3511 #endif
3512       /*
3513        * Check if the size is not greater than the size available
3514        * in the bucket. If so, then the buffer must have been allocated
3515        * from next bucket.  We don't need to check the validity of the
3516        * next bucket, otherwise buffer must have been allocated from heap
3517        * pool.
3518        */
3519        if (size > bkt->size)
3520        {
3521           bkt = &(regCb->bktTbl[regCb->mapTbl[++idx].bktIdx]);
3522        }
3523
3524       /*cm_mem_c_001.main_23 Removed support of SSI_DEBUG_LEVEL1 and SS_HISTOGRAM_SUPPORT for SS_FAP*/
3525       *((CmMmEntry **)ptr) =  bkt->next; 
3526       bkt->next = (CmMmEntry *)ptr;
3527
3528       /* 
3529       * Decrement the statistics variable of number of memory block 
3530       * allocated 
3531       */
3532       bkt->numAlloc--;
3533
3534       return ROK;
3535    }
3536
3537    /* The memory block was allocated from the heap pool */ 
3538    return (cmHeapFree (&(regCb->heapCb), ptr, size));
3539 #else /* use pure is on */
3540 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
3541 #ifdef SS_4GMX_LCORE
3542    (Void)MxHeapFree(SsiHeap, ptr);
3543 #else
3544 /*   (Void)free(ptr); */
3545 #endif
3546 /*   avail_size += size; */
3547    free(ptr);
3548
3549    return ROK;
3550 #endif /* USE_PURE */
3551
3552
3553 } /* end of cmFreeWL */
3554
3555 \f
3556 /*
3557 *
3558 *       Fun:   cmCtl
3559 *
3560 *       Desc:  Control request function. 
3561 *
3562 *
3563 *       Ret:   ROK     - successful
3564 *              RFAILED - unsuccessful.
3565 *
3566 *       Notes: The current semantics of the control function is defined for two 
3567 *              types of events: virtual address to physical address translation 
3568 *              and memory resource check. 
3569 *
3570 *              The physical address translation is valid only for the memory 
3571 *              region physically contiguous and non pagable.
3572 *
3573 *
3574 *
3575 *       File:  cm_mem_wl.c
3576 *
3577 */
3578
3579 static S16  cmCtl
3580 (
3581 Void    *regionCb,
3582 Event    event, 
3583 SMemCtl *memCtl
3584 )
3585 {
3586    CmMmRegCb *regCb;
3587
3588
3589    regCb = (CmMmRegCb *)regionCb;
3590
3591 #if (ERRCLASS & ERRCLS_INT_PAR)
3592
3593    /* error check on parameters */
3594    if ((regCb == NULLP) || (memCtl == NULLP))
3595    {
3596       return RFAILED;
3597    }
3598
3599 #endif
3600
3601    switch (event)
3602    {
3603       case SS_MEM_V_TO_P:
3604       {
3605          Size       offset;
3606   
3607 #if (ERRCLASS & ERRCLS_INT_PAR)
3608          if ((memCtl->u.vtop.vaddr == NULLP) || 
3609              (memCtl->u.vtop.paddr == NULLP))
3610          {
3611             return RFAILED;
3612          }
3613 #endif
3614    
3615          /* Check if the virtual to physical address translation is valid */
3616          if (regCb->chFlag & CMM_REG_PHY_VALID) 
3617          {
3618             offset = memCtl->u.vtop.vaddr - regCb->regInfo.start;
3619             *(memCtl->u.vtop.paddr) = regCb->pAddr + offset;
3620    
3621             return ROK;
3622          }
3623          break;
3624       }
3625
3626       case SS_MEM_CHK_RES:
3627       {
3628
3629 #if (ERRCLASS & ERRCLS_INT_PAR)
3630          if (!(memCtl->u.chkres.size) || 
3631             (memCtl->u.chkres.status == NULLP))
3632          {
3633             return RFAILED;
3634          }
3635 #endif
3636 #ifndef USE_PURE
3637          /* Check if the Bucket pool is configured */
3638          if (regCb->bktSize)
3639          {
3640             uint16_t        idx;
3641             CmMmBkt   *bkt;
3642             uint32_t        avlSize, totSize;
3643             /* 
3644              * The bucket pool is configured. The status value returned
3645              * does reflect on the memory availabilty in the bucket pool. 
3646              * The value does not consider the available memory in the
3647              * heap pool. 
3648              */
3649              idx = ((memCtl->u.chkres.size - 1) >> regCb->bktQnPwr);
3650              bkt = &(regCb->bktTbl[regCb->mapTbl[idx].bktIdx]); 
3651              avlSize = (bkt->numBlks - bkt->numAlloc) * bkt->size;
3652              avlSize += regCb->heapCb.avlSize;
3653              totSize = (bkt->numBlks * bkt->size) + regCb->heapSize;
3654              *(memCtl->u.chkres.status) = (avlSize/(totSize/10)); 
3655          }
3656          else
3657          {
3658             /* Bucket pool not configured */
3659
3660             /* 
3661              * Find the percentage memory available in the heap pool. The value
3662              * does not consider the fragmentation of the heap pool.
3663              */
3664             *(memCtl->u.chkres.status) = ((regCb->heapCb.avlSize) /
3665                                           (regCb->heapSize/10)); 
3666          }
3667
3668          return ROK;
3669 #else /* use pure is on */
3670             *(memCtl->u.chkres.status) = ((avail_size) /
3671                                           (regCb->regInfo.size/10));
3672          return ROK;
3673 #endif /* USE_PURE */
3674
3675       }
3676
3677       default:
3678       {
3679          /* No other event is supported currently */
3680          return RFAILED;
3681       }
3682    }
3683
3684    /* shouldn't reach here */
3685    return RFAILED;
3686 } /* end of cmCtl */
3687
3688 \f
3689 /*
3690 *
3691 *       Fun:   cmMmHeapInit
3692 *
3693 *       Desc:  Initialize the heap pool. 
3694 *
3695 *
3696 *       Ret:   ROK     - successful
3697 *              RFAILED - unsuccessful.
3698 *
3699 *       Notes: This function is called by the cmMmRegInit. 
3700 *
3701 *       File:  cm_mem_wl.c
3702 *
3703 */
3704 static Void  cmMmHeapInit 
3705 (
3706 Data        *memAddr,
3707 CmMmHeapCb  *heapCb,
3708 Size         size 
3709 )
3710 {
3711 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3712 #ifdef SSI_DEBUG_LEVEL1
3713    uint16_t idx;
3714 #endif /* SSI_DEBUG_LEVEL1 */
3715
3716    /* Initialize the heap control block */
3717    heapCb->vStart      = memAddr;
3718    heapCb->vEnd        = memAddr + size;
3719    heapCb->avlSize    = size; 
3720    heapCb->minSize    = CMM_MINBUFSIZE; 
3721
3722    heapCb->next       = (CmHEntry *)memAddr;
3723    heapCb->next->next = NULLP;
3724 /* cm_mem_c_001.main_12 - addition for header initialization */
3725 #ifdef SSI_DEBUG_LEVEL1
3726    heapCb->next->size = size - sizeof(CmHEntry);
3727    heapCb->next->requestedSize = 0;
3728    for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3729    {
3730       heapCb->next->trSignature[idx] = 0xAB;
3731    }
3732    CMM_SET_FREE_FLAG(heapCb->next->memFlags);
3733    heapCb->staticHeapMemUsed = 0;
3734    heapCb->dynamicHeapMemUsed = 0;
3735    heapCb->nextOffset = sizeof(heapCb->next->trSignature) +
3736                         sizeof(heapCb->next->memFlags) +
3737                         sizeof(heapCb->next->requestedSize);
3738    heapCb->numAllocAttempts = 0;
3739    heapCb->numDeallocAttempts = 0;
3740    heapCb->trampleCount = 0;
3741 #else
3742    heapCb->next->size = size; 
3743 #endif /* SSI_DEBUG_LEVEL1 */
3744
3745 #if (ERRCLASS & ERRCLS_DEBUG)
3746    heapCb->numFragBlk  = 0;
3747    heapCb->numReq      = 0;
3748    heapCb->numFailure  = 0;
3749 #endif
3750
3751    heapCb->heapAllocCnt = 0;
3752 /*  cm_mem_c_001.main_15 : Additions */
3753 #ifdef SS_HISTOGRAM_SUPPORT 
3754    /* Initialise the memory histogram hash list */
3755    cmHstGrmHashListInit(&(heapCb->heapHstGrmHashListCp));
3756 #endif /* SS_HISTOGRAM_SUPPORT */
3757    return;
3758
3759 } /* end of cmMmHeapInit */
3760
3761 #ifndef USE_PURE
3762 \f
3763 /*
3764 *
3765 *       Fun:   cmHeapAlloc
3766 *
3767 *       Desc:  Allocates the memory block from the heap pool. 
3768 *
3769 *
3770 *       Ret:   ROK     - successful
3771 *              RFAILED - unsuccessful.
3772 *
3773 *       Notes: This function is called by the cmAlloc. cmAlloc calls this
3774 *              function when there is no memory block available in the bucket 
3775 *              and the  heap pool is configured.
3776 *
3777 *
3778 *
3779 *       File:  cm_mem_wl.c
3780 *
3781 */
3782 /* cm_mem_c_001.main_12 - addition for taking another parameter memType(static/dynamic) */
3783 /*  cm_mem_c_001.main_15 : Additions */
3784 #ifdef SS_HISTOGRAM_SUPPORT 
3785 #ifdef SSI_DEBUG_LEVEL1
3786 static S16  cmHeapAlloc
3787 (
3788 CmMmHeapCb  *heapCb,
3789 Data       **ptr,
3790 Size        *size,
3791 uint32_t        memType,
3792 uint32_t     line,
3793 uint8_t     *fileName,
3794 uint8_t      entId,
3795 Bool    hstReg
3796 )
3797 #else
3798 static S16  cmHeapAlloc 
3799 (
3800 CmMmHeapCb  *heapCb,
3801 Data       **ptr,
3802 Size        *size,
3803 uint32_t     line,
3804 uint8_t     *fileName,
3805 uint8_t      entId,
3806 Bool    hstReg
3807 )
3808 #endif /* SSI_DEBUG_LEVEL1 */
3809 #else
3810 #ifdef SSI_DEBUG_LEVEL1
3811 static S16  cmHeapAlloc
3812 (
3813 CmMmHeapCb  *heapCb,
3814 Data       **ptr,
3815 Size        *size,
3816 uint32_t        memType
3817 )
3818 #else
3819 static S16  cmHeapAlloc 
3820 (
3821 CmMmHeapCb  *heapCb,
3822 Data       **ptr,
3823 Size        *size 
3824 )
3825 #endif /* SSI_DEBUG_LEVEL1 */
3826 /*  cm_mem_c_001.main_15 : Additions */
3827 #endif /* SS_HISTOGRAM_SUPPORT */ 
3828 {
3829    CmHEntry  *prvHBlk;    /* Previous heap block */
3830    CmHEntry  *curHBlk;    /* Current heap block */ 
3831    Size       tmpSize;
3832 /*  cm_mem_c_001.main_15 : Additions */
3833 #ifdef SS_MEM_LEAK_STS 
3834    Size       reqSz;
3835 #endif /* SS_MEM_LEAK_STS */
3836 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
3837 #ifdef SSI_DEBUG_LEVEL1
3838    CmHEntry *alocHeapBlk;
3839    Size requestedSize;
3840    Size hdr;
3841    uint16_t idx;
3842 #endif /* SSI_DEBUG_LEVEL1 */
3843 /*  cm_mem_c_001.main_15 : Additions */
3844 #ifdef SS_HISTOGRAM_SUPPORT 
3845         S8 hstGrmBuf[256];
3846 #endif /* SS_HISTOGRAM_SUPPORT */
3847
3848 /*  cm_mem_c_001.main_15 : Additions */
3849    /* Acquire the heap lock */ 
3850    /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
3851 #ifdef SS_WIN
3852    (Void) WTLock (&(heapCb->heapLock));
3853 #else
3854    (Void) SLock (&(heapCb->heapLock));
3855 #endif
3856
3857 #ifdef SS_MEM_LEAK_STS
3858    reqSz = *size;
3859 #endif /* SS_MEM_LEAK_STS */
3860 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
3861 #ifdef SSI_DEBUG_LEVEL1
3862    heapCb->numAllocAttempts++;
3863    requestedSize = *size;
3864 #endif /* SSI_DEBUG_LEVEL1 */
3865
3866    /* Roundup the requested size */
3867    *size = CMM_DATALIGN(*size, (heapCb->minSize));
3868    
3869    /* Check if the available total size is adequate. */
3870    if ((*size) >= heapCb->avlSize)
3871    {
3872 /*  cm_mem_c_001.main_15 : Additions */
3873 #ifdef SS_WIN
3874                         (Void) WTUnlock (&(heapCb->heapLock));
3875 #else
3876                         (Void) SUnlock (&(heapCb->heapLock));
3877 #endif
3878       return (ROUTRES);
3879    }
3880
3881
3882 /* cm_mem_c_001.main_12 - addition for aligning the header size */
3883 #ifdef SSI_DEBUG_LEVEL1
3884    hdr = PTRALIGN(sizeof(CmHEntry));
3885 #endif /* SSI_DEBUG_LEVEL1 */
3886
3887    /* 
3888     * Search through the heap block list in the heap pool of size 
3889     * greater than or equal to the requested size.
3890     *
3891     */ 
3892 /* cm_mem_c_001.main_12 - addition for accessing the heapCb->next */
3893 #ifdef SSI_DEBUG_LEVEL1
3894    prvHBlk = (CmHEntry *)((Data *)&(heapCb->next) - heapCb->nextOffset);
3895 #else
3896    prvHBlk = (CmHEntry *)&(heapCb->next);
3897 #endif /* SSI_DEBUG_LEVEL1 */
3898    for (curHBlk = prvHBlk->next; curHBlk; curHBlk = curHBlk->next,
3899                                                    prvHBlk = prvHBlk->next)
3900    {
3901       /*
3902        * Since the size of the block is always multiple of CMM_MINBUFSIZE 
3903        * and the requested size is rounded to the size multiple of
3904        * CMM_MINBUFSIZE, the difference between the size of the heap block
3905        * and the size to allocate will be either zero or multiple of
3906        * CMM_MINBUFSIZE. 
3907        */
3908       if ((*size) <= curHBlk->size) 
3909       {
3910 /* cm_mem_c_001.main_12 - addition for block size calculation */
3911 #ifdef SSI_DEBUG_LEVEL1
3912       tmpSize = curHBlk->size - (*size);
3913       if (tmpSize != 0)
3914          tmpSize = tmpSize - hdr;
3915       if (tmpSize)
3916 #else
3917          if ((tmpSize = (curHBlk->size - (*size))))
3918 #endif /* SSI_DEBUG_LEVEL1 */
3919          {
3920             /* Heap block of bigger size */
3921 /* cm_mem_c_001.main_12 - addition for allocating memory */
3922 #ifdef SSI_DEBUG_LEVEL1
3923             *ptr = (Data *)curHBlk + hdr + tmpSize + hdr;
3924             alocHeapBlk = (CmHEntry *) ((Data *)curHBlk + hdr + tmpSize);
3925             /*
3926             * No need to look for memory trampling as this is a new block altogether
3927             * Update the header only for this case as it is new block formed 
3928             */
3929             for (idx=0; idx < CMM_TRAMPLING_SIGNATURE_LEN; idx++)
3930             {
3931                alocHeapBlk->trSignature[idx] = 0xAB;
3932             }
3933             alocHeapBlk->size = *size;
3934 #else
3935             *ptr = (Data *)curHBlk + tmpSize;             
3936 #endif /* SSI_DEBUG_LEVEL1 */
3937              curHBlk->size = tmpSize;
3938          } 
3939          else
3940          {
3941             /* Heap block is same size of the requested size */
3942 /* cm_mem_c_001.main_12 - addition for sanity check and allocation. This is a fresh block */
3943 #ifdef SSI_DEBUG_LEVEL1
3944             /* look for memory trampling as this is a pure block*/
3945             if (curHBlk)
3946             {
3947                if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
3948                {
3949                      /* detected a trampled memory block in this bucket */
3950                   #ifdef DEBUGP
3951                      /* display an error message here */
3952 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
3953 #ifdef ALIGN_64BIT          
3954                      sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)curHBlk, requestedSize);
3955 #else                     
3956                      sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)curHBlk, requestedSize);
3957 #endif                     
3958                      SDisplay(0, dbgPrntBuf);
3959                   #endif /* DEBUGP */
3960
3961                      if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
3962                      {
3963                         /* Release the lock */
3964                         /* cm_mem_c_001.main_13: Replaced SUnlock with
3965                            WTUnlock for NT */
3966 #ifdef SS_WIN
3967                         (Void) WTUnlock (&(heapCb->heapLock));
3968 #else
3969                         (Void) SUnlock (&(heapCb->heapLock));
3970 #endif
3971                         /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
3972                         return (RTRAMPLINGNOK);
3973                      }
3974                      else
3975                      {
3976                         /* Release the lock */
3977                         /* cm_mem_c_001.main_13: Replaced SUnlock with
3978                            WTUnlock for NT */
3979 #ifdef SS_WIN
3980                         (Void) WTUnlock (&(heapCb->heapLock));
3981 #else
3982                         (Void) SUnlock (&(heapCb->heapLock));
3983 #endif
3984                         return RFAILED;
3985                      }
3986                }
3987             }
3988
3989             *ptr = (Data *)curHBlk + hdr;
3990             alocHeapBlk =  curHBlk;
3991             *size = curHBlk->size;
3992 #else
3993             *ptr = (Data *)curHBlk;
3994 #endif /* SSI_DEBUG_LEVEL1 */
3995              prvHBlk->next = curHBlk->next;
3996          }
3997
3998 /* cm_mem_c_001.main_12 - addition for header updation */
3999 #ifdef SSI_DEBUG_LEVEL1
4000          /* update the header fields */
4001          alocHeapBlk->requestedSize = requestedSize;
4002          alocHeapBlk->memFlags = 0;
4003          if (memType == CMM_STATIC_MEM_FLAG)
4004          {
4005             CMM_SET_STATIC_FLAG(alocHeapBlk->memFlags);
4006             heapCb->staticHeapMemUsed += (*size + hdr);
4007          }
4008          else
4009          {
4010             CMM_SET_DYNAMIC_FLAG(alocHeapBlk->memFlags);
4011             heapCb->dynamicHeapMemUsed += (*size + hdr);
4012          }
4013          heapCb->avlSize -= ((*size) + hdr);
4014 #else
4015          heapCb->avlSize -= (*size); 
4016 #endif /* SSI_DEBUG_LEVEL1 */
4017
4018 #ifdef MEMCAL_DEBUG
4019         if (tryHeap)
4020         {
4021             sprintf(prntBuf,
4022                  "SGetSBuf:%08lu:Size  Heap Alloc Times:%05lu  Pointer: %8p\n",
4023                  *size, num_times, *ptr);
4024             SDisplay(0, prntBuf);
4025             tryHeap = 0;
4026         }
4027 #endif
4028 /*  cm_mem_c_001.main_15 : Additions */
4029 #ifdef SS_MEM_LEAK_STS 
4030         /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4031          cmStorAllocBlk((PTR)*ptr, (Size) reqSz, (Size) *size, MT_MAX_BKTS);
4032 #endif /* SS_MEM_LEAK_STS */
4033          /* Release the lock */
4034 /*  cm_mem_c_001.main_16 : cm_mem_c_001.main_18  Additions */
4035 #ifdef SS_WIN
4036    (Void) WTUnlock (&(heapCb->heapLock));
4037 #else
4038    (Void) SUnlock (&(heapCb->heapLock));
4039 #endif
4040
4041 #ifdef SS_HISTOGRAM_SUPPORT
4042             /* If If Tapa task (entId)is registerd for histogram then insert Memrory allocated
4043              * information into the hash list */
4044             if(hstReg)
4045             {
4046                if (cmHstGrmAllocInsert(&(heapCb->heapHstGrmHashListCp), *size, size, line, fileName, entId) != ROK)
4047                {
4048                  sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4049                                           SPrint(hstGrmBuf);
4050                }
4051             }/* End of if */
4052
4053 #endif /* SS_HISTOGRAM_SUPPORT */
4054
4055          return ROK;
4056       }
4057    }
4058
4059 /* cm_mem_c_008.104 - Addition for memory calculator tool */
4060 #ifdef MEMCAL_DEBUG
4061         tryHeap = 0;
4062 #endif
4063    
4064
4065    /* Release the lock */
4066    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4067 #ifdef SS_WIN
4068    (Void) WTUnlock (&(heapCb->heapLock));
4069 #else
4070    (Void) SUnlock (&(heapCb->heapLock));
4071 #endif
4072
4073    return (ROUTRES);
4074
4075 } /* end of cmHeapAlloc */
4076
4077 \f
4078 /*
4079 *
4080 *       Fun:   cmHeapFree
4081 *
4082 *       Desc:  Return the memory block from the heap pool. 
4083 *
4084 *
4085 *       Ret:   ROK     - successful
4086 *              RFAILED - unsuccessful.
4087 *
4088 *       Notes: This function returns the memory block to the heap  pool. This 
4089 *              function is called by cmFree. The function does not check the 
4090 *              validity of the memory block. The caller must be sure that the 
4091 *              block was previously allocated and belongs to the heap pool. The 
4092 *              function maintain the sorting order of the memory block on the
4093 *              starting address of the block. This function also do compaction 
4094 *              if the neighbouring blocks are already in the heap. 
4095 *
4096 *
4097 *
4098 *       File:  cm_mem_wl.c
4099 *
4100 */
4101 /*  cm_mem_c_001.main_15 : Additions */
4102 #ifdef SS_HISTOGRAM_SUPPORT  
4103 static S16  cmHeapFree 
4104 (
4105 CmMmHeapCb  *heapCb,
4106 Data        *ptr,
4107 Size         size,
4108 uint32_t     line,
4109 uint8_t     *fileName,
4110 uint8_t      entId,
4111 Bool    hstReg
4112 )
4113 #else
4114 static S16  cmHeapFree 
4115 (
4116 CmMmHeapCb  *heapCb,
4117 Data        *ptr,
4118 Size         size 
4119 )
4120 /*  cm_mem_c_001.main_15 : Additions */
4121 #endif /* SS_HISTOGRAM_SUPPORT */ 
4122 {
4123    CmHEntry  *p;    
4124    CmHEntry  *curHBlk;    /* Current heap block */ 
4125 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4126 #ifdef SSI_DEBUG_LEVEL1
4127    Size  hdr;
4128 #endif /* SSI_DEBUG_LEVEL1 */
4129 /*  cm_mem_c_001.main_15 : Additions */
4130 #ifdef SS_HISTOGRAM_SUPPORT 
4131    Size allocSize = size;
4132         S8 hstGrmBuf[256];
4133 #endif /* SS_HISTOGRAM_SUPPORT */
4134
4135
4136    /* Roundup the requested size */
4137    size = CMM_DATALIGN(size, (heapCb->minSize));
4138 /*  cm_mem_c_001.main_15: Additions */
4139 #ifdef SS_HISTOGRAM_SUPPORT  
4140    allocSize = size;
4141 #endif /* SS_HISTOGRAM_SUPPORT */
4142
4143    /* Acquire the heap lock */
4144    /* cm_mem_c_001.main_13 : Replaced SLock with WTLock for NT */
4145 #ifdef SS_WIN
4146    (Void) WTLock (&(heapCb->heapLock));
4147 #else
4148    (Void) SLock (&(heapCb->heapLock));
4149 #endif
4150
4151    /* increase the avlSize */
4152 /* cm_mem_c_001.main_12 - addition for manipulation of statistics related data */
4153 #ifdef SSI_DEBUG_LEVEL1
4154    hdr = PTRALIGN(sizeof(CmHEntry));
4155    heapCb->avlSize += (size + hdr);
4156    heapCb->numDeallocAttempts++;
4157 #else
4158    heapCb->avlSize += size;
4159 #endif /* SSI_DEBUG_LEVEL1 */
4160    
4161 /* cm_mem_c_001.main_12 - addition for pointing to the block */
4162 #ifdef SSI_DEBUG_LEVEL1
4163    p = (CmHEntry *)(ptr - hdr);
4164 #else
4165    p = (CmHEntry *)ptr; 
4166 /*  cm_mem_c_001.main_15 : Additions */
4167 #ifdef SS_MEM_LEAK_STS
4168    /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4169    cmRlsAllocBlk((PTR)ptr);
4170 #endif /* SS_MEM_LEAK_STS */
4171 #endif /* SSI_DEBUG_LEVEL1 */
4172
4173
4174 /* cm_mem_c_001.main_12 - addition for sanity and double-free checks */
4175 #ifdef SSI_DEBUG_LEVEL1
4176    /* look for memory trampling */
4177    if (cmMmRegIsBlkSane((CmMmBlkHdr *)p) != ROK)
4178    {
4179       /* detected a trampled memory block in heap */
4180    #ifdef DEBUGP
4181       /* display an error message here */
4182 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
4183 #ifdef ALIGN_64BIT          
4184       sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %u bytes \n", (void *)p, size);
4185 #else      
4186       sprintf(dbgPrntBuf, "Memory Trampling in heap at: %8p, size %lu bytes \n", (void *)p, size);
4187 #endif      
4188       SDisplay(0, dbgPrntBuf);
4189    #endif /* DEBUGP */
4190
4191       if (cmMmHeapSanityChk(heapCb) == RTRAMPLINGNOK)
4192       {
4193          /* Release the lock */
4194          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4195 #ifdef SS_WIN
4196          (Void) WTUnlock (&(heapCb->heapLock));
4197 #else
4198          (Void) SUnlock (&(heapCb->heapLock));
4199 #endif
4200          /* handle RTRAMPLINGNOK in SAlloc/SGetSBuf */
4201          return (RTRAMPLINGNOK);
4202       }
4203       else
4204       {
4205          /* do not add to the free heap */
4206          heapCb->avlSize -= (size + hdr);
4207          /* Release the heap lock */
4208          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4209 #ifdef SS_WIN
4210          (Void) WTUnlock (&(heapCb->heapLock));
4211 #else
4212          (Void) SUnlock (&(heapCb->heapLock));
4213 #endif
4214
4215          return ROK;
4216       }
4217    }
4218
4219    /* look for any double free */
4220    if (CMM_IS_FREE(p->memFlags))
4221    {
4222    #ifdef DEBUGP
4223 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
4224 #ifdef ALIGN_64BIT          
4225       sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %u in HEAP \n", (void *)p, size);
4226 #else
4227       sprintf(dbgPrntBuf, "DOUBLE FREE at %8p for size %lu in HEAP \n", (void *)p, size);
4228 #endif      
4229       SDisplay(0, dbgPrntBuf);
4230    #endif /* DEBUGP */
4231
4232       heapCb->avlSize -= (size + hdr);
4233 /*  cm_mem_c_001.main_15 : Additions */
4234 #ifdef SS_WIN 
4235          (Void) WTUnlock (&(heapCb->heapLock));
4236 #else
4237          (Void) SUnlock (&(heapCb->heapLock));
4238 #endif
4239
4240       return (RDBLFREE);
4241    }
4242 #endif /* SSI_DEBUG_LEVEL1 */
4243
4244    for ( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
4245    {
4246       /* 
4247        * The block will be inserted to maintain the sorted order on the
4248        * starting address of the block.
4249        */
4250       if (p > curHBlk)
4251       {
4252          if (!(curHBlk->next) || 
4253              (p < (curHBlk->next)))
4254          {
4255             /* Heap block should be inserted here */
4256
4257             /* 
4258              * Check if the block to be returned can be merged with the
4259              * current block.
4260              */
4261 /* cm_mem_c_001.main_12 - addition for header consideration */
4262 #ifdef SSI_DEBUG_LEVEL1
4263              if (((Data *)curHBlk + hdr + curHBlk->size) == (Data *)p)
4264 #else
4265              if (((Data *)curHBlk + curHBlk->size) == (Data *)p)
4266 #endif /* SSI_DEBUG_LEVEL1 */
4267              {
4268                  /* Merge the block */
4269 /* cm_mem_c_001.main_12 - addition for updating statistics related data */
4270 #ifdef SSI_DEBUG_LEVEL1
4271                   /* update the flags */
4272                   if (CMM_IS_STATIC(p->memFlags))
4273                      heapCb->staticHeapMemUsed -= (size + hdr);
4274                   else if (CMM_IS_DYNAMIC(p->memFlags))
4275                      heapCb->dynamicHeapMemUsed -= (size + hdr);
4276                   size = (curHBlk->size += (size + hdr));
4277 #else
4278                   size = (curHBlk->size += size);
4279 #endif /*SSI_DEBUG_LEVEL1*/
4280                   p = curHBlk;
4281              }
4282              else
4283              {
4284 /* cm_mem_c_001.main_12 - addition for double-free check */
4285 #ifdef SSI_DEBUG_LEVEL1
4286                 /* Check for double deallocation in heap */
4287                 if ((Data *)p < ((Data *)curHBlk + curHBlk->size))
4288                 {
4289                    /* Release the lock */
4290                    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4291 #ifdef SS_WIN
4292                    (Void) WTUnlock (&(heapCb->heapLock));
4293 #else
4294                    (Void) SUnlock (&(heapCb->heapLock));
4295 #endif
4296
4297                    /* This block is already freed in the heap */
4298                    return (RDBLFREE);
4299                 }
4300                 /* update the flags as it is a new node */
4301                 if (CMM_IS_STATIC(p->memFlags))
4302                 {
4303                    heapCb->staticHeapMemUsed -= (size + hdr);
4304                    CMM_RESET_STATIC_FLAG(p->memFlags);
4305                 }
4306                 else if (CMM_IS_DYNAMIC(p->memFlags))
4307                 {
4308                    heapCb->dynamicHeapMemUsed -= (size + hdr);
4309                    CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4310                 }
4311                 CMM_SET_FREE_FLAG(p->memFlags);
4312                 p->requestedSize = 0;
4313 #endif /*SSI_DEBUG_LEVEL1*/
4314                 /* insert the block */
4315                 p->next = curHBlk->next;
4316                 p->size = size; 
4317                 curHBlk->next = p;
4318              }
4319
4320             /* Try to merge with the next block in the chain */
4321 /* cm_mem_c_001.main_12 - addition for ssi enhancements */
4322 #ifdef SSI_DEBUG_LEVEL1
4323             if (((Data *)p + hdr + size) == (Data *)(p->next))
4324 #else
4325             if (((Data *)p + size) == (Data *)(p->next))
4326 #endif /*SSI_DEBUG_LEVEL1*/
4327             {
4328                /* p->next can not be NULL */
4329 /* cm_mem_c_001.main_12 - addition for header consideration */
4330 #ifdef SSI_DEBUG_LEVEL1
4331                p->size += (p->next->size + hdr);
4332 #else
4333                p->size += p->next->size; 
4334 #endif /*SSI_DEBUG_LEVEL1*/
4335                p->next  = p->next->next;
4336             }
4337
4338             /* Release the lock */
4339             /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4340 #ifdef SS_WIN
4341             (Void) WTUnlock (&(heapCb->heapLock));
4342 #else
4343             (Void) SUnlock (&(heapCb->heapLock));
4344 #endif
4345 /*  cm_mem_c_001.main_15 : Additions */             
4346 #ifdef SS_HISTOGRAM_SUPPORT 
4347         /* If If Tapa task (entId)is registerd for histogram then insert 
4348                    Memrory Freed information into the hash list */
4349         if(hstReg)
4350         {
4351             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4352                                            fileName, entId) != ROK)
4353             {
4354                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4355                                         SPrint(hstGrmBuf);
4356             }
4357          }/* End of if */
4358 #endif /* SS_HISTOGRAM_SUPPORT */
4359             return ROK;
4360          }
4361       }
4362       else if (p < curHBlk)
4363       {
4364          /*
4365          * Check if the block to be returned can be merged with the
4366          * current block.
4367          */
4368 /* cm_mem_c_001.main_12 - addition for header consideration */
4369 #ifdef SSI_DEBUG_LEVEL1
4370          if (((Data *)p + hdr + size) == (Data *)curHBlk)
4371 #else
4372          if (((Data *)p + size) == (Data *)curHBlk)
4373 #endif /* SSI_DEBUG_LEVEL1 */
4374          {
4375             /* Merge the block */
4376 /* cm_mem_c_001.main_12 - addition for header consideration */
4377 #ifdef SSI_DEBUG_LEVEL1
4378             p->size = size + (curHBlk->size + hdr);
4379 #else
4380             p->size = size + curHBlk->size;
4381 #endif /* SSI_DEBUG_LEVEL1 */
4382             p->next = curHBlk->next;
4383          }
4384          else
4385          {
4386             /* insert the block */
4387             p->next = curHBlk;
4388             p->size = size;
4389          }
4390 /* cm_mem_c_001.main_12 - addition for header updation */
4391 #ifdef SSI_DEBUG_LEVEL1
4392          /* update the flags in both cases as they are new start nodes*/
4393          if (CMM_IS_STATIC(p->memFlags))
4394          {
4395             heapCb->staticHeapMemUsed -= (size + hdr);
4396             CMM_RESET_STATIC_FLAG(p->memFlags);
4397          }
4398          else if (CMM_IS_DYNAMIC(p->memFlags))
4399          {
4400             heapCb->dynamicHeapMemUsed -= (size + hdr);
4401             CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4402          }
4403          CMM_SET_FREE_FLAG(p->memFlags);
4404          p->requestedSize = 0;
4405 #endif /* SSI_DEBUG_LEVEL1 */
4406
4407          heapCb->next = p;
4408
4409          /* Release the lock */
4410          /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4411 #ifdef SS_WIN
4412          (Void) WTUnlock (&(heapCb->heapLock));
4413 #else
4414          (Void) SUnlock (&(heapCb->heapLock));
4415 #endif
4416 /*  cm_mem_c_001.main_15 : Additions */
4417 #ifdef SS_HISTOGRAM_SUPPORT  
4418         /* If If Tapa task (entId)is registerd for histogram then insert 
4419                    Memrory Freed information into the hash list */
4420         if(hstReg)
4421         {
4422             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4423                                            fileName, entId) != ROK)
4424             {
4425                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4426                                         SPrint(hstGrmBuf);
4427             }
4428          }/* End of if */
4429 #endif /* SS_HISTOGRAM_SUPPORT */
4430          return ROK;
4431       }
4432
4433    }
4434
4435    if (heapCb->next == NULLP)
4436    {
4437       /* Heap block is empty. Insert the block in the head. */
4438       heapCb->next = p;
4439       p->next = NULLP;
4440       p->size = size;
4441
4442 /* cm_mem_c_001.main_12 - addition for header updation */
4443 #ifdef SSI_DEBUG_LEVEL1
4444       if (CMM_IS_STATIC(p->memFlags))
4445       {
4446          heapCb->staticHeapMemUsed -= (size + hdr);
4447          CMM_RESET_STATIC_FLAG(p->memFlags);
4448       }
4449       else if (CMM_IS_DYNAMIC(p->memFlags))
4450       {
4451          heapCb->dynamicHeapMemUsed -= (size + hdr);
4452          CMM_RESET_DYNAMIC_FLAG(p->memFlags);
4453       }
4454       CMM_SET_FREE_FLAG(p->memFlags);
4455       p->requestedSize = 0;
4456 #endif /* SSI_DEBUG_LEVEL1 */
4457
4458       /* Release the heap lock */
4459       /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4460 #ifdef SS_WIN
4461       (Void) WTUnlock (&(heapCb->heapLock));
4462 #else
4463       (Void) SUnlock (&(heapCb->heapLock));
4464 #endif
4465 /*  cm_mem_c_001.main_15 : Additions */
4466 #ifdef SS_HISTOGRAM_SUPPORT 
4467         /* If If Tapa task (entId)is registerd for histogram then insert 
4468                    Memrory Freed information into the hash list */
4469         if(hstReg)
4470         {
4471             if (cmHstGrmFreeInsert(&heapCb->heapHstGrmHashListCp, allocSize, line, 
4472                                            fileName, entId) != ROK)
4473             {
4474                sprintf(hstGrmBuf, "Unable to Insert into the histgram hash list\n");
4475                                         SPrint(hstGrmBuf);
4476             }
4477          }/* End of if */
4478 #endif /* SS_HISTOGRAM_SUPPORT */
4479       return ROK;
4480    }
4481
4482    /* Release the lock */
4483    /* cm_mem_c_001.main_13: Replaced SUnlock with WTUnlock for NT */
4484 #ifdef SS_WIN
4485    (Void) WTUnlock (&(heapCb->heapLock));
4486 #else
4487    (Void) SUnlock (&(heapCb->heapLock));
4488 #endif
4489
4490    return RFAILED;
4491 } /* end of cmHeapFree */
4492 /*  cm_mem_c_001.main_15 : Additions */
4493 #endif
4494 #ifdef SS_MEM_LEAK_STS 
4495 /*
4496 *
4497 *       Fun:   cmInitMemLeakMdl
4498 *
4499 *       Desc:  Initializes the memory leak detection module
4500 *
4501 *
4502 *       Ret:   void
4503 *
4504 *       Notes: This function initializes the memory leak detection module.
4505 *
4506 *
4507 *       File:  cm_mem_wl.c
4508 *
4509 */
4510 Void cmInitMemLeakMdl(Void)
4511 {
4512    uint8_t   memMdl;
4513    uint8_t   hashIdx;
4514
4515
4516    memLkCb.memLkMdlInit = FALSE;
4517    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4518    {
4519            for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4520                 {
4521        SInitLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck, 1);
4522        cmHashListInit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4523                       500, 0, FALSE, CM_HASH_KEYTYPE_UINT32_MOD, 0, 0);
4524        memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4525                 }
4526    }
4527    if(memLkCb.fileLkLog == NULLP)
4528    {
4529       memLkCb.fileLkLog = (FILE *) stdout;
4530    }
4531    memLkCb.memLkMdlInit = TRUE;
4532
4533    return;
4534 } /* cmInitMemLeakMdl */
4535 /* cm_mem_c_002.main_21 Added for shutdown procedure */
4536 /*
4537  *
4538  * Fun:   cmDeinitMemLeakMdl
4539  * 
4540  * Desc:  De-initializes the memory leak detection module
4541  * 
4542  * 
4543  * Ret:   void
4544  * 
4545  * Notes: This function de-initializes the memory leak detection module.
4546  * 
4547  * 
4548  * File:  cm_mem_wl.c
4549  * 
4550  **/
4551 Void cmDeinitMemLeakMdl (Void)
4552 {
4553   uint8_t   memMdl;
4554   uint8_t   hashIdx;
4555
4556
4557   memLkCb.memLkMdlInit = FALSE;
4558   for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4559   {
4560          for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4561          {
4562                 SDestroyLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4563                 cmHashListDeinit(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp);
4564                 memLkCb.memUsrMdl[memMdl][hashIdx].used = FALSE;
4565          }
4566   }
4567   return;
4568 }
4569 /*
4570 *
4571 *       Fun:   cmMemOpenMemLkFile
4572 *
4573 *       Desc:  Initializes the memory leak detection module
4574 *
4575 *
4576 *       Ret:   void
4577 *
4578 *       Notes: This function initializes the memory leak detection module.
4579 *
4580 *
4581 *       File:  cm_mem_wl.c
4582 *
4583 */
4584 Void cmMemOpenMemLkFile(S8 *arg)
4585 {
4586    memLkCb.fileLkLog = NULLP;
4587    memLkCb.fileLkLog = fopen(arg, "w");
4588    return;
4589 }
4590
4591 /*
4592 *
4593 *       Fun:   SLogLkInfo
4594 *
4595 *       Desc:  Initializes the memory leak detection module
4596 *
4597 *
4598 *       Ret:   void
4599 *
4600 *       Notes: This function initializes the memory leak detection module.
4601 *
4602 *
4603 *       File:  cm_mem_wl.c
4604 *
4605 */
4606 Void SLogLkInfo (Void)
4607 {
4608
4609    MemAllocInfo  *oldMemInfo;
4610    MemAllocInfo  *newMemInfo;
4611    uint8_t       memMdl;  
4612    uint8_t       hashIdx;  
4613    uint8_t       idx;
4614    Txt           prntBuf[255];
4615    S8            **funcNm;
4616    if( memLkCb.memLkMdlInit == FALSE)
4617    {
4618      return;
4619    }
4620    sprintf(prntBuf, "\n------- START OF LEAK LOG -------\n");
4621    fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4622
4623    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4624    {
4625            for (hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4626                 {
4627          if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4628          {
4629             continue;
4630          }
4631          oldMemInfo = NULLP;
4632          newMemInfo = NULLP;
4633          SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4634          while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4635                                  (PTR)oldMemInfo, (PTR *)&newMemInfo) == ROK)
4636          {
4637              sprintf(prntBuf, "[LBIS]\n");
4638              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4639              /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
4640 #ifdef ALIGN_64BIT
4641              sprintf(prntBuf, "Address: 0x%u\n", newMemInfo->memAddr);
4642 #else
4643              sprintf(prntBuf, "Address: 0x%lu\n", newMemInfo->memAddr);
4644 #endif
4645              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4646              sprintf(prntBuf, "Module Name: %s\n", 
4647                      memUsrMdlStr[newMemInfo->moduleId].mdlStr);
4648              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4649              sprintf(prntBuf, "Requested Size: %d\n", (S16)newMemInfo->reqSz);
4650              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4651              sprintf(prntBuf, "Allocated Size: %d\n", (S16)newMemInfo->allocSz);
4652              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4653              sprintf(prntBuf, "Bucket Idx: %d\n", newMemInfo->bktIdx);
4654              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4655              sprintf(prntBuf,"Memory Allocation Path:\n");
4656              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4657              funcNm = (S8 **)newMemInfo->backTrace;
4658              for(idx = 0; idx < newMemInfo->bTrcSz; idx ++)
4659              {
4660                 sprintf(prntBuf,"==> %s\n", funcNm[idx]);
4661                 fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4662              }
4663              sprintf(prntBuf, "[LBIE]\n\n");
4664              fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4665              fflush(memLkCb.fileLkLog);
4666              oldMemInfo = newMemInfo;
4667              newMemInfo = NULLP;
4668          } 
4669          SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4670                 }
4671    }
4672    sprintf(prntBuf, "\n------- END OF LEAK LOG -------\n");
4673    fwrite(prntBuf, strlen(prntBuf), 1, memLkCb.fileLkLog);
4674    return;
4675 }
4676
4677 /*
4678 *
4679 *       Fun:   SFlushLkInfo
4680 *
4681 *       Desc:  Initializes the memory leak detection module
4682 *
4683 *
4684 *       Ret:   void
4685 *
4686 *       Notes: This function initializes the memory leak detection module.
4687 *
4688 *
4689 *       File:  cm_mem_wl.c
4690 *
4691 */
4692 Void SFlushLkInfo (Void)
4693 {
4694    MemAllocInfo *newMemInfo;
4695    uint8_t      memMdl;
4696    uint8_t      hashIdx;
4697    S8           **funcNm;
4698 #ifdef SS_MEM_LEAK_SOL
4699    uint8_t      i;
4700 #endif /* SS_MEM_LEAK_SOL */
4701
4702    if( memLkCb.memLkMdlInit == FALSE)
4703    {
4704      return;
4705    }
4706
4707    for(memMdl = 0; memMdl < CM_MEM_USR_MDL; memMdl++)
4708    {
4709            for(hashIdx = 0; hashIdx < CM_MAX_HASH_PER_TSK; hashIdx++)
4710                 {
4711          if(memLkCb.memUsrMdl[memMdl][hashIdx].used == FALSE)
4712          {
4713             continue;
4714          }
4715          newMemInfo = NULLP;
4716          SLock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4717          while(cmHashListGetNext(&memLkCb.memUsrMdl[memMdl][hashIdx].memHashCp,
4718                                  (PTR)NULLP, (PTR *)&newMemInfo) == ROK)
4719          {
4720              funcNm = (S8 **)newMemInfo->backTrace;
4721 #ifdef SS_MEM_LEAK_SOL
4722              for(i = 0; i < newMemInfo->bTrcSz; i++)
4723              {
4724 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4725 #ifdef SS_4GMX_LCORE
4726                 MxHeapFree(SsiHeap, funcNm[i]); 
4727 #else
4728                 free(funcNm[i]); 
4729 #endif
4730                                     /* SPutSBuf(DFLT_REGION, DFLT_POOL, funcNm[i], sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4731              }
4732 #endif /* SS_MEM_LEAK_SOl */
4733 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4734 #ifdef SS_4GMX_LCORE
4735              MxHeapFree(SsiHeap, funcNm);
4736              MxHeapFree(SsiHeap, newMemInfo);
4737 #else
4738              free(funcNm);
4739              free(newMemInfo);
4740 #endif
4741          }
4742          SUnlock(&memLkCb.memUsrMdl[memMdl][hashIdx].memLck);
4743                 }
4744     }
4745     return;
4746 }
4747
4748 /*
4749 *
4750 *       Fun:   cmStorAllocBlk
4751 *
4752 *       Desc:  Initializes the memory leak detection module
4753 *
4754 *
4755 *       Ret:   void
4756 *
4757 *       Notes: This function initializes the memory leak detection module.
4758 *
4759 *
4760 *       File:  cm_mem_wl.c
4761 *
4762 */
4763 Void cmStorAllocBlk
4764 (
4765 uint32_t    addr,
4766 Size   reqSz,
4767 Size   allocSz,
4768 uint16_t    bktIdx
4769 )
4770 {
4771 #ifndef SS_MEM_LEAK_SOL
4772    Ptr           trace[CM_MAX_STACK_TRACE];
4773 #endif  /* SS_MEM_LEAK_SOL */
4774    S8            **funcNm;
4775    S32           traceSize;
4776    MemAllocInfo  *allocInfo;
4777    uint8_t            moduleId;
4778
4779    if( memLkCb.memLkMdlInit == FALSE)
4780    {
4781      return;
4782    }
4783
4784 #ifdef SS_MEM_LEAK_SOL
4785    /* I need to do this for solaris, because it does not implement 
4786     * backtrace. Here backtrace is my function. See below for the 
4787     * implementation. */
4788 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4789 #ifdef SS_4GMX_LCORE
4790    funcNm = (S8 **)MxHeapAlloc(SsiHeap, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4791    memset(funcNm, 0, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4792 #else
4793    funcNm = (S8 **)calloc(1, (sizeof(uint32_t) * CM_MAX_STACK_TRACE));
4794 #endif
4795         /* SGetSBuf(DFLT_REGION, DFLT_POOL, &funcNm, sizeof(uint32_t) * CM_MAX_STACK_TRACE); */
4796    traceSize = backtrace((Void **)funcNm, CM_MAX_STACK_TRACE);
4797 #else /* SS_MEM_LEAK_SOL */
4798    traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
4799    funcNm = backtrace_symbols(trace, traceSize); 
4800 #endif /* SS_MEM_LEAK_SOL */
4801    
4802    moduleId = cmMemGetModuleId(funcNm, traceSize);
4803
4804    (Void)SLock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4805 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
4806 #ifdef SS_4GMX_LCORE
4807    allocInfo = (MemAllocInfo *)MxHeapAlloc(SsiHeap, sizeof(MemAllocInfo)); 
4808    memset(allocInfo, 0, sizeof(MemAllocInfo));
4809 #else
4810    allocInfo = (MemAllocInfo *)calloc(1, sizeof(MemAllocInfo)); 
4811 #endif
4812         /* SGetSBuf(DFLT_REGION, DFLT_POOL, &allocInfo,  sizeof(MemAllocInfo)); */
4813    allocInfo->memAddr    = addr;
4814    allocInfo->reqSz      = reqSz;
4815    allocInfo->allocSz    = allocSz;
4816    allocInfo->bktIdx     = bktIdx;
4817    allocInfo->backTrace  = (PTR) funcNm;
4818    allocInfo->moduleId   = moduleId;
4819    allocInfo->bTrcSz     = traceSize;
4820
4821    cmHashListInsert(&memLkCb.memUsrMdl[moduleId][addr & 0x3].memHashCp, 
4822                     (PTR)allocInfo, (uint8_t *)&(allocInfo->memAddr),
4823                     sizeof(allocInfo->memAddr));
4824    memLkCb.memUsrMdl[moduleId][addr & 0x3].used = TRUE;
4825
4826    (Void) SUnlock(&(memLkCb.memUsrMdl[moduleId][addr & 0x3].memLck));
4827    return;
4828 } /* cmStorAllocBlk */
4829
4830 /*
4831 *
4832 *       Fun:   cmMemGetModuleId
4833 *
4834 *       Desc:  Initializes the memory leak detection module
4835 *
4836 *
4837 *       Ret:   void
4838 *
4839 *       Notes: This function initializes the memory leak detection module.
4840 *
4841 *
4842 *       File:  cm_mem_wl.c
4843 *
4844 */
4845 uint8_t cmMemGetModuleId
4846 (
4847 S8     **funNm,
4848 S32    traceSize
4849 )
4850 {
4851    uint8_t    idx;
4852    uint8_t    memStrIdx;
4853    uint32_t   len;
4854    S32   retVal;
4855    S16   memReqIdx;
4856    S16   mdlFunStrIdx;
4857
4858    Txt   *memFn[]={"SGetMsg", "SGetSBuf", "SGetDBuf", NULLP};
4859                  
4860    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
4861    for(idx = 0; idx < traceSize; idx++)
4862    {
4863       memReqIdx = -1;
4864       memStrIdx = 0;
4865       while((memReqIdx < 0) && (memFn[memStrIdx] != NULLP))
4866       {
4867          memReqIdx = cmMemGetStrMtchIdx(0, traceSize, memFn[memStrIdx], 
4868                                         funNm);
4869          memStrIdx++;
4870       }
4871       mdlFunStrIdx = 0;
4872       while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4873       {
4874          len = strlen((const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4875          memReqIdx = cmMemGetStrMtchIdx((memReqIdx + 1), traceSize, 
4876                                         memUsrMdlStr[mdlFunStrIdx].fPStr,
4877                                         funNm);
4878          if(memReqIdx >= 0)
4879          {
4880             return (mdlFunStrIdx);
4881          }
4882          mdlFunStrIdx++;
4883       }
4884       mdlFunStrIdx = 0;
4885       while(memUsrMdlStr[mdlFunStrIdx].fPStr != NULLP)
4886       {
4887           retVal = strcmp((const S8 *)"DEFAULT", 
4888                                (const S8 *)memUsrMdlStr[mdlFunStrIdx].fPStr);
4889          if(retVal == NULLD)
4890          {
4891             return (mdlFunStrIdx);
4892          } 
4893          mdlFunStrIdx++;
4894       }
4895    }
4896
4897    return (0);
4898 } /* cmMemGetModuleId */
4899
4900 /*
4901 *
4902 *       Fun:   cmMemGetStrMtchIdx
4903 *
4904 *       Desc:  Initializes the memory leak detection module
4905 *
4906 *
4907 *       Ret:   void
4908 *
4909 *       Notes: This function initializes the memory leak detection module.
4910 *
4911 *
4912 *       File:  cm_mem_wl.c
4913 *
4914 */
4915 S16 cmMemGetStrMtchIdx  
4916 (
4917 uint8_t strtIdx, 
4918 uint8_t endIdx,
4919 S8 *str, 
4920 S8 **strLst
4921 )
4922 {
4923
4924    S8   cmpStr[255];
4925    uint32_t  len;
4926    Bool found;
4927    uint32_t  tempLen;
4928    uint8_t   idx;
4929    S32  retVal;
4930
4931    len = strlen((const S8 *)str);
4932    cmpStr[0] = '(';
4933    strncpy((S8 *)&cmpStr[1], (const S8 *)str, len);
4934    cmpStr[len + 1] = '\0';
4935    len++;
4936    found = FALSE;
4937    for(;strtIdx < endIdx && !found; strtIdx++)
4938    {
4939        idx = 0;
4940        tempLen = strlen((const S8 *)strLst[strtIdx]);
4941        if(tempLen < len)
4942          continue;
4943
4944        while(*(strLst[strtIdx] + idx + len) != '\0')
4945        {
4946          retVal = strncmp((const S8 *)cmpStr, 
4947                          ((const S8 *)strLst[strtIdx] + idx), len);
4948          if(0 == retVal)
4949          {
4950            found = TRUE;
4951            break;
4952          }
4953          idx++;
4954        }
4955    }
4956
4957    if(!found)
4958    {
4959      return (-1); 
4960    }
4961    return (strtIdx);
4962
4963 }  /* cmMemGetStrMtchIdx */
4964
4965 /*
4966 *
4967 *       Fun:   cmRlsAllocBlk
4968 *
4969 *       Desc:  Initializes the memory leak detection module
4970 *
4971 *
4972 *       Ret:   void
4973 *
4974 *       Notes: This function initializes the memory leak detection module.
4975 *
4976 *
4977 *       File:  cm_mem_wl.c
4978 *
4979 */
4980 Void cmRlsAllocBlk
4981 (
4982 uint32_t    addr
4983 )
4984 {
4985     Ptr           trace[CM_MAX_STACK_TRACE];
4986     S8            **funcNm;
4987     uint8_t       idx;
4988     uint8_t       i;
4989     S16           retVal;
4990     S32           traceSize;
4991     MemAllocInfo  *memAllocInfo;
4992
4993     if( memLkCb.memLkMdlInit == FALSE)
4994     {
4995       return;
4996     }
4997
4998
4999     for(idx = 0; idx < CM_MEM_USR_MDL; idx++)
5000     {
5001        SLock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5002        retVal = cmHashListFind(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5003                                (uint8_t *)&addr, sizeof(uint32_t), 0,
5004                                (PTR *)&memAllocInfo);                              
5005        if(retVal == ROK)
5006        {
5007          cmHashListDelete(&memLkCb.memUsrMdl[idx][addr & 0x3].memHashCp,
5008                           (PTR)memAllocInfo);
5009          SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5010          funcNm = (S8 **) memAllocInfo->backTrace;
5011 #ifdef SS_MEM_LEAK_SOL
5012          for(i = 0; i < memAllocInfo->bTrcSz; i++)
5013          {
5014 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5015 #ifdef SS_4GMX_LCORE
5016             MxHeapFree(SsiHeap, funcNm[i]);
5017 #else
5018             free(funcNm[i]);
5019 #endif
5020          }
5021 #endif /* SS_MEM_LEAK_SOL */
5022 #ifdef SS_MEM_LEAK_FREE_TRACE
5023          {
5024
5025             Txt   prntBuf[255];
5026             sprintf( prntBuf, "\n==============================\n");
5027             SPrint(prntBuf);
5028             /* cm_mem_c_001.main_25 - Fixed compilation warnings 32/64 bit */
5029 #ifdef ALIGN_64BIT
5030             sprintf( prntBuf, "Address: [%x]\n", addr);
5031 #else
5032             sprintf( prntBuf, "Address: [%lx]\n", addr);
5033 #endif
5034             SPrint(prntBuf);
5035             traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5036             funcNm    = backtrace_symbols(trace, traceSize);
5037             sprintf( prntBuf, "[bt] Execution path:\n");
5038             SPrint(prntBuf);
5039             for (i=0; i < traceSize; ++i)
5040             {
5041               sprintf( prntBuf, "[bt] %s\n", funcNm[i]);
5042               SPrint(prntBuf);
5043             }
5044             sprintf( prntBuf, "\n==============================\n");
5045             SPrint(prntBuf);
5046          }
5047 #endif   /* SS_MEM_LEAK_FREE_TRACE */
5048 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5049 #ifdef SS_4GMX_LCORE
5050          MxHeapFree(SsiHeap, funcNm);
5051          MxHeapFree(SsiHeap, memAllocInfo);
5052 #else
5053          free(funcNm);
5054          free(memAllocInfo);
5055 #endif
5056          break;
5057        }
5058        SUnlock(&memLkCb.memUsrMdl[idx][addr & 0x3].memLck);
5059     }
5060
5061 #ifndef SS_MEM_LEAK_SOL
5062      if(idx == CM_MEM_USR_MDL)
5063      {
5064        Txt   prntBuf[255];
5065        sprintf( prntBuf,"\nPossible Double-Deallocation.\n");
5066        SPrint(prntBuf);
5067 /*cm_mem_c_001.main_23 Fix for specifier mismatch warnings in 64BIT compilation*/          
5068 #ifdef ALIGN_64BIT          
5069        sprintf( prntBuf, "Address: [%u]\n", addr);
5070 #else       
5071        sprintf( prntBuf, "Address: [%lu]\n", addr);
5072 #endif       
5073        SPrint(prntBuf);
5074        traceSize = backtrace(trace, CM_MAX_STACK_TRACE);
5075        funcNm    = backtrace_symbols(trace, traceSize);
5076        sprintf( prntBuf,"[bt] Execution path:\n");
5077        SPrint(prntBuf);
5078        for (i=0; i < traceSize; ++i)
5079        {
5080              sprintf( prntBuf,"[bt] %s\n", funcNm[i]);
5081              SPrint(prntBuf);
5082        }
5083        printf("\n==============================\n");
5084 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5085 #ifdef SS_4GMX_LCORE
5086        MxHeapFree(SsiHeap, funcNm);
5087 #else
5088        free(funcNm);
5089 #endif
5090      }
5091 #endif /* SS_MEM_LEAK_SOL */
5092
5093    /*cm_mem_c_001.main_25 : */
5094    return;
5095 } /* cmRlsAllocBlk */
5096
5097
5098 #ifdef SS_MEM_LEAK_SOL
5099 /*
5100 *
5101 *       Fun:   cmAddrToSymStr
5102 *
5103 *       Desc:  Initializes the memory leak detection module
5104 *
5105 *
5106 *       Ret:   void
5107 *
5108 *       Notes: This function initializes the memory leak detection module.
5109 *
5110 *
5111 *       File:  cm_mem_wl.c
5112 *
5113 */
5114 S32 cmAddrToSymStr
5115 (
5116 Void   *pc, 
5117 S8     *buffer, 
5118 S32    size
5119 )
5120 {
5121
5122    Dl_info info;
5123    Sym *sym;
5124
5125
5126    if (dladdr1(pc, &info, (Void **)&sym, RTLD_DL_SYMENT) == 0)
5127    {
5128        return (snprintf(buffer, size, "[0x%p]", pc));
5129    }
5130
5131    if ((info.dli_fname != NULLP && info.dli_sname != NULLP) &&
5132        ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size))
5133    {
5134       return (snprintf(buffer, size, "%s(%s+0x%x) [0x%p]",
5135                        info.dli_fname,
5136                        info.dli_sname,
5137                        (unsigned long)pc - (unsigned long)info.dli_saddr, pc));
5138    }
5139    else
5140    {
5141       return (snprintf(buffer, size, "%s(0x%p [0x%p]",
5142                       info.dli_fname,
5143                       (unsigned long)pc - (unsigned long)info.dli_fbase, pc));
5144    }
5145
5146 } /* cmAddrToSymStr */
5147
5148 /*
5149 *
5150 *       Fun:   cmLeakCallBack
5151 *
5152 *       Desc:  Initializes the memory leak detection module
5153 *
5154 *
5155 *       Ret:   void
5156 *
5157 *       Notes: This function initializes the memory leak detection module.
5158 *
5159 *
5160 *       File:  cm_mem_wl.c
5161 *
5162 */
5163 S32 cmLeakCallBack
5164 (
5165 uintptr_t pc,
5166 S32       sigNo, 
5167 Void      *arg
5168 )
5169 {
5170     S8   *buffer;
5171
5172     Backtrace_t *bt = (Backtrace_t *)arg;
5173     if (bt->bt_actcount >= bt->bt_maxcount)
5174          return (-1);
5175 /*cm_mem_c_001.main_27 SSI-4GMX specfic changes*/   
5176 #ifdef SS_4GMX_LCORE
5177     buffer = (S8 *)MxHeapAlloc(SsiHeap, 510); 
5178     memset(buffer, 0, 510);
5179 #else
5180     buffer = (S8 *)calloc(1, 510); 
5181 #endif
5182          /* SGetSBuf(DFLT_REGION, DFLT_POOL, &buffer, 510); */
5183     (void) cmAddrToSymStr((void *)pc, buffer, 505);
5184     bt->bt_buffer[bt->bt_actcount++] = (S8 *)buffer;
5185
5186     return (0);
5187 } /* cmLeakCallBack */
5188
5189 /*
5190 *
5191 *       Fun:   backtrace
5192 *
5193 *       Desc:  Initializes the memory leak detection module
5194 *
5195 *
5196 *       Ret:   void
5197 *
5198 *       Notes: This function initializes the memory leak detection module.
5199 *
5200 *
5201 *       File:  cm_mem_wl.c
5202 *
5203 */
5204 S32 backtrace
5205 (
5206 Void  **buffer,
5207 S32   count
5208 )
5209 {
5210
5211     Backtrace_t  bt;
5212     ucontext_t   u;
5213
5214     bt.bt_buffer = buffer;
5215     bt.bt_maxcount = count;
5216     bt.bt_actcount = 0;
5217
5218     if (getcontext(&u) < 0)
5219        return (0);
5220     (Void) walkcontext(&u, cmLeakCallBack, &bt);
5221     return (bt.bt_actcount);
5222
5223 } /* backtrace */
5224
5225 #endif /* SS_MEM_LEAK_SOL */
5226
5227 #endif /* SS_MEM_LEAK_STS */
5228 /* cm_mem_c_001.main_12 - addition related to SSI enhancemens
5229 * These include sanity check functions for bucket and heap,
5230 * for printing several memory related statistics 
5231 */
5232 #ifdef SSI_DEBUG_LEVEL1
5233 /*
5234 *
5235 *       Fun:   cmMmBktSanityChk
5236 *
5237 *       Desc:  Performs the sanity check for the memory blocks in a memory bucket.
5238 *              This API gets called when trampling is detected in a memory block.
5239 *
5240 *       Ret:   RTRAMPLINGNOK - Trampling, serious error
5241 *              RTRAMPLINGOK  - Trampling, but OK to proceed
5242 *
5243 *       Notes: This function performs the memory block sanity in a bucket. This
5244 *              function is called by cmAlloc and cmFree as part of error handling mechanism.
5245 *              Performs sanity check for the whole bucket by traversing each
5246 *              of the memory blocks using the pointer bktStartPtr.
5247 *              Keeps track of number of tramplings happened. If the count
5248 *              exceeds the threshold decided, then invalidates this bucket.
5249 *
5250 *       File:  cm_mem_wl.c
5251 *
5252 */
5253 static S16  cmMmBktSanityChk(CmMmBkt  *bkt)
5254 {
5255    CmMmBlkHdr *ptrBlk;
5256    uint32_t blkCnt;
5257
5258
5259    bkt->trampleCount = 0;
5260
5261    /* scan the entire memory list of the bucket */
5262    for (blkCnt = 0, ptrBlk = (CmMmBlkHdr *)bkt->bktStartPtr;
5263          blkCnt < (bkt->numBlks); blkCnt++)
5264    {
5265       if (cmMmRegIsBlkSane(ptrBlk) != ROK)
5266       {
5267          bkt->trampleCount++;
5268          if (bkt->trampleCount > CMM_TRAMPLING_THRESHOLD)
5269          {
5270             /* Take action to invalidate the entire bucket */
5271             return (RTRAMPLINGNOK);
5272          }
5273       }
5274       /* reach next memory block in this bucket manually */
5275       ptrBlk = (CmMmBlkHdr *)((Data *)ptrBlk + ((bkt->size) + (sizeof(CmMmBlkHdr))));
5276    }
5277
5278  #ifdef  DEBUGP
5279    /* display an error message here */
5280    sprintf(dbgPrntBuf, " %d Memory tramplings detected in the bucket!\n", bkt->trampleCount);
5281    SDisplay(0, dbgPrntBuf);
5282  #endif /* DEBUGP */
5283
5284    return (RTRAMPLINGOK);
5285 }
5286
5287 /*
5288 *
5289 *       Fun:   cmMmHeapSanityChk
5290 *
5291 *       Desc:  Performs the sanity check for the memory blocks in the memory heap.
5292 *              This API gets called when trampling is detected in heap(Alloc/Free).
5293 *
5294 *       Ret:   RTRAMPLINGNOK - Trampling, serious error
5295 *              RTRAMPLINGOK  - Trampling, but OK to proceed
5296 *
5297 *       Notes: This function performs the memory block sanity in the heap. This
5298 *              function is called by cmHeapAlloc and cmHeapFree as part of error
5299 *              handling mechanism. Keeps track of number of tramplings happened.
5300 *              If the count exceeds the threshold then return RTRAMPLINGNOK. If the
5301 *              count is less than threshold, then return RTRAMPLINGOK.
5302 *
5303 *       File:  cm_mem_wl.c
5304 *
5305 */
5306 static S16  cmMmHeapSanityChk(CmMmHeapCb  *heapCb)
5307 {
5308
5309    /* increment the trample count */
5310    heapCb->trampleCount++;
5311
5312    if (heapCb->trampleCount > CMM_TRAMPLING_THRESHOLD)
5313    {
5314       return (RTRAMPLINGNOK);
5315    }
5316
5317    return (RTRAMPLINGOK);
5318 }
5319
5320 /*
5321 *
5322 *       Fun:   cmMmRegIsBlkSane
5323 *
5324 *       Desc:  Performs the sanity check for the memory block by checking its header.
5325 *
5326 *       Ret:   ROK - If no trampling is detected in the block
5327 *              RFAILED  - If trampling is detected in the block
5328 *
5329 *       Notes: This function performs the memory block sanity in a block.
5330 *
5331 *       File:  cm_mem_wl.c
5332 *
5333 */
5334 S16 cmMmRegIsBlkSane(CmMmBlkHdr *blkPtr)
5335 {
5336    uint32_t sigCnt;
5337
5338
5339    for ( sigCnt=0; sigCnt < CMM_TRAMPLING_SIGNATURE_LEN; sigCnt++)
5340    {
5341       if (blkPtr->trSignature[sigCnt] != 0xAB)
5342       {
5343          return RFAILED;
5344       }
5345    }
5346
5347    return ROK;
5348 }
5349
5350 /*
5351 *
5352 *       Fun:   cmMmHashFunc
5353 *
5354 *       Desc:  Computes the hash list index (bin number) for a specified
5355 *              key of type (x % 101).
5356 *
5357 *       return (idx % hash_table_size);
5358 *
5359 *       Ret:   ROK     - successful, *idx contains computed index
5360 *
5361 *       Notes: None.
5362 *
5363 *       File:  cm_mem_wl.c
5364 *
5365 */
5366 static S16 cmMmHashFunc
5367 (
5368 CmMmHashListCp *hashListCp,
5369 uint32_t key,
5370 uint16_t *idx
5371 )
5372 {
5373
5374    *idx = (uint16_t)(key % hashListCp->numOfbins);
5375
5376    return ROK;
5377
5378 } /* end of cmMmHashFunc () */
5379
5380 /*
5381 *
5382 *       Fun:   cmMmHashListInit
5383 *
5384 *       Desc:  Initializes a hash list. Parameters are:
5385 *
5386 *              hashListCp   control point for hash list
5387 *              nmbBins      number of bins in the hash list. Storage will
5388 *                           be allocated for them from the indicated memory
5389 *                           region and pool.
5390 *              region
5391 *              pool         for allocating storage for bins.
5392 *
5393 *       Ret:   ROK      - initialization successful
5394 *              RFAILED  - initialization failed, lack of memory
5395 *
5396 *       Notes: None
5397 *
5398 *       File:  cm_mem_wl.c
5399 *
5400 */
5401 static S16 cmMmHashListInit
5402 (
5403 CmMmHashListCp *hashListCp,  /* hash list to initialize */
5404 uint16_t     nmbBins,      /* number of hash list bins */
5405 Region       region,       /* memory region to allocate bins */
5406 Pool         pool          /* memory pool to allocate bins */
5407 )
5408 {
5409    uint16_t i;
5410    CmMmHashListEnt *hl;
5411
5412
5413    /* initialize control point fields */
5414    hashListCp->hashList = NULLP;
5415    hashListCp->numOfbins = 0;
5416    hashListCp->numOfEntries  = 0;
5417
5418    /* allocate memory for bins */
5419    if (nmbBins)
5420    {
5421       if (SGetSBuf(region, pool, (Data **) &hashListCp->hashList,
5422                (Size)(nmbBins * sizeof(CmMmHashListEnt))) != ROK)
5423       return RFAILED;
5424
5425       /* initialize bin pointers */
5426       hl = hashListCp->hashList;
5427       for(i = 0; i < nmbBins; i++)
5428       {
5429          hl[i].size = hl[i].numAttempts = 0;
5430       }
5431
5432       /* initialize bin size */
5433       hashListCp->numOfbins = nmbBins;
5434    }
5435
5436    return ROK;
5437 }
5438
5439 /*
5440 *
5441 *       Fun:   cmMmHashListDeinit
5442 *
5443 *       Desc:  Deinitializes a hash list. Deallocates memory for bins
5444 *              and resets header fields. Parameters are:
5445 *
5446 *              hashListCp   control point for hash list
5447 *              region
5448 *              pool         for allocating storage for bins.
5449 *
5450 *       Ret:   ROK      - successful
5451 *              RFAILED - failure, invalid parameters
5452 *
5453 *       Notes: None
5454 *
5455 *       File:  cm_mem_wl.c
5456 *
5457 */
5458 static S16 cmMmHashListDeinit
5459 (
5460 CmMmHashListCp *hashListCp,   /* hash list to deinitialize */
5461 Region       region,       /* memory region to allocate bins */
5462 Pool         pool          /* memory pool to allocate bins */
5463 )
5464 {
5465
5466    /* deallocate memory for bins */
5467    if (hashListCp->numOfbins)
5468       (Void) SPutSBuf(region, pool,
5469                       (Data *) hashListCp->hashList,
5470                       (Size) (hashListCp->numOfbins * sizeof(CmMmHashListEnt)));
5471
5472    /* deinitialize control point fields */
5473    hashListCp->hashList = NULLP;
5474    hashListCp->numOfbins = 0;
5475    hashListCp->numOfEntries = 0;
5476
5477    return ROK;
5478 } /* end of cmMmHashListDeinit */
5479
5480 /*
5481 *
5482 *       Fun:   cmMmHashListInsert
5483 *
5484 *       Desc:  Inserts a new entry in the hash list. Parameters are:
5485 *
5486 *              hashListCp   control point for hash list
5487 *              key          pointer to key string in the new entry
5488 *
5489 *       Ret:   ROK      - insertion successful
5490 *              RFAILED  - insertion failed (incorrect parameter values)
5491 *
5492 *       Notes: None
5493 *
5494 *       File:  cm_mem_wl.c
5495 *
5496 */
5497 static S16 cmMmHashListInsert
5498 (
5499 CmMmHashListCp *hashListCp,  /* hash list to add to */
5500 uint32_t       key         /* pointer to key */
5501 )
5502 {
5503    CmMmHashListEnt *hashListEnt;    /* pointer to hash list entry header */
5504    uint16_t idx;                       /* index for insertion into hash list */
5505    uint16_t i;
5506
5507
5508    /* check if hashListCp is initialised yet */
5509    if ( hashListCp->numOfbins == 0)
5510       return ROK;
5511
5512    /* compute index for insertion */
5513    if (cmMmHashFunc(hashListCp, key, &idx) != ROK)
5514       return RFAILED;
5515
5516    hashListEnt = hashListCp->hashList;
5517
5518    if (hashListEnt[idx].numAttempts == 0)
5519    {
5520       /* new entry, insert here */
5521       hashListEnt[idx].size = key;
5522       hashListEnt[idx].numAttempts++;
5523       /* increment count of entries in hash list */
5524       hashListCp->numOfEntries++;
5525    }
5526    else
5527    {
5528       /* this hash is occupied, re-hash it using linear probing */
5529       for (i=idx; i < CMM_STAT_HASH_TBL_LEN; i++)
5530       {
5531          if (hashListEnt[i].size == key)
5532          {
5533             hashListEnt[i].numAttempts++;
5534             break;
5535          }
5536
5537          if (hashListEnt[i].numAttempts == 0)
5538          {
5539             hashListEnt[i].size = key;
5540             hashListEnt[i].numAttempts++;
5541             /* increment count of entries in hash list */
5542             hashListCp->numOfEntries++;
5543             break;
5544          }
5545    }
5546
5547    if (i == CMM_STAT_HASH_TBL_LEN)
5548    {
5549       /* there is no free slot for this key */
5550       return RFAILED;
5551    }
5552    }
5553
5554    return ROK;
5555 } /* end of cmMmHashListInsert */
5556
5557 #endif /* SSI_DEBUG_LEVEL1 */
5558 /*  cm_mem_c_001.main_15 : Additions */
5559 #ifdef SS_HISTOGRAM_SUPPORT  
5560 /*
5561 *
5562 *       Fun:   cmHstGrmHashListInit
5563 *
5564 *       Desc:  Initializes a hash list. Parameters are:
5565 *
5566 *              hashListCp   control point for hash list
5567 *       Ret:   ROK      - initialization successful
5568 *              RFAILED  - initialization failed, lack of memory
5569 *
5570 *       Notes: None
5571 *
5572 *       File:  cm_mem_wl.c
5573 *
5574 */
5575 static S16 cmHstGrmHashListInit
5576 (
5577 CmHstGrmHashListCp *hashListCp  /* hash list to initialize */
5578 )
5579 {
5580    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5581 #ifdef  DEBUGP
5582    /* display an error message here */
5583    /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/ 
5584 #ifdef ALIGN_64BIT
5585     sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5586 #else
5587     sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5588 #endif
5589     SDisplay(0, dbgPrntBuf);
5590 #endif /* DEBUGP */
5591     memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5592     return ROK;
5593 }
5594
5595 /*
5596 *
5597 *       Fun:   cmHstGrmHashListDeInit
5598 *
5599 *       Desc:  De-initializes a hash list. Parameters are:
5600 *
5601 *              hashListCp   control point for hash list
5602 *       Ret:   ROK      - initialization successful
5603 *              RFAILED  - initialization failed, lack of memory
5604 *
5605 *       Notes: None
5606 *
5607 *       File:  cm_mem_wl.c
5608 *
5609 */
5610 static S16 cmHstGrmHashListDeInit
5611 (
5612 CmHstGrmHashListCp *hashListCp  /* hash list to initialize */
5613 )
5614 {
5615    /*cm_mem_c_001.main_25 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
5616 #ifdef  DEBUGP
5617    /* display an error message here */
5618    /*cm_mem_c_001.main_25: Fixed Warnings for 32/64 bit compilation*/ 
5619 #ifdef ALIGN_64BIT
5620     sprintf(dbgPrntBuf, " %lu size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5621 #else
5622     sprintf(dbgPrntBuf, " %d size of memory histogram hash List\n", sizeof(CmHstGrmHashListCp));
5623 #endif
5624     SDisplay(0, dbgPrntBuf);
5625 #endif /* DEBUGP */
5626     memset(hashListCp, 0, sizeof(CmHstGrmHashListCp));
5627     return ROK;
5628 }
5629
5630 /*
5631 *
5632 *       Fun:   cmHstGrmFreeInsert
5633 *
5634 *       Desc:  Inserts a Freed information in into the hash list. Parameters are:
5635 *
5636 *              bkt : pointer to bucket for which memory is freed.
5637 *              line : Line where memory is freed.
5638 *              file : file where memory is freed.
5639 *              entId : Tapa task which releases the memory.
5640 *
5641 *       Ret:   ROK      - insertion successful
5642 *              RFAILED  - insertion failed (incorrect parameter values)
5643 *
5644 *       Notes: None
5645 *
5646 *       File:  cm_mem_wl.c
5647 *
5648 */
5649 static S16 cmHstGrmFreeInsert
5650 (
5651 CmHstGrmHashListCp* hashListCp, /* hash list cp */
5652 uint32_t blkSz, /* size of the block freed */
5653 uint32_t line, /* Line number */
5654 uint8_t  *fileName, /* file name */
5655 uint8_t  entId    /* Tapa task which free the memory */
5656 )
5657 {
5658    uint32_t      binIdx = 0; /* Bin index to insert the entry into the hash list */
5659    uint32_t      key = 0; /* Key to fine the bin index */
5660    uint32_t      ret = 0; /* Return value */
5661    CmMemEntries  *entry = NULLP; /* Entry which contains the information */
5662
5663
5664
5665    /* check for the total number of entries in the hash list. *
5666     * If there is no place for new entry return failure */
5667     cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5668
5669    /* After comuting the hash bind and key, check the entity already *
5670       existing or not. if we found the entry then update the information */
5671    ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5672    if(ret == ROK)
5673    {
5674                 entry->freedBytes += blkSz;
5675       entry->bucketFreeReq++;
5676       return ROK;
5677    } /* End of if */
5678
5679    /* If hash list is full then print the error tna continue */
5680    if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5681    {
5682         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");
5683         return RFAILED;
5684    } /* End of if */
5685
5686    /* Take the address of next free entry in the hash bin */
5687    entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5688
5689    /* Increase the number of time frees called */
5690    entry->bucketFreeReq++;
5691         entry->freedBytes += blkSz;
5692
5693    /* Fill the information into the entry structure */
5694    cmHstGrmFillEntry(entry, key, line, fileName, entId);
5695    /* Increase the total numbet of entries in the bin */
5696    hashListCp->hashList[binIdx].numOfEntries++;
5697
5698    /* Increase the total number of entries in the hash list */
5699    hashListCp->totalNumEntries++;
5700
5701    return ROK;
5702 } /* end of cmHstGrmFreeInsert */
5703
5704
5705 /*
5706 *
5707 *       Fun:  ret = cmHstGrmAllocInsert
5708 *
5709 *       Desc:  Inserts a memory allocated information in the hash list. Parameters are:
5710 *
5711 *              hashListCp   control point for hash list
5712 *              key          pointer to key string in the new entry
5713 *
5714 *       Ret:   ROK      - insertion successful
5715 *              RFAILED  - insertion failed (incorrect parameter values)
5716 *
5717 *       Notes: None
5718 *
5719 *       File:  cm_mem_wl.c
5720 *
5721 */
5722 static S16 cmHstGrmAllocInsert
5723 (
5724 CmHstGrmHashListCp     *hashListCp,
5725 uint32_t blkSz,
5726 uint32_t *reqSz,
5727 uint32_t line,
5728 uint8_t  *fileName,
5729 uint8_t  entId
5730 )
5731 {
5732    uint32_t      binIdx = 0;
5733    uint32_t      key = 0;
5734    uint32_t      ret = 0;
5735    CmMemEntries  *entry = NULLP;
5736
5737
5738    /* check for the total number of entries in the hash list. *
5739     * If there is no place for new entry return failure */
5740    cmHstGrmGetHashIdxAndKey(fileName, line, &binIdx, &key);
5741
5742    /* After comuting the hash bind and key, check the entity already *
5743       existing or not. if we found the entry then update the information */
5744    ret = cmHstGrmFindEntry(hashListCp, key, &binIdx, &entry);
5745
5746    if(ret == ROK)
5747    {
5748            entry->allocBytes += blkSz;
5749       entry->bucketAllocReq++;
5750       entry->wastedBytes += (blkSz - *reqSz);
5751       return ROK;
5752    } /* End of if */
5753
5754    if(hashListCp->totalNumEntries == (CMM_HIST_MAX_MEM_BIN * CMM_HIST_MAX_MEM_ENTRY_PER_BIN))
5755    {
5756         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");
5757         return RFAILED;
5758    } /* End of if */
5759
5760    /* Take the address of next free entry in the hash bin */
5761    entry = &(hashListCp->hashList[binIdx].entries[hashListCp->hashList[binIdx].numOfEntries]);
5762
5763    /* Clauculae the wasted bytes */
5764    /* Here wasted byte is differnce between the byte user
5765     * has requested and the byte the ssi allocated */
5766    entry->wastedBytes += (blkSz - *reqSz);
5767    entry->bucketAllocReq++;
5768         entry->allocBytes += blkSz;
5769
5770    /* Fill the information into the entry structure */
5771    cmHstGrmFillEntry(entry, key, line, fileName, entId);
5772    /* Increase the total numbet of entries in the bin */
5773    hashListCp->hashList[binIdx].numOfEntries++;
5774
5775    /* Increase the total number of entries in the hash list */
5776    hashListCp->totalNumEntries++;
5777
5778    return ROK;
5779 } /* end of cmHstGrmAllocInsert */
5780
5781
5782 /*
5783 *
5784 *       Fun:   cmHstGrmGetHashIdxAndKey
5785 *
5786 *       Desc:  Finds an entry in the hash list. Parameters are:
5787 *
5788 *              hashListCp   control point for hash list
5789 *              key          pointer to key string in the new entry
5790 *
5791 *       Ret:   ROK      - insertion successful
5792 *              RFAILED  - insertion failed (incorrect parameter values)
5793 *
5794 *       Notes: None
5795 *
5796 *       File:  cm_mem_wl.c
5797 *
5798 */
5799 static S16 cmHstGrmGetHashIdxAndKey
5800 (
5801 uint8_t   *fileName,
5802 uint32_t  line,
5803 uint32_t  *binIdx,
5804 uint32_t  *key
5805 )
5806 {
5807
5808    uint32_t  i = 0;
5809
5810    /* Calculate the key using file name and line number */
5811    for(i = 0 ; fileName[i] != '\0'; i++)
5812    {
5813        *key += fileName[i];
5814    }/* End of for */
5815        *key += line;
5816    *binIdx = ( *key % CMM_HIST_MAX_MEM_BIN);
5817    return ROK;
5818 } /* end of cmHstGrmFillEntry */
5819
5820 /*
5821 *
5822 *       Fun:   cmHstGrmFillEntry
5823 *
5824 *       Desc:  Insert the entry into the hash list.
5825 *
5826 *              entry : Infornation which will be inserted into the hash list
5827 *              key   : Which will be used ti find the entry.
5828 *              line  : Line number
5829 *              fileName : File name
5830 *              entId   : Tapa task Id
5831 *
5832 *       Ret:   ROK      - insertion successful
5833 *              RFAILED  - insertion failed (incorrect parameter values)
5834 *
5835 *       Notes: None
5836 *
5837 *       File:  cm_mem_wl.c
5838 *
5839 */
5840 static S16 cmHstGrmFillEntry
5841 (
5842 CmMemEntries       *entry,
5843 uint32_t key,
5844 uint32_t line,
5845 uint8_t  *fileName,
5846 uint8_t  entId
5847 )
5848 {
5849
5850    uint32_t       idx = 0;
5851    entry->key = key;
5852    entry->line = line;
5853    entry->entId = entId;
5854    for(idx = 0; fileName[idx] != '\0'; idx++)
5855    {
5856       entry->fileName[idx] = fileName[idx];
5857    }
5858    entry->fileName[idx] = '\0';
5859    return ROK;
5860 } /* end of cmHstGrmFillEntry */
5861
5862 /*
5863 *
5864 *       Fun:  cmHstGrmFindEntry
5865 *
5866 *       Desc:  Finds an entry in the hash list. Parameters are:
5867 *
5868 *              hashListCp   control point for hash list
5869 *              key          pointer to key string in the new entry
5870 *
5871 *       Ret:   ROK      - insertion successful
5872 *              RFAILED  - insertion failed (incorrect parameter values)
5873 *
5874 *       Notes: None
5875 *
5876 *       File:  cm_mem_wl.c
5877 *
5878 */
5879 static S16 cmHstGrmFindEntry
5880 (
5881 CmHstGrmHashListCp  *hashListCp,
5882 uint32_t            key,
5883 uint32_t            *binIdx,
5884 CmMemEntries        **entry
5885 )
5886 {
5887
5888    uint32_t             numEnt = 0;
5889    uint32_t             numBin = 0;
5890    CmHstGrmHashListEnt  *tmpBin = NULLP;
5891
5892
5893    for(numBin = 0; numBin < CMM_HIST_MAX_MEM_BIN; numBin++)
5894    {
5895       /* find for the entry in the bin */
5896       tmpBin = &(hashListCp->hashList[*binIdx]);
5897       for(numEnt = 0; numEnt < tmpBin->numOfEntries; numEnt++)
5898       {
5899          /* If key supplied is matched with the stored key then
5900           * return that entity */
5901          if(tmpBin->entries[numEnt].key == key)
5902          {
5903             *entry = &(tmpBin->entries[numEnt]);
5904             return ROK;
5905          }/* End of if (tmpBin->entries[numEnt].key) */
5906       }/* end of for (numEnt = 0) */
5907
5908       /* Here we are checking for any room left in the bin. If the room *
5909          exists its mean that there is no entry with the Key. so return *
5910          failure.
5911          If there is no room in the bin, then check the other bins to find *
5912          the entry */
5913       if(numEnt == CMM_HIST_MAX_MEM_ENTRY_PER_BIN)
5914       {
5915         if(*binIdx == CMM_HIST_MAX_MEM_BIN)
5916         {
5917             *binIdx = 0;
5918         }/* End of if (binIdx) */
5919         else
5920         {
5921             *binIdx++;
5922         }/* End of else (binIdx) */
5923       } /* End of if (numEnt) */
5924       else
5925       {
5926          printf ("Unable to find the entry in hash list\n");
5927          return RFAILED;
5928       }/* End of else (numEnt) */
5929    }/* end of for (numBin = 0) */
5930
5931    printf("Unable to find the entry in the hash list\n");
5932    return RFAILED;
5933 } /* end of cmHstGrmFindEntry */
5934
5935 #endif /* SS_HISTOGRAM_SUPPORT */
5936 #ifdef T2K_MEM_LEAK_DBG
5937 T2kMeamLeakInfo gMemLeakInfo[T2K_MEM_LEAK_INFO_TABLE_SIZE];
5938 uint32_t getT2kMemLeakIndex(uint32_t address)
5939 {
5940    return ((address - T2K_MEM_LEAK_START_ADDR) >> 8);
5941 }
5942
5943 static uint32_t t2kMemAllocTick;
5944 static uint32_t smallTick;
5945
5946 void InsertToT2kMemLeakInfo(uint32_t address, uint32_t size, uint32_t lineNo, char* fileName)
5947 {
5948    uint32_t idx = getT2kMemLeakIndex(address);
5949
5950    if(((uint32_t)(address - T2K_MEM_LEAK_START_ADDR) & 0xff) !=0)
5951    {
5952      printf("address in InsertToT2kMemLeakInfo is %lx size = %ld file is %s"
5953            "line is %ld \n", address, size, fileName, lineNo);
5954    }
5955
5956    if(gMemLeakInfo[idx].address == 0)
5957    {
5958       gMemLeakInfo[idx].address = address;
5959       gMemLeakInfo[idx].size = size;
5960       gMemLeakInfo[idx].lineNo = lineNo;
5961       gMemLeakInfo[idx].fileName = fileName;
5962       gMemLeakInfo[idx].age = t2kMemAllocTick; 
5963       gMemLeakInfo[idx].prevRemLineNo = 0;
5964       gMemLeakInfo[idx].prevRemFileName = '\0';
5965
5966       if(smallTick++ == 4096)
5967       {
5968          smallTick = 0;
5969               gMemLeakInfo[idx].age = (++t2kMemAllocTick); 
5970       }
5971    }
5972    else
5973    {
5974          printf("Something is wrong, trying to insert %lx idx = %ld file is %s"
5975                "line is %ld \n",address, idx, fileName, lineNo);
5976          printf("Address present :%lx, from File:%s, Line:%ld, Size:%ld,"
5977                "Age:%ld, differnce in Age:%ld",
5978                gMemLeakInfo[idx].address, gMemLeakInfo[idx].fileName,
5979                gMemLeakInfo[idx].lineNo, gMemLeakInfo[idx].size,
5980                gMemLeakInfo[idx].age, (t2kMemAllocTick-gMemLeakInfo[idx].age));
5981    }
5982 }
5983
5984
5985 void RemoveFromT2kMemLeakInfo(uint32_t address, char *file, uint32_t line)
5986 {
5987    uint32_t idx = getT2kMemLeakIndex(address);
5988
5989    if(idx >= T2K_MEM_LEAK_INFO_TABLE_SIZE)
5990    {
5991       printf("Idx out of range = %ld address is %lx file = %s line = %ld. We are going to crash!!!\n",
5992               idx,
5993               address,
5994               file,
5995               line);
5996    }
5997    if(gMemLeakInfo[idx].address == address)
5998    {
5999       gMemLeakInfo[idx].address = 0;
6000       gMemLeakInfo[idx].age = 0; 
6001       gMemLeakInfo[idx].prevRemLineNo = gMemLeakInfo[idx].lineNo;
6002       gMemLeakInfo[idx].prevRemFileName = gMemLeakInfo[idx].fileName; 
6003
6004       gMemLeakInfo[idx].lastDelLineNum = line;
6005       gMemLeakInfo[idx].lastDelFileName = file; 
6006       /*printf("Something is wrong, Trying to double free Address = %x, Idx = %d \n",address,idx);*/
6007    }
6008    else
6009    {
6010          printf("Something is wrong, trying to remove %lx idx = %ld  from"
6011                "File=%s, line=%ld address present is %lx\n",address, idx, file,line, 
6012                    gMemLeakInfo[idx].address);
6013
6014
6015          printf("\n Last Del file %s line %ld\n",gMemLeakInfo[idx].lastDelFileName,
6016                  gMemLeakInfo[idx].lastDelLineNum);
6017
6018          if(gMemLeakInfo[idx].prevRemFileName != NULLP)
6019          {
6020             printf("Previous File:%s, Previous Line:%ld\n",
6021                   gMemLeakInfo[idx].prevRemFileName, gMemLeakInfo[idx].prevRemLineNo);
6022          }
6023    }
6024 }
6025
6026 void DumpT2kMemLeakInfoToFile()
6027 {
6028    int i;
6029   
6030    FILE *fp = fopen("memLeakInfo.txt","wb");
6031
6032    if(fp == NULL)
6033    {
6034       printf("Could not open file for dumping mem leak info\n");
6035       return;
6036    }
6037
6038    for(i = 0; i< T2K_MEM_LEAK_INFO_TABLE_SIZE; i++)
6039    {
6040       if(gMemLeakInfo[i].address != 0)
6041       {
6042          char* onlyFileName = rindex(gMemLeakInfo[i].fileName,'/');
6043          if(onlyFileName == NULL)
6044          {
6045             onlyFileName = gMemLeakInfo[i].fileName;
6046          }
6047
6048          fprintf(fp, "%ld  s=%ld  a=%ld  l=%ld  f=%s\n",gMemLeakInfo[i].address,
6049                                             gMemLeakInfo[i].size,
6050                                             gMemLeakInfo[i].age,
6051                                             gMemLeakInfo[i].lineNo,
6052                                             onlyFileName);
6053       }
6054    }
6055
6056    fprintf(fp,"Current t2kMemAllocTick = %ld\n",t2kMemAllocTick);
6057
6058    fclose(fp);
6059 }
6060 #endif
6061
6062 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6063
6064 /* For Updating SOC Specific Memory Information */
6065 S16 UpdateSocMemInfo
6066 (
6067 uint8_t areaIndex,
6068 CmLteMemInfo *mInfo
6069 )
6070 {
6071    uint8_t  idxReg;
6072    uint8_t  idxPool;
6073    uint16_t  numPool;
6074    void *iccHdl = NULLP;
6075    uint32_t poolFreeCnt[4];
6076    uint32_t poolUsedCnt[4];
6077    uint32_t poolSize[4];
6078    uint32_t poolTotAvail[4];
6079
6080    idxReg = mInfo->numRegions;
6081    mInfo->numRegions = mInfo->numRegions + 1;
6082    /* Calling Soc specific API to get shared memory status */
6083    numPool = 4; /* For Intel it is fixed to 4. Change to API call when available */
6084    iccHdl = ssGetIccHdl(areaIndex);
6085
6086    /* Populating global memory information */
6087    mInfo->regInfo[idxReg].numPools = numPool;
6088    mInfo->regInfo[idxReg].regionId = areaIndex;
6089    mInfo->regInfo[idxReg].regionType = 1; /* 1 - SHARED REGION */
6090
6091    /* Calling INTEL API's to Get Free MEM BLOCKS */
6092    poolFreeCnt[0] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6093    poolFreeCnt[1] = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6094    poolFreeCnt[2] = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6095    poolFreeCnt[3] = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6096
6097    poolUsedCnt[0] = ICC_POOL_ZERO_TOTAL_BLKS - poolFreeCnt[0];
6098    poolUsedCnt[1] = ICC_POOL_ONE_TOTAL_BLKS - poolFreeCnt[1];
6099    poolUsedCnt[2] = ICC_POOL_TWO_TOTAL_BLKS - poolFreeCnt[2];
6100    poolUsedCnt[3] = ICC_POOL_THREE_TOTAL_BLKS - poolFreeCnt[3];
6101      
6102    poolSize[0] = ICC_POOL_ZERO_SIZE;
6103    poolSize[1] = ICC_POOL_ONE_SIZE;
6104    poolSize[2] = ICC_POOL_TWO_SIZE;
6105    poolSize[3] = ICC_POOL_THREE_SIZE;
6106
6107    poolTotAvail[0] = ICC_POOL_ZERO_TOTAL_BLKS;
6108    poolTotAvail[1] = ICC_POOL_ONE_TOTAL_BLKS;
6109    poolTotAvail[2] = ICC_POOL_TWO_TOTAL_BLKS;
6110    poolTotAvail[3] = ICC_POOL_THREE_TOTAL_BLKS;
6111
6112    for(idxPool=0; idxPool<numPool;idxPool++)
6113    {
6114       mInfo->regInfo[idxReg].poolInfo[idxPool].poolSize = poolSize[idxPool];
6115       mInfo->regInfo[idxReg].poolInfo[idxPool].totAvailable = 
6116                                                 poolTotAvail[idxPool];
6117       mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed = poolUsedCnt[idxPool];
6118       if(mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed > 
6119                    mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed)
6120       {
6121          mInfo->regInfo[idxReg].poolInfo[idxPool].maxUsed = 
6122                          mInfo->regInfo[idxReg].poolInfo[idxPool].crntUsed;
6123       }
6124    }
6125
6126    return ROK;
6127 }
6128
6129 /*
6130 *
6131 *       Fun:   isL2MemUsageBelowLowerThreshold
6132 *
6133 *       Desc:  Checks for the Lower threshold of ICC memory.
6134 *
6135 *              region       region for obtaining the ICC handle
6136 *
6137 *       Ret:   TRUE      - Threshold has reached
6138 *              FALSE     - Threshold has not reached
6139 *
6140 *       Notes: None
6141 *
6142 *       File:  cm_mem_wl.c
6143 *
6144 */
6145 uint32_t isL2MemUsageBelowLowerThreshold(
6146 Region region
6147 )
6148 {
6149    void * iccHdl = ssGetIccHdl(region);
6150
6151    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6152    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6153
6154    /* We are below the threshold if free count in BOTH of the pools
6155     * is above the ICC_MEM_LOWER_THRESHOLD % */
6156    if(((poolZeroFreeCnt * 100) > 
6157       (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6158       ((poolOneFreeCnt * 100) >
6159        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)))
6160      {
6161         return (TRUE);
6162      }
6163
6164    return (FALSE);
6165 }
6166
6167
6168 /*
6169 *
6170 *       Fun:   isMemUsageBelowLowerThreshold
6171 *
6172 *       Desc:  Checks for the Lower threshold of ICC memory.
6173 *
6174 *              region       region for obtaining the ICC handle
6175 *
6176 *       Ret:   TRUE      - Threshold has reached
6177 *              FALSE     - Threshold has not reached
6178 *
6179 *       Notes: None
6180 *
6181 *       File:  cm_mem_wl.c
6182 *
6183 */
6184 uint32_t isMemUsageBelowLowerThreshold(
6185 Region region
6186 )
6187 {
6188    void * iccHdl = ssGetIccHdl(region);
6189
6190    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6191    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6192    uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6193    uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6194
6195    /* We are below the threshold if free count in BOTH of the pools
6196     * is above the ICC_MEM_LOWER_THRESHOLD % */
6197    if(((poolZeroFreeCnt * 100) > 
6198       (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) &&
6199       ((poolOneFreeCnt * 100) >
6200        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) &&
6201       ((poolTwoFreeCnt * 100) >
6202        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) &&
6203       ((poolThreeFreeCnt * 100) >
6204        (ICC_MEM_LOWER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6205      {
6206         return (TRUE);
6207      }
6208
6209    return (FALSE);
6210 }
6211
6212 /*
6213 *
6214 *       Fun:   isMemUsageAboveUpperThreshold
6215 *
6216 *       Desc:  Checks for the Upper threshold of ICC memory.
6217 *
6218 *              region       region for obtaining the ICC handle
6219 *
6220 *       Ret:   TRUE      - Threshold has reached
6221 *              FALSE     - Threshold has not reached
6222 *
6223 *       Notes: None
6224 *
6225 *       File:  cm_mem_wl.c
6226 *
6227 */
6228 static uint32_t isMemUsageAboveUpperThreshold(
6229 Region region
6230 )
6231 {
6232    void * iccHdl = ssGetIccHdl(region);
6233
6234    uint32_t poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE);
6235    uint32_t poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE);
6236    uint32_t poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE);
6237    uint32_t poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE);
6238
6239    /* We are above the threshold if free count in either of the pools
6240     * is below the ICC_MEM_UPPER_THRESHOLD % */
6241    if(((poolZeroFreeCnt * 100) < 
6242       (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ZERO_TOTAL_BLKS)) ||
6243       ((poolOneFreeCnt * 100) <
6244        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_ONE_TOTAL_BLKS)) ||
6245       ((poolTwoFreeCnt * 100) <
6246        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_TWO_TOTAL_BLKS)) ||
6247       ((poolThreeFreeCnt * 100) <
6248        (ICC_MEM_UPPER_THRESHOLD * ICC_POOL_THREE_TOTAL_BLKS)))
6249      {
6250         return (TRUE);
6251      }
6252
6253    return (FALSE);
6254 }
6255
6256 /* ccpu00142274- Function to check if we have reached the 
6257  * Threshold for dropping UL packets at the RLC. This function
6258  * measures the free count of the ICC memory and based on the 
6259  * volume of packets it sets an alarm to drop packets. 
6260  * In DL, the PDCP packets are dropped at Admission Control, but 
6261  * at UL we need to check if its an AM(Data only and 
6262  * not Status PDU) or UM packet and free the PDU 
6263  * Note: With the current design, we have PDCP DL and RLC UL
6264  * running in the same thread and the below function will be 
6265  * accessed in tandem. But if PDCP DL and RLC UL are made to run 
6266  * in different threads then there might be a race condition.
6267  * Please revisit this function in such a case.
6268  * */
6269 /*
6270 *
6271 *       Fun:   isMemThreshReached
6272 *
6273 *       Desc:  Checks whether the system has reached the 
6274 *              designated threshold of ICC memory.
6275 *
6276 *              region       region for obtaining the ICC handle
6277 *
6278 *       Ret:   ROK         - Threshold has not reached
6279 *              RFAILED     - Threshold has reached
6280 *
6281 *       Notes: None
6282 *
6283 *       File:  cm_mem_wl.c
6284 *
6285 */
6286 uint32_t isMemThreshReached(
6287 Region reg
6288 )
6289 {
6290    if(gMemoryAlarm)
6291    {
6292       gMemoryAlarm = !(isMemUsageBelowLowerThreshold(reg));
6293       return RFAILED;
6294    }
6295    else
6296    {
6297       if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_AGAIN)
6298       {
6299          gMemoryAlarm = isMemUsageAboveUpperThreshold(reg);
6300          memoryCheckCounter = 0;
6301       }
6302    }
6303    return ROK;
6304 }
6305 #endif
6306 #endif /* SS_LOCKLESS_MEMORY */
6307 /**********************************************************************
6308          End of file
6309  **********************************************************************/
6310