📄 qus.c
字号:
/* Determine if the read pointer is at the top of the queue
area. */
if (destination == queue -> qu_start)
/* Prepare to place the message in the lower part
of the queue area. */
destination = queue -> qu_end - size;
else
/* Backup the length of a message from the current
read pointer. */
destination = destination - size;
/* Adjust the actual read pointer before the copy is done. */
queue -> qu_read = destination;
/* Copy the message into the queue area. */
i = (INT) size;
do
{
*(destination++) = *(source);
if ((--i) == 0)
break;
source++;
} while (1);
}
else
{
/* Variable-size message queue. */
/* Calculate the number of words remaining at the top of the
queue. */
copy_size = destination - queue -> qu_start;
/* Determine if part of the message needs to be placed at the
bottom of the queue area. */
if (copy_size < (size + i))
/* Compute the starting location for the message. */
destination = queue -> qu_end - ((size +i) - copy_size);
else
/* Compute the starting location for the message. */
destination = destination - (size + i);
/* Adjust the actual queue read pointer also. */
queue -> qu_read = destination;
/* Place message size in first location. */
*(destination++) = size;
/* Check for a wrap-around condition on the queue. */
if (destination >= queue -> qu_end)
/* Wrap the write pointer back to the top of the queue
area. */
destination = queue -> qu_start;
/* Decrement the number of words remaining by 1 for this
extra word of overhead. */
queue -> qu_available--;
/* Calculate the number of words remaining from the
destination pointer to the bottom of the queue. */
copy_size = queue -> qu_end - destination;
/* Determine if the message needs to be wrapped around the
edge of the queue area. */
if (copy_size >= size)
{
/* Copy the whole message at once. */
i = (INT) size;
do
{
*(destination++) = *(source);
if ((--i) == 0)
break;
source++;
} while (1);
}
else
{
/* Copy the first half of the message. */
i = (INT) copy_size;
do
{
*(destination) = *(source++);
if ((--i) == 0)
break;
destination++;
} while (1);
/* Copy the second half of the message. */
destination = queue -> qu_start;
i = (INT) (size - copy_size);
do
{
*(destination++) = *(source);
if ((--i) == 0)
break;
source++;
} while (1);
}
}
/* Decrement the number of available words. */
queue -> qu_available = queue -> qu_available - size;
/* Increment the number of messages in the queue. */
queue -> qu_messages++;
}
}
/* Release protection against access to the queue. */
TCT_Unprotect();
/* Return the completion status. */
return(status);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* QUS_Broadcast_To_Queue */
/* */
/* DESCRIPTION */
/* */
/* This function sends a message to all tasks waiting for a message */
/* from the specified queue. If there are no tasks waiting for a */
/* message the service performs like a standard send request. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* Application */
/* QUSE_Broadcast_To_Queue Error checking shell */
/* */
/* CALLS */
/* */
/* CSC_Place_On_List Place on suspend list */
/* CSC_Priority_Place_On_List Place on priority list */
/* CSC_Remove_From_List Remove from suspend list */
/* [HIC_Make_History_Entry] Make entry in history log */
/* TCC_Resume_Task Resume a suspended task */
/* TCC_Suspend_Task Suspend calling task */
/* TCC_Task_Priority Pickup task's priority */
/* [TCT_Check_Stack] Stack checking function */
/* TCT_Control_To_System Transfer control to system */
/* TCT_Current_Thread Pickup current thread pointer*/
/* TCT_System_Protect Protect queue */
/* TCT_Unprotect Release protection */
/* */
/* INPUTS */
/* */
/* queue_ptr Queue control block pointer */
/* message Pointer to message to send */
/* size Size of message to send */
/* suspend Suspension option if full */
/* */
/* OUTPUTS */
/* */
/* NU_SUCCESS If service is successful */
/* NU_QUEUE_FULL If queue is currently full */
/* NU_TIMEOUT If timeout on service expires*/
/* NU_QUEUE_DELETED If queue was deleted during */
/* suspension */
/* NU_QUEUE_RESET If queue was reset during */
/* suspension */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* W. Lamie 03-01-1993 Created initial version 1.0 */
/* D. Lamie 04-19-1993 Verified version 1.0 */
/* W. Lamie 03-01-1994 Changed function interfaces to */
/* match those in prototype, */
/* added register options, changed*/
/* protection logic to reduce */
/* overhead, optimized copy loop, */
/* resulting in version 1.1 */
/* R. Pfaff - */
/* D. Lamie 03-18-1994 Verified version 1.1 */
/* */
/*************************************************************************/
STATUS QUS_Broadcast_To_Queue(NU_QUEUE *queue_ptr, VOID *message,
UNSIGNED size, UNSIGNED suspend)
{
R1 QU_QCB *queue; /* Queue control block ptr */
QU_SUSPEND suspend_block; /* Allocate suspension block */
QU_SUSPEND *suspend_ptr; /* Pointer to suspend block */
R3 UNSIGNED_PTR source; /* Pointer to source */
R4 UNSIGNED_PTR destination; /* Pointer to destination */
UNSIGNED copy_size; /* Partial copy size */
R2 INT i; /* Working counter */
TC_TCB *task; /* Task pointer */
STATUS preempt; /* Preempt flag */
STATUS status; /* Completion status */
/* Move input queue pointer into internal pointer. */
queue = (QU_QCB *) queue_ptr;
#ifdef NU_ENABLE_STACK_CHECK
/* Call stack checking function to check for an overflow condition. */
TCT_Check_Stack();
#endif
#ifdef NU_ENABLE_HISTORY
/* Make an entry that corresponds to this function in the system history
log. */
HIC_Make_History_Entry(NU_BROADCAST_TO_QUEUE_ID, (UNSIGNED) queue,
(UNSIGNED) message, (UNSIGNED) size);
#endif
/* Initialize the status as successful. */
status = NU_SUCCESS;
/* Protect against simultaneous access to the queue. */
TCT_System_Protect();
/* Determine if an extra word of overhead needs to be added to the
calculation. */
if (queue -> qu_fixed_size)
/* No overhead. */
i = 0;
else
{
/* Variable messages have one additional word of overhead. */
i = 1;
/* Make special check to see if a suspension needs to be
forced for a variable length message. */
if ((queue -> qu_suspension_list) && (queue -> qu_messages))
{
/* Pickup task control block pointer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -