[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Implementation of in-active timer
[o-du/l2.git] / src / mt / ss_queue.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:     System Services -- Queueing
22  
23      Type:     C source file
24  
25      Desc:     Source code for System Services queuing functions.
26  
27      File:     ss_queue.c
28  
29 *********************************************************************21*/
30
31
32 \f
33 /* header include files (.h) */
34
35 #include "envopt.h"        /* environment options */
36 #include "envdep.h"        /* environment dependent */
37 #include "envind.h"        /* environment independent */
38   
39 #include "gen.h"           /* general layer */
40 #include "ssi.h"           /* system services */
41
42 #include "ss_err.h"        /* errors */
43 #include "ss_dep.h"        /* implementation-specific */
44 #include "ss_queue.h"      /* queues */
45 #include "ss_task.h"       /* tasking */
46 #include "ss_strm.h"       /* STREAMS */
47 #include "ss_msg.h"        /* messaging */
48 #include "ss_mem.h"        /* memory management interface */
49 #include "ss_gen.h"        /* general */
50 #include "cm_mem.h"        /* memory management */
51 /* ss040.103: addition */
52 #include <errno.h>
53
54 /* header/extern include files (.x) */
55
56 #include "gen.x"           /* general layer */
57 #include "ssi.x"           /* system services */
58
59 #include "ss_dep.x"        /* implementation-specific */
60 #include "ss_queue.x"      /* queues */
61 #include "ss_task.x"       /* tasking */
62 #include "ss_timer.x"      /* timers */
63 #include "ss_strm.x"       /* STREAMS */
64 #include "ss_msg.x"        /* messaging */
65 #include "ss_mem.x"        /* memory management interface */
66 #include "ss_drvr.x"       /* driver tasks */
67 #ifdef SS_LOCKLESS_MEMORY
68 #include "cm_llist.x"
69 #include "cm_hash.x"
70 #include "cm_mem_wl.x"        /* common memory manager */
71 #else
72 #include "cm_mem.x"        /* common memory manager */
73 #endif /* SS_LOCKLESS_MEMORY */
74 #include "ss_gen.x"        /* general */
75
76
77 \f  
78 /*
79 *
80 *       Fun:   SInitQueue
81 *
82 *       Desc:  This function initializes a queue.
83 *
84 *       Ret:   ROK      - ok
85 *              RFAILED  - failed, general (optional)
86 *
87 *       Notes: no assumptions are made about the previous state
88 *              of the queue.
89 *
90 *              queue size is set to zero.
91 *
92 *       File:  ss_queue.c
93 *
94 */
95 S16 SInitQueue
96 (
97 Queue *q               /* queue */
98 )
99 {
100
101 #if (ERRCLASS & ERRCLS_INT_PAR)
102    /* check queue pointer */
103    if (q == NULLP)
104    {
105       SSLOGERROR(ERRCLS_INT_PAR, ESS266, ERRZERO, "Null Ptr");
106       return RFAILED;
107    }
108 #endif
109    q->head     = NULLP;
110    q->tail     = NULLP;
111    q->crntSize = 0;
112
113    return ROK;
114
115 } /* end of SInitQueue */
116
117 \f  
118 /*
119 *
120 *       Fun:   SFlushQueue
121 *
122 *       Desc:  This function will release all of the data or message
123 *              buffers on the specified queue.
124 *
125 *       Ret:   ROK      - ok
126 *              RFAILED  - failed, general (optional)
127 *
128 *       Notes: if queue is empty: no action is taken.
129 *
130 *              if queue is not empty: all buffers in queue are returned
131 *              to memory. queue length is set to zero.
132 *
133 *              if dequeud buffer is a message buffer, all data buffers
134 *              associated with the message buffer are returned to memory
135 *
136 *       File:  ss_queue.c
137 *
138 */
139 S16 SFlushQueue
140 (
141 Queue *q                    /* queue */
142 )
143 {
144    Buffer *tBuf;
145    Buffer *mBuf;
146    SsMsgInfo *minfo;
147
148 #ifdef T2K_MEM_LEAK_DBG
149    char* file = __FILE__;
150    uint32_t line = __LINE__;
151 #endif
152
153
154 #if (ERRCLASS & ERRCLS_INT_PAR)
155    /* check queue */
156    if (q == NULLP)
157    {
158       SSLOGERROR(ERRCLS_INT_PAR, ESS267, ERRZERO, "Null Q Ptr");
159       return RFAILED;
160    }
161 #endif
162
163    tBuf = q->head;
164    while (tBuf != NULLP)
165    {
166       mBuf = tBuf->b_next;
167       if (tBuf->b_datap->db_type == SS_M_PROTO)
168          SPutMsg(tBuf);
169       else
170       {
171          minfo = (SsMsgInfo *) tBuf->b_rptr;
172          SPutDBuf(minfo->region, minfo->pool, tBuf);
173       }
174       tBuf = mBuf;
175    }
176    q->crntSize = 0;
177    q->head     = NULLP;
178    q->tail     = NULLP;
179
180    return ROK;
181
182 } /* end of SFlushQueue */
183
184 \f  
185 /*
186 *
187 *       Fun:   SCatQueue
188 *
189 *       Desc:  This function will concatenate the two specified queues
190 *              into one queue.
191 *
192 *       Ret:   ROK     - ok
193 *              RFAILED - failed, general (optional)
194 *
195 *       Notes: if order equals Q1Q2: all buffers attached to queue 2 are
196 *              moved to the end of queue 1. queue 2 is set to empty.
197 *              queue 1 length is increased by length of queue 2. queue
198 *              2 length is set to zero. return is ok.
199 *
200 *              if order equals Q2Q1: all buffers attached to queue 2 are
201 *              moved to the front of queue 1. queue 2 is set to empty.
202 *              queue 1 length is increased by length of queue 2. queue
203 *              2 length is set to zero. return is ok.
204 *
205 *       File:  ss_queue.c
206 *
207 */
208 S16 SCatQueue
209 (
210 Queue *q1,                  /* queue 1 */
211 Queue *q2,                  /* queue 2 */
212 Order order                 /* order */
213 )
214 {
215  
216 #if (ERRCLASS & ERRCLS_INT_PAR)
217    if (q1 == NULLP)
218    {
219       SSLOGERROR(ERRCLS_INT_PAR, ESS268, ERRZERO, "Null Q1 Ptr");
220       return RFAILED;
221    }
222  
223    if (q2 == NULLP)
224    {
225       SSLOGERROR(ERRCLS_INT_PAR, ESS269, ERRZERO, "Null Q2 Ptr");
226       return RFAILED;
227    }
228    
229    if ((order != Q1Q2) && (order != Q2Q1))
230    {
231       SSLOGERROR(ERRCLS_INT_PAR, ESS270, ERRZERO, "Invalid queue order");
232       return RFAILED;
233    }
234
235    /* ss021.103 - Addition if Q1 is Q2 */
236    if (q2 == q1)
237    {
238       SSLOGERROR(ERRCLS_INT_PAR, ESS271, ERRZERO, "Q1 == Q2");
239       return RFAILED;
240    }
241    
242 #endif /* ERRCLASS */
243    
244    if (q1->crntSize == 0)
245    {
246       q1->head       = q2->head;
247       q1->tail       = q2->tail;
248       q1->crntSize   = q2->crntSize;
249
250       q2->head       = NULLP;
251       q2->tail       = NULLP;
252       q2->crntSize   = 0;
253       
254       return ROK;
255    }
256
257    if (q2->crntSize == 0)
258    {
259       return ROK;
260    }
261    
262    switch (order)
263    {
264       case Q1Q2:
265       {
266          q1->tail->b_next = q2->head;
267          q2->head->b_prev = q1->tail;
268          q1->tail         = q2->tail;
269
270          break;
271       }
272
273       case Q2Q1:
274       {
275          q2->tail->b_next = q1->head;
276          q1->head->b_prev = q2->tail;
277          q1->head         = q2->head;
278
279          break;
280       }
281       default:
282          return RFAILED;
283    }
284
285    q1->crntSize  += q2->crntSize;
286
287    q2->head       = NULLP;
288    q2->tail       = NULLP;
289    q2->crntSize   = 0;
290
291    return ROK;
292
293 } /* end of SCatQueue */
294
295
296 \f  
297 /*
298 *
299 *       Fun:   SFndLenQueue
300 *
301 *       Desc:  This function determines the length of a queue.
302 *
303 *       Ret:   ROK      - ok
304 *              RFAILED  - failed
305 *
306 *       Notes: length of queue is determined, queue is unchanged
307 *              and length is returned via pointer to length.
308 *              
309 *       File:  ss_queue.c
310 *
311 */
312 S16 SFndLenQueue
313 (
314 Queue *q,                   /* queue */
315 QLen  *lngPtr               /* pointer to length */
316 )
317 {
318
319 #if (ERRCLASS & ERRCLS_INT_PAR)
320    /* check queue */
321    if (q == NULLP)
322    {
323       SSLOGERROR(ERRCLS_INT_PAR, ESS272, ERRZERO, "Null Q Ptr");
324       return RFAILED;
325    }
326    /* check length */
327    if (lngPtr == NULLP)
328    {
329       SSLOGERROR(ERRCLS_INT_PAR, ESS273, ERRZERO, "Null Q Len Ptr");
330       return RFAILED;
331    }
332 #endif
333
334    *lngPtr = q->crntSize;
335
336    return ROK;
337
338 } /* end of SFndLenQueue */
339
340 \f
341 /*
342 *
343 *       Fun:   SExamQueue
344 *
345 *       Desc:  This function examines the queue at the desired index.
346 *
347 *       Ret:   ROK      - ok
348 *              ROKDNA   - ok, data not available
349 *              RFAILED  - failed 
350 *
351 *       Notes: index is 0 based and indicates location in queue.
352 *
353 *              if queue is empty: pointer to buffer is set to null and
354 *              return is ok, data not available. queue length is unchanged.
355 *
356 *              if queue is not empty: pointer to buffer is set to indexed
357 *              buffer in queue. return is ok. queue length is unchanged.
358 *
359 *       File:  ss_queue.c
360 *
361 */
362 S16 SExamQueue
363 (
364 Buffer **bufPtr,            /* pointer to buffer */
365 Queue  *q,                  /* queue */
366 QLen   idx                  /* index */
367 )
368 {
369    Buffer *tmpBuf;
370    QLen   i;
371
372  
373 #if (ERRCLASS & ERRCLS_INT_PAR)
374    /* check buffer pointer */
375    if (bufPtr == NULLP)
376    {
377       SSLOGERROR(ERRCLS_INT_PAR, ESS274, ERRZERO, "Null Buf Ptr");
378       return RFAILED;
379    }
380  
381    /* check index */
382    if ((S32)idx < 0)
383    {
384       SSLOGERROR(ERRCLS_INT_PAR, ESS275, ERRZERO, "-ve index ");
385       return RFAILED;
386    }
387  
388    /* check queue */
389    if (q == NULLP)
390    {
391       SSLOGERROR(ERRCLS_INT_PAR, ESS276, ERRZERO, "Null Q Ptr");
392       return RFAILED;
393    }
394 #endif /* ERRCLASS */
395  
396    if (idx >= q->crntSize)
397    {
398       *bufPtr = NULLP;
399       return (ROKDNA);
400    }
401
402    if (idx == 0)
403    {
404       *bufPtr = q->head;
405    }
406    else  if (idx == q->crntSize -1)
407    {
408       *bufPtr = q->tail;
409    }
410    else 
411    {
412       tmpBuf = q->head;
413       for (i = 0; i < idx; i++)
414       {
415          tmpBuf = tmpBuf->b_next;
416       }
417       *bufPtr = tmpBuf;
418    }
419
420    return ROK;
421
422 } /* end of SExamQueue */
423
424 \f
425 /*
426 *
427 *       Fun:   SAddQueue
428 *
429 *       Desc:  This function inserts a bufer into the queue before 
430 *              the desired index.
431 *
432 *       Ret:   ROK     - ok
433 *              RFAILED - failed
434 *              ROKDNA  - failed - specified index not available
435 *
436 *       Notes: index is 0 based and indicates location in queue.
437 *
438 *              if queue is empty: buffer is placed in the queue.
439 *              queue length is incremented.
440 *
441 *              if queue is not empty: if index is less than the queue length, 
442 *              buffer is inserted before the desired index;
443 *              otherwise, buffer is placed behind all other buffers in queue.
444 *              queue length is incremented.
445 *
446 *       File:  ss_queue.c
447 *
448 */
449 S16 SAddQueue
450 (
451 Buffer *mBuf,                /* buffer */
452 Queue  *q,                   /* queue */
453 QLen   idx                   /* index */
454 )
455 {
456    Buffer *tBuf;
457    QLen   i;
458
459  
460 #if (ERRCLASS & ERRCLS_INT_PAR)
461    /* check queue */
462    if (q == NULLP)
463    {
464       SSLOGERROR(ERRCLS_INT_PAR, ESS277, ERRZERO, "Null Q Ptr");
465       return RFAILED;
466    }
467  
468    if (mBuf == NULLP)
469    {
470       SSLOGERROR(ERRCLS_INT_PAR, ESS278, ERRZERO, "Null Buf Ptr");
471       return RFAILED;
472    }
473  
474    if ((S32)idx < 0)
475    {
476       SSLOGERROR(ERRCLS_INT_PAR, ESS279, ERRZERO, "-ve index");
477       return RFAILED;
478    }
479    /* ss021.103 - Addition to check buffer type and if duplicate message */
480    if (mBuf->b_datap->db_type != SS_M_PROTO)
481    {
482       SSLOGERROR(ERRCLS_INT_PAR, ESS280, ERRZERO, 
483                  "Incorrect buffer type");
484       return RFAILED;
485    }
486    tBuf = q->head;
487    while (tBuf != (Buffer *)NULLP)
488    {
489       if (tBuf == mBuf)
490       {
491          SSLOGERROR(ERRCLS_INT_PAR, ESS281, ERRZERO, "Duplicate queued mBuf");
492          return RFAILED;
493       }
494       tBuf = tBuf->b_next;
495    }
496 #endif /* ERRCLASS */
497
498    if (idx > q->crntSize)
499    {
500       SSLOGERROR(ERRCLS_DEBUG, ESS282, ERRZERO, "Invalid index");
501       return (ROKDNA);
502    }
503    else if (q->crntSize == 0)
504    {
505       q->head = mBuf;
506       q->tail = mBuf;
507
508       mBuf->b_next = NULLP;
509       mBuf->b_prev = NULLP;
510    }
511    else if (idx == 0)
512    {
513       mBuf->b_next     = q->head;
514       mBuf->b_prev     = NULLP;
515       q->head->b_prev  = mBuf;
516       q->head          = mBuf;
517    }
518    else if (idx == q->crntSize)
519    {
520       mBuf->b_prev    = q->tail;
521       mBuf->b_next    = NULLP;
522       q->tail->b_next = mBuf;
523       q->tail         = mBuf;
524    }
525    else
526    {
527       tBuf = q->head;
528       for (i = 0; i < idx; i++)
529       {
530          tBuf = tBuf->b_next;
531       }
532     
533       tBuf->b_prev->b_next = mBuf;
534       mBuf->b_prev         = tBuf->b_prev;
535       mBuf->b_next         = tBuf;
536       tBuf->b_prev         = mBuf;
537    }
538    q->crntSize++;
539    return ROK;
540
541 } /* end of SAddQueue */
542
543 \f
544 /*
545 *
546 *       Fun:   SRemQueue
547 *
548 *       Desc:  This function removes a buffer from the queue at 
549 *              the desired index.
550 *
551 *       Ret:   ROK      - ok
552 *              ROKDNA   - ok, data not available
553 *              RFAILED  - failed
554 *
555 *       Notes: index is 0 based and indicates location in queue.
556 *
557 *              if queue is empty: pointer to buffer is set to null and
558 *              return is ok, data not available. queue length is unchanged.
559 *
560 *              if queue is not empty: pointer to buffer is set to indexed
561 *              buffer in queue. return is ok. queue length is decremented.
562 *
563 *       File:  ss_queue.c
564 *
565 */
566 S16 SRemQueue
567 (
568 Buffer **bufPtr,            /* pointer to buffer */
569 Queue  *q,                  /* queue */
570 QLen   idx                  /* index */
571 )
572 {
573    Buffer *tBuf;
574    QLen   i;
575
576  
577 #if (ERRCLASS & ERRCLS_INT_PAR)
578    /* check buffer pointer */
579    if (bufPtr == NULLP)
580    {
581       SSLOGERROR(ERRCLS_INT_PAR, ESS283, ERRZERO, "Null Buf Ptr");
582       return RFAILED;
583    }
584  
585    /* check queue */
586    if (q == NULLP)
587    {
588       SSLOGERROR(ERRCLS_INT_PAR, ESS284, ERRZERO, "Null Q Ptr");
589       return RFAILED;
590    }
591  
592    if ((S32)idx < 0)
593    {
594       SSLOGERROR(ERRCLS_INT_PAR, ESS285, ERRZERO, "-ve Index");
595       return RFAILED;
596    }      
597 #endif /* ERRCLASS */   
598  
599    if (idx >= q->crntSize)
600    {
601       *bufPtr = NULLP;
602       return (ROKDNA);
603    }
604    if (idx == 0)
605    {
606       *bufPtr = q->head;
607       if (q->crntSize == 1)
608       {
609          q->head = NULLP;
610          q->tail = NULLP;
611       }
612       else
613       {
614          q->head         = q->head->b_next;
615          q->head->b_prev = NULLP;
616       }
617    }
618    else if (idx == q->crntSize -1)
619    {
620       *bufPtr = q->tail;
621       q->tail = q->tail->b_prev;
622       q->tail->b_next = NULLP;
623    }
624    else 
625    {
626       tBuf = q->head;
627
628       for (i = 0; i < idx; i++)
629       {
630          tBuf = tBuf->b_next;
631       }
632       *bufPtr = tBuf;
633       
634       tBuf->b_prev->b_next = tBuf->b_next;
635       tBuf->b_next->b_prev = tBuf->b_prev;
636    }
637    q->crntSize--;
638
639    return ROK;
640
641 } /* end of SRemQueue */
642
643
644 #ifndef SS_ENABLE_MACROS
645
646 \f
647 /*
648 *
649 *       Fun:   SQueueFirst
650 *
651 *       Desc:  This function queues a data or message buffer to the
652 *              front of the specified queue.
653 *
654 *       Ret:   ROK     - ok
655 *              RFAILED - failed, general (optional)
656 *
657 *       Notes: if queue is empty: buffer is placed in the queue. queue
658 *              length is incremented.
659 *              
660 *              if queue is not empty: buffer is placed in front of all
661 *              other buffers in queue. queue length is incremented.
662 *
663 *       File:  ss_queue.c
664 *
665 */
666 inline S16 SQueueFirst
667 (
668 Buffer *buf,                /* buffer */
669 Queue *q                    /* queue */
670 )
671 {
672
673    return (SAddQueue(buf, q, 0));
674 } /* end of SQueueFirst */
675
676 \f  
677 /*
678 *
679 *       Fun:   SDequeueFirst
680 *
681 *       Desc:  This function dequeues a data or message buffer from
682 *              the front of the specified queue.
683 *
684 *       Ret:   ROK      - ok
685 *              ROKDNA   - ok, data not available
686 *              RFAILED  - failed, general (optional)
687 *
688 *       Notes: if queue is empty: pointer to buffer is set to null and
689 *              return is ok, data not available. queue length is unchanged.
690 *              
691 *              if queue is not empty: pointer to buffer is set to first
692 *              buffer in queue, first buffer in queue is removed and
693 *              return is ok. queue length is decremented.
694 *
695 *       File:  ss_queue.c
696 *
697 */
698 inline S16 SDequeueFirst
699 (
700 Buffer **bufPtr,            /* pointer to buffer */
701 Queue *q                    /* queue */
702 )
703 {
704
705    return (SRemQueue(bufPtr, q, 0));
706 } /* end of SDequeueFirst */
707
708 \f  
709 /*
710 *
711 *       Fun:   SQueueLast
712 *
713 *       Desc:  This function queues a data or message buffer to the
714 *              back of the specified queue.
715 *
716 *       Ret:   ROK      - ok
717 *              RFAILED  - failed, general (optional)
718 *
719 *       Notes: if queue is empty: buffer is placed in the queue.
720 *              queue length is incremented.
721 *              
722 *              if queue is not empty: buffer is placed behind all
723 *              other buffers in queue. queue length is incremented.
724 *
725 *       File:  ss_queue.c
726 *
727 */
728 S16 SQueueLast
729 (
730 Buffer *buf,                /* buffer */
731 Queue *q                    /* queue */
732 )
733 {
734
735 #if (ERRCLASS & ERRCLS_INT_PAR)
736    /* check queue */
737    if (q == NULLP)
738    {
739       SSLOGERROR(ERRCLS_INT_PAR, ESS286, ERRZERO, "Null Q Ptr");
740       return RFAILED;
741    }
742    /* check queue */
743    if (buf == NULLP)
744    {
745       SSLOGERROR(ERRCLS_INT_PAR, ESS287, ERRZERO, "Null Buf Ptr");
746       return RFAILED;
747    }
748 #endif
749    return (SAddQueue(buf, (q), ((q)->crntSize)));
750 }
751
752
753 \f  
754 /*
755 *
756 *       Fun:   SDequeueLast
757 *
758 *       Desc:  This function dequeues a data or message buffer from the
759 *              back of the specified queue.
760 *
761 *       Ret:   ROK     - ok
762 *              ROKDNA  - ok, data not available
763 *              RFAILED - failed, general (optional)
764 *
765 *       Notes: if queue is empty: pointer to buffer is set to null and
766 *              return is ok, data not available. queue length is unchanged.
767 *              
768 *              if queue is not empty: pointer to buffer is set to last
769 *              buffer in queue, last buffer in queue is removed and
770 *              return is ok. queue length is decremented.
771 *
772 *       File:  ss_queue.c
773 *
774 */
775 S16 SDequeueLast
776 (
777 Buffer **bufPtr,            /* pointer to buffer */
778 Queue *q                    /* queue */
779 )
780 {
781    S16   ret;
782
783
784 #if (ERRCLASS & ERRCLS_INT_PAR)
785    /* check buffer pointer */
786    if (!bufPtr)
787    {
788       SSLOGERROR(ERRCLS_INT_PAR, ESS288, ERRZERO, "Null Buf Ptr");
789       return RFAILED;
790    }
791    /* check queue */
792    if (!q)
793    {
794       SSLOGERROR(ERRCLS_INT_PAR, ESS289, ERRZERO, "Null Q Ptr");
795       return RFAILED;
796    }
797 #endif
798    if(q->crntSize > 0)
799       ret = SRemQueue(bufPtr, q, q->crntSize-1);
800    else
801       ret = SRemQueue(bufPtr, q, q->crntSize);
802
803    return (ret);
804 }
805
806 #endif /* SS_ENABLE_MACROS */
807
808 \f
809 /*
810 *
811 *       Fun:   ssInitDmndQ
812 *
813 *       Desc:  This function initializes a Demand Queue
814 *
815 *       Ret:   ROK      - ok
816 *              RFAILED  - failed
817 *
818 *       Notes: 
819 *
820 *       File:  ss_queue.c
821 *
822 */
823 S16 ssInitDmndQ
824 (
825 SsDmndQ *dQueue                 /* Demand Queue */
826 )
827 {
828    uint8_t  i;
829    S16 ret;
830
831
832 #if (ERRCLASS & ERRCLS_INT_PAR)
833    if (dQueue == NULLP)
834    {
835       SSLOGERROR(ERRCLS_INT_PAR, ESS290, ERRZERO, "NULL DQ Pointer");
836       return RFAILED;
837    }
838 #endif
839
840    for (i = 0; i < SS_MAX_NUM_DQ; i++)
841    {
842       dQueue->queue[i].head     = NULLP;
843       dQueue->queue[i].tail     = NULLP;
844       dQueue->queue[i].crntSize = 0;
845    }
846
847 #ifndef TENB_RTLIN_CHANGES
848    for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
849 #else
850    for (i = 0; i < SS_MAX_NUM_DQ; i++)
851 #endif
852    {
853 #ifndef TENB_RTLIN_CHANGES
854       dQueue->bitMask[i] =  0;
855 #endif
856       /* ss039.103 : Replaced SInitLock with WTInitLock */
857 #ifdef SS_WIN
858       ret = WTInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
859 #else
860       ret = SInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
861 #endif
862       if (ret != ROK)
863       {
864 #if (ERRCLASS & ERRCLS_DEBUG)
865          SSLOGERROR(ERRCLS_DEBUG, ESS291, (ErrVal)ret,
866                                    "Failed to initialize lock");
867 #endif
868          return RFAILED;
869       }
870    }
871
872    /* initialize the semaphore */
873    ret = ssInitSema(&dQueue->dmndQSema, 0);
874    if (ret != ROK)
875    {
876 #ifndef TENB_RTLIN_CHANGES
877       for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
878 #else
879       for (i = 0; i < SS_MAX_NUM_DQ; i++)
880 #endif
881       {
882          /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
883 #ifdef SS_WIN
884          WTDestroyLock(&dQueue->dmndQLock[i]);
885 #else
886          SDestroyLock(&dQueue->dmndQLock[i]);
887 #endif
888       }
889 #if (ERRCLASS & ERRCLS_DEBUG)
890       SSLOGERROR(ERRCLS_DEBUG, ESS292, (ErrVal)ret, 
891                                    "Failed to init semaphore");
892 #endif
893       return RFAILED;
894    }
895    return  (ROK);
896
897 } /* End of ssInitDmndQ */
898
899 \f
900 /*
901 *
902 *       Fun:   ssDestroyDmndQ
903 *
904 *       Desc:  This function destroys a Demand Queue by releasing all the
905 *              queued messages and detroying all the associated locks
906 *
907 *       Ret:   ROK      - ok
908 *              RFAILED  - failed, general (optional)
909 *
910 *       Notes: 
911 *
912 *       File:  ss_queue.c
913 *
914 */
915 S16 ssDestroyDmndQ
916 (
917 SsDmndQ *dQueue                        /* demand Queue */
918 )
919 {
920    uint8_t     i;
921    Buffer *tBuf;
922    S16    ret;
923
924
925 #if (ERRCLASS & ERRCLS_INT_PAR)
926    if (dQueue == NULLP)
927    {
928       SSLOGERROR(ERRCLS_INT_PAR, ESS293, ERRZERO, "NULL DQ Pointer");
929       return RFAILED;
930    }
931 #endif
932
933 #ifndef TENB_RTLIN_CHANGES
934       for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
935 #else
936       for (i = 0; i < SS_MAX_NUM_DQ; i++)
937 #endif
938    {
939       /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
940 #ifdef SS_WIN
941       ret = WTDestroyLock(&dQueue->dmndQLock[i]);
942 #else
943       ret = SDestroyLock(&dQueue->dmndQLock[i]);
944 #endif
945       if (ret != ROK)
946       {
947 #if (ERRCLASS & ERRCLS_DEBUG)
948          SSLOGERROR(ERRCLS_DEBUG, ESS294, (ErrVal)ret, "Failed to destroy lock");
949 #endif
950          return RFAILED;
951       }
952    }
953    for (i = 0; i < SS_MAX_NUM_DQ; i++)
954    {
955       while (dQueue->queue[i].head != NULLP)
956       {
957          tBuf = dQueue->queue[i].head;
958          dQueue->queue[i].head = dQueue->queue[i].head->b_next;
959          SPutMsg(tBuf);
960       }
961    }
962
963 /* ss06.13:addition */
964    if( ssDestroySema(&dQueue->dmndQSema) != ROK)
965    {
966       SSLOGERROR(ERRCLS_DEBUG, ESS295, ERRZERO,
967                          "Could not delete the Semaphore");
968       return RFAILED;
969
970    }
971    return  (ROK);
972
973 } /* end of ssDestroyDmndQ */
974
975 \f
976 /*
977 *
978 *       Fun:   ssDmndQPut
979 *
980 *       Desc:  This function adds a message to the head or tail of the 
981 *              priority queue specified. The priority specified is the 
982 *              destination Q index i.e 
983 *              ((dst_Tsk_pri * SS_MAX_MSG_PRI) + msg_pri)
984 *
985 *       Ret:   ROK      - ok
986 *              RFAILED  - failed
987 *
988 *       Notes: 
989 *
990 *       File:  ss_queue.c
991 *
992 */
993 S16 ssDmndQPut
994 (
995 SsDmndQ *dQueue,                       /* demand Queue */
996 Buffer  *mBuf,                         /* message buffer */
997 Prior   priority,                      /* priority */
998 Order   order                          /* position */
999 )
1000 {
1001 #ifndef TENB_RTLIN_CHANGES
1002    uint8_t     maskIndex;                   /* mask Index */
1003    uint8_t     bitPosition;                 /* bit position in index */
1004 #else
1005    uint8_t    qIndex;
1006 #endif
1007    Queue *queue;                       /* queue in demand queue */
1008    S16    ret;                         /* return value */
1009 #ifdef SS_PERF
1010    int    value;
1011    uint32_t    size;
1012 #endif
1013 #ifdef MSPD_MLOG_NEW 
1014    uint32_t    t = MacGetTick();
1015 #endif 
1016
1017
1018 #if (ERRCLASS & ERRCLS_INT_PAR)
1019    if (dQueue == NULLP)
1020    {
1021       SSLOGERROR(ERRCLS_INT_PAR, ESS296, ERRZERO, "NULL DQ Pointer");
1022       return RFAILED;
1023    }
1024
1025    if (mBuf == NULLP)
1026    {
1027       SSLOGERROR(ERRCLS_INT_PAR, ESS297, ERRZERO, "NULL mBuf Pointer");
1028       return RFAILED;
1029    }
1030
1031    if ((priority == PRIORNC) || (priority > SS_MAX_DQ_PRIOR))
1032    {
1033       SSLOGERROR(ERRCLS_INT_PAR, ESS298, ERRZERO, "invalid priority ");
1034       return RFAILED;
1035    }
1036
1037    if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1038    {
1039       SSLOGERROR(ERRCLS_INT_PAR, ESS299, ERRZERO, "invalid order ");
1040       return RFAILED;
1041    }
1042 #endif
1043    
1044 #ifndef TENB_RTLIN_CHANGES
1045    maskIndex   = priority >> 3;
1046    bitPosition = 7 - (priority % 8);
1047    queue       = &dQueue->queue[priority];
1048 #else
1049    qIndex      = priority;
1050    queue       = &dQueue->queue[qIndex];
1051 #endif
1052
1053    /* ss039.103 : Replaced SLock with WTLock */
1054 #ifdef SS_WIN
1055 #ifndef TENB_RTLIN_CHANGES
1056    ret = WTLock(&dQueue->dmndQLock[maskIndex]);
1057 #else
1058    ret = WTLock(&dQueue->dmndQLock[qIndex]);
1059 #endif
1060 #else
1061 #ifndef TENB_RTLIN_CHANGES
1062    ret = SLock(&dQueue->dmndQLock[maskIndex]);
1063 #else
1064    ret = SLock(&dQueue->dmndQLock[qIndex]);
1065 #endif
1066 #endif
1067    if (ret != ROK)
1068    {
1069 #if (ERRCLASS & ERRCLS_DEBUG)
1070       SSLOGERROR(ERRCLS_DEBUG, ESS300, (ErrVal)ret, "Failed to get lock");
1071 #endif
1072       return  (RFAILED);
1073    }
1074
1075    if (queue->crntSize == 0)
1076    {
1077       queue->head   = mBuf;
1078       queue->tail   = mBuf;
1079       mBuf->b_next  = NULLP;
1080       mBuf->b_prev  = NULLP;
1081
1082 #ifndef TENB_RTLIN_CHANGES
1083       /* Set the corresponding bit in bit mask */
1084       dQueue->bitMask[maskIndex] |= (1 << bitPosition);
1085 #endif
1086    }
1087    else
1088    {
1089       if (order == SS_DQ_LAST)
1090       {
1091          mBuf->b_prev        = queue->tail;
1092          mBuf->b_next        = NULLP;
1093          queue->tail->b_next = mBuf;
1094          queue->tail         = mBuf;
1095       }
1096       else
1097       {
1098          mBuf->b_next        = queue->head;
1099          mBuf->b_prev        = NULLP;
1100          queue->head->b_prev = mBuf;
1101          queue->head         = mBuf;
1102       }
1103    }
1104    queue->crntSize++;
1105 #ifdef SS_PERF
1106    size = queue->crntSize;
1107 #endif
1108
1109    /* ss039.103 : Replaced SUnlock with WTUnlock */
1110 #ifdef SS_WIN
1111 #ifndef TENB_RTLIN_CHANGES
1112    ret = WTUnlock(&dQueue->dmndQLock[maskIndex]);
1113 #else
1114    ret = WTUnlock(&dQueue->dmndQLock[qIndex]);
1115 #endif
1116 #else
1117 #ifndef TENB_RTLIN_CHANGES
1118    ret = SUnlock(&dQueue->dmndQLock[maskIndex]);
1119 #else
1120    ret = SUnlock(&dQueue->dmndQLock[qIndex]);
1121 #endif
1122 #endif
1123    if (ret != ROK)
1124    {
1125 #if (ERRCLASS & ERRCLS_DEBUG)
1126       SSLOGERROR(ERRCLS_DEBUG, ESS301, (ErrVal)ret, "Failed to release lock");
1127 #endif
1128       /* ss035.103 */
1129       if (order == SS_DQ_LAST)
1130       {
1131          SDequeueLast(&mBuf, queue);
1132       }
1133       else
1134       {
1135          SDequeueFirst(&mBuf, queue);
1136       }
1137       return  (RFAILED);
1138    }
1139
1140    /* increment the counting semaphore */
1141    /* ss006.13: addition */
1142
1143 /* ss037.103 for Performance enhancement : this is to ensure that semaphore is posted every time the first message is posted to the queue so that permanent tick is picked */
1144 #ifdef SS_PERF
1145   if (size > 1)
1146   {
1147      sem_getvalue(&dQueue->dmndQSema, &value);
1148      if (value > 0)
1149            return ROK;
1150   }
1151 #endif
1152    if (ssPostSema(&dQueue->dmndQSema) != ROK)
1153    {
1154 #if (ERRCLASS & ERRCLS_DEBUG)
1155        SSLOGERROR(ERRCLS_DEBUG, ESS302, ERRZERO,
1156                          "Could not unlock the Semaphore");
1157        /* ss035.103 */
1158        if (order == SS_DQ_LAST)
1159        {
1160           SDequeueLast(&mBuf, queue);
1161        }
1162        else
1163        {
1164           SDequeueFirst(&mBuf, queue);
1165        } 
1166        return RFAILED;
1167 #endif
1168    }
1169    return ROK;
1170
1171 } /* End of ssDmndQPut */
1172
1173 \f
1174 /*
1175 *
1176 *       Fun:   ssDmndQWait
1177 *
1178 *       Desc:  This function removes a message from head or tail of the 
1179 *              highest non-empty priority queue message. 
1180 *
1181 *       Ret:   ROK      - ok
1182 *              RFAILED  - failed
1183 *              ROKDNA   - ok, no data available in queue
1184 *
1185 *       Notes:  This is a blocking call
1186 *
1187 *       File:  ss_queue.c
1188 *
1189 */
1190 S16 ssDmndQWait
1191 (
1192 SsDmndQ *dQueue                          /* demand queue */
1193 )
1194 {
1195    S16   ret;
1196
1197
1198 #if (ERRCLASS & ERRCLS_INT_PAR)
1199    if (dQueue == NULLP)
1200    {
1201       SSLOGERROR(ERRCLS_INT_PAR, ESS303, ERRZERO, "NULL DQ Pointer");
1202       return RFAILED;
1203    }
1204
1205 #endif
1206
1207    /* ss040.103 updating for possible non-fatal retur from sem_wait */
1208    while ((ret = ssWaitSema(&dQueue->dmndQSema) != ROK) && (errno == EINTR))
1209       continue;
1210    if (ret != ROK)
1211    {
1212 #if (ERRCLASS & ERRCLS_DEBUG)
1213       SSLOGERROR(ERRCLS_DEBUG, ESS306, (ErrVal)ret, "Failed to get semaphore");
1214 #endif
1215       return  (RFAILED);
1216    }
1217
1218    return  (ROK);
1219 } /* End of ssDmndQWait */
1220
1221
1222 \f
1223 /*
1224 *
1225 *       Fun:   ssDmndQGet
1226 *
1227 *       Desc:  This function removes a message from head or tail of the 
1228 *              highest non-empty priority queue message. 
1229 *
1230 *       Ret:   ROK      - ok
1231 *              RFAILED  - failed
1232 *              ROKDNA   - ok, no data available in queue
1233 *
1234 *       Notes:  This is a blocking call
1235 *
1236 *       File:  ss_queue.c
1237 *
1238 */
1239 S16 ssDmndQGet
1240 (
1241 SsDmndQ *dQueue,                          /* demand queue */
1242 Buffer  **mBuf,                           /* message buffer */
1243 Order   order                             /* position */ 
1244 )
1245 {
1246    Queue *queue;
1247    S16   ret;
1248    S16   i;
1249 #ifndef TENB_RTLIN_CHANGES
1250    uint8_t    bitPosition;
1251    uint8_t    qIndex;
1252 #endif
1253
1254
1255 #if (ERRCLASS & ERRCLS_INT_PAR)
1256    if (mBuf == NULLP)
1257    {
1258       SSLOGERROR(ERRCLS_INT_PAR, ESS304, ERRZERO, "NULL mBuf Pointer");
1259       return RFAILED;
1260    }
1261
1262    if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1263    {
1264       SSLOGERROR(ERRCLS_INT_PAR, ESS305, ERRZERO, "invalid order ");
1265       return RFAILED;
1266    }
1267 #endif
1268
1269 #ifndef TENB_RTLIN_CHANGES
1270    for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1271    {
1272       /* ss039.103 : Replaced SLock with WTLock */
1273 #ifdef SS_WIN
1274       ret = WTLock(&dQueue->dmndQLock[i]);
1275 #else
1276       ret = SLock(&dQueue->dmndQLock[i]);
1277 #endif
1278       if (ret != ROK)
1279       {
1280 #if (ERRCLASS & ERRCLS_DEBUG)
1281          SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1282 #endif
1283          return  (RFAILED);
1284       }
1285
1286       bitPosition = osCp.dmndQLookupTbl[dQueue->bitMask[i]];
1287       if (bitPosition != 255)
1288          break;
1289
1290       /* ss039.103 : Replaced SUnlock with WTUnlock */
1291 #ifdef SS_WIN
1292       ret = WTUnlock(&dQueue->dmndQLock[i]);
1293 #else
1294       ret = SUnlock(&dQueue->dmndQLock[i]);
1295 #endif
1296       if (ret != ROK)
1297       {
1298 #if (ERRCLASS & ERRCLS_DEBUG)
1299          SSLOGERROR(ERRCLS_DEBUG, ESS308, ret, "Failed to release lock");
1300 #endif
1301          return  (RFAILED);
1302       }
1303    }
1304    if (i >= SS_DQ_BIT_MASK_LEN)
1305    {
1306       /* Demand Queue is empty */
1307       *mBuf = NULLP;
1308       return  (ROKDNA);
1309    }
1310    
1311    qIndex = (i * 8) +  (7 - bitPosition);
1312    queue = &dQueue->queue[qIndex];
1313
1314 #else
1315    for (i = 0; i < SS_MAX_NUM_DQ; i++)
1316    {
1317       queue = &dQueue->queue[i];
1318       if (queue->crntSize)
1319          break;
1320    }
1321
1322    if (i >= SS_MAX_NUM_DQ)
1323    {
1324       /* Demand Queue is empty */
1325       *mBuf = NULLP;
1326       return  (ROKDNA);
1327    }
1328
1329    /* ss039.103 : Replaced SLock with WTLock */
1330 #ifdef SS_WIN
1331    ret = WTLock(&dQueue->dmndQLock[i]);
1332 #else
1333    ret = SLock(&dQueue->dmndQLock[i]);
1334 #endif
1335    if (ret != ROK)
1336    {
1337 #if (ERRCLASS & ERRCLS_DEBUG)
1338       SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1339 #endif
1340       return  (RFAILED);
1341    }
1342
1343 #endif
1344 /* ss037.103 For performance enhancement replace the check sequence with simple 
1345 setting the crntSize to 0 and removing the message */
1346 #ifndef SS_PERF
1347    if (queue->crntSize == 1)
1348    {
1349       *mBuf = queue->head;
1350       queue->head = NULLP;
1351       queue->tail = NULLP;
1352
1353       /* Reset the corresponding bit in bit mask */
1354       dQueue->bitMask[i] &= (~( 1 << (bitPosition)));
1355    }
1356    else
1357    {
1358       if (order == SS_DQ_FIRST)
1359       {
1360          *mBuf = queue->head;
1361          queue->head = queue->head->b_next;
1362          queue->head->b_prev = NULLP;
1363       }
1364       else
1365       {
1366          *mBuf = queue->tail;
1367          queue->tail = queue->tail->b_prev;
1368          queue->tail->b_next = NULLP;
1369       }
1370    }
1371    queue->crntSize--;
1372 #else
1373    queue->crntSize = 0;
1374    *mBuf = queue->head;
1375    queue->head = NULLP;
1376    queue->tail = NULLP;
1377        
1378 #endif
1379
1380    /* ss039.103 : Replaced SUnlock with WTUnlock */
1381 #ifdef SS_WIN
1382    ret = WTUnlock(&dQueue->dmndQLock[i]); 
1383 #else
1384    ret = SUnlock(&dQueue->dmndQLock[i]); 
1385 #endif
1386    if (ret != ROK)
1387    {
1388 #if (ERRCLASS & ERRCLS_DEBUG)
1389       SSLOGERROR(ERRCLS_DEBUG, ESS309, (ErrVal)ret, "Failed to release lock");
1390 #endif
1391       return  (RFAILED);
1392    }
1393
1394    return  (ROK);
1395
1396 } /* End of ssDmndQGet */
1397
1398 \f
1399 /*
1400 *
1401 *       Fun:   ssFndLenDmndQ 
1402 *
1403 *       Desc:  This function returns the number of messages in a queue
1404 *              If priority is specified, length of the associated Q is 
1405 *              returned otherwise total length of all Qs is returned.
1406 *
1407 *       Ret:   ROK      - ok
1408 *              RFAILED  - failed
1409 *
1410 *       Notes: 
1411 *
1412 *       File:  ss_queue.c
1413 *
1414 */
1415 S16 ssFndLenDmndQ
1416 (
1417 SsDmndQ *dQueue,                               /* demand queue */
1418 Prior   priority,                              /* priority */
1419 QLen    *len                                   /* queue length */
1420 )
1421 {
1422    
1423    S16  ret;                                   /* return value */
1424    uint8_t   i;
1425
1426
1427 #if (ERRCLASS & ERRCLS_INT_PAR)
1428    if ((dQueue == NULLP) || (len == NULLP))
1429    {
1430       SSLOGERROR(ERRCLS_INT_PAR, ESS310, ERRZERO, "NULL Pointer");
1431       return RFAILED;
1432    }
1433 #endif
1434
1435    *len = 0;
1436    if (priority != PRIORNC)
1437    {
1438       i = priority >> 3; 
1439       /* ss039.103 : Replaced SLock with WTLock */
1440 #ifdef SS_WIN
1441       ret = WTLock(&dQueue->dmndQLock[i]);
1442 #else
1443       ret = SLock(&dQueue->dmndQLock[i]);
1444 #endif
1445       if (ret != ROK)
1446       {
1447 #if (ERRCLASS & ERRCLS_DEBUG)
1448          SSLOGERROR(ERRCLS_DEBUG, ESS311, (ErrVal)ret, "Failed to get lock");
1449 #endif
1450          return  (RFAILED);
1451       }
1452
1453       *len = dQueue->queue[priority].crntSize;
1454
1455       /* ss039.103 : Replaced SUnlock with WTUnlock */
1456 #ifdef SS_WIN
1457       ret = WTUnlock(&dQueue->dmndQLock[i]);
1458 #else
1459       ret = SUnlock(&dQueue->dmndQLock[i]);
1460 #endif
1461       if (ret != ROK)
1462       {
1463 #if (ERRCLASS & ERRCLS_DEBUG)
1464          SSLOGERROR(ERRCLS_DEBUG, ESS312, (ErrVal)ret,  \
1465                                          "Failed to release lock");
1466 #endif
1467          return  (RFAILED);
1468       }
1469    }
1470    else
1471    {
1472 #ifndef TENB_RTLIN_CHANGES
1473       for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1474 #else
1475       for (i = 0; i < SS_MAX_NUM_DQ; i++)
1476 #endif
1477       {
1478          /* ss039.103 : Replaced SLock with WTLock */
1479 #ifdef SS_WIN
1480          ret = WTLock(&dQueue->dmndQLock[i]);
1481 #else
1482          ret = SLock(&dQueue->dmndQLock[i]);
1483 #endif
1484          if (ret != ROK)
1485          {
1486 #if (ERRCLASS & ERRCLS_DEBUG)
1487             SSLOGERROR(ERRCLS_DEBUG, ESS313, (ErrVal)ret, "Failed to get lock");
1488 #endif
1489             /* Release all the locks aquired */
1490             while (i > 0)
1491             {
1492
1493 /* ss006.13: addition */
1494                 /* ss039.103 : Replaced SUnlock with WTUnlock */
1495 #ifdef SS_WIN
1496                 if( WTUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1497 #else
1498                 if( SUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1499 #endif
1500                 {
1501 #if (ERRCLASS & ERRCLS_DEBUG)
1502                    SSLOGERROR(ERRCLS_DEBUG, ESS314, ERRZERO,
1503                          "Could not give the Semaphore");
1504                    return RFAILED;
1505 #endif
1506                 }
1507
1508                i--;
1509             }
1510
1511             return  (RFAILED);
1512          }
1513       }
1514
1515       for (i = 0; i  < SS_MAX_NUM_DQ; i++)
1516          *len  += dQueue->queue[i].crntSize;
1517
1518 #ifndef TENB_RTLIN_CHANGES
1519       for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1520 #else
1521       for ( i = 0; i < SS_MAX_NUM_DQ; i++)
1522 #endif
1523       {
1524          /* ss039.103 : Replaced SUnlock with WTUnlock */ 
1525 #ifdef SS_WIN
1526          ret = WTUnlock(&dQueue->dmndQLock[i]);
1527 #else
1528          ret = SUnlock(&dQueue->dmndQLock[i]);
1529 #endif
1530          if (ret != ROK)
1531          {
1532 #if (ERRCLASS & ERRCLS_DEBUG)
1533             SSLOGERROR(ERRCLS_DEBUG, ESS315, (ErrVal)ret, "Failed to get lock");
1534 #endif
1535             return  (RFAILED);
1536          }
1537       }
1538    }
1539    return ROK;
1540
1541 } /* End of ssFndLenDmndQ */
1542
1543 /**********************************************************************
1544          End of file
1545 **********************************************************************/