📄 evc.c
字号:
/* End of the list has been reached. Set the suspend pointer
to NULL to end the search. */
suspend_ptr = NU_NULL;
} while (suspend_ptr);
/* Apply all of the gathered consumption bits. */
event_group -> ev_current_events =
event_group -> ev_current_events & ~consume;
/* Determine if a preempt condition is present. */
if (preempt)
/* Transfer control to the system if the resumed task function
detects a preemption condition. */
TCT_Control_To_System();
}
/* Release protection of the event_group. */
TCT_Unprotect();
/* Return a successful status. */
return(NU_SUCCESS);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* EVC_Retrieve_Events */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves various combinations of event flags from */
/* the specified event group. If the group does not contain the */
/* necessary flags, suspension of the calling task is possible. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* Application */
/* EVCE_Retrieve_Events Error checking shell */
/* */
/* CALLS */
/* */
/* CSC_Place_On_List Place on suspend list */
/* [HIC_Make_History_Entry] Make entry in history log */
/* TCC_Suspend_Task Suspend calling task */
/* [TCT_Check_Stack] Stack checking function */
/* TCT_Current_Thread Pickup current thread pointer*/
/* TCT_System_Protect Protect event group */
/* TCT_Unprotect Release protection */
/* */
/* INPUTS */
/* */
/* event_group_ptr Event Group control block ptr*/
/* requested_events Requested event flags */
/* operation AND/OR selection of flags */
/* retrieved_events Pointer to destination for */
/* actual flags retrieved */
/* suspend Suspension option */
/* */
/* OUTPUTS */
/* */
/* NU_SUCCESS If successful completion */
/* NU_TIMEOUT If timeout on suspension */
/* NU_NOT_PRESENT If event flags are not */
/* present */
/* */
/* 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, resulting in */
/* version 1.1 */
/* R. Pfaff - */
/* D. Lamie 03-18-1994 Verified version 1.1 */
/* */
/*************************************************************************/
STATUS EVC_Retrieve_Events(NU_EVENT_GROUP *event_group_ptr,
UNSIGNED requested_events, OPTION operation,
UNSIGNED *retrieved_events, UNSIGNED suspend)
{
R1 EV_GCB *event_group; /* Event control block ptr */
R2 EV_SUSPEND *suspend_ptr; /* Pointer to suspend block */
EV_SUSPEND suspend_block; /* Suspension block */
R3 UNSIGNED compare; /* Event comparison variable */
TC_TCB *task; /* Pointer to task */
STATUS status; /* Completion status */
/* Move input event group pointer into internal pointer. */
event_group = (EV_GCB *) event_group_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_RETRIEVE_EVENTS_ID, (UNSIGNED) event_group,
(UNSIGNED) requested_events, (UNSIGNED) operation);
#endif
/* Initialize the status as successful. */
status = NU_SUCCESS;
/* Protect against simultaneous access to the event group. */
TCT_System_Protect();
/* Determine if the events requested are present. */
/* Isolate common event flags. */
compare = event_group -> ev_current_events & requested_events;
/* Determine if all of the events must be present. */
if (operation & EV_AND)
/* Yes, all events must be present. See if the compare value is
the same as the requested value. */
compare = (compare == requested_events);
/* Determine if the requested combination of event flags are present. */
if (compare)
{
/* Yes, necessary event flags are present. */
/* Copy the current event flags into the appropriate destination. */
*retrieved_events = event_group -> ev_current_events;
/* Determine if consumption is required. If so, consume the event
flags present in the group. */
if (operation & EV_CONSUME)
event_group -> ev_current_events =
event_group -> ev_current_events & ~requested_events;
}
else
{
/* Determine if the task requested suspension. */
if (suspend)
{
/* Suspension is selected. */
/* Increment the number of tasks waiting. */
event_group -> ev_tasks_waiting++;
/* Setup the suspend block and suspend the calling task. */
suspend_ptr = &suspend_block;
suspend_ptr -> ev_event_group = event_group;
suspend_ptr -> ev_suspend_link.cs_next = NU_NULL;
suspend_ptr -> ev_suspend_link.cs_previous = NU_NULL;
task = (TC_TCB *) TCT_Current_Thread();
suspend_ptr -> ev_suspended_task = task;
suspend_ptr -> ev_requested_events = requested_events;
suspend_ptr -> ev_operation = operation;
/* Link the suspend block into the list of suspended tasks on this
event group. */
CSC_Place_On_List((CS_NODE **)
&(event_group -> ev_suspension_list),
&(suspend_ptr -> ev_suspend_link));
/* Finally, suspend the calling task. Note that the suspension call
automatically clears the protection on the event group. */
TCC_Suspend_Task((NU_TASK *) task, NU_EVENT_SUSPEND,
EVC_Cleanup, suspend_ptr, suspend);
/* Pickup the return status and the actual retrieved events. */
status = suspend_ptr -> ev_return_status;
*retrieved_events = suspend_ptr -> ev_actual_events;
}
else
{
/* No suspension requested. Simply return an error status
and zero the retrieved events variable. */
status = NU_NOT_PRESENT;
*retrieved_events = 0;
}
}
/* Release protection of the event_group. */
TCT_Unprotect();
/* Return the completion status. */
return(status);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* EVC_Cleanup */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for removing a suspension block */
/* from a event group. It is not called unless a timeout or a task */
/* terminate is in progress. Note that protection is already in */
/* effect - the same protection at suspension time. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* TCC_Timeout Task timeout */
/* TCC_Terminate Task terminate */
/* */
/* CALLS */
/* */
/* CSC_Remove_From_List Remove suspend block from */
/* the suspension list */
/* */
/* INPUTS */
/* */
/* information Pointer to suspend block */
/* */
/* OUTPUTS */
/* */
/* None */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* W. Lamie 03-01-1993 Created initial version 1.0 */
/* D. Lamie 04-19-1993 Verified version 1.0 */
/* */
/*************************************************************************/
VOID EVC_Cleanup(VOID *information)
{
EV_SUSPEND *suspend_ptr; /* Suspension block pointer */
/* Use the information pointer as a suspend pointer. */
suspend_ptr = (EV_SUSPEND *) information;
/* By default, indicate that the service timed-out. It really does not
matter if this function is called from a terminate request since
the task does not resume. */
suspend_ptr -> ev_return_status = NU_TIMEOUT;
/* Decrement the number of tasks waiting counter. */
(suspend_ptr -> ev_event_group) -> ev_tasks_waiting--;
/* Unlink the suspend block from the suspension list. */
CSC_Remove_From_List((CS_NODE **)
&((suspend_ptr -> ev_event_group) -> ev_suspension_list),
&(suspend_ptr -> ev_suspend_link));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -