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