📄 em.c
字号:
/* */
/************************************************************************/
void EM_Remove_From_List(struct EM_SUSPENSION_STRUCT **ptr_head_ptr,
struct EM_SUSPENSION_STRUCT **ptr_tail_ptr,
struct EM_SUSPENSION_STRUCT *suspend_ptr)
{
/* Determine if this suspension block is still linked in. */
if ((suspend_ptr -> em_prev_susp != NU_NULL) ||
(suspend_ptr -> em_next_susp != NU_NULL) ||
(suspend_ptr == *ptr_head_ptr))
{
/* Check the previous pointers. */
if (suspend_ptr -> em_prev_susp != NU_NULL)
{
/* Link the previous suspension block to the next. */
(suspend_ptr -> em_prev_susp) -> em_next_susp =
suspend_ptr -> em_next_susp;
}
else
{
/* We are deleting the head node, adjust the head pointer. */
*ptr_head_ptr = suspend_ptr -> em_next_susp;
/* Adjust the head of the list. */
if (*ptr_head_ptr != NU_NULL)
(*ptr_head_ptr) -> em_prev_susp = NU_NULL;
}
/* Check the next pointers. */
if (suspend_ptr -> em_next_susp != NU_NULL)
{
/* Link the next suspension block to the previous. */
(suspend_ptr -> em_next_susp) -> em_prev_susp =
suspend_ptr -> em_prev_susp;
}
else
{
/* We are deleting the tail node, adjust the tail pointer. */
*ptr_tail_ptr = suspend_ptr -> em_prev_susp;
/* Adjust the tail of the list. */
if (*ptr_tail_ptr != NU_NULL)
(*ptr_tail_ptr) -> em_next_susp = NU_NULL;
}
/* Reset the pointers of the removed suspension block. */
suspend_ptr -> em_next_susp = NU_NULL;
suspend_ptr -> em_prev_susp = NU_NULL;
}
} /* end EM_Remove_From_List */
/************************************************************************/
/* */
/* FUNCTION "EM_Set_Events" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function sets event flags of the specified event group */
/* and checks to see if there are any suspended tasks that are */
/* now able to proceceed. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Service routines that set event flags */
/* */
/* ROUTINES CALLED */
/* */
/* EM_Remove_From_List Lift task suspension */
/* SKP_Ready_Task Place the task on ready lst */
/* SKD_Leave_Task Leave the task if necessary */
/* */
/* INPUTS */
/* */
/* event_group_id Event group identification */
/* event_operation How to apply the events */
/* event_flags New event flags */
/* */
/* OUTPUTS */
/* */
/* return(status) */
/* */
/************************************************************************/
signed int EM_Set_Events(signed int event_group_id,
signed int event_operation, unsigned int event_flags)
{
struct EM_EVENT_CONTROL_STRUCT
*ECB_ptr; /* Pointer to ECB entry */
struct EM_SUSPENSION_STRUCT
*suspend_ptr; /* Suspension pointer */
unsigned int compare; /* Event compare field */
unsigned int consume; /* Event consume bits */
unsigned int lift; /* Lift suspension flag */
signed int context_switch = 0; /* Context switch counter */
/* Point to the event group control block. */
ECB_ptr = &EM_ECB_List[event_group_id];
/* Initialize the events to consume to 0. */
consume = 0;
/* Apply the new event flags to this group. */
if (event_operation == NU_EVENT_AND)
/* And the new events with the current groups events. */
ECB_ptr -> em_event_flags = ECB_ptr -> em_event_flags & event_flags;
else
/* Or the new events with the current group events. */
ECB_ptr -> em_event_flags = ECB_ptr -> em_event_flags | event_flags;
/* Walk through the list of suspended tasks to see if any can be
resumed. */
suspend_ptr = ECB_ptr -> em_wait_head;
while (suspend_ptr != NU_NULL)
{
/* Initialize the lift suspension flag to false. */
lift = NU_FALSE;
/* Determine if the suspened task can be resumed, i.e. see if the
appropriate events have taken place. */
if ((suspend_ptr -> em_operation == NU_EVENT_AND) ||
(suspend_ptr -> em_operation == NU_EVENT_AND_CONSUME))
{
/* Need all of the bits in the request set in the event group
to lift suspension. */
compare = ECB_ptr -> em_event_flags & suspend_ptr -> em_flags;
/* If compare is equal to the value suspended on, lift the
suspension. */
if (compare == suspend_ptr -> em_flags)
{
/* Set lift suspension flag. */
lift = NU_TRUE;
/* Determine if the original request specified a consume. */
if (suspend_ptr -> em_operation == NU_EVENT_AND_CONSUME)
/* Or in the events of this request into the consume
accumulator. */
consume = consume | suspend_ptr -> em_flags;
}
}
else
{
/* Need just one of the bits in the request to lift suspension. */
compare = ECB_ptr -> em_event_flags & suspend_ptr -> em_flags;
/* If compare has any bits set, at least one of the bits in the
request has been set. */
if (compare)
{
/* Set lift suspension flag. */
lift = NU_TRUE;
/* Determine if the original request specified a consume. */
if (suspend_ptr -> em_operation == NU_EVENT_OR_CONSUME)
/* Or in the events of this request into the consume
accumulator. */
consume = consume | suspend_ptr -> em_flags;
}
}
/* Lift the suspension, if necessary. */
if (lift)
{
/* Put the contents of the event flag group in the designated
place. */
*(suspend_ptr -> em_flags_value) = ECB_ptr -> em_event_flags;
/* Show that the request completed successfully. */
*(suspend_ptr -> em_return_addr) = NU_SUCCESS;
/* Lift the suspension on the task that was waiting
for the resource. At the end of this loop the context
switch variable is greater than 0 if a context switch is
called for. */
context_switch = context_switch +
SKP_Ready_Task(suspend_ptr -> em_task_id);
/* Remove the suspend pointer from the suspend list. */
EM_Remove_From_List(&(EM_ECB_List[event_group_id].em_wait_head),
&(EM_ECB_List[event_group_id].em_wait_tail),
suspend_ptr);
/* Point to the next suspension block. This was updated by the
previous call. */
suspend_ptr = ECB_ptr -> em_wait_head;
}
else
/* Just get the next suspension pointer. */
suspend_ptr = suspend_ptr -> em_next_susp;
}
/* Apply the consume bits into the event flag. */
ECB_ptr -> em_event_flags = ECB_ptr -> em_event_flags & ~consume;
/* Determine if a context switch is required. */
if (context_switch)
{
/* Leave this task temporarily. */
SKD_Leave_Task();
}
/* Return the status to the caller. */
return(NU_SUCCESS);
} /* end of EM_Set_Events */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -