e2fee9b2355fa29e6e488ed8ef912f480afd210b
[o-du/l2.git] / src / cm / cm_mblk.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 \f
19 /********************************************************************20**
20   
21      Name:     common memory allocation library 
22   
23      Type:     C include file
24   
25      Desc:     memory library routines 
26  
27      File:     cm_mblk.c
28   
29 *********************************************************************21*/
30
31
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 */
39
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 */
45
46 #ifdef SS_LOCKLESS_MEMORY
47 pthread_t tmpRegTidMap[20];
48 #define CM_MEM_GET_REGION(_region)                        \
49 {                                                         \
50    uint8_t  _regCnt;                                           \
51    _region = 0xFF;                                        \
52                                                           \
53    for(_regCnt = 0; _regCnt < 12; _regCnt++)              \
54    {                                                      \
55       if(tmpRegTidMap[_regCnt] == pthread_self())         \
56       {                                                   \
57          _region = _regCnt;                               \
58          break;                                           \
59       }                                                   \
60    }                                                      \
61 }
62 #endif
63
64
65
66 static Void cmAddMemNode ARGS((CmMemListCp *lCp,CmMemList *node)); 
67
68 \f
69 /*
70 *
71 *       Fun:   cmAllocEvnt
72 *
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.
77 *
78 *       Ret:   ROK 
79 *
80 *       Notes: None 
81 *
82 *       File:  cm_mblk.c
83 *
84 */
85   
86 S16 cmAllocEvnt
87 (
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 */
92 )
93 {
94
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 */
99
100
101   /* Validation check */
102 #ifndef LTE_ENB_PAL
103   if( evntSize > maxBlkSize)
104   {
105      DU_LOG("\nERROR  -->  Not Allocating memory for Event\n");
106 #ifdef ALIGN_64BIT
107      DU_LOG("\nERROR  -->  eventSize [%d] greater than maxBlkSize [%d]\n",
108            evntSize, maxBlkSize);
109 #else
110      DU_LOG("\nERROR  -->  eventSize [%ld] greater than maxBlkSize [%ld]\n",
111            evntSize, maxBlkSize);
112 #endif
113      return RFAILED;
114   }
115 #endif
116  
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)
122 #else
123   if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, 
124                (Data **)&allocPtr, 
125                (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
126 #endif /* SS_LOCKLESS_MEMORY */
127
128      return RFAILED;
129
130   /* Reset the contents */
131   memset(allocPtr, 0, 
132            (maxBlkSize + sizeof(CmMemList)) );
133
134   /* The above allocated memory chunk is structured as follows 
135
136   +-------------------+
137   |  CmMemList        |
138   +-------------------+   <---- Event Structure begins here
139   |  CmMemListCp      |      ^
140   +-------------------+      |
141   |  Event data part  |      |  evntSize
142   +-------------------+      |
143        ....                  |
144        ....                  \/ 
145   +-------------------+    
146   
147   */
148
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;
153
154   /* Get to CmMemListCp start */
155   memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
156   
157   /* Initialise memListCp */
158   CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
159
160   /* Add link list node to link list */
161   cmAddMemNode(memCp, node); 
162
163   /* Get pointer to memCb inside MemListCp */
164   cb = (CmMemCb *)&(memCp->memCb);
165
166   /* Align evntSize, if necessary */
167   CM_ALIGN_SIZE(evntSize);
168
169   cb->memAllocated = (evntSize + sizeof(CmMemList) );
170   cb->initPtr = (PTR)allocPtr;
171   *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
172   cb->runPtr = ((PTR)(*ptr) + evntSize);
173
174   return ROK;
175
176 } /* End of cmAllocEvnt */
177
178 \f
179 /*
180 *
181 *       Fun:   cmInitMemCp
182 *
183 *       Desc:  This function intialises Memory Link List
184 *              Control point  
185 *
186 *       Ret:   ROK 
187 *
188 *       Notes: None 
189 *
190 *       File:  cm_mblk.c
191 *
192 */
193   
194 Void cmInitMemCp
195 (
196 CmMemListCp     *memCp,     /* Memory control pointer */
197 Size            maxBlkSize, /* Chunk Memory size */
198 Mem             *sMem       /* Static memory region and pool */
199 )
200 {
201
202   /* Intialise Memory Control Point */
203   CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
204
205   return;
206
207 } /* End of cmInitMemCp */ 
208
209 \f
210 /*
211 *
212 *       Fun:   cmGetMem
213 *
214 *       Desc:  This function parcels memory from memory chunks 
215 *              It allocated big chunk as and when required
216 *
217 *       Ret:   ROK 
218 *
219 *       Notes: None 
220 *
221 *       File:  cm_mblk.c
222 *
223 */
224   
225 S16 cmGetMem
226 (
227 Ptr           memPtr,    /* Pointer to memCp */
228 Size          size,      /* Memory size requested */
229 Ptr           *allocPtr  /* location to place pointer */
230 )
231 {
232  
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 */
238
239
240   memCp = (CmMemListCp *)memPtr;
241   cb = &memCp->memCb; 
242
243   /* Make requested size aligned, if necessary */
244   CM_ALIGN_SIZE(size);
245
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)
252      blkSize = size;
253    else
254      blkSize = cb->maxSize;
255  
256   if( cb->initPtr)
257   { 
258     /* if a chunk is already there */
259     if( (cb->memAllocated + size) <= 
260            (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
261     {
262       /* Requested memory is available in present chunk */
263       *allocPtr = (Ptr) cb->runPtr;
264       cb->memAllocated += size;
265       cb->runPtr += size;
266       return ROK;
267     }
268   }
269   
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)
277 #else
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 */
282      return RFAILED;
283
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) ));
289
290   /* The above allocated memory chunk is structured as follows 
291
292   +-------------------+
293   |  CmMemList        |
294   +-------------------+
295       Data Portion
296        ....
297        ....
298   +-------------------+    */
299
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;
304
305   /* Add link list node to link list */
306   cmAddMemNode(memCp, node); 
307
308   cb->memAllocated = (size + sizeof(CmMemList) );
309   *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
310   cb->runPtr = ((PTR)(*allocPtr) + size);
311
312   return ROK;   
313
314 } /* End of cmGetMem */
315
316
317 #ifdef TFU_ALLOC_EVENT_NO_INIT
318 \f
319 /*
320 *
321 *       Fun:   cmAllocEvntNoInit
322 *
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.
327 *
328 *       Ret:   ROK 
329 *
330 *       Notes: None 
331 *
332 *       File:  cm_mblk.c
333 *
334 */
335   
336 S16 cmAllocEvntNoInit
337 (
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 */
342 )
343 {
344
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 */
349
350
351   /* Validation check */
352   if( evntSize > maxBlkSize)
353      return RFAILED;
354  
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)
360 #else
361   if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, 
362                (Data **)&allocPtr, 
363                (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
364 #endif /* SS_LOCKLESS_MEMORY */
365
366      return RFAILED;
367
368   /* Reset the contents */
369   memset(allocPtr, 0, 
370            (sizeof(CmMemList)) );
371
372   /* The above allocated memory chunk is structured as follows 
373
374   +-------------------+
375   |  CmMemList        |
376   +-------------------+   <---- Event Structure begins here
377   |  CmMemListCp      |      ^
378   +-------------------+      |
379   |  Event data part  |      |  evntSize
380   +-------------------+      |
381        ....                  |
382        ....                  \/ 
383   +-------------------+    
384   
385   */
386
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;
391
392   /* Get to CmMemListCp start */
393   memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
394   
395   /* Initialise memListCp */
396   CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
397
398   /* Add link list node to link list */
399   cmAddMemNode(memCp, node); 
400
401   /* Get pointer to memCb inside MemListCp */
402   cb = (CmMemCb *)&(memCp->memCb);
403
404   /* Align evntSize, if necessary */
405   CM_ALIGN_SIZE(evntSize);
406
407   cb->memAllocated = (evntSize + sizeof(CmMemList) );
408   cb->initPtr = (PTR)allocPtr;
409   *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
410   cb->runPtr = ((PTR)(*ptr) + evntSize);
411
412   return ROK;
413
414 } /* End of cmAllocEvntNoInit */
415
416 /*
417 *
418 *       Fun:   cmGetMemNoInit
419 *
420 *       Desc:  This function parcels memory from memory chunks 
421 *              It allocated big chunk as and when required
422 *
423 *       Ret:   ROK 
424 *
425 *       Notes: None 
426 *
427 *       File:  cm_mblk.c
428 *
429 */
430   
431 S16 cmGetMemNoInit
432 (
433 Ptr           memPtr,    /* Pointer to memCp */
434 Size          size,      /* Memory size requested */
435 Ptr           *allocPtr  /* location to place pointer */
436 )
437 {
438  
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 */
444
445
446   memCp = (CmMemListCp *)memPtr;
447   cb = &memCp->memCb; 
448
449   /* Make requested size aligned, if necessary */
450   CM_ALIGN_SIZE(size);
451
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)
458      blkSize = size;
459    else
460      blkSize = cb->maxSize;
461  
462   if( cb->initPtr)
463   { 
464     /* if a chunk is already there */
465     if( (cb->memAllocated + size) <= 
466            (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
467     {
468       /* Requested memory is available in present chunk */
469       *allocPtr = (Ptr) cb->runPtr;
470       //memset(*allocPtr, (uint8_t )0, 
471         //   (PTR)(size) );
472       cb->memAllocated += size;
473       cb->runPtr += size;
474       return ROK;
475     }
476   }
477   
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)
485 #else
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 */
490      return RFAILED;
491
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 
498
499   +-------------------+
500   |  CmMemList        |
501   +-------------------+
502       Data Portion
503        ....
504        ....
505   +-------------------+    */
506
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;
511
512   /* Add link list node to link list */
513   cmAddMemNode(memCp, node); 
514
515   cb->memAllocated = (size + sizeof(CmMemList) );
516   *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
517   cb->runPtr = ((PTR)(*allocPtr) + size);
518
519   return ROK;   
520
521 } /* End of cmGetMemNoInit */
522
523
524
525
526 #endif
527 \f
528 /*
529 *
530 *       Fun:   cmFreeMem
531 *
532 *       Desc:  This function frees memory chunks after
533 *              traversing link list
534 *
535 *       Ret:   ROK 
536 *
537 *       Notes: None 
538 *
539 *       File:  cm_mblk.c
540 *
541 */
542   
543 Void cmFreeMem
544 (
545 Ptr    memPtr      /* Link List CP */
546 )
547 {
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 */
554
555
556   lcp = (CmMemListCp *)memPtr;
557
558   sMem.region = lcp->memCb.sMem.region;
559   sMem.pool   = lcp->memCb.sMem.pool;
560   count       = lcp->count; 
561   /* cm_mblk_c_001.101: removed getting maxSize value */
562
563   /* Free Memory by traversing Back to Front */
564   node = lcp->last;
565
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);
571
572   while(count && node)
573   {
574     prevNode = node->prev;
575
576     /* Release complete memory for present chunk */
577     /* cm_mblk_c_001.101: use node->size instead of maxSize */
578     if( node )
579     {
580 #ifdef SS_LOCKLESS_MEMORY
581        SPutStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region, sMem.pool,
582                         (Data *)node, (node->size + sizeof(CmMemList)), 0);
583 #else
584        SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region,sMem.pool, 
585                 (Data *)node, (node->size + sizeof(CmMemList)));
586 #endif /* SS_LOCKLESS_MEMORY */
587     }
588     node = prevNode;
589     count--;
590   }
591
592   return;   
593
594 } /* End of cmFreeMem */
595
596 \f
597 /*
598 *
599 *       Fun:   cmAddMemNode
600 *
601 *       Desc:  adds node to Memory linked list after last.
602 *
603 *       Ret:   ROK   - ok
604 *
605 *       Notes: None
606 *
607 *       File:  cm_mblk.c
608 *
609 */
610 static Void cmAddMemNode
611 (
612 CmMemListCp *lCp,               /* list control point */
613 CmMemList   *node               /* node to be added */
614 )
615 {
616
617    lCp->count++;
618
619    node->prev = lCp->last;
620    node->next = NULLP;
621    lCp->last = node;
622    
623    if (!node->prev)
624    {
625       lCp->first = node;
626       return;
627    }
628    
629    node->prev->next = node;
630    return;
631
632 } /* end of cmAddMemNode */
633
634
635 \f
636 /*
637 *
638 *       Fun:   cmGetMemStatus
639 *
640 *       Desc:  This function returns the static memory status with
641 *              parameters such as memory  region and pool etc
642 *
643 *       Ret:   ROK 
644 *
645 *       Notes: None 
646 *
647 *       File:  cm_mblk.c
648 *
649 */
650   
651 Void cmGetMemStatus
652 (
653 Ptr             memPtr,    /* Memory control pointer */
654 CmMemStatus     *status    /* memory region,pool and status */
655 )
656 {
657
658   CmMemListCp *memCp;    /* Memory Link List */
659
660
661   memCp = (CmMemListCp *)memPtr;
662
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;
669
670   return;
671
672 } /* End of cmGetMemStatus */ 
673
674 /**********************************************************************
675          End of file
676 **********************************************************************/