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.
87 PUBLIC S16 cmAllocEvnt
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 PUBLIC 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 */
110 /* Validation check */
112 if( evntSize > maxBlkSize)
114 printf("\nNot Allocating memory for Event\n");
116 printf("eventSize [%d] greater than maxBlkSize [%d]\n",
117 evntSize, maxBlkSize);
119 printf("eventSize [%ld] greater than maxBlkSize [%ld]\n",
120 evntSize, maxBlkSize);
126 /* Allocate memory for the first Memory Chunk */
127 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
128 #ifdef SS_LOCKLESS_MEMORY
129 if(SGetStaticBuffer(sMem->region, sMem->pool, (Data **)&allocPtr,
130 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
132 if (SGetSBuf(sMem->region, sMem->pool,
134 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
135 #endif /* SS_LOCKLESS_MEMORY */
139 /* Reset the contents */
140 cmMemset((U8 *)allocPtr, (U8 )0,
141 (PTR)(maxBlkSize + sizeof(CmMemList)) );
143 /* The above allocated memory chunk is structured as follows
145 +-------------------+
147 +-------------------+ <---- Event Structure begins here
149 +-------------------+ |
150 | Event data part | | evntSize
151 +-------------------+ |
154 +-------------------+
158 /* Overlay CmMemList structure on top of this allocated chunk */
159 node = (CmMemList *)allocPtr;
160 /* cm_mblk_c_001.101: update size value */
161 node->size = maxBlkSize;
163 /* Get to CmMemListCp start */
164 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
166 /* Initialise memListCp */
167 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
169 /* Add link list node to link list */
170 cmAddMemNode(memCp, node);
172 /* Get pointer to memCb inside MemListCp */
173 cb = (CmMemCb *)&(memCp->memCb);
175 /* Align evntSize, if necessary */
176 CM_ALIGN_SIZE(evntSize);
178 cb->memAllocated = (evntSize + sizeof(CmMemList) );
179 cb->initPtr = (PTR)allocPtr;
180 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
181 cb->runPtr = ((PTR)(*ptr) + evntSize);
185 } /* End of cmAllocEvnt */
192 * Desc: This function intialises Memory Link List
204 PUBLIC Void cmInitMemCp
206 CmMemListCp *memCp, /* Memory control pointer */
207 Size maxBlkSize, /* Chunk Memory size */
208 Mem *sMem /* Static memory region and pool */
211 PUBLIC Void cmInitMemCp (memCp,maxBlkSize,sMem)
212 CmMemListCp *memCp; /* Memory control pointer */
213 Size maxBlkSize; /* Memory size requested */
214 Mem *sMem; /* Static Memory region and pool */
220 /* Intialise Memory Control Point */
221 CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
225 } /* End of cmInitMemCp */
232 * Desc: This function parcels memory from memory chunks
233 * It allocated big chunk as and when required
246 Ptr memPtr, /* Pointer to memCp */
247 Size size, /* Memory size requested */
248 Ptr *allocPtr /* location to place pointer */
251 PUBLIC S16 cmGetMem (memPtr,size,allocPtr)
252 Ptr memPtr; /* Pointer to memCp */
253 Size size; /* Memory size requested */
254 Ptr *allocPtr; /* location to place pointer */
258 CmMemCb *cb; /* Pointer to Memory Control Block */
259 CmMemList *node; /* Memory List node */
260 CmMemListCp *memCp; /* Memory Control Point */
261 /* cm_mblk_c_001.101: added local variable */
262 Size blkSize; /* required block size */
266 memCp = (CmMemListCp *)memPtr;
269 /* Make requested size aligned, if necessary */
272 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
273 * max size, then allocate a new block with the requested size. This will
274 * enable us to handle large allocation requests in H.323 stack for certain
275 * information elements. This will not impact any normal allocation request
276 * as we fall back to the configured size */
277 if( size > cb->maxSize)
280 blkSize = cb->maxSize;
284 /* if a chunk is already there */
285 if( (cb->memAllocated + size) <=
286 (U32)(cb->maxSize + sizeof(CmMemList)) )
288 /* Requested memory is available in present chunk */
289 *allocPtr = (Ptr) cb->runPtr;
290 cb->memAllocated += size;
296 /* For all other cases, We need to allocate a new memory chunk */
297 /* Allocate buffer */
298 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
299 #ifdef SS_LOCKLESS_MEMORY
300 if(SGetStaticBuffer(cb->sMem.region, cb->sMem.pool,
301 (Data **)&(cb->initPtr),
302 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
304 if (SGetSBuf(cb->sMem.region, cb->sMem.pool,
305 (Data **)&(cb->initPtr),
306 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
307 #endif /* SS_LOCKLESS_MEMORY */
310 /* Reset the contents */
311 /* Initialise above allocated structure */
312 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
313 cmMemset((U8 *)cb->initPtr, (U8 )0,
314 (PTR)(blkSize + sizeof(CmMemList) ));
316 /* The above allocated memory chunk is structured as follows
318 +-------------------+
320 +-------------------+
324 +-------------------+ */
326 /* Overlay CmMemList structure on top of this allocated chunk */
327 node = (CmMemList *)cb->initPtr;
328 /* cm_mblk_c_001.101: update size */
329 node->size = blkSize;
331 /* Add link list node to link list */
332 cmAddMemNode(memCp, node);
334 cb->memAllocated = (size + sizeof(CmMemList) );
335 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
336 cb->runPtr = ((PTR)(*allocPtr) + size);
340 } /* End of cmGetMem */
343 #ifdef TFU_ALLOC_EVENT_NO_INIT
347 * Fun: cmAllocEvntNoInit
349 * Desc: This function allocates the first memory chunk,
350 * which contains CmMemListCp structure at the top,
351 * parcels the requested event structure out of this
352 * chunk and return to the user.
363 PUBLIC S16 cmAllocEvntNoInit
365 Size evntSize, /* Size of the Event structure */
366 Size maxBlkSize, /* Chunk Memory size */
367 Mem *sMem, /* Static memory region and pool */
368 Ptr *ptr /* Location to place allocated event ptr */
371 PUBLIC S16 cmAllocEvntNoInit (evntSize,maxBlkSize,sMem,ptr)
372 Size evntSize; /* Size of the Event structure */
373 Size maxBlkSize; /* Memory size requested */
374 Mem *sMem; /* Static Memory region and pool */
375 Ptr *ptr; /* Location to place allocated event ptr */
379 Data *allocPtr; /* Allocated Memory Pointer */
380 CmMemList *node; /* Memory Link List Node */
381 CmMemListCp *memCp; /* memory Link list control point */
382 CmMemCb *cb; /* Allocated Memory Control Block */
384 TRC2(cmAllocEvntNoInit)
386 /* Validation check */
387 if( evntSize > maxBlkSize)
390 /* Allocate memory for the first Memory Chunk */
391 /* Allocated memory should be maxBlkSize + sizeof(CmMemList) */
392 #ifdef SS_LOCKLESS_MEMORY
393 if(SGetStaticBuffer(sMem->region, sMem->pool, (Data **)&allocPtr,
394 (Size)(maxBlkSize + sizeof(CmMemList)), 0) != ROK)
396 if (SGetSBuf(sMem->region, sMem->pool,
398 (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
399 #endif /* SS_LOCKLESS_MEMORY */
403 /* Reset the contents */
404 cmMemset((U8 *)allocPtr, (U8 )0,
405 (PTR)(sizeof(CmMemList)) );
407 /* The above allocated memory chunk is structured as follows
409 +-------------------+
411 +-------------------+ <---- Event Structure begins here
413 +-------------------+ |
414 | Event data part | | evntSize
415 +-------------------+ |
418 +-------------------+
422 /* Overlay CmMemList structure on top of this allocated chunk */
423 node = (CmMemList *)allocPtr;
424 /* cm_mblk_c_001.101: update size value */
425 node->size = maxBlkSize;
427 /* Get to CmMemListCp start */
428 memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
430 /* Initialise memListCp */
431 CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
433 /* Add link list node to link list */
434 cmAddMemNode(memCp, node);
436 /* Get pointer to memCb inside MemListCp */
437 cb = (CmMemCb *)&(memCp->memCb);
439 /* Align evntSize, if necessary */
440 CM_ALIGN_SIZE(evntSize);
442 cb->memAllocated = (evntSize + sizeof(CmMemList) );
443 cb->initPtr = (PTR)allocPtr;
444 *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
445 cb->runPtr = ((PTR)(*ptr) + evntSize);
449 } /* End of cmAllocEvntNoInit */
453 * Fun: cmGetMemNoInit
455 * Desc: This function parcels memory from memory chunks
456 * It allocated big chunk as and when required
467 PUBLIC S16 cmGetMemNoInit
469 Ptr memPtr, /* Pointer to memCp */
470 Size size, /* Memory size requested */
471 Ptr *allocPtr /* location to place pointer */
474 PUBLIC S16 cmGetMemNoInit (memPtr,size,allocPtr)
475 Ptr memPtr; /* Pointer to memCp */
476 Size size; /* Memory size requested */
477 Ptr *allocPtr; /* location to place pointer */
481 CmMemCb *cb; /* Pointer to Memory Control Block */
482 CmMemList *node; /* Memory List node */
483 CmMemListCp *memCp; /* Memory Control Point */
484 /* cm_mblk_c_001.101: added local variable */
485 Size blkSize; /* required block size */
489 memCp = (CmMemListCp *)memPtr;
492 /* Make requested size aligned, if necessary */
495 /* cm_mblk_c_001.101 : If the requested size is greater than the configured
496 * max size, then allocate a new block with the requested size. This will
497 * enable us to handle large allocation requests in H.323 stack for certain
498 * information elements. This will not impact any normal allocation request
499 * as we fall back to the configured size */
500 if( size > cb->maxSize)
503 blkSize = cb->maxSize;
507 /* if a chunk is already there */
508 if( (cb->memAllocated + size) <=
509 (U32)(cb->maxSize + sizeof(CmMemList)) )
511 /* Requested memory is available in present chunk */
512 *allocPtr = (Ptr) cb->runPtr;
513 //cmMemset((U8 *)*allocPtr, (U8 )0,
515 cb->memAllocated += size;
521 /* For all other cases, We need to allocate a new memory chunk */
522 /* Allocate buffer */
523 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
524 #ifdef SS_LOCKLESS_MEMORY
525 if(SGetStaticBuffer(cb->sMem.region, cb->sMem.pool,
526 (Data **)&(cb->initPtr),
527 (Size)(blkSize + sizeof(CmMemList)), 0) != ROK)
529 if (SGetSBuf(cb->sMem.region, cb->sMem.pool,
530 (Data **)&(cb->initPtr),
531 (Size)(blkSize + sizeof(CmMemList)) ) != ROK)
532 #endif /* SS_LOCKLESS_MEMORY */
535 /* Reset the contents */
536 /* Initialise above allocated structure */
537 /* cm_mblk_c_001.101: use blkSize instead of cb->maxSize */
538 cmMemset((U8 *)cb->initPtr, (U8 )0,
539 (PTR)(sizeof(CmMemList)));
540 /* The above allocated memory chunk is structured as follows
542 +-------------------+
544 +-------------------+
548 +-------------------+ */
550 /* Overlay CmMemList structure on top of this allocated chunk */
551 node = (CmMemList *)cb->initPtr;
552 /* cm_mblk_c_001.101: update size */
553 node->size = blkSize;
555 /* Add link list node to link list */
556 cmAddMemNode(memCp, node);
558 cb->memAllocated = (size + sizeof(CmMemList) );
559 *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
560 cb->runPtr = ((PTR)(*allocPtr) + size);
564 } /* End of cmGetMemNoInit */
575 * Desc: This function frees memory chunks after
576 * traversing link list
587 PUBLIC Void cmFreeMem
589 Ptr memPtr /* Link List CP */
592 PUBLIC Void cmFreeMem (memPtr)
593 Ptr memPtr; /* Link List CP */
596 Mem sMem; /* Static Memory region and pool */
597 S32 count; /* Count of linked blocks */
598 /* cm_mblk_c_001.101: removed local variable maxSize */
599 CmMemList *node; /* Pointer to link list node */
600 CmMemList *prevNode; /* Pointer to previous node */
601 CmMemListCp *lcp; /* Memory Link List */
605 lcp = (CmMemListCp *)memPtr;
607 sMem.region = lcp->memCb.sMem.region;
608 sMem.pool = lcp->memCb.sMem.pool;
610 /* cm_mblk_c_001.101: removed getting maxSize value */
612 /* Free Memory by traversing Back to Front */
615 /* Initialise memCp running variables */
616 /* User may want to reuse same memCp for further */
617 /* allocations, if memCp was not a part of */
618 /* event structure */
619 CM_INIT_MEMCPVAR(lcp);
623 prevNode = node->prev;
625 /* Release complete memory for present chunk */
626 /* cm_mblk_c_001.101: use node->size instead of maxSize */
629 #ifdef SS_LOCKLESS_MEMORY
630 SPutStaticBuffer(sMem.region, sMem.pool,
631 (Data *)node, (node->size + sizeof(CmMemList)), 0);
633 SPutSBuf(sMem.region,sMem.pool,
634 (Data *)node, (node->size + sizeof(CmMemList)));
635 #endif /* SS_LOCKLESS_MEMORY */
643 } /* End of cmFreeMem */
650 * Desc: adds node to Memory linked list after last.
660 PRIVATE Void cmAddMemNode
662 CmMemListCp *lCp, /* list control point */
663 CmMemList *node /* node to be added */
666 PRIVATE Void cmAddMemNode (lCp, node)
667 CmMemListCp *lCp; /* list control point */
668 CmMemList *node; /* node to be added */
675 node->prev = lCp->last;
685 node->prev->next = node;
688 } /* end of cmAddMemNode */
694 * Fun: cmGetMemStatus
696 * Desc: This function returns the static memory status with
697 * parameters such as memory region and pool etc
708 PUBLIC Void cmGetMemStatus
710 Ptr memPtr, /* Memory control pointer */
711 CmMemStatus *status /* memory region,pool and status */
714 PUBLIC Void cmGetMemStatus (memPtr,status)
715 Ptr memPtr; /* Memory control pointer */
716 CmMemStatus *status; /* memory region,pool and status */
720 CmMemListCp *memCp; /* Memory Link List */
724 memCp = (CmMemListCp *)memPtr;
726 /* Copy relevant parameters */
727 status->sMem.region = memCp->memCb.sMem.region;
728 status->sMem.pool = memCp->memCb.sMem.pool;
729 status->memBlkCnt = memCp->count;
730 status->maxBlkSize = memCp->memCb.maxSize;
731 status->memAllocated = memCp->memCb.memAllocated;
735 } /* End of cmGetMemStatus */
737 /**********************************************************************
739 **********************************************************************/