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