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