1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /********************************************************************20**
21 Name: common memory allocation library
25 Desc: memory library routines
29 *********************************************************************21*/
32 /* header include files (.h) */
33 #include "envopt.h" /* environment options */
34 #include "envdep.h" /* environment dependent */
35 #include "envind.h" /* environment independent */
36 #include "gen.h" /* general layer */
37 #include "ssi.h" /* system services */
38 #include "cm_mblk.h" /* Header file */
40 /* header/extern include files (.x) */
41 #include "gen.x" /* general layer */
42 #include "ssi.x" /* system services */
43 #include "cm_lib.x" /* Common library */
44 #include "cm_mblk.x" /* Typedef file */
46 #ifdef SS_LOCKLESS_MEMORY
47 pthread_t tmpRegTidMap[20];
48 #define CM_MEM_GET_REGION(_region) \
53 for(_regCnt = 0; _regCnt < 12; _regCnt++) \
55 if(tmpRegTidMap[_regCnt] == pthread_self()) \
66 static Void cmAddMemNode ARGS((CmMemListCp *lCp,CmMemList *node));
73 * Desc: This function allocates the first memory chunk,
74 * which contains CmMemListCp structure at the top,
75 * parcels the requested event structure out of this
76 * chunk and return to the user.
88 Size evntSize, /* Size of the Event structure */
89 Size maxBlkSize, /* Chunk Memory size */
90 Mem *sMem, /* Static memory region and pool */
91 Ptr *ptr /* Location to place allocated event ptr */
95 Data *allocPtr; /* Allocated Memory Pointer */
96 CmMemList *node; /* Memory Link List Node */
97 CmMemListCp *memCp; /* memory Link list control point */
98 CmMemCb *cb; /* Allocated Memory Control Block */
101 /* Validation check */
103 if( evntSize > maxBlkSize)
105 DU_LOG("\nERROR --> Not Allocating memory for Event\n");
107 DU_LOG("\nERROR --> eventSize [%d] greater than maxBlkSize [%d]\n",
108 evntSize, maxBlkSize);
110 DU_LOG("\nERROR --> eventSize [%ld] greater than maxBlkSize [%ld]\n",
111 evntSize, maxBlkSize);
117 /* Allocate memory for the first Memory Chunk */
118 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
119 #ifdef SS_LOCKLESS_MEMORY
120 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, (Data **)&allocPtr,
121 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
123 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool,
125 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
126 #endif /* SS_LOCKLESS_MEMORY */
130 /* Reset the contents */
132 (maxBlkSize + sizeof(CmMemList)) );
134 /* The above allocated memory chunk is structured as follows
136 +-------------------+
138 +-------------------+ <---- Event Structure begins here
140 +-------------------+ |
141 | Event data part | | evntSize
142 +-------------------+ |
145 +-------------------+
149 /* Overlay CmMemList structure on top of this allocated chunk */
150 node = (CmMemList *)allocPtr;
151 /* cm_mblk_c_001.101: update size value */
152 node->size = maxBlkSize;
154 /* Get to CmMemListCp start */
155 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
157 /* Initialise memListCp */
158 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
160 /* Add link list node to link list */
161 cmAddMemNode(memCp, node);
163 /* Get pointer to memCb inside MemListCp */
164 cb = (CmMemCb *)&(memCp->memCb);
166 /* Align evntSize, if necessary */
167 CM_ALIGN_SIZE(evntSize);
169 cb->memAllocated = (evntSize + sizeof(CmMemList) );
170 cb->initPtr = (PTR)allocPtr;
171 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
172 cb->runPtr = ((PTR)(*ptr) + evntSize);
176 } /* End of cmAllocEvnt */
183 * Desc: This function intialises Memory Link List
196 CmMemListCp *memCp, /* Memory control pointer */
197 Size maxBlkSize, /* Chunk Memory size */
198 Mem *sMem /* Static memory region and pool */
202 /* Intialise Memory Control Point */
203 CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
207 } /* End of cmInitMemCp */
214 * Desc: This function parcels memory from memory chunks
215 * It allocated big chunk as and when required
227 Ptr memPtr, /* Pointer to memCp */
228 Size size, /* Memory size requested */
229 Ptr *allocPtr /* location to place pointer */
233 CmMemCb *cb; /* Pointer to Memory Control Block */
234 CmMemList *node; /* Memory List node */
235 CmMemListCp *memCp; /* Memory Control Point */
236 /* cm_mblk_c_001.101: added local variable */
237 Size blkSize; /* required block size */
240 memCp = (CmMemListCp *)memPtr;
243 /* Make requested size aligned, if necessary */
246 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
247 * max size, then allocate a new block with the requested size. This will
248 * enable us to handle large allocation requests in H.323 stack for certain
249 * information elements. This will not impact any normal allocation request
250 * as we fall back to the configured size */
251 if( size > cb->maxSize)
254 blkSize = cb->maxSize;
258 /* if a chunk is already there */
259 if( (cb->memAllocated + size) <=
260 (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
262 /* Requested memory is available in present chunk */
263 *allocPtr = (Ptr) cb->runPtr;
264 cb->memAllocated += size;
270 /* For all other cases, We need to allocate a new memory chunk */
271 /* Allocate buffer */
272 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
273 #ifdef SS_LOCKLESS_MEMORY
274 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
275 (Data **)&(cb->initPtr),
276 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
278 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
279 (Data **)&(cb->initPtr),
280 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
281 #endif /* SS_LOCKLESS_MEMORY */
284 /* Reset the contents */
285 /* Initialise above allocated structure */
286 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
287 memset(&(cb->initPtr), 0,
288 (blkSize + sizeof(CmMemList) ));
290 /* The above allocated memory chunk is structured as follows
292 +-------------------+
294 +-------------------+
298 +-------------------+ */
300 /* Overlay CmMemList structure on top of this allocated chunk */
301 node = (CmMemList *)cb->initPtr;
302 /* cm_mblk_c_001.101: update size */
303 node->size = blkSize;
305 /* Add link list node to link list */
306 cmAddMemNode(memCp, node);
308 cb->memAllocated = (size + sizeof(CmMemList) );
309 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
310 cb->runPtr = ((PTR)(*allocPtr) + size);
314 } /* End of cmGetMem */
317 #ifdef TFU_ALLOC_EVENT_NO_INIT
321 * Fun: cmAllocEvntNoInit
323 * Desc: This function allocates the first memory chunk,
324 * which contains CmMemListCp structure at the top,
325 * parcels the requested event structure out of this
326 * chunk and return to the user.
336 S16 cmAllocEvntNoInit
338 Size evntSize, /* Size of the Event structure */
339 Size maxBlkSize, /* Chunk Memory size */
340 Mem *sMem, /* Static memory region and pool */
341 Ptr *ptr /* Location to place allocated event ptr */
345 Data *allocPtr; /* Allocated Memory Pointer */
346 CmMemList *node; /* Memory Link List Node */
347 CmMemListCp *memCp; /* memory Link list control point */
348 CmMemCb *cb; /* Allocated Memory Control Block */
351 /* Validation check */
352 if( evntSize > maxBlkSize)
355 /* Allocate memory for the first Memory Chunk */
356 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
357 #ifdef SS_LOCKLESS_MEMORY
358 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, (Data **)&allocPtr,
359 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
361 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool,
363 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
364 #endif /* SS_LOCKLESS_MEMORY */
368 /* Reset the contents */
370 (sizeof(CmMemList)) );
372 /* The above allocated memory chunk is structured as follows
374 +-------------------+
376 +-------------------+ <---- Event Structure begins here
378 +-------------------+ |
379 | Event data part | | evntSize
380 +-------------------+ |
383 +-------------------+
387 /* Overlay CmMemList structure on top of this allocated chunk */
388 node = (CmMemList *)allocPtr;
389 /* cm_mblk_c_001.101: update size value */
390 node->size = maxBlkSize;
392 /* Get to CmMemListCp start */
393 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
395 /* Initialise memListCp */
396 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
398 /* Add link list node to link list */
399 cmAddMemNode(memCp, node);
401 /* Get pointer to memCb inside MemListCp */
402 cb = (CmMemCb *)&(memCp->memCb);
404 /* Align evntSize, if necessary */
405 CM_ALIGN_SIZE(evntSize);
407 cb->memAllocated = (evntSize + sizeof(CmMemList) );
408 cb->initPtr = (PTR)allocPtr;
409 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
410 cb->runPtr = ((PTR)(*ptr) + evntSize);
414 } /* End of cmAllocEvntNoInit */
418 * Fun: cmGetMemNoInit
420 * Desc: This function parcels memory from memory chunks
421 * It allocated big chunk as and when required
433 Ptr memPtr, /* Pointer to memCp */
434 Size size, /* Memory size requested */
435 Ptr *allocPtr /* location to place pointer */
439 CmMemCb *cb; /* Pointer to Memory Control Block */
440 CmMemList *node; /* Memory List node */
441 CmMemListCp *memCp; /* Memory Control Point */
442 /* cm_mblk_c_001.101: added local variable */
443 Size blkSize; /* required block size */
446 memCp = (CmMemListCp *)memPtr;
449 /* Make requested size aligned, if necessary */
452 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
453 * max size, then allocate a new block with the requested size. This will
454 * enable us to handle large allocation requests in H.323 stack for certain
455 * information elements. This will not impact any normal allocation request
456 * as we fall back to the configured size */
457 if( size > cb->maxSize)
460 blkSize = cb->maxSize;
464 /* if a chunk is already there */
465 if( (cb->memAllocated + size) <=
466 (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
468 /* Requested memory is available in present chunk */
469 *allocPtr = (Ptr) cb->runPtr;
470 //memset(*allocPtr, (uint8_t )0,
472 cb->memAllocated += size;
478 /* For all other cases, We need to allocate a new memory chunk */
479 /* Allocate buffer */
480 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
481 #ifdef SS_LOCKLESS_MEMORY
482 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
483 (Data **)&(cb->initPtr),
484 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
486 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
487 (Data **)&(cb->initPtr),
488 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
489 #endif /* SS_LOCKLESS_MEMORY */
492 /* Reset the contents */
493 /* Initialise above allocated structure */
494 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
495 memset(&(cb->initPtr), 0,
496 (sizeof(CmMemList)));
497 /* The above allocated memory chunk is structured as follows
499 +-------------------+
501 +-------------------+
505 +-------------------+ */
507 /* Overlay CmMemList structure on top of this allocated chunk */
508 node = (CmMemList *)cb->initPtr;
509 /* cm_mblk_c_001.101: update size */
510 node->size = blkSize;
512 /* Add link list node to link list */
513 cmAddMemNode(memCp, node);
515 cb->memAllocated = (size + sizeof(CmMemList) );
516 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
517 cb->runPtr = ((PTR)(*allocPtr) + size);
521 } /* End of cmGetMemNoInit */
532 * Desc: This function frees memory chunks after
533 * traversing link list
545 Ptr memPtr /* Link List CP */
548 Mem sMem; /* Static Memory region and pool */
549 S32 count; /* Count of linked blocks */
550 /* cm_mblk_c_001.101: removed local variable maxSize */
551 CmMemList *node; /* Pointer to link list node */
552 CmMemList *prevNode; /* Pointer to previous node */
553 CmMemListCp *lcp; /* Memory Link List */
556 lcp = (CmMemListCp *)memPtr;
558 sMem.region = lcp->memCb.sMem.region;
559 sMem.pool = lcp->memCb.sMem.pool;
561 /* cm_mblk_c_001.101: removed getting maxSize value */
563 /* Free Memory by traversing Back to Front */
566 /* Initialise memCp running variables */
567 /* User may want to reuse same memCp for further */
568 /* allocations, if memCp was not a part of */
569 /* event structure */
570 CM_INIT_MEMCPVAR(lcp);
574 prevNode = node->prev;
576 /* Release complete memory for present chunk */
577 /* cm_mblk_c_001.101: use node->size instead of maxSize */
580 #ifdef SS_LOCKLESS_MEMORY
581 SPutStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region, sMem.pool,
582 (Data *)node, (node->size + sizeof(CmMemList)), 0);
584 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region,sMem.pool,
585 (Data *)node, (node->size + sizeof(CmMemList)));
586 #endif /* SS_LOCKLESS_MEMORY */
594 } /* End of cmFreeMem */
601 * Desc: adds node to Memory linked list after last.
610 static Void cmAddMemNode
612 CmMemListCp *lCp, /* list control point */
613 CmMemList *node /* node to be added */
619 node->prev = lCp->last;
629 node->prev->next = node;
632 } /* end of cmAddMemNode */
638 * Fun: cmGetMemStatus
640 * Desc: This function returns the static memory status with
641 * parameters such as memory region and pool etc
653 Ptr memPtr, /* Memory control pointer */
654 CmMemStatus *status /* memory region,pool and status */
658 CmMemListCp *memCp; /* Memory Link List */
661 memCp = (CmMemListCp *)memPtr;
663 /* Copy relevant parameters */
664 status->sMem.region = memCp->memCb.sMem.region;
665 status->sMem.pool = memCp->memCb.sMem.pool;
666 status->memBlkCnt = memCp->count;
667 status->maxBlkSize = memCp->memCb.maxSize;
668 status->memAllocated = memCp->memCb.memAllocated;
672 } /* End of cmGetMemStatus */
674 /**********************************************************************
676 **********************************************************************/