32 #define UP_MSGS_WHEN_Q_FULL 41 #define CRITICAL_Q_SIZE (1 << 3) 42 #define HIGH_Q_SIZE (1 << 3) 43 #define NORMAL_Q_SIZE (1 << 8) 44 #define LOW_Q_SIZE (1 << 4) 48 #define EXCLUSION_RATIO (35) 64 static void *vq_read_sema = 0;
65 static void *queue_mutex = 0;
67 static U16BIT queue_size[PRTY_INVALID] =
68 { CRITICAL_Q_SIZE, HIGH_Q_SIZE, NORMAL_Q_SIZE, LOW_Q_SIZE };
71 static E_PRIORITY urgent_priority = PRTY_CRITICAL;
74 static int show_yeild_failure = 0;
77 static int put_sema_total = 0;
78 static int get_sema_total = 0;
79 static int put_msg_total[PRTY_INVALID] = {0, 0, 0, 0, 0};
80 static int get_msg_total[PRTY_INVALID] = {0, 0, 0, 0, 0};
81 #if defined(STACK_DEBUGGING) 82 void STB_OSTaskPrint(
void);
100 if (queue_mutex != 0)
102 return MHERR_COMP_ALREADY_OPEN;
107 if (queue_mutex == NULL)
109 TRACE(TERROR, (
"failed to create mutex"));
110 return MHERR_INTERNAL;
113 if (vq_read_sema == NULL)
115 TRACE(TERROR, (
"failed to create semaphore"));
116 return MHERR_INTERNAL;
119 for (i = 0; i != PRTY_INVALID; i++)
122 if (msg_queue[i] == NULL)
126 return MHERR_ALLOCATING_MEMORY;
128 msg_queue[i]->read_q_index = 0;
129 msg_queue[i]->write_q_index = 0;
161 p_queue = msg_queue[i];
162 while (p_queue->read_q_index != p_queue->write_q_index)
164 nx = p_queue->read_q_index;
167 switch (p_elem->data_type)
170 case DT_NONE:
case DT_VALUE:
175 MHEG5freeMem((
void *)p_elem->data.content.data );
179 if (p_elem->data.content.destroy)
181 p_elem->data.content.destroy( p_elem->data.content.fs_handle );
186 if (p_elem->data.content.destroy)
188 p_elem->data.content.destroy( &p_elem->data.content );
193 p_elem->proc_msg_func( &(p_elem->data.content));
197 STR_DataFree( p_elem->data.content.data, p_elem->data.content.size );
201 if (nx == queue_size[i])
205 p_queue->read_q_index = nx;
218 static U16BIT SizeFree( E_PRIORITY priority )
222 assert( priority < PRTY_INVALID );
225 if (msg_queue[priority]->read_q_index > msg_queue[priority]->write_q_index)
227 count = msg_queue[priority]->read_q_index - msg_queue[priority]->write_q_index;
231 count = queue_size[priority] + msg_queue[priority]->read_q_index - msg_queue[priority]->write_q_index;
250 E_MhegErr result = MHERR_OK;
257 assert( priority < PRTY_INVALID );
258 if (queue_mutex == 0)
260 TRACE(TERROR, (
"Queue not open"));
261 result = MHERR_COMP_NOT_OPEN;
265 p_queue = msg_queue[priority];
270 new_ndx = p_queue->write_q_index;
273 if (new_ndx == queue_size[priority])
277 if (new_ndx == p_queue->read_q_index)
281 for (i = 0; i != PRTY_INVALID; i++)
283 p += put_msg_total[i];
284 g += get_msg_total[i];
286 TRACE(TQUEUE, (
"QQQ FULL sema=(%d,%d) qp=(%d,%d) all=(%d,%d) QQQ FULL",
287 put_sema_total, get_sema_total, put_msg_total[priority], get_msg_total[priority], p, g))
289 TRACE(TWARN | TQUEUE, (
"VGR QUEUE(%d) is FULL", priority))
292 show_yeild_failure = 1;
294 result = MHERR_QUEUE_FULL;
298 if (priority == PRTY_CRITICAL)
300 vqn = vq_notify_head;
303 vqn->critical_rcvd_func();
307 else if (priority != PRTY_LOW)
309 if (SizeFree(priority) < (queue_size[priority] >> 2))
311 urgent_priority = priority;
313 vqn = vq_notify_head;
316 vqn->normal_rcvd_func();
321 p_queue->write_q_index = new_ndx;
322 Q_STATS(put_msg_total[priority]++; )
323 Q_STATS(put_sema_total++; )
343 E_MhegErr result = MHERR_INTERNAL;
352 if (put_sema_total == get_sema_total)
363 Q_STATS(get_sema_total++; )
372 if (urgent_priority != PRTY_CRITICAL &&
373 msg_queue[PRTY_CRITICAL]->read_q_index != msg_queue[PRTY_CRITICAL]->write_q_index)
381 for (; i != PRTY_INVALID; i++)
383 p_queue = msg_queue[i];
384 if (p_queue->read_q_index != p_queue->write_q_index)
386 nxt_ndx = p_queue->read_q_index;
390 if (nxt_ndx == queue_size[i])
394 p_queue->read_q_index = nxt_ndx;
398 vqn = vq_notify_head;
401 vqn->critical_done_func();
406 Q_STATS(get_msg_total[i]++; )
410 if (urgent_priority != PRTY_CRITICAL &&
411 SizeFree(urgent_priority) > ((queue_size[urgent_priority] * 3) >> 2))
413 urgent_priority = PRTY_CRITICAL;
418 for (i = 0; i != PRTY_INVALID; i++)
420 p += put_msg_total[i];
421 g += get_msg_total[i];
423 if (put_sema_total - get_sema_total != p - g)
425 TRACE(TQUEUE, (
"QQQ sema=(%d,%d) all=(%d,%d) QQQ", put_sema_total, get_sema_total, p, g))
438 assert( priority < PRTY_INVALID );
439 if (queue_mutex == 0)
446 count = SizeFree(priority);
460 BOOLEAN needed = FALSE;
462 if (queue_mutex != NULL)
465 if (msg_queue[PRTY_CRITICAL]->read_q_index != msg_queue[PRTY_CRITICAL]->write_q_index)
468 TRACE(TQUEUE, (
"Critical MESSAGE"))
473 for (priority = PRTY_NORMAL; priority != PRTY_INVALID; priority++)
477 if (SizeFree(priority) < (queue_size[priority] >> 2))
479 urgent_priority = priority;
480 TRACE(TQUEUE, (
"Priority %d low on space", priority))
489 if (!needed && show_yeild_failure)
491 for (priority = PRTY_NORMAL; priority != PRTY_INVALID; priority++)
493 TRACE(TQUEUE, (
"p=%d, fsz=%d qsz=%d", priority, SizeFree(priority), queue_size[priority] >> 2));
495 show_yeild_failure = 0;
516 vqn->critical_rcvd_func = critical_rcvd;
517 vqn->normal_rcvd_func = normal_rcvd;
518 vqn->critical_done_func = critical_done;
519 vqn->next = vq_notify_head;
520 vq_notify_head = vqn;
534 ppvqn = &vq_notify_head;
539 *ppvqn = (*ppvqn)->next;
543 ppvqn = &((*ppvqn)->next);
U32BIT STB_OSGetClockMilliseconds(void)
Get Current Computer Clock Time.
void STB_OSSemaphoreWait(void *semaphore)
Wait on Semaphore Indefinity or Until Released.
void VQ_Close(void)
Close component control and section queue component. Destroys all allocated memory and resources for ...
U16BIT VQ_GetSizeFree(E_PRIORITY priority)
Get size available on a queue.
E_MhegErr VQ_GetMsg(S_MhegMessage *pMsg)
Get an event or section from the component queues. This is a blocking function.
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
void(* F_QueueNotify)(void)
E_MhegErr VQ_Open(S_MhegConfig *cfg_params)
Initialise component control and section queues. Allocates memory for, sets up and creates event (com...
BOOLEAN VQ_EventNeedsProcessing(void)
Check whether any events on component queues needs processing.
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
void * STB_OSCreateMutex(void)
Create a mutex.
void VQ_UnRegisterNotify(void *qn)
System Wide Global Technical Data Type Definitions.
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post an event or section into component queues. Copies data into queue.
void * VQ_RegisterNotify(F_QueueNotify normal_rcvd, F_QueueNotify critical_rcvd, F_QueueNotify critical_done)
void * STB_OSCreateCountSemaphore(U32BIT value)
Create a counting semaphore.
void STB_OSDeleteSemaphore(void *semaphore)
Delete a Semaphore.
void STB_OSSemaphoreSignal(void *semaphore)
Signal a Semaphore to Release it by decrementing its counter.
Header file - Function prototypes for operating system.