📄 evc.c
字号:
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 to user mode */ NU_USER_MODE(); /* 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. *//* *//* 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 *//* *//* DATE REMARKS *//* *//* 03-01-1993 Created initial version 1.0 *//* 04-19-1993 Verified version 1.0 *//* 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 *//* *//* 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 */NU_SUPERV_USER_VARIABLES /* Switch to supervisor mode */ NU_SUPERVISOR_MODE(); /* 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;#ifdef INCLUDE_PROVIEW _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group, RT_PROF_OK);#endif /*INCLUDE_PROVIEW*/ } else { /* Determine if the task requested suspension. */ if (suspend) { /* Suspension is selected. */ /* Increment the number of tasks waiting. */ event_group -> ev_tasks_waiting++;#ifdef INCLUDE_PROVIEW _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group, RT_PROF_WAIT);#endif /*INCLUDE_PROVIEW*/ /* 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;#ifdef INCLUDE_PROVIEW _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group,RT_PROF_FAIL);#endif /*INCLUDE_PROVIEW*/ } } /* Release protection of the event_group. */ TCT_Unprotect(); /* Return to user mode */ NU_USER_MODE(); /* 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. This routine *//* must be called from Supervisor mode in Supervisor/User mode *//* switching kernels. *//* *//* 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 *//* *//* DATE REMARKS *//* *//* 03-01-1993 Created initial version 1.0 *//* 04-19-1993 Verified version 1.0 *//* *//*************************************************************************/VOID EVC_Cleanup(VOID *information){EV_SUSPEND *suspend_ptr; /* Suspension block pointer */NU_SUPERV_USER_VARIABLES /* Switch to supervisor mode */ NU_SUPERVISOR_MODE(); /* 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)); /* Return to user mode */ NU_USER_MODE();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -