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.
102 Queue *q; /* queue */
106 #if (ERRCLASS & ERRCLS_INT_PAR)
107 /* check queue pointer */
110 SSLOGERROR(ERRCLS_INT_PAR, ESS266, ERRZERO, "Null Ptr");
120 } /* end of SInitQueue */
127 * Desc: This function will release all of the data or message
128 * buffers on the specified queue.
131 * RFAILED - failed, general (optional)
133 * Notes: if queue is empty: no action is taken.
135 * if queue is not empty: all buffers in queue are returned
136 * to memory. queue length is set to zero.
138 * if dequeud buffer is a message buffer, all data buffers
139 * associated with the message buffer are returned to memory
151 Queue *q; /* queue */
158 #ifdef T2K_MEM_LEAK_DBG
159 char* file = __FILE__;
160 uint32_t line = __LINE__;
164 #if (ERRCLASS & ERRCLS_INT_PAR)
168 SSLOGERROR(ERRCLS_INT_PAR, ESS267, ERRZERO, "Null Q Ptr");
174 while (tBuf != NULLP)
177 if (tBuf->b_datap->db_type == SS_M_PROTO)
181 minfo = (SsMsgInfo *) tBuf->b_rptr;
182 SPutDBuf(minfo->region, minfo->pool, tBuf);
192 } /* end of SFlushQueue */
199 * Desc: This function will concatenate the two specified queues
203 * RFAILED - failed, general (optional)
205 * Notes: if order equals Q1Q2: all buffers attached to queue 2 are
206 * moved to the end of queue 1. queue 2 is set to empty.
207 * queue 1 length is increased by length of queue 2. queue
208 * 2 length is set to zero. return is ok.
210 * if order equals Q2Q1: all buffers attached to queue 2 are
211 * moved to the front of queue 1. queue 2 is set to empty.
212 * queue 1 length is increased by length of queue 2. queue
213 * 2 length is set to zero. return is ok.
221 Queue *q1, /* queue 1 */
222 Queue *q2, /* queue 2 */
223 Order order /* order */
226 S16 SCatQueue(q1, q2, order)
227 Queue *q1; /* queue 1 */
228 Queue *q2; /* queue 2 */
229 Order order; /* order */
233 #if (ERRCLASS & ERRCLS_INT_PAR)
236 SSLOGERROR(ERRCLS_INT_PAR, ESS268, ERRZERO, "Null Q1 Ptr");
242 SSLOGERROR(ERRCLS_INT_PAR, ESS269, ERRZERO, "Null Q2 Ptr");
246 if ((order != Q1Q2) && (order != Q2Q1))
248 SSLOGERROR(ERRCLS_INT_PAR, ESS270, ERRZERO, "Invalid queue order");
252 /* ss021.103 - Addition if Q1 is Q2 */
255 SSLOGERROR(ERRCLS_INT_PAR, ESS271, ERRZERO, "Q1 == Q2");
259 #endif /* ERRCLASS */
261 if (q1->crntSize == 0)
265 q1->crntSize = q2->crntSize;
274 if (q2->crntSize == 0)
283 q1->tail->b_next = q2->head;
284 q2->head->b_prev = q1->tail;
292 q2->tail->b_next = q1->head;
293 q1->head->b_prev = q2->tail;
302 q1->crntSize += q2->crntSize;
310 } /* end of SCatQueue */
318 * Desc: This function determines the length of a queue.
323 * Notes: length of queue is determined, queue is unchanged
324 * and length is returned via pointer to length.
332 Queue *q, /* queue */
333 QLen *lngPtr /* pointer to length */
336 S16 SFndLenQueue(q, lngPtr)
337 Queue *q; /* queue */
338 QLen *lngPtr; /* pointer to length */
342 #if (ERRCLASS & ERRCLS_INT_PAR)
346 SSLOGERROR(ERRCLS_INT_PAR, ESS272, ERRZERO, "Null Q Ptr");
352 SSLOGERROR(ERRCLS_INT_PAR, ESS273, ERRZERO, "Null Q Len Ptr");
357 *lngPtr = q->crntSize;
361 } /* end of SFndLenQueue */
368 * Desc: This function examines the queue at the desired index.
371 * ROKDNA - ok, data not available
374 * Notes: index is 0 based and indicates location in queue.
376 * if queue is empty: pointer to buffer is set to null and
377 * return is ok, data not available. queue length is unchanged.
379 * if queue is not empty: pointer to buffer is set to indexed
380 * buffer in queue. return is ok. queue length is unchanged.
388 Buffer **bufPtr, /* pointer to buffer */
389 Queue *q, /* queue */
393 S16 SExamQueue(bufPtr, q, idx)
394 Buffer **bufPtr; /* pointer to buffer */
395 Queue *q; /* queue */
396 QLen idx; /* index */
403 #if (ERRCLASS & ERRCLS_INT_PAR)
404 /* check buffer pointer */
407 SSLOGERROR(ERRCLS_INT_PAR, ESS274, ERRZERO, "Null Buf Ptr");
414 SSLOGERROR(ERRCLS_INT_PAR, ESS275, ERRZERO, "-ve index ");
421 SSLOGERROR(ERRCLS_INT_PAR, ESS276, ERRZERO, "Null Q Ptr");
424 #endif /* ERRCLASS */
426 if (idx >= q->crntSize)
436 else if (idx == q->crntSize -1)
443 for (i = 0; i < idx; i++)
445 tmpBuf = tmpBuf->b_next;
452 } /* end of SExamQueue */
459 * Desc: This function inserts a bufer into the queue before
464 * ROKDNA - failed - specified index not available
466 * Notes: index is 0 based and indicates location in queue.
468 * if queue is empty: buffer is placed in the queue.
469 * queue length is incremented.
471 * if queue is not empty: if index is less than the queue length,
472 * buffer is inserted before the desired index;
473 * otherwise, buffer is placed behind all other buffers in queue.
474 * queue length is incremented.
482 Buffer *mBuf, /* buffer */
483 Queue *q, /* queue */
487 S16 SAddQueue(mBuf, q, idx)
488 Buffer *mBuf; /* buffer */
489 Queue *q; /* queue */
490 QLen idx; /* index */
497 #if (ERRCLASS & ERRCLS_INT_PAR)
501 SSLOGERROR(ERRCLS_INT_PAR, ESS277, ERRZERO, "Null Q Ptr");
507 SSLOGERROR(ERRCLS_INT_PAR, ESS278, ERRZERO, "Null Buf Ptr");
513 SSLOGERROR(ERRCLS_INT_PAR, ESS279, ERRZERO, "-ve index");
516 /* ss021.103 - Addition to check buffer type and if duplicate message */
517 if (mBuf->b_datap->db_type != SS_M_PROTO)
519 SSLOGERROR(ERRCLS_INT_PAR, ESS280, ERRZERO,
520 "Incorrect buffer type");
524 while (tBuf != (Buffer *)NULLP)
528 SSLOGERROR(ERRCLS_INT_PAR, ESS281, ERRZERO, "Duplicate queued mBuf");
533 #endif /* ERRCLASS */
535 if (idx > q->crntSize)
537 SSLOGERROR(ERRCLS_DEBUG, ESS282, ERRZERO, "Invalid index");
540 else if (q->crntSize == 0)
545 mBuf->b_next = NULLP;
546 mBuf->b_prev = NULLP;
550 mBuf->b_next = q->head;
551 mBuf->b_prev = NULLP;
552 q->head->b_prev = mBuf;
555 else if (idx == q->crntSize)
557 mBuf->b_prev = q->tail;
558 mBuf->b_next = NULLP;
559 q->tail->b_next = mBuf;
565 for (i = 0; i < idx; i++)
570 tBuf->b_prev->b_next = mBuf;
571 mBuf->b_prev = tBuf->b_prev;
578 } /* end of SAddQueue */
585 * Desc: This function removes a buffer from the queue at
589 * ROKDNA - ok, data not available
592 * Notes: index is 0 based and indicates location in queue.
594 * if queue is empty: pointer to buffer is set to null and
595 * return is ok, data not available. queue length is unchanged.
597 * if queue is not empty: pointer to buffer is set to indexed
598 * buffer in queue. return is ok. queue length is decremented.
606 Buffer **bufPtr, /* pointer to buffer */
607 Queue *q, /* queue */
611 S16 SRemQueue(bufPtr, q, idx)
612 Buffer **bufPtr; /* pointer to buffer */
613 Queue *q; /* queue */
614 QLen idx; /* index */
621 #if (ERRCLASS & ERRCLS_INT_PAR)
622 /* check buffer pointer */
625 SSLOGERROR(ERRCLS_INT_PAR, ESS283, ERRZERO, "Null Buf Ptr");
632 SSLOGERROR(ERRCLS_INT_PAR, ESS284, ERRZERO, "Null Q Ptr");
638 SSLOGERROR(ERRCLS_INT_PAR, ESS285, ERRZERO, "-ve Index");
641 #endif /* ERRCLASS */
643 if (idx >= q->crntSize)
651 if (q->crntSize == 1)
658 q->head = q->head->b_next;
659 q->head->b_prev = NULLP;
662 else if (idx == q->crntSize -1)
665 q->tail = q->tail->b_prev;
666 q->tail->b_next = NULLP;
672 for (i = 0; i < idx; i++)
678 tBuf->b_prev->b_next = tBuf->b_next;
679 tBuf->b_next->b_prev = tBuf->b_prev;
685 } /* end of SRemQueue */
688 #ifndef SS_ENABLE_MACROS
695 * Desc: This function queues a data or message buffer to the
696 * front of the specified queue.
699 * RFAILED - failed, general (optional)
701 * Notes: if queue is empty: buffer is placed in the queue. queue
702 * length is incremented.
704 * if queue is not empty: buffer is placed in front of all
705 * other buffers in queue. queue length is incremented.
711 INLINE S16 SQueueFirst
713 Buffer *buf, /* buffer */
717 INLINE S16 SQueueFirst(buf, q)
718 Buffer *buf; /* buffer */
719 Queue *q; /* queue */
723 return (SAddQueue(buf, q, 0));
724 } /* end of SQueueFirst */
731 * Desc: This function dequeues a data or message buffer from
732 * the front of the specified queue.
735 * ROKDNA - ok, data not available
736 * RFAILED - failed, general (optional)
738 * Notes: if queue is empty: pointer to buffer is set to null and
739 * return is ok, data not available. queue length is unchanged.
741 * if queue is not empty: pointer to buffer is set to first
742 * buffer in queue, first buffer in queue is removed and
743 * return is ok. queue length is decremented.
749 INLINE S16 SDequeueFirst
751 Buffer **bufPtr, /* pointer to buffer */
755 INLINE S16 SDequeueFirst(bufPtr, q)
756 Buffer **bufPtr; /* pointer to buffer */
757 Queue *q; /* queue */
761 return (SRemQueue(bufPtr, q, 0));
762 } /* end of SDequeueFirst */
769 * Desc: This function queues a data or message buffer to the
770 * back of the specified queue.
773 * RFAILED - failed, general (optional)
775 * Notes: if queue is empty: buffer is placed in the queue.
776 * queue length is incremented.
778 * if queue is not empty: buffer is placed behind all
779 * other buffers in queue. queue length is incremented.
787 Buffer *buf, /* buffer */
791 S16 SQueueLast(buf, q)
792 Buffer *buf; /* buffer */
793 Queue *q; /* queue */
797 #if (ERRCLASS & ERRCLS_INT_PAR)
801 SSLOGERROR(ERRCLS_INT_PAR, ESS286, ERRZERO, "Null Q Ptr");
807 SSLOGERROR(ERRCLS_INT_PAR, ESS287, ERRZERO, "Null Buf Ptr");
811 return (SAddQueue(buf, (q), ((q)->crntSize)));
820 * Desc: This function dequeues a data or message buffer from the
821 * back of the specified queue.
824 * ROKDNA - ok, data not available
825 * RFAILED - failed, general (optional)
827 * Notes: if queue is empty: pointer to buffer is set to null and
828 * return is ok, data not available. queue length is unchanged.
830 * if queue is not empty: pointer to buffer is set to last
831 * buffer in queue, last buffer in queue is removed and
832 * return is ok. queue length is decremented.
840 Buffer **bufPtr, /* pointer to buffer */
844 S16 SDequeueLast(bufPtr, q)
845 Buffer **bufPtr; /* pointer to buffer */
846 Queue *q; /* queue */
852 #if (ERRCLASS & ERRCLS_INT_PAR)
853 /* check buffer pointer */
856 SSLOGERROR(ERRCLS_INT_PAR, ESS288, ERRZERO, "Null Buf Ptr");
862 SSLOGERROR(ERRCLS_INT_PAR, ESS289, ERRZERO, "Null Q Ptr");
867 ret = SRemQueue(bufPtr, q, q->crntSize-1);
869 ret = SRemQueue(bufPtr, q, q->crntSize);
874 #endif /* SS_ENABLE_MACROS */
881 * Desc: This function initializes a Demand Queue
894 SsDmndQ *dQueue /* Demand Queue */
897 S16 ssInitDmndQ(dQueue)
898 SsDmndQ *dQueue; /* Demand Queue */
905 #if (ERRCLASS & ERRCLS_INT_PAR)
908 SSLOGERROR(ERRCLS_INT_PAR, ESS290, ERRZERO, "NULL DQ Pointer");
913 for (i = 0; i < SS_MAX_NUM_DQ; i++)
915 dQueue->queue[i].head = NULLP;
916 dQueue->queue[i].tail = NULLP;
917 dQueue->queue[i].crntSize = 0;
920 #ifndef TENB_RTLIN_CHANGES
921 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
923 for (i = 0; i < SS_MAX_NUM_DQ; i++)
926 #ifndef TENB_RTLIN_CHANGES
927 dQueue->bitMask[i] = 0;
929 /* ss039.103 : Replaced SInitLock with WTInitLock */
931 ret = WTInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
933 ret = SInitLock(&dQueue->dmndQLock[i], SS_DMNDQ_LOCK);
937 #if (ERRCLASS & ERRCLS_DEBUG)
938 SSLOGERROR(ERRCLS_DEBUG, ESS291, (ErrVal)ret,
939 "Failed to initialize lock");
945 /* initialize the semaphore */
946 ret = ssInitSema(&dQueue->dmndQSema, 0);
949 #ifndef TENB_RTLIN_CHANGES
950 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
952 for (i = 0; i < SS_MAX_NUM_DQ; i++)
955 /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
957 WTDestroyLock(&dQueue->dmndQLock[i]);
959 SDestroyLock(&dQueue->dmndQLock[i]);
962 #if (ERRCLASS & ERRCLS_DEBUG)
963 SSLOGERROR(ERRCLS_DEBUG, ESS292, (ErrVal)ret,
964 "Failed to init semaphore");
970 } /* End of ssInitDmndQ */
975 * Fun: ssDestroyDmndQ
977 * Desc: This function destroys a Demand Queue by releasing all the
978 * queued messages and detroying all the associated locks
981 * RFAILED - failed, general (optional)
991 SsDmndQ *dQueue /* demand Queue */
994 S16 ssDestroyDmndQ(dQueue)
995 SsDmndQ *dQueue; /* demand Queue */
1003 #if (ERRCLASS & ERRCLS_INT_PAR)
1004 if (dQueue == NULLP)
1006 SSLOGERROR(ERRCLS_INT_PAR, ESS293, ERRZERO, "NULL DQ Pointer");
1011 #ifndef TENB_RTLIN_CHANGES
1012 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1014 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1017 /* ss039.103 : Replaced SDestroyLock with WTDestroyLock */
1019 ret = WTDestroyLock(&dQueue->dmndQLock[i]);
1021 ret = SDestroyLock(&dQueue->dmndQLock[i]);
1025 #if (ERRCLASS & ERRCLS_DEBUG)
1026 SSLOGERROR(ERRCLS_DEBUG, ESS294, (ErrVal)ret, "Failed to destroy lock");
1031 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1033 while (dQueue->queue[i].head != NULLP)
1035 tBuf = dQueue->queue[i].head;
1036 dQueue->queue[i].head = dQueue->queue[i].head->b_next;
1041 /* ss06.13:addition */
1042 if( ssDestroySema(&dQueue->dmndQSema) != ROK)
1044 SSLOGERROR(ERRCLS_DEBUG, ESS295, ERRZERO,
1045 "Could not delete the Semaphore");
1051 } /* end of ssDestroyDmndQ */
1058 * Desc: This function adds a message to the head or tail of the
1059 * priority queue specified. The priority specified is the
1060 * destination Q index i.e
1061 * ((dst_Tsk_pri * SS_MAX_MSG_PRI) + msg_pri)
1074 SsDmndQ *dQueue, /* demand Queue */
1075 Buffer *mBuf, /* message buffer */
1076 Prior priority, /* priority */
1077 Order order /* position */
1080 S16 ssDmndQPut(dQueue, mBuf, priority, order)
1081 SsDmndQ *dQueue; /* demand Queue */
1082 Buffer *mBuf; /* message buffer */
1083 Prior priority; /* priority */
1084 Order order; /* position */
1087 #ifndef TENB_RTLIN_CHANGES
1088 uint8_t maskIndex; /* mask Index */
1089 uint8_t bitPosition; /* bit position in index */
1093 Queue *queue; /* queue in demand queue */
1094 S16 ret; /* return value */
1099 #ifdef MSPD_MLOG_NEW
1100 uint32_t t = MacGetTick();
1104 #if (ERRCLASS & ERRCLS_INT_PAR)
1105 if (dQueue == NULLP)
1107 SSLOGERROR(ERRCLS_INT_PAR, ESS296, ERRZERO, "NULL DQ Pointer");
1113 SSLOGERROR(ERRCLS_INT_PAR, ESS297, ERRZERO, "NULL mBuf Pointer");
1117 if ((priority == PRIORNC) || (priority > SS_MAX_DQ_PRIOR))
1119 SSLOGERROR(ERRCLS_INT_PAR, ESS298, ERRZERO, "invalid priority ");
1123 if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1125 SSLOGERROR(ERRCLS_INT_PAR, ESS299, ERRZERO, "invalid order ");
1130 #ifndef TENB_RTLIN_CHANGES
1131 maskIndex = priority >> 3;
1132 bitPosition = 7 - (priority % 8);
1133 queue = &dQueue->queue[priority];
1136 queue = &dQueue->queue[qIndex];
1139 /* ss039.103 : Replaced SLock with WTLock */
1141 #ifndef TENB_RTLIN_CHANGES
1142 ret = WTLock(&dQueue->dmndQLock[maskIndex]);
1144 ret = WTLock(&dQueue->dmndQLock[qIndex]);
1147 #ifndef TENB_RTLIN_CHANGES
1148 ret = SLock(&dQueue->dmndQLock[maskIndex]);
1150 ret = SLock(&dQueue->dmndQLock[qIndex]);
1155 #if (ERRCLASS & ERRCLS_DEBUG)
1156 SSLOGERROR(ERRCLS_DEBUG, ESS300, (ErrVal)ret, "Failed to get lock");
1161 if (queue->crntSize == 0)
1165 mBuf->b_next = NULLP;
1166 mBuf->b_prev = NULLP;
1168 #ifndef TENB_RTLIN_CHANGES
1169 /* Set the corresponding bit in bit mask */
1170 dQueue->bitMask[maskIndex] |= (1 << bitPosition);
1175 if (order == SS_DQ_LAST)
1177 mBuf->b_prev = queue->tail;
1178 mBuf->b_next = NULLP;
1179 queue->tail->b_next = mBuf;
1184 mBuf->b_next = queue->head;
1185 mBuf->b_prev = NULLP;
1186 queue->head->b_prev = mBuf;
1192 size = queue->crntSize;
1195 /* ss039.103 : Replaced SUnlock with WTUnlock */
1197 #ifndef TENB_RTLIN_CHANGES
1198 ret = WTUnlock(&dQueue->dmndQLock[maskIndex]);
1200 ret = WTUnlock(&dQueue->dmndQLock[qIndex]);
1203 #ifndef TENB_RTLIN_CHANGES
1204 ret = SUnlock(&dQueue->dmndQLock[maskIndex]);
1206 ret = SUnlock(&dQueue->dmndQLock[qIndex]);
1211 #if (ERRCLASS & ERRCLS_DEBUG)
1212 SSLOGERROR(ERRCLS_DEBUG, ESS301, (ErrVal)ret, "Failed to release lock");
1215 if (order == SS_DQ_LAST)
1217 SDequeueLast(&mBuf, queue);
1221 SDequeueFirst(&mBuf, queue);
1226 /* increment the counting semaphore */
1227 /* ss006.13: addition */
1229 /* 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 */
1233 sem_getvalue(&dQueue->dmndQSema, &value);
1238 if (ssPostSema(&dQueue->dmndQSema) != ROK)
1240 #if (ERRCLASS & ERRCLS_DEBUG)
1241 SSLOGERROR(ERRCLS_DEBUG, ESS302, ERRZERO,
1242 "Could not unlock the Semaphore");
1244 if (order == SS_DQ_LAST)
1246 SDequeueLast(&mBuf, queue);
1250 SDequeueFirst(&mBuf, queue);
1257 } /* End of ssDmndQPut */
1264 * Desc: This function removes a message from head or tail of the
1265 * highest non-empty priority queue message.
1269 * ROKDNA - ok, no data available in queue
1271 * Notes: This is a blocking call
1279 SsDmndQ *dQueue /* demand queue */
1282 S16 ssDmndQWait(dQueue)
1283 SsDmndQ *dQueue; /* demand queue */
1289 #if (ERRCLASS & ERRCLS_INT_PAR)
1290 if (dQueue == NULLP)
1292 SSLOGERROR(ERRCLS_INT_PAR, ESS303, ERRZERO, "NULL DQ Pointer");
1298 /* ss040.103 updating for possible non-fatal retur from sem_wait */
1299 while ((ret = ssWaitSema(&dQueue->dmndQSema) != ROK) && (errno == EINTR))
1303 #if (ERRCLASS & ERRCLS_DEBUG)
1304 SSLOGERROR(ERRCLS_DEBUG, ESS306, (ErrVal)ret, "Failed to get semaphore");
1310 } /* End of ssDmndQWait */
1318 * Desc: This function removes a message from head or tail of the
1319 * highest non-empty priority queue message.
1323 * ROKDNA - ok, no data available in queue
1325 * Notes: This is a blocking call
1333 SsDmndQ *dQueue, /* demand queue */
1334 Buffer **mBuf, /* message buffer */
1335 Order order /* position */
1338 S16 ssDmndQGet(dQueue, mBuf, order)
1339 SsDmndQ *dQueue; /* demand queue */
1340 Buffer **mBuf; /* message buffer */
1341 Order order; /* position */
1347 #ifndef TENB_RTLIN_CHANGES
1348 uint8_t bitPosition;
1353 #if (ERRCLASS & ERRCLS_INT_PAR)
1356 SSLOGERROR(ERRCLS_INT_PAR, ESS304, ERRZERO, "NULL mBuf Pointer");
1360 if ((order != SS_DQ_FIRST) && (order != SS_DQ_LAST))
1362 SSLOGERROR(ERRCLS_INT_PAR, ESS305, ERRZERO, "invalid order ");
1367 #ifndef TENB_RTLIN_CHANGES
1368 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1370 /* ss039.103 : Replaced SLock with WTLock */
1372 ret = WTLock(&dQueue->dmndQLock[i]);
1374 ret = SLock(&dQueue->dmndQLock[i]);
1378 #if (ERRCLASS & ERRCLS_DEBUG)
1379 SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1384 bitPosition = osCp.dmndQLookupTbl[dQueue->bitMask[i]];
1385 if (bitPosition != 255)
1388 /* ss039.103 : Replaced SUnlock with WTUnlock */
1390 ret = WTUnlock(&dQueue->dmndQLock[i]);
1392 ret = SUnlock(&dQueue->dmndQLock[i]);
1396 #if (ERRCLASS & ERRCLS_DEBUG)
1397 SSLOGERROR(ERRCLS_DEBUG, ESS308, ret, "Failed to release lock");
1402 if (i >= SS_DQ_BIT_MASK_LEN)
1404 /* Demand Queue is empty */
1409 qIndex = (i * 8) + (7 - bitPosition);
1410 queue = &dQueue->queue[qIndex];
1413 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1415 queue = &dQueue->queue[i];
1416 if (queue->crntSize)
1420 if (i >= SS_MAX_NUM_DQ)
1422 /* Demand Queue is empty */
1427 /* ss039.103 : Replaced SLock with WTLock */
1429 ret = WTLock(&dQueue->dmndQLock[i]);
1431 ret = SLock(&dQueue->dmndQLock[i]);
1435 #if (ERRCLASS & ERRCLS_DEBUG)
1436 SSLOGERROR(ERRCLS_DEBUG, ESS307, (ErrVal)ret, "Failed to get lock");
1442 /* ss037.103 For performance enhancement replace the check sequence with simple
1443 setting the crntSize to 0 and removing the message */
1445 if (queue->crntSize == 1)
1447 *mBuf = queue->head;
1448 queue->head = NULLP;
1449 queue->tail = NULLP;
1451 /* Reset the corresponding bit in bit mask */
1452 dQueue->bitMask[i] &= (~( 1 << (bitPosition)));
1456 if (order == SS_DQ_FIRST)
1458 *mBuf = queue->head;
1459 queue->head = queue->head->b_next;
1460 queue->head->b_prev = NULLP;
1464 *mBuf = queue->tail;
1465 queue->tail = queue->tail->b_prev;
1466 queue->tail->b_next = NULLP;
1471 queue->crntSize = 0;
1472 *mBuf = queue->head;
1473 queue->head = NULLP;
1474 queue->tail = NULLP;
1478 /* ss039.103 : Replaced SUnlock with WTUnlock */
1480 ret = WTUnlock(&dQueue->dmndQLock[i]);
1482 ret = SUnlock(&dQueue->dmndQLock[i]);
1486 #if (ERRCLASS & ERRCLS_DEBUG)
1487 SSLOGERROR(ERRCLS_DEBUG, ESS309, (ErrVal)ret, "Failed to release lock");
1494 } /* End of ssDmndQGet */
1499 * Fun: ssFndLenDmndQ
1501 * Desc: This function returns the number of messages in a queue
1502 * If priority is specified, length of the associated Q is
1503 * returned otherwise total length of all Qs is returned.
1516 SsDmndQ *dQueue, /* demand queue */
1517 Prior priority, /* priority */
1518 QLen *len /* queue length */
1521 S16 ssFndLenDmndQ(dQueue, priority, len)
1522 SsDmndQ *dQueue; /* demand queue */
1523 Prior priority; /* priority */
1524 QLen *len; /* queue length */
1528 S16 ret; /* return value */
1532 #if (ERRCLASS & ERRCLS_INT_PAR)
1533 if ((dQueue == NULLP) || (len == NULLP))
1535 SSLOGERROR(ERRCLS_INT_PAR, ESS310, ERRZERO, "NULL Pointer");
1541 if (priority != PRIORNC)
1544 /* ss039.103 : Replaced SLock with WTLock */
1546 ret = WTLock(&dQueue->dmndQLock[i]);
1548 ret = SLock(&dQueue->dmndQLock[i]);
1552 #if (ERRCLASS & ERRCLS_DEBUG)
1553 SSLOGERROR(ERRCLS_DEBUG, ESS311, (ErrVal)ret, "Failed to get lock");
1558 *len = dQueue->queue[priority].crntSize;
1560 /* ss039.103 : Replaced SUnlock with WTUnlock */
1562 ret = WTUnlock(&dQueue->dmndQLock[i]);
1564 ret = SUnlock(&dQueue->dmndQLock[i]);
1568 #if (ERRCLASS & ERRCLS_DEBUG)
1569 SSLOGERROR(ERRCLS_DEBUG, ESS312, (ErrVal)ret, \
1570 "Failed to release lock");
1577 #ifndef TENB_RTLIN_CHANGES
1578 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1580 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1583 /* ss039.103 : Replaced SLock with WTLock */
1585 ret = WTLock(&dQueue->dmndQLock[i]);
1587 ret = SLock(&dQueue->dmndQLock[i]);
1591 #if (ERRCLASS & ERRCLS_DEBUG)
1592 SSLOGERROR(ERRCLS_DEBUG, ESS313, (ErrVal)ret, "Failed to get lock");
1594 /* Release all the locks aquired */
1598 /* ss006.13: addition */
1599 /* ss039.103 : Replaced SUnlock with WTUnlock */
1601 if( WTUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1603 if( SUnlock(&dQueue->dmndQLock[i-1]) != ROK)
1606 #if (ERRCLASS & ERRCLS_DEBUG)
1607 SSLOGERROR(ERRCLS_DEBUG, ESS314, ERRZERO,
1608 "Could not give the Semaphore");
1620 for (i = 0; i < SS_MAX_NUM_DQ; i++)
1621 *len += dQueue->queue[i].crntSize;
1623 #ifndef TENB_RTLIN_CHANGES
1624 for (i = 0; i < SS_DQ_BIT_MASK_LEN; i++)
1626 for ( i = 0; i < SS_MAX_NUM_DQ; i++)
1629 /* ss039.103 : Replaced SUnlock with WTUnlock */
1631 ret = WTUnlock(&dQueue->dmndQLock[i]);
1633 ret = SUnlock(&dQueue->dmndQLock[i]);
1637 #if (ERRCLASS & ERRCLS_DEBUG)
1638 SSLOGERROR(ERRCLS_DEBUG, ESS315, (ErrVal)ret, "Failed to get lock");
1646 } /* End of ssFndLenDmndQ */
1648 /**********************************************************************
1650 **********************************************************************/