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