[Epic-ID: ODUHIGH-475][Task-ID: ODUHIGH-476]Integration fixes upto PRACH scheduling...
[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 "common_def.h"       /* Header file */
34
35 #ifdef SS_LOCKLESS_MEMORY
36 pthread_t tmpRegTidMap[20];
37 #define CM_MEM_GET_REGION(_region)                        \
38 {                                                         \
39    uint8_t  _regCnt;                                           \
40    _region = 0xFF;                                        \
41                                                           \
42    for(_regCnt = 0; _regCnt < 12; _regCnt++)              \
43    {                                                      \
44       if(tmpRegTidMap[_regCnt] == pthread_self())         \
45       {                                                   \
46          _region = _regCnt;                               \
47          break;                                           \
48       }                                                   \
49    }                                                      \
50 }
51 #endif
52
53
54
55 static Void cmAddMemNode ARGS((CmMemListCp *lCp,CmMemList *node)); 
56
57 \f
58 /*
59 *
60 *       Fun:   cmAllocEvnt
61 *
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.
66 *
67 *       Ret:   ROK 
68 *
69 *       Notes: None 
70 *
71 *       File:  cm_mblk.c
72 *
73 */
74   
75 S16 cmAllocEvnt
76 (
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 */
81 )
82 {
83
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 */
88
89
90   /* Validation check */
91 #ifndef LTE_ENB_PAL
92   if( evntSize > maxBlkSize)
93   {
94      DU_LOG("\nERROR  -->  Not Allocating memory for Event\n");
95 #ifdef ALIGN_64BIT
96      DU_LOG("\nERROR  -->  eventSize [%d] greater than maxBlkSize [%d]\n",
97            evntSize, maxBlkSize);
98 #else
99      DU_LOG("\nERROR  -->  eventSize [%ld] greater than maxBlkSize [%ld]\n",
100            evntSize, maxBlkSize);
101 #endif
102      return RFAILED;
103   }
104 #endif
105  
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)
111 #else
112   if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, 
113                (Data **)&allocPtr, 
114                (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
115 #endif /* SS_LOCKLESS_MEMORY */
116
117      return RFAILED;
118
119   /* Reset the contents */
120   memset(allocPtr, 0, 
121            (maxBlkSize + sizeof(CmMemList)) );
122
123   /* The above allocated memory chunk is structured as follows 
124
125   +-------------------+
126   |  CmMemList        |
127   +-------------------+   <---- Event Structure begins here
128   |  CmMemListCp      |      ^
129   +-------------------+      |
130   |  Event data part  |      |  evntSize
131   +-------------------+      |
132        ....                  |
133        ....                  \/ 
134   +-------------------+    
135   
136   */
137
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;
142
143   /* Get to CmMemListCp start */
144   memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
145   
146   /* Initialise memListCp */
147   CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
148
149   /* Add link list node to link list */
150   cmAddMemNode(memCp, node); 
151
152   /* Get pointer to memCb inside MemListCp */
153   cb = (CmMemCb *)&(memCp->memCb);
154
155   /* Align evntSize, if necessary */
156   CM_ALIGN_SIZE(evntSize);
157
158   cb->memAllocated = (evntSize + sizeof(CmMemList) );
159   cb->initPtr = (PTR)allocPtr;
160   *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
161   cb->runPtr = ((PTR)(*ptr) + evntSize);
162
163   return ROK;
164
165 } /* End of cmAllocEvnt */
166
167 \f
168 /*
169 *
170 *       Fun:   cmInitMemCp
171 *
172 *       Desc:  This function intialises Memory Link List
173 *              Control point  
174 *
175 *       Ret:   ROK 
176 *
177 *       Notes: None 
178 *
179 *       File:  cm_mblk.c
180 *
181 */
182   
183 Void cmInitMemCp
184 (
185 CmMemListCp     *memCp,     /* Memory control pointer */
186 Size            maxBlkSize, /* Chunk Memory size */
187 Mem             *sMem       /* Static memory region and pool */
188 )
189 {
190
191   /* Intialise Memory Control Point */
192   CM_INIT_MEMCP(memCp,maxBlkSize,sMem);
193
194   return;
195
196 } /* End of cmInitMemCp */ 
197
198 \f
199 /*
200 *
201 *       Fun:   cmGetMem
202 *
203 *       Desc:  This function parcels memory from memory chunks 
204 *              It allocated big chunk as and when required
205 *
206 *       Ret:   ROK 
207 *
208 *       Notes: None 
209 *
210 *       File:  cm_mblk.c
211 *
212 */
213   
214 S16 cmGetMem
215 (
216 Ptr           memPtr,    /* Pointer to memCp */
217 Size          size,      /* Memory size requested */
218 Ptr           *allocPtr  /* location to place pointer */
219 )
220 {
221  
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 */
227
228
229   memCp = (CmMemListCp *)memPtr;
230   cb = &memCp->memCb; 
231
232   /* Make requested size aligned, if necessary */
233   CM_ALIGN_SIZE(size);
234
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)
241      blkSize = size;
242    else
243      blkSize = cb->maxSize;
244  
245   if( cb->initPtr)
246   { 
247     /* if a chunk is already there */
248     if( (cb->memAllocated + size) <= 
249            (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
250     {
251       /* Requested memory is available in present chunk */
252       *allocPtr = (Ptr) cb->runPtr;
253       cb->memAllocated += size;
254       cb->runPtr += size;
255       return ROK;
256     }
257   }
258   
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)
266 #else
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 */
271      return RFAILED;
272
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) ));
278
279   /* The above allocated memory chunk is structured as follows 
280
281   +-------------------+
282   |  CmMemList        |
283   +-------------------+
284       Data Portion
285        ....
286        ....
287   +-------------------+    */
288
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;
293
294   /* Add link list node to link list */
295   cmAddMemNode(memCp, node); 
296
297   cb->memAllocated = (size + sizeof(CmMemList) );
298   *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
299   cb->runPtr = ((PTR)(*allocPtr) + size);
300
301   return ROK;   
302
303 } /* End of cmGetMem */
304
305
306 #ifdef TFU_ALLOC_EVENT_NO_INIT
307 \f
308 /*
309 *
310 *       Fun:   cmAllocEvntNoInit
311 *
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.
316 *
317 *       Ret:   ROK 
318 *
319 *       Notes: None 
320 *
321 *       File:  cm_mblk.c
322 *
323 */
324   
325 S16 cmAllocEvntNoInit
326 (
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 */
331 )
332 {
333
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 */
338
339
340   /* Validation check */
341   if( evntSize > maxBlkSize)
342      return RFAILED;
343  
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)
349 #else
350   if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem->region, sMem->pool, 
351                (Data **)&allocPtr, 
352                (Size)(maxBlkSize + sizeof(CmMemList))) != ROK)
353 #endif /* SS_LOCKLESS_MEMORY */
354
355      return RFAILED;
356
357   /* Reset the contents */
358   memset(allocPtr, 0, 
359            (sizeof(CmMemList)) );
360
361   /* The above allocated memory chunk is structured as follows 
362
363   +-------------------+
364   |  CmMemList        |
365   +-------------------+   <---- Event Structure begins here
366   |  CmMemListCp      |      ^
367   +-------------------+      |
368   |  Event data part  |      |  evntSize
369   +-------------------+      |
370        ....                  |
371        ....                  \/ 
372   +-------------------+    
373   
374   */
375
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;
380
381   /* Get to CmMemListCp start */
382   memCp = (CmMemListCp *) ((PTR)allocPtr + sizeof(CmMemList));
383   
384   /* Initialise memListCp */
385   CM_INIT_MEMCP( memCp,maxBlkSize,sMem);
386
387   /* Add link list node to link list */
388   cmAddMemNode(memCp, node); 
389
390   /* Get pointer to memCb inside MemListCp */
391   cb = (CmMemCb *)&(memCp->memCb);
392
393   /* Align evntSize, if necessary */
394   CM_ALIGN_SIZE(evntSize);
395
396   cb->memAllocated = (evntSize + sizeof(CmMemList) );
397   cb->initPtr = (PTR)allocPtr;
398   *ptr = (Ptr) ((PTR)allocPtr + sizeof(CmMemList));
399   cb->runPtr = ((PTR)(*ptr) + evntSize);
400
401   return ROK;
402
403 } /* End of cmAllocEvntNoInit */
404
405 /*
406 *
407 *       Fun:   cmGetMemNoInit
408 *
409 *       Desc:  This function parcels memory from memory chunks 
410 *              It allocated big chunk as and when required
411 *
412 *       Ret:   ROK 
413 *
414 *       Notes: None 
415 *
416 *       File:  cm_mblk.c
417 *
418 */
419   
420 S16 cmGetMemNoInit
421 (
422 Ptr           memPtr,    /* Pointer to memCp */
423 Size          size,      /* Memory size requested */
424 Ptr           *allocPtr  /* location to place pointer */
425 )
426 {
427  
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 */
433
434
435   memCp = (CmMemListCp *)memPtr;
436   cb = &memCp->memCb; 
437
438   /* Make requested size aligned, if necessary */
439   CM_ALIGN_SIZE(size);
440
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)
447      blkSize = size;
448    else
449      blkSize = cb->maxSize;
450  
451   if( cb->initPtr)
452   { 
453     /* if a chunk is already there */
454     if( (cb->memAllocated + size) <= 
455            (uint32_t)(cb->maxSize + sizeof(CmMemList)) )
456     {
457       /* Requested memory is available in present chunk */
458       *allocPtr = (Ptr) cb->runPtr;
459       //memset(*allocPtr, (uint8_t )0, 
460         //   (PTR)(size) );
461       cb->memAllocated += size;
462       cb->runPtr += size;
463       return ROK;
464     }
465   }
466   
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)
474 #else
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 */
479      return RFAILED;
480
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 
487
488   +-------------------+
489   |  CmMemList        |
490   +-------------------+
491       Data Portion
492        ....
493        ....
494   +-------------------+    */
495
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;
500
501   /* Add link list node to link list */
502   cmAddMemNode(memCp, node); 
503
504   cb->memAllocated = (size + sizeof(CmMemList) );
505   *allocPtr = (Ptr) ((PTR)cb->initPtr + sizeof(CmMemList));
506   cb->runPtr = ((PTR)(*allocPtr) + size);
507
508   return ROK;   
509
510 } /* End of cmGetMemNoInit */
511
512
513
514
515 #endif
516 \f
517 /*
518 *
519 *       Fun:   cmFreeMem
520 *
521 *       Desc:  This function frees memory chunks after
522 *              traversing link list
523 *
524 *       Ret:   ROK 
525 *
526 *       Notes: None 
527 *
528 *       File:  cm_mblk.c
529 *
530 */
531   
532 Void cmFreeMem
533 (
534 Ptr    memPtr      /* Link List CP */
535 )
536 {
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 */
543
544
545   lcp = (CmMemListCp *)memPtr;
546
547   sMem.region = lcp->memCb.sMem.region;
548   sMem.pool   = lcp->memCb.sMem.pool;
549   count       = lcp->count; 
550   /* cm_mblk_c_001.101: removed getting maxSize value */
551
552   /* Free Memory by traversing Back to Front */
553   node = lcp->last;
554
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);
560
561   while(count && node)
562   {
563     prevNode = node->prev;
564
565     /* Release complete memory for present chunk */
566     /* cm_mblk_c_001.101: use node->size instead of maxSize */
567     if( node )
568     {
569 #ifdef SS_LOCKLESS_MEMORY
570        SPutStaticBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region, sMem.pool,
571                         (Data *)node, (node->size + sizeof(CmMemList)), 0);
572 #else
573        SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,sMem.region,sMem.pool, 
574                 (Data *)node, (node->size + sizeof(CmMemList)));
575 #endif /* SS_LOCKLESS_MEMORY */
576     }
577     node = prevNode;
578     count--;
579   }
580
581   return;   
582
583 } /* End of cmFreeMem */
584
585 \f
586 /*
587 *
588 *       Fun:   cmAddMemNode
589 *
590 *       Desc:  adds node to Memory linked list after last.
591 *
592 *       Ret:   ROK   - ok
593 *
594 *       Notes: None
595 *
596 *       File:  cm_mblk.c
597 *
598 */
599 static Void cmAddMemNode
600 (
601 CmMemListCp *lCp,               /* list control point */
602 CmMemList   *node               /* node to be added */
603 )
604 {
605
606    lCp->count++;
607
608    node->prev = lCp->last;
609    node->next = NULLP;
610    lCp->last = node;
611    
612    if (!node->prev)
613    {
614       lCp->first = node;
615       return;
616    }
617    
618    node->prev->next = node;
619    return;
620
621 } /* end of cmAddMemNode */
622
623
624 \f
625 /*
626 *
627 *       Fun:   cmGetMemStatus
628 *
629 *       Desc:  This function returns the static memory status with
630 *              parameters such as memory  region and pool etc
631 *
632 *       Ret:   ROK 
633 *
634 *       Notes: None 
635 *
636 *       File:  cm_mblk.c
637 *
638 */
639   
640 Void cmGetMemStatus
641 (
642 Ptr             memPtr,    /* Memory control pointer */
643 CmMemStatus     *status    /* memory region,pool and status */
644 )
645 {
646
647   CmMemListCp *memCp;    /* Memory Link List */
648
649
650   memCp = (CmMemListCp *)memPtr;
651
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;
658
659   return;
660
661 } /* End of cmGetMemStatus */ 
662
663 /**********************************************************************
664          End of file
665 **********************************************************************/