1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: System Services -- Queueing
25 Desc: Source code for System Services queuing functions.
29 *********************************************************************21*/
33 /* header include files (.h) */
35 #include "envopt.h" /* environment options */
36 #include "envdep.h" /* environment dependent */
37 #include "envind.h" /* environment independent */
39 #include "gen.h" /* general layer */
40 #include "ssi.h" /* system services */
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 */
54 /* header/extern include files (.x) */
56 #include "gen.x" /* general layer */
57 #include "ssi.x" /* system services */
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
70 #include "cm_mem_wl.x" /* common memory manager */
72 #include "cm_mem.x" /* common memory manager */
73 #endif /* SS_LOCKLESS_MEMORY */
74 #include "ss_gen.x" /* general */
82 * Desc: This function initializes a queue.
85 * RFAILED - failed, general (optional)
87 * Notes: no assumptions are made about the previous state
90 * queue size is set to zero.
101 PUBLIC S16 SInitQueue(q)
102 Queue *q; /* queue */
107 #if (ERRCLASS & ERRCLS_INT_PAR)
108 /* check queue pointer */
111 SSLOGERROR(ERRCLS_INT_PAR, ESS266, ERRZERO, "Null Ptr");
121 } /* end of SInitQueue */
128 * Desc: This function will release all of the data or message
129 * buffers on the specified queue.
132 * RFAILED - failed, general (optional)
134 * Notes: if queue is empty: no action is taken.
136 * if queue is not empty: all buffers in queue are returned
137 * to memory. queue length is set to zero.
139 * if dequeud buffer is a message buffer, all data buffers
140 * associated with the message buffer are returned to memory
146 PUBLIC S16 SFlushQueue
151 PUBLIC S16 SFlushQueue(q)
152 Queue *q; /* queue */
159 #ifdef T2K_MEM_LEAK_DBG
160 char* file = __FILE__;
166 #if (ERRCLASS & ERRCLS_INT_PAR)
170 SSLOGERROR(ERRCLS_INT_PAR, ESS267, ERRZERO, "Null Q Ptr");
176 while (tBuf != NULLP)
179 if (tBuf->b_datap->db_type == SS_M_PROTO)
183 minfo = (SsMsgInfo *) tBuf->b_rptr;
184 SPutDBuf(minfo->region, minfo->pool, tBuf);
194 } /* end of SFlushQueue */
201 * Desc: This function will concatenate the two specified queues
205 * RFAILED - failed, general (optional)
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.
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.
223 Queue *q1, /* queue 1 */
224 Queue *q2, /* queue 2 */
225 Order order /* order */
228 PUBLIC S16 SCatQueue(q1, q2, order)
229 Queue *q1; /* queue 1 */
230 Queue *q2; /* queue 2 */
231 Order order; /* order */
236 #if (ERRCLASS & ERRCLS_INT_PAR)
239 SSLOGERROR(ERRCLS_INT_PAR, ESS268, ERRZERO, "Null Q1 Ptr");
245 SSLOGERROR(ERRCLS_INT_PAR, ESS269, ERRZERO, "Null Q2 Ptr");
249 if ((order != Q1Q2) && (order != Q2Q1))
251 SSLOGERROR(ERRCLS_INT_PAR, ESS270, ERRZERO, "Invalid queue order");
255 /* ss021.103 - Addition if Q1 is Q2 */
258 SSLOGERROR(ERRCLS_INT_PAR, ESS271, ERRZERO, "Q1 == Q2");
262 #endif /* ERRCLASS */
264 if (q1->crntSize == 0)
268 q1->crntSize = q2->crntSize;
277 if (q2->crntSize == 0)
286 q1->tail->b_next = q2->head;
287 q2->head->b_prev = q1->tail;
295 q2->tail->b_next = q1->head;
296 q1->head->b_prev = q2->tail;
305 q1->crntSize += q2->crntSize;
313 } /* end of SCatQueue */
321 * Desc: This function determines the length of a queue.
326 * Notes: length of queue is determined, queue is unchanged
327 * and length is returned via pointer to length.
333 PUBLIC S16 SFndLenQueue
335 Queue *q, /* queue */
336 QLen *lngPtr /* pointer to length */
339 PUBLIC S16 SFndLenQueue(q, lngPtr)
340 Queue *q; /* queue */
341 QLen *lngPtr; /* pointer to length */
346 #if (ERRCLASS & ERRCLS_INT_PAR)
350 SSLOGERROR(ERRCLS_INT_PAR, ESS272, ERRZERO, "Null Q Ptr");
356 SSLOGERROR(ERRCLS_INT_PAR, ESS273, ERRZERO, "Null Q Len Ptr");
361 *lngPtr = q->crntSize;
365 } /* end of SFndLenQueue */
372 * Desc: This function examines the queue at the desired index.
375 * ROKDNA - ok, data not available
378 * Notes: index is 0 based and indicates location in queue.
380 * if queue is empty: pointer to buffer is set to null and
381 * return is ok, data not available. queue length is unchanged.
383 * if queue is not empty: pointer to buffer is set to indexed
384 * buffer in queue. return is ok. queue length is unchanged.
390 PUBLIC S16 SExamQueue
392 Buffer **bufPtr, /* pointer to buffer */
393 Queue *q, /* queue */
397 PUBLIC S16 SExamQueue(bufPtr, q, idx)
398 Buffer **bufPtr; /* pointer to buffer */
399 Queue *q; /* queue */
400 QLen idx; /* index */
408 #if (ERRCLASS & ERRCLS_INT_PAR)
409 /* check buffer pointer */
412 SSLOGERROR(ERRCLS_INT_PAR, ESS274, ERRZERO, "Null Buf Ptr");
419 SSLOGERROR(ERRCLS_INT_PAR, ESS275, ERRZERO, "-ve index ");
426 SSLOGERROR(ERRCLS_INT_PAR, ESS276, ERRZERO, "Null Q Ptr");
429 #endif /* ERRCLASS */
431 if (idx >= q->crntSize)
441 else if (idx == q->crntSize -1)
448 for (i = 0; i < idx; i++)
450 tmpBuf = tmpBuf->b_next;
457 } /* end of SExamQueue */
464 * Desc: This function inserts a bufer into the queue before
469 * ROKDNA - failed - specified index not available
471 * Notes: index is 0 based and indicates location in queue.
473 * if queue is empty: buffer is placed in the queue.
474 * queue length is incremented.
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.
487 Buffer *mBuf, /* buffer */
488 Queue *q, /* queue */
492 PUBLIC S16 SAddQueue(mBuf, q, idx)
493 Buffer *mBuf; /* buffer */
494 Queue *q; /* queue */
495 QLen idx; /* index */
503 #if (ERRCLASS & ERRCLS_INT_PAR)
507 SSLOGERROR(ERRCLS_INT_PAR, ESS277, ERRZERO, "Null Q Ptr");
513 SSLOGERROR(ERRCLS_INT_PAR, ESS278, ERRZERO, "Null Buf Ptr");
519 SSLOGERROR(ERRCLS_INT_PAR, ESS279, ERRZERO, "-ve index");
522 /* ss021.103 - Addition to check buffer type and if duplicate message */
523 if (mBuf->b_datap->db_type != SS_M_PROTO)
525 SSLOGERROR(ERRCLS_INT_PAR, ESS280, ERRZERO,
526 "Incorrect buffer type");
530 while (tBuf != (Buffer *)NULLP)
534 SSLOGERROR(ERRCLS_INT_PAR, ESS281, ERRZERO, "Duplicate queued mBuf");
539 #endif /* ERRCLASS */
541 if (idx > q->crntSize)
543 SSLOGERROR(ERRCLS_DEBUG, ESS282, ERRZERO, "Invalid index");
546 else if (q->crntSize == 0)
551 mBuf->b_next = NULLP;
552 mBuf->b_prev = NULLP;
556 mBuf->b_next = q->head;
557 mBuf->b_prev = NULLP;
558 q->head->b_prev = mBuf;
561 else if (idx == q->crntSize)
563 mBuf->b_prev = q->tail;
564 mBuf->b_next = NULLP;
565 q->tail->b_next = mBuf;
571 for (i = 0; i < idx; i++)
576 tBuf->b_prev->b_next = mBuf;
577 mBuf->b_prev = tBuf->b_prev;
584 } /* end of SAddQueue */
591 * Desc: This function removes a buffer from the queue at
595 * ROKDNA - ok, data not available
598 * Notes: index is 0 based and indicates location in queue.
600 * if queue is empty: pointer to buffer is set to null and
601 * return is ok, data not available. queue length is unchanged.
603 * if queue is not empty: pointer to buffer is set to indexed
604 * buffer in queue. return is ok. queue length is decremented.
612 Buffer **bufPtr, /* pointer to buffer */
613 Queue *q, /* queue */
617 PUBLIC S16 SRemQueue(bufPtr, q, idx)
618 Buffer **bufPtr; /* pointer to buffer */
619 Queue *q; /* queue */
620 QLen idx; /* index */
628 #if (ERRCLASS & ERRCLS_INT_PAR)
629 /* check buffer pointer */
632 SSLOGERROR(ERRCLS_INT_PAR, ESS283, ERRZERO, "Null Buf Ptr");
639 SSLOGERROR(ERRCLS_INT_PAR, ESS284, ERRZERO, "Null Q Ptr");
645 SSLOGERROR(ERRCLS_INT_PAR, ESS285, ERRZERO, "-ve Index");
648 #endif /* ERRCLASS */
650 if (idx >= q->crntSize)
658 if (q->crntSize == 1)
665 q->head = q->head->b_next;
666 q->head->b_prev = NULLP;
669 else if (idx == q->crntSize -1)
672 q->tail = q->tail->b_prev;
673 q->tail->b_next = NULLP;
679 for (i = 0; i < idx; i++)
685 tBuf->b_prev->b_next = tBuf->b_next;
686 tBuf->b_next->b_prev = tBuf->b_prev;
692 } /* end of SRemQueue */
695 #ifndef SS_ENABLE_MACROS
702 * Desc: This function queues a data or message buffer to the
703 * front of the specified queue.
706 * RFAILED - failed, general (optional)
708 * Notes: if queue is empty: buffer is placed in the queue. queue
709 * length is incremented.
711 * if queue is not empty: buffer is placed in front of all
712 * other buffers in queue. queue length is incremented.
718 PUBLIC INLINE S16 SQueueFirst
720 Buffer *buf, /* buffer */
724 PUBLIC INLINE S16 SQueueFirst(buf, q)
725 Buffer *buf; /* buffer */
726 Queue *q; /* queue */
731 RETVALUE(SAddQueue(buf, q, 0));
732 } /* end of SQueueFirst */
739 * Desc: This function dequeues a data or message buffer from
740 * the front of the specified queue.
743 * ROKDNA - ok, data not available
744 * RFAILED - failed, general (optional)
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.
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.
757 PUBLIC INLINE S16 SDequeueFirst
759 Buffer **bufPtr, /* pointer to buffer */
763 PUBLIC INLINE S16 SDequeueFirst(bufPtr, q)
764 Buffer **bufPtr; /* pointer to buffer */
765 Queue *q; /* queue */
770 RETVALUE(SRemQueue(bufPtr, q, 0));
771 } /* end of SDequeueFirst */
778 * Desc: This function queues a data or message buffer to the
779 * back of the specified queue.
782 * RFAILED - failed, general (optional)
784 * Notes: if queue is empty: buffer is placed in the queue.
785 * queue length is incremented.
787 * if queue is not empty: buffer is placed behind all
788 * other buffers in queue. queue length is incremented.
794 PUBLIC S16 SQueueLast
796 Buffer *buf, /* buffer */
800 PUBLIC S16 SQueueLast(buf, q)
801 Buffer *buf; /* buffer */
802 Queue *q; /* queue */
807 #if (ERRCLASS & ERRCLS_INT_PAR)
811 SSLOGERROR(ERRCLS_INT_PAR, ESS286, ERRZERO, "Null Q Ptr");
817 SSLOGERROR(ERRCLS_INT_PAR, ESS287, ERRZERO, "Null Buf Ptr");
821 RETVALUE(SAddQueue(buf, (q), ((q)->crntSize)));
830 * Desc: This function dequeues a data or message buffer from the
831 * back of the specified queue.
834 * ROKDNA - ok, data not available
835 * RFAILED - failed, general (optional)
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.
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.
848 PUBLIC S16 SDequeueLast
850 Buffer **bufPtr, /* pointer to buffer */
854 PUBLIC S16 SDequeueLast(bufPtr, q)
855 Buffer **bufPtr; /* pointer to buffer */
856 Queue *q; /* queue */
863 #if (ERRCLASS & ERRCLS_INT_PAR)
864 /* check buffer pointer */
867 SSLOGERROR(ERRCLS_INT_PAR, ESS288, ERRZERO, "Null Buf Ptr");
873 SSLOGERROR(ERRCLS_INT_PAR, ESS289, ERRZERO, "Null Q Ptr");
878 ret = SRemQueue(bufPtr, q, q->crntSize-1);
880 ret = SRemQueue(bufPtr, q, q->crntSize);
885 #endif /* SS_ENABLE_MACROS */
892 * Desc: This function initializes a Demand Queue
903 PUBLIC S16 ssInitDmndQ
905 SsDmndQ *dQueue /* Demand Queue */
908 PUBLIC S16 ssInitDmndQ(dQueue)
909 SsDmndQ *dQueue; /* Demand Queue */
917 #if (ERRCLASS & ERRCLS_INT_PAR)
920 SSLOGERROR(ERRCLS_INT_PAR, ESS290, ERRZERO, "NULL DQ Pointer");
925 for (i = 0; i < SS_MAX_NUM_DQ; i++)
927 dQueue->queue[i].head = NULLP;
928 dQueue->queue[i].tail = NULLP;
929 dQueue->queue[i].crntSize = 0;
932 #ifndef TENB_RTLIN_CHANGES
933 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
935 for (i = 0; i < SS_MAX_NUM_DQ; i++)
938 #ifndef TENB_RTLIN_CHANGES
939 dQueue->bitMask[i] = 0;
941 /* ss039.103 : Replaced SInitLock with WTInitLock */
943 ret = WTInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
945 ret = SInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
949 #if (ERRCLASS & ERRCLS_DEBUG)
950 SSLOGERROR(ERRCLS_DEBUG, ESS291, (ErrVal)ret,
951 "Failed to initialize lock");
957 /* initialize the semaphore */
958 ret = ssInitSema(&dQueue->dmndQSema, 0);
961 #ifndef TENB_RTLIN_CHANGES
962 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
964 for (i = 0; i < SS_MAX_NUM_DQ; i++)
967 /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
969 WTDestroyLock(&dQueue->dmndQLock[i]);
971 SDestroyLock(&dQueue->dmndQLock[i]);
974 #if (ERRCLASS & ERRCLS_DEBUG)
975 SSLOGERROR(ERRCLS_DEBUG, ESS292, (ErrVal)ret,
976 "Failed to init semaphore");
982 } /* End of ssInitDmndQ */
987 * Fun: ssDestroyDmndQ
989 * Desc: This function destroys a Demand Queue by releasing all the
990 * queued messages and detroying all the associated locks
993 * RFAILED - failed, general (optional)
1001 PUBLIC S16 ssDestroyDmndQ
1003 SsDmndQ *dQueue /* demand Queue */
1006 PUBLIC S16 ssDestroyDmndQ(dQueue)
1007 SsDmndQ *dQueue; /* demand Queue */
1014 TRC0(ssDestroyDmndQ)
1016 #if (ERRCLASS & ERRCLS_INT_PAR)
1017 if (dQueue == NULLP)
1019 SSLOGERROR(ERRCLS_INT_PAR, ESS293, ERRZERO, "NULL DQ Pointer");
1024 #ifndef TENB_RTLIN_CHANGES
1025 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1027 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1030 /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
1032 ret = WTDestroyLock(&dQueue->dmndQLock[i]);
1034 ret = SDestroyLock(&dQueue->dmndQLock[i]);
1038 #if (ERRCLASS & ERRCLS_DEBUG)
1039 SSLOGERROR(ERRCLS_DEBUG, ESS294, (ErrVal)ret, "Failed to destroy lock");
1044 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1046 while (dQueue->queue[i].head != NULLP)
1048 tBuf = dQueue->queue[i].head;
1049 dQueue->queue[i].head = dQueue->queue[i].head->b_next;
1054 /* ss06.13:addition */
1055 if( ssDestroySema(&dQueue->dmndQSema) != ROK)
1057 SSLOGERROR(ERRCLS_DEBUG, ESS295, ERRZERO,
1058 "Could not delete the Semaphore");
1064 } /* end of ssDestroyDmndQ */
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)
1085 PUBLIC S16 ssDmndQPut
1087 SsDmndQ *dQueue, /* demand Queue */
1088 Buffer *mBuf, /* message buffer */
1089 Prior priority, /* priority */
1090 Order order /* position */
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 */
1100 #ifndef TENB_RTLIN_CHANGES
1101 U8 maskIndex; /* mask Index */
1102 U8 bitPosition; /* bit position in index */
1106 Queue *queue; /* queue in demand queue */
1107 S16 ret; /* return value */
1112 #ifdef MSPD_MLOG_NEW
1113 U32 t = MacGetTick();
1118 #if (ERRCLASS & ERRCLS_INT_PAR)
1119 if (dQueue == NULLP)
1121 SSLOGERROR(ERRCLS_INT_PAR, ESS296, ERRZERO, "NULL DQ Pointer");
1127 SSLOGERROR(ERRCLS_INT_PAR, ESS297, ERRZERO, "NULL mBuf Pointer");
1131 if ((priority == PRIORNC) || (priority > SS_MAX_DQ_PRIOR))
1133 SSLOGERROR(ERRCLS_INT_PAR, ESS298, ERRZERO, "invalid priority ");
1137 if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1139 SSLOGERROR(ERRCLS_INT_PAR, ESS299, ERRZERO, "invalid order ");
1144 #ifndef TENB_RTLIN_CHANGES
1145 maskIndex = priority >> 3;
1146 bitPosition = 7 - (priority % 8);
1147 queue = &dQueue->queue[priority];
1150 queue = &dQueue->queue[qIndex];
1153 /* ss039.103 : Replaced SLock with WTLock */
1155 #ifndef TENB_RTLIN_CHANGES
1156 ret = WTLock(&dQueue->dmndQLock[maskIndex]);
1158 ret = WTLock(&dQueue->dmndQLock[qIndex]);
1161 #ifndef TENB_RTLIN_CHANGES
1162 ret = SLock(&dQueue->dmndQLock[maskIndex]);
1164 ret = SLock(&dQueue->dmndQLock[qIndex]);
1169 #if (ERRCLASS & ERRCLS_DEBUG)
1170 SSLOGERROR(ERRCLS_DEBUG, ESS300, (ErrVal)ret, "Failed to get lock");
1175 if (queue->crntSize == 0)
1179 mBuf->b_next = NULLP;
1180 mBuf->b_prev = NULLP;
1182 #ifndef TENB_RTLIN_CHANGES
1183 /* Set the corresponding bit in bit mask */
1184 dQueue->bitMask[maskIndex] |= (1 << bitPosition);
1189 if (order == SS_DQ_LAST)
1191 mBuf->b_prev = queue->tail;
1192 mBuf->b_next = NULLP;
1193 queue->tail->b_next = mBuf;
1198 mBuf->b_next = queue->head;
1199 mBuf->b_prev = NULLP;
1200 queue->head->b_prev = mBuf;
1206 size = queue->crntSize;
1209 /* ss039.103 : Replaced SUnlock with WTUnlock */
1211 #ifndef TENB_RTLIN_CHANGES
1212 ret = WTUnlock(&dQueue->dmndQLock[maskIndex]);
1214 ret = WTUnlock(&dQueue->dmndQLock[qIndex]);
1217 #ifndef TENB_RTLIN_CHANGES
1218 ret = SUnlock(&dQueue->dmndQLock[maskIndex]);
1220 ret = SUnlock(&dQueue->dmndQLock[qIndex]);
1225 #if (ERRCLASS & ERRCLS_DEBUG)
1226 SSLOGERROR(ERRCLS_DEBUG, ESS301, (ErrVal)ret, "Failed to release lock");
1229 if (order == SS_DQ_LAST)
1231 SDequeueLast(&mBuf, queue);
1235 SDequeueFirst(&mBuf, queue);
1240 /* increment the counting semaphore */
1241 /* ss006.13: addition */
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 */
1247 sem_getvalue(&dQueue->dmndQSema, &value);
1252 if (ssPostSema(&dQueue->dmndQSema) != ROK)
1254 #if (ERRCLASS & ERRCLS_DEBUG)
1255 SSLOGERROR(ERRCLS_DEBUG, ESS302, ERRZERO,
1256 "Could not unlock the Semaphore");
1258 if (order == SS_DQ_LAST)
1260 SDequeueLast(&mBuf, queue);
1264 SDequeueFirst(&mBuf, queue);
1271 } /* End of ssDmndQPut */
1278 * Desc: This function removes a message from head or tail of the
1279 * highest non-empty priority queue message.
1283 * ROKDNA - ok, no data available in queue
1285 * Notes: This is a blocking call
1291 PUBLIC S16 ssDmndQWait
1293 SsDmndQ *dQueue /* demand queue */
1296 PUBLIC S16 ssDmndQWait(dQueue)
1297 SsDmndQ *dQueue; /* demand queue */
1304 #if (ERRCLASS & ERRCLS_INT_PAR)
1305 if (dQueue == NULLP)
1307 SSLOGERROR(ERRCLS_INT_PAR, ESS303, ERRZERO, "NULL DQ Pointer");
1313 /* ss040.103 updating for possible non-fatal retur from sem_wait */
1314 while ((ret = ssWaitSema(&dQueue->dmndQSema) != ROK) && (errno == EINTR))
1318 #if (ERRCLASS & ERRCLS_DEBUG)
1319 SSLOGERROR(ERRCLS_DEBUG, ESS306, (ErrVal)ret, "Failed to get semaphore");
1325 } /* End of ssDmndQWait */
1333 * Desc: This function removes a message from head or tail of the
1334 * highest non-empty priority queue message.
1338 * ROKDNA - ok, no data available in queue
1340 * Notes: This is a blocking call
1346 PUBLIC S16 ssDmndQGet
1348 SsDmndQ *dQueue, /* demand queue */
1349 Buffer **mBuf, /* message buffer */
1350 Order order /* position */
1353 PUBLIC S16 ssDmndQGet(dQueue, mBuf, order)
1354 SsDmndQ *dQueue; /* demand queue */
1355 Buffer **mBuf; /* message buffer */
1356 Order order; /* position */
1362 #ifndef TENB_RTLIN_CHANGES
1369 #if (ERRCLASS & ERRCLS_INT_PAR)
1372 SSLOGERROR(ERRCLS_INT_PAR, ESS304, ERRZERO, "NULL mBuf Pointer");
1376 if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1378 SSLOGERROR(ERRCLS_INT_PAR, ESS305, ERRZERO, "invalid order ");
1383 #ifndef TENB_RTLIN_CHANGES
1384 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1386 /* ss039.103 : Replaced SLock with WTLock */
1388 ret = WTLock(&dQueue->dmndQLock[i]);
1390 ret = SLock(&dQueue->dmndQLock[i]);
1394 #if (ERRCLASS & ERRCLS_DEBUG)
1395 SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1400 bitPosition = osCp.dmndQLookupTbl[dQueue->bitMask[i]];
1401 if (bitPosition != 255)
1404 /* ss039.103 : Replaced SUnlock with WTUnlock */
1406 ret = WTUnlock(&dQueue->dmndQLock[i]);
1408 ret = SUnlock(&dQueue->dmndQLock[i]);
1412 #if (ERRCLASS & ERRCLS_DEBUG)
1413 SSLOGERROR(ERRCLS_DEBUG, ESS308, ret, "Failed to release lock");
1418 if (i >= SS_DQ_BIT_MASK_LEN)
1420 /* Demand Queue is empty */
1425 qIndex = (i * 8) + (7 - bitPosition);
1426 queue = &dQueue->queue[qIndex];
1429 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1431 queue = &dQueue->queue[i];
1432 if (queue->crntSize)
1436 if (i >= SS_MAX_NUM_DQ)
1438 /* Demand Queue is empty */
1443 /* ss039.103 : Replaced SLock with WTLock */
1445 ret = WTLock(&dQueue->dmndQLock[i]);
1447 ret = SLock(&dQueue->dmndQLock[i]);
1451 #if (ERRCLASS & ERRCLS_DEBUG)
1452 SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1458 /* ss037.103 For performance enhancement replace the check sequence with simple
1459 setting the crntSize to 0 and removing the message */
1461 if (queue->crntSize == 1)
1463 *mBuf = queue->head;
1464 queue->head = NULLP;
1465 queue->tail = NULLP;
1467 /* Reset the corresponding bit in bit mask */
1468 dQueue->bitMask[i] &= (~( 1 << (bitPosition)));
1472 if (order == SS_DQ_FIRST)
1474 *mBuf = queue->head;
1475 queue->head = queue->head->b_next;
1476 queue->head->b_prev = NULLP;
1480 *mBuf = queue->tail;
1481 queue->tail = queue->tail->b_prev;
1482 queue->tail->b_next = NULLP;
1487 queue->crntSize = 0;
1488 *mBuf = queue->head;
1489 queue->head = NULLP;
1490 queue->tail = NULLP;
1494 /* ss039.103 : Replaced SUnlock with WTUnlock */
1496 ret = WTUnlock(&dQueue->dmndQLock[i]);
1498 ret = SUnlock(&dQueue->dmndQLock[i]);
1502 #if (ERRCLASS & ERRCLS_DEBUG)
1503 SSLOGERROR(ERRCLS_DEBUG, ESS309, (ErrVal)ret, "Failed to release lock");
1510 } /* End of ssDmndQGet */
1515 * Fun: ssFndLenDmndQ
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.
1530 PUBLIC S16 ssFndLenDmndQ
1532 SsDmndQ *dQueue, /* demand queue */
1533 Prior priority, /* priority */
1534 QLen *len /* queue length */
1537 PUBLIC S16 ssFndLenDmndQ(dQueue, priority, len)
1538 SsDmndQ *dQueue; /* demand queue */
1539 Prior priority; /* priority */
1540 QLen *len; /* queue length */
1544 S16 ret; /* return value */
1549 #if (ERRCLASS & ERRCLS_INT_PAR)
1550 if ((dQueue == NULLP) || (len == NULLP))
1552 SSLOGERROR(ERRCLS_INT_PAR, ESS310, ERRZERO, "NULL Pointer");
1558 if (priority != PRIORNC)
1561 /* ss039.103 : Replaced SLock with WTLock */
1563 ret = WTLock(&dQueue->dmndQLock[i]);
1565 ret = SLock(&dQueue->dmndQLock[i]);
1569 #if (ERRCLASS & ERRCLS_DEBUG)
1570 SSLOGERROR(ERRCLS_DEBUG, ESS311, (ErrVal)ret, "Failed to get lock");
1575 *len = dQueue->queue[priority].crntSize;
1577 /* ss039.103 : Replaced SUnlock with WTUnlock */
1579 ret = WTUnlock(&dQueue->dmndQLock[i]);
1581 ret = SUnlock(&dQueue->dmndQLock[i]);
1585 #if (ERRCLASS & ERRCLS_DEBUG)
1586 SSLOGERROR(ERRCLS_DEBUG, ESS312, (ErrVal)ret, \
1587 "Failed to release lock");
1594 #ifndef TENB_RTLIN_CHANGES
1595 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1597 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1600 /* ss039.103 : Replaced SLock with WTLock */
1602 ret = WTLock(&dQueue->dmndQLock[i]);
1604 ret = SLock(&dQueue->dmndQLock[i]);
1608 #if (ERRCLASS & ERRCLS_DEBUG)
1609 SSLOGERROR(ERRCLS_DEBUG, ESS313, (ErrVal)ret, "Failed to get lock");
1611 /* Release all the locks aquired */
1615 /* ss006.13: addition */
1616 /* ss039.103 : Replaced SUnlock with WTUnlock */
1618 if( WTUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1620 if( SUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1623 #if (ERRCLASS & ERRCLS_DEBUG)
1624 SSLOGERROR(ERRCLS_DEBUG, ESS314, ERRZERO,
1625 "Could not give the Semaphore");
1637 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1638 *len += dQueue->queue[i].crntSize;
1640 #ifndef TENB_RTLIN_CHANGES
1641 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1643 for ( i = 0; i < SS_MAX_NUM_DQ; i++)
1646 /* ss039.103 : Replaced SUnlock with WTUnlock */
1648 ret = WTUnlock(&dQueue->dmndQLock[i]);
1650 ret = SUnlock(&dQueue->dmndQLock[i]);
1654 #if (ERRCLASS & ERRCLS_DEBUG)
1655 SSLOGERROR(ERRCLS_DEBUG, ESS315, (ErrVal)ret, "Failed to get lock");
1663 } /* End of ssFndLenDmndQ */
1665 /**********************************************************************
1667 **********************************************************************/