在Nucleus的等待事件函数EVC_Retrieve_Events中有这么一段函数
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
..........
我们看到当task因为该事件而阻塞的代码
/* 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);
执行后紧接着的就是将等待事件的状态和接受到消息的变量进行了赋值,这是为什么呢,这样正确吗?
原来是这样的。当TCC_Suspend_Task被调用后当前task被挂起,这个函数以后的代码已经不会再接着执行了。等到这个task恢复时说明这个事件已经等到了,这个事件的值是在EVC_Set_Events函数中被设置的。
if (compare)
{
/* Decrement the number of tasks waiting counter. */
event_group -> ev_tasks_waiting--;
/* Determine if consumption is requested. */
if (suspend_ptr -> ev_operation & EV_CONSUME)
/* Keep track of the event flags to consume. */
consume = consume | suspend_ptr -> ev_requested_events;
/* Remove the first suspended block from the list. */
CSC_Remove_From_List((CS_NODE **)
&(event_group -> ev_suspension_list),
&(suspend_ptr -> ev_suspend_link));
/* Setup the appropriate return value. */
suspend_ptr -> ev_return_status = NU_SUCCESS;
suspend_ptr -> ev_actual_events =
event_group -> ev_current_events;
/* Resume the suspended task. */
preempt = preempt |
TCC_Resume_Task((NU_TASK *) suspend_ptr -> ev_suspended_task,
NU_EVENT_SUSPEND);
}
可以看到设置的返回值就是EVC_Retrieve_Events函数中的返回值。