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 "common_def.h" /* Header file */
35 #ifdef SS_LOCKLESS_MEMORY
36 pthread_t tmpRegTidMap[20];
37 #define CM_MEM_GET_REGION(_region) \
42 for(_regCnt = 0; _regCnt < 12; _regCnt++) \
44 if(tmpRegTidMap[_regCnt] == pthread_self()) \
55 static Void cmAddMemNode ARGS((CmMemListCp *lCp,CmMemList *node));
62 * Desc: This function allocates the first memory chunk,
63 * which contains CmMemListCp structure at the top,
64 * parcels the requested event structure out of this
65 * chunk and return to the user.
77 Size evntSize, /* Size of the Event structure */
78 Size maxBlkSize, /* Chunk Memory size */
79 Mem *sMem, /* Static memory region and pool */
80 Ptr *ptr /* Location to place allocated event ptr */
84 Data *allocPtr; /* Allocated Memory Pointer */
85 CmMemList *node; /* Memory Link List Node */
86 CmMemListCp *memCp; /* memory Link list control point */
87 CmMemCb *cb; /* Allocated Memory Control Block */
90 /* Validation check */
92 if( evntSize > maxBlkSize)
94 DU_LOG("\nERROR --> Not Allocating memory for Event\n");
96 DU_LOG("\nERROR --> eventSize [%d] greater than maxBlkSize [%d]\n",
97 evntSize, maxBlkSize);
99 DU_LOG("\nERROR --> eventSize [%ld] greater than maxBlkSize [%ld]\n",
100 evntSize, maxBlkSize);
106 /* Allocate memory for the first Memory Chunk */
107 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
108 #ifdef SS_LOCKLESS_MEMORY
109 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, (Data **)&allocPtr,
110 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
112 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool,
114 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
115 #endif /* SS_LOCKLESS_MEMORY */
119 /* Reset the contents */
121 (maxBlkSize + sizeof(CmMemList)) );
123 /* The above allocated memory chunk is structured as follows
125 +-------------------+
127 +-------------------+ <---- Event Structure begins here
129 +-------------------+ |
130 | Event data part | | evntSize
131 +-------------------+ |
134 +-------------------+
138 /* Overlay CmMemList structure on top of this allocated chunk */
139 node = (CmMemList *)allocPtr;
140 /* cm_mblk_c_001.101: update size value */
141 node->size = maxBlkSize;
143 /* Get to CmMemListCp start */
144 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
146 /* Initialise memListCp */
147 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
149 /* Add link list node to link list */
150 cmAddMemNode(memCp, node);
152 /* Get pointer to memCb inside MemListCp */
153 cb = (CmMemCb *)&(memCp->memCb);
155 /* Align evntSize, if necessary */
156 CM_ALIGN_SIZE(evntSize);
158 cb->memAllocated = (evntSize + sizeof(CmMemList) );
159 cb->initPtr = (PTR)allocPtr;
160 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
161 cb->runPtr = ((PTR)(*ptr) + evntSize);
165 } /* End of cmAllocEvnt */
172 * Desc: This function intialises Memory Link List
185 CmMemListCp *memCp, /* Memory control pointer */
186 Size maxBlkSize, /* Chunk Memory size */
187 Mem *sMem /* Static memory region and pool */
191 /* Intialise Memory Control Point */
192 CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
196 } /* End of cmInitMemCp */
203 * Desc: This function parcels memory from memory chunks
204 * It allocated big chunk as and when required
216 Ptr memPtr, /* Pointer to memCp */
217 Size size, /* Memory size requested */
218 Ptr *allocPtr /* location to place pointer */
222 CmMemCb *cb; /* Pointer to Memory Control Block */
223 CmMemList *node; /* Memory List node */
224 CmMemListCp *memCp; /* Memory Control Point */
225 /* cm_mblk_c_001.101: added local variable */
226 Size blkSize; /* required block size */
229 memCp = (CmMemListCp *)memPtr;
232 /* Make requested size aligned, if necessary */
235 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
236 * max size, then allocate a new block with the requested size. This will
237 * enable us to handle large allocation requests in H.323 stack for certain
238 * information elements. This will not impact any normal allocation request
239 * as we fall back to the configured size */
240 if( size > cb->maxSize)
243 blkSize = cb->maxSize;
247 /* if a chunk is already there */
248 if( (cb->memAllocated + size) <=
249 (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
251 /* Requested memory is available in present chunk */
252 *allocPtr = (Ptr) cb->runPtr;
253 cb->memAllocated += size;
259 /* For all other cases, We need to allocate a new memory chunk */
260 /* Allocate buffer */
261 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
262 #ifdef SS_LOCKLESS_MEMORY
263 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
264 (Data **)&(cb->initPtr),
265 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
267 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
268 (Data **)&(cb->initPtr),
269 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
270 #endif /* SS_LOCKLESS_MEMORY */
273 /* Reset the contents */
274 /* Initialise above allocated structure */
275 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
276 memset(&(cb->initPtr), 0,
277 (blkSize + sizeof(CmMemList) ));
279 /* The above allocated memory chunk is structured as follows
281 +-------------------+
283 +-------------------+
287 +-------------------+ */
289 /* Overlay CmMemList structure on top of this allocated chunk */
290 node = (CmMemList *)cb->initPtr;
291 /* cm_mblk_c_001.101: update size */
292 node->size = blkSize;
294 /* Add link list node to link list */
295 cmAddMemNode(memCp, node);
297 cb->memAllocated = (size + sizeof(CmMemList) );
298 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
299 cb->runPtr = ((PTR)(*allocPtr) + size);
303 } /* End of cmGetMem */
306 #ifdef TFU_ALLOC_EVENT_NO_INIT
310 * Fun: cmAllocEvntNoInit
312 * Desc: This function allocates the first memory chunk,
313 * which contains CmMemListCp structure at the top,
314 * parcels the requested event structure out of this
315 * chunk and return to the user.
325 S16 cmAllocEvntNoInit
327 Size evntSize, /* Size of the Event structure */
328 Size maxBlkSize, /* Chunk Memory size */
329 Mem *sMem, /* Static memory region and pool */
330 Ptr *ptr /* Location to place allocated event ptr */
334 Data *allocPtr; /* Allocated Memory Pointer */
335 CmMemList *node; /* Memory Link List Node */
336 CmMemListCp *memCp; /* memory Link list control point */
337 CmMemCb *cb; /* Allocated Memory Control Block */
340 /* Validation check */
341 if( evntSize > maxBlkSize)
344 /* Allocate memory for the first Memory Chunk */
345 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
346 #ifdef SS_LOCKLESS_MEMORY
347 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, (Data **)&allocPtr,
348 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
350 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool,
352 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
353 #endif /* SS_LOCKLESS_MEMORY */
357 /* Reset the contents */
359 (sizeof(CmMemList)) );
361 /* The above allocated memory chunk is structured as follows
363 +-------------------+
365 +-------------------+ <---- Event Structure begins here
367 +-------------------+ |
368 | Event data part | | evntSize
369 +-------------------+ |
372 +-------------------+
376 /* Overlay CmMemList structure on top of this allocated chunk */
377 node = (CmMemList *)allocPtr;
378 /* cm_mblk_c_001.101: update size value */
379 node->size = maxBlkSize;
381 /* Get to CmMemListCp start */
382 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
384 /* Initialise memListCp */
385 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
387 /* Add link list node to link list */
388 cmAddMemNode(memCp, node);
390 /* Get pointer to memCb inside MemListCp */
391 cb = (CmMemCb *)&(memCp->memCb);
393 /* Align evntSize, if necessary */
394 CM_ALIGN_SIZE(evntSize);
396 cb->memAllocated = (evntSize + sizeof(CmMemList) );
397 cb->initPtr = (PTR)allocPtr;
398 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
399 cb->runPtr = ((PTR)(*ptr) + evntSize);
403 } /* End of cmAllocEvntNoInit */
407 * Fun: cmGetMemNoInit
409 * Desc: This function parcels memory from memory chunks
410 * It allocated big chunk as and when required
422 Ptr memPtr, /* Pointer to memCp */
423 Size size, /* Memory size requested */
424 Ptr *allocPtr /* location to place pointer */
428 CmMemCb *cb; /* Pointer to Memory Control Block */
429 CmMemList *node; /* Memory List node */
430 CmMemListCp *memCp; /* Memory Control Point */
431 /* cm_mblk_c_001.101: added local variable */
432 Size blkSize; /* required block size */
435 memCp = (CmMemListCp *)memPtr;
438 /* Make requested size aligned, if necessary */
441 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
442 * max size, then allocate a new block with the requested size. This will
443 * enable us to handle large allocation requests in H.323 stack for certain
444 * information elements. This will not impact any normal allocation request
445 * as we fall back to the configured size */
446 if( size > cb->maxSize)
449 blkSize = cb->maxSize;
453 /* if a chunk is already there */
454 if( (cb->memAllocated + size) <=
455 (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
457 /* Requested memory is available in present chunk */
458 *allocPtr = (Ptr) cb->runPtr;
459 //memset(*allocPtr, (uint8_t )0,
461 cb->memAllocated += size;
467 /* For all other cases, We need to allocate a new memory chunk */
468 /* Allocate buffer */
469 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
470 #ifdef SS_LOCKLESS_MEMORY
471 if(SGetStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
472 (Data **)&(cb->initPtr),
473 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
475 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,cb->sMem.region, cb->sMem.pool,
476 (Data **)&(cb->initPtr),
477 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
478 #endif /* SS_LOCKLESS_MEMORY */
481 /* Reset the contents */
482 /* Initialise above allocated structure */
483 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
484 memset(&(cb->initPtr), 0,
485 (sizeof(CmMemList)));
486 /* The above allocated memory chunk is structured as follows
488 +-------------------+
490 +-------------------+
494 +-------------------+ */
496 /* Overlay CmMemList structure on top of this allocated chunk */
497 node = (CmMemList *)cb->initPtr;
498 /* cm_mblk_c_001.101: update size */
499 node->size = blkSize;
501 /* Add link list node to link list */
502 cmAddMemNode(memCp, node);
504 cb->memAllocated = (size + sizeof(CmMemList) );
505 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
506 cb->runPtr = ((PTR)(*allocPtr) + size);
510 } /* End of cmGetMemNoInit */
521 * Desc: This function frees memory chunks after
522 * traversing link list
534 Ptr memPtr /* Link List CP */
537 Mem sMem; /* Static Memory region and pool */
538 S32 count; /* Count of linked blocks */
539 /* cm_mblk_c_001.101: removed local variable maxSize */
540 CmMemList *node; /* Pointer to link list node */
541 CmMemList *prevNode; /* Pointer to previous node */
542 CmMemListCp *lcp; /* Memory Link List */
545 lcp = (CmMemListCp *)memPtr;
547 sMem.region = lcp->memCb.sMem.region;
548 sMem.pool = lcp->memCb.sMem.pool;
550 /* cm_mblk_c_001.101: removed getting maxSize value */
552 /* Free Memory by traversing Back to Front */
555 /* Initialise memCp running variables */
556 /* User may want to reuse same memCp for further */
557 /* allocations, if memCp was not a part of */
558 /* event structure */
559 CM_INIT_MEMCPVAR(lcp);
563 prevNode = node->prev;
565 /* Release complete memory for present chunk */
566 /* cm_mblk_c_001.101: use node->size instead of maxSize */
569 #ifdef SS_LOCKLESS_MEMORY
570 SPutStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region, sMem.pool,
571 (Data *)node, (node->size + sizeof(CmMemList)), 0);
573 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region,sMem.pool,
574 (Data *)node, (node->size + sizeof(CmMemList)));
575 #endif /* SS_LOCKLESS_MEMORY */
583 } /* End of cmFreeMem */
590 * Desc: adds node to Memory linked list after last.
599 static Void cmAddMemNode
601 CmMemListCp *lCp, /* list control point */
602 CmMemList *node /* node to be added */
608 node->prev = lCp->last;
618 node->prev->next = node;
621 } /* end of cmAddMemNode */
627 * Fun: cmGetMemStatus
629 * Desc: This function returns the static memory status with
630 * parameters such as memory region and pool etc
642 Ptr memPtr, /* Memory control pointer */
643 CmMemStatus *status /* memory region,pool and status */
647 CmMemListCp *memCp; /* Memory Link List */
650 memCp = (CmMemListCp *)memPtr;
652 /* Copy relevant parameters */
653 status->sMem.region = memCp->memCb.sMem.region;
654 status->sMem.pool = memCp->memCb.sMem.pool;
655 status->memBlkCnt = memCp->count;
656 status->maxBlkSize = memCp->memCb.maxSize;
657 status->memAllocated = memCp->memCb.memAllocated;
661 } /* End of cmGetMemStatus */
663 /**********************************************************************
665 **********************************************************************/