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