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 EXTERN 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 PRIVATE 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.
89 Size evntSize, /* Size of the Event structure */
90 Size maxBlkSize, /* Chunk Memory size */
91 Mem *sMem, /* Static memory region and pool */
92 Ptr *ptr /* Location to place allocated event ptr */
95 S16 cmAllocEvnt (evntSize,maxBlkSize,sMem,ptr)
96 Size evntSize; /* Size of the Event structure */
97 Size maxBlkSize; /* Memory size requested */
98 Mem *sMem; /* Static Memory region and pool */
99 Ptr *ptr; /* Location to place allocated event ptr */
103 Data *allocPtr; /* Allocated Memory Pointer */
104 CmMemList *node; /* Memory Link List Node */
105 CmMemListCp *memCp; /* memory Link list control point */
106 CmMemCb *cb; /* Allocated Memory Control Block */
109 /* Validation check */
111 if( evntSize > maxBlkSize)
113 printf("\nNot Allocating memory for Event\n");
115 printf("eventSize [%d] greater than maxBlkSize [%d]\n",
116 evntSize, maxBlkSize);
118 printf("eventSize [%ld] greater than maxBlkSize [%ld]\n",
119 evntSize, maxBlkSize);
125 /* Allocate memory for the first Memory Chunk */
126 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
127 #ifdef SS_LOCKLESS_MEMORY
128 if(SGetStaticBuffer(sMem->region, sMem->pool, (Data **)&allocPtr,
129 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
131 if (SGetSBuf(sMem->region, sMem->pool,
133 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
134 #endif /* SS_LOCKLESS_MEMORY */
138 /* Reset the contents */
140 (maxBlkSize + sizeof(CmMemList)) );
142 /* The above allocated memory chunk is structured as follows
144 +-------------------+
146 +-------------------+ <---- Event Structure begins here
148 +-------------------+ |
149 | Event data part | | evntSize
150 +-------------------+ |
153 +-------------------+
157 /* Overlay CmMemList structure on top of this allocated chunk */
158 node = (CmMemList *)allocPtr;
159 /* cm_mblk_c_001.101: update size value */
160 node->size = maxBlkSize;
162 /* Get to CmMemListCp start */
163 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
165 /* Initialise memListCp */
166 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
168 /* Add link list node to link list */
169 cmAddMemNode(memCp, node);
171 /* Get pointer to memCb inside MemListCp */
172 cb = (CmMemCb *)&(memCp->memCb);
174 /* Align evntSize, if necessary */
175 CM_ALIGN_SIZE(evntSize);
177 cb->memAllocated = (evntSize + sizeof(CmMemList) );
178 cb->initPtr = (PTR)allocPtr;
179 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
180 cb->runPtr = ((PTR)(*ptr) + evntSize);
184 } /* End of cmAllocEvnt */
191 * Desc: This function intialises Memory Link List
205 CmMemListCp *memCp, /* Memory control pointer */
206 Size maxBlkSize, /* Chunk Memory size */
207 Mem *sMem /* Static memory region and pool */
210 Void cmInitMemCp (memCp,maxBlkSize,sMem)
211 CmMemListCp *memCp; /* Memory control pointer */
212 Size maxBlkSize; /* Memory size requested */
213 Mem *sMem; /* Static Memory region and pool */
218 /* Intialise Memory Control Point */
219 CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
223 } /* End of cmInitMemCp */
230 * Desc: This function parcels memory from memory chunks
231 * It allocated big chunk as and when required
244 Ptr memPtr, /* Pointer to memCp */
245 Size size, /* Memory size requested */
246 Ptr *allocPtr /* location to place pointer */
249 S16 cmGetMem (memPtr,size,allocPtr)
250 Ptr memPtr; /* Pointer to memCp */
251 Size size; /* Memory size requested */
252 Ptr *allocPtr; /* location to place pointer */
256 CmMemCb *cb; /* Pointer to Memory Control Block */
257 CmMemList *node; /* Memory List node */
258 CmMemListCp *memCp; /* Memory Control Point */
259 /* cm_mblk_c_001.101: added local variable */
260 Size blkSize; /* required block size */
263 memCp = (CmMemListCp *)memPtr;
266 /* Make requested size aligned, if necessary */
269 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
270 * max size, then allocate a new block with the requested size. This will
271 * enable us to handle large allocation requests in H.323 stack for certain
272 * information elements. This will not impact any normal allocation request
273 * as we fall back to the configured size */
274 if( size > cb->maxSize)
277 blkSize = cb->maxSize;
281 /* if a chunk is already there */
282 if( (cb->memAllocated + size) <=
283 (U32)(cb->maxSize + sizeof(CmMemList)) )
285 /* Requested memory is available in present chunk */
286 *allocPtr = (Ptr) cb->runPtr;
287 cb->memAllocated += size;
293 /* For all other cases, We need to allocate a new memory chunk */
294 /* Allocate buffer */
295 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
296 #ifdef SS_LOCKLESS_MEMORY
297 if(SGetStaticBuffer(cb->sMem.region, cb->sMem.pool,
298 (Data **)&(cb->initPtr),
299 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
301 if (SGetSBuf(cb->sMem.region, cb->sMem.pool,
302 (Data **)&(cb->initPtr),
303 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
304 #endif /* SS_LOCKLESS_MEMORY */
307 /* Reset the contents */
308 /* Initialise above allocated structure */
309 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
310 memset(&(cb->initPtr), 0,
311 (blkSize + sizeof(CmMemList) ));
313 /* The above allocated memory chunk is structured as follows
315 +-------------------+
317 +-------------------+
321 +-------------------+ */
323 /* Overlay CmMemList structure on top of this allocated chunk */
324 node = (CmMemList *)cb->initPtr;
325 /* cm_mblk_c_001.101: update size */
326 node->size = blkSize;
328 /* Add link list node to link list */
329 cmAddMemNode(memCp, node);
331 cb->memAllocated = (size + sizeof(CmMemList) );
332 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
333 cb->runPtr = ((PTR)(*allocPtr) + size);
337 } /* End of cmGetMem */
340 #ifdef TFU_ALLOC_EVENT_NO_INIT
344 * Fun: cmAllocEvntNoInit
346 * Desc: This function allocates the first memory chunk,
347 * which contains CmMemListCp structure at the top,
348 * parcels the requested event structure out of this
349 * chunk and return to the user.
360 S16 cmAllocEvntNoInit
362 Size evntSize, /* Size of the Event structure */
363 Size maxBlkSize, /* Chunk Memory size */
364 Mem *sMem, /* Static memory region and pool */
365 Ptr *ptr /* Location to place allocated event ptr */
368 S16 cmAllocEvntNoInit (evntSize,maxBlkSize,sMem,ptr)
369 Size evntSize; /* Size of the Event structure */
370 Size maxBlkSize; /* Memory size requested */
371 Mem *sMem; /* Static Memory region and pool */
372 Ptr *ptr; /* Location to place allocated event ptr */
376 Data *allocPtr; /* Allocated Memory Pointer */
377 CmMemList *node; /* Memory Link List Node */
378 CmMemListCp *memCp; /* memory Link list control point */
379 CmMemCb *cb; /* Allocated Memory Control Block */
382 /* Validation check */
383 if( evntSize > maxBlkSize)
386 /* Allocate memory for the first Memory Chunk */
387 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
388 #ifdef SS_LOCKLESS_MEMORY
389 if(SGetStaticBuffer(sMem->region, sMem->pool, (Data **)&allocPtr,
390 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
392 if (SGetSBuf(sMem->region, sMem->pool,
394 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
395 #endif /* SS_LOCKLESS_MEMORY */
399 /* Reset the contents */
401 (sizeof(CmMemList)) );
403 /* The above allocated memory chunk is structured as follows
405 +-------------------+
407 +-------------------+ <---- Event Structure begins here
409 +-------------------+ |
410 | Event data part | | evntSize
411 +-------------------+ |
414 +-------------------+
418 /* Overlay CmMemList structure on top of this allocated chunk */
419 node = (CmMemList *)allocPtr;
420 /* cm_mblk_c_001.101: update size value */
421 node->size = maxBlkSize;
423 /* Get to CmMemListCp start */
424 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
426 /* Initialise memListCp */
427 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
429 /* Add link list node to link list */
430 cmAddMemNode(memCp, node);
432 /* Get pointer to memCb inside MemListCp */
433 cb = (CmMemCb *)&(memCp->memCb);
435 /* Align evntSize, if necessary */
436 CM_ALIGN_SIZE(evntSize);
438 cb->memAllocated = (evntSize + sizeof(CmMemList) );
439 cb->initPtr = (PTR)allocPtr;
440 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
441 cb->runPtr = ((PTR)(*ptr) + evntSize);
445 } /* End of cmAllocEvntNoInit */
449 * Fun: cmGetMemNoInit
451 * Desc: This function parcels memory from memory chunks
452 * It allocated big chunk as and when required
465 Ptr memPtr, /* Pointer to memCp */
466 Size size, /* Memory size requested */
467 Ptr *allocPtr /* location to place pointer */
470 S16 cmGetMemNoInit (memPtr,size,allocPtr)
471 Ptr memPtr; /* Pointer to memCp */
472 Size size; /* Memory size requested */
473 Ptr *allocPtr; /* location to place pointer */
477 CmMemCb *cb; /* Pointer to Memory Control Block */
478 CmMemList *node; /* Memory List node */
479 CmMemListCp *memCp; /* Memory Control Point */
480 /* cm_mblk_c_001.101: added local variable */
481 Size blkSize; /* required block size */
484 memCp = (CmMemListCp *)memPtr;
487 /* Make requested size aligned, if necessary */
490 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
491 * max size, then allocate a new block with the requested size. This will
492 * enable us to handle large allocation requests in H.323 stack for certain
493 * information elements. This will not impact any normal allocation request
494 * as we fall back to the configured size */
495 if( size > cb->maxSize)
498 blkSize = cb->maxSize;
502 /* if a chunk is already there */
503 if( (cb->memAllocated + size) <=
504 (U32)(cb->maxSize + sizeof(CmMemList)) )
506 /* Requested memory is available in present chunk */
507 *allocPtr = (Ptr) cb->runPtr;
508 //memset(*allocPtr, (U8 )0,
510 cb->memAllocated += size;
516 /* For all other cases, We need to allocate a new memory chunk */
517 /* Allocate buffer */
518 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
519 #ifdef SS_LOCKLESS_MEMORY
520 if(SGetStaticBuffer(cb->sMem.region, cb->sMem.pool,
521 (Data **)&(cb->initPtr),
522 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
524 if (SGetSBuf(cb->sMem.region, cb->sMem.pool,
525 (Data **)&(cb->initPtr),
526 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
527 #endif /* SS_LOCKLESS_MEMORY */
530 /* Reset the contents */
531 /* Initialise above allocated structure */
532 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
533 memset(&(cb->initPtr), 0,
534 (sizeof(CmMemList)));
535 /* The above allocated memory chunk is structured as follows
537 +-------------------+
539 +-------------------+
543 +-------------------+ */
545 /* Overlay CmMemList structure on top of this allocated chunk */
546 node = (CmMemList *)cb->initPtr;
547 /* cm_mblk_c_001.101: update size */
548 node->size = blkSize;
550 /* Add link list node to link list */
551 cmAddMemNode(memCp, node);
553 cb->memAllocated = (size + sizeof(CmMemList) );
554 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
555 cb->runPtr = ((PTR)(*allocPtr) + size);
559 } /* End of cmGetMemNoInit */
570 * Desc: This function frees memory chunks after
571 * traversing link list
584 Ptr memPtr /* Link List CP */
587 Void cmFreeMem (memPtr)
588 Ptr memPtr; /* Link List CP */
591 Mem sMem; /* Static Memory region and pool */
592 S32 count; /* Count of linked blocks */
593 /* cm_mblk_c_001.101: removed local variable maxSize */
594 CmMemList *node; /* Pointer to link list node */
595 CmMemList *prevNode; /* Pointer to previous node */
596 CmMemListCp *lcp; /* Memory Link List */
599 lcp = (CmMemListCp *)memPtr;
601 sMem.region = lcp->memCb.sMem.region;
602 sMem.pool = lcp->memCb.sMem.pool;
604 /* cm_mblk_c_001.101: removed getting maxSize value */
606 /* Free Memory by traversing Back to Front */
609 /* Initialise memCp running variables */
610 /* User may want to reuse same memCp for further */
611 /* allocations, if memCp was not a part of */
612 /* event structure */
613 CM_INIT_MEMCPVAR(lcp);
617 prevNode = node->prev;
619 /* Release complete memory for present chunk */
620 /* cm_mblk_c_001.101: use node->size instead of maxSize */
623 #ifdef SS_LOCKLESS_MEMORY
624 SPutStaticBuffer(sMem.region, sMem.pool,
625 (Data *)node, (node->size + sizeof(CmMemList)), 0);
627 SPutSBuf(sMem.region,sMem.pool,
628 (Data *)node, (node->size + sizeof(CmMemList)));
629 #endif /* SS_LOCKLESS_MEMORY */
637 } /* End of cmFreeMem */
644 * Desc: adds node to Memory linked list after last.
654 PRIVATE Void cmAddMemNode
656 CmMemListCp *lCp, /* list control point */
657 CmMemList *node /* node to be added */
660 PRIVATE Void cmAddMemNode (lCp, node)
661 CmMemListCp *lCp; /* list control point */
662 CmMemList *node; /* node to be added */
668 node->prev = lCp->last;
678 node->prev->next = node;
681 } /* end of cmAddMemNode */
687 * Fun: cmGetMemStatus
689 * Desc: This function returns the static memory status with
690 * parameters such as memory region and pool etc
703 Ptr memPtr, /* Memory control pointer */
704 CmMemStatus *status /* memory region,pool and status */
707 Void cmGetMemStatus (memPtr,status)
708 Ptr memPtr; /* Memory control pointer */
709 CmMemStatus *status; /* memory region,pool and status */
713 CmMemListCp *memCp; /* Memory Link List */
716 memCp = (CmMemListCp *)memPtr;
718 /* Copy relevant parameters */
719 status->sMem.region = memCp->memCb.sMem.region;
720 status->sMem.pool = memCp->memCb.sMem.pool;
721 status->memBlkCnt = memCp->count;
722 status->maxBlkSize = memCp->memCb.maxSize;
723 status->memAllocated = memCp->memCb.memAllocated;
727 } /* End of cmGetMemStatus */
729 /**********************************************************************
731 **********************************************************************/