📄 eventlib.c
字号:
/* windview - level 2 event logging */ EVT_TASK_0(EVENT_OBJ_EVENTRECEIVE);#endif /* WV_INSTRUMENTATION */ windPendQPut (&vxEventPendQ, timeout); if ((status = windExit()) == RESTART) { timeout = SIG_TIMEOUT_RECALC(timeout); goto again; } else if (status == ERROR) { if (taskIdCurrent->errorStatus == S_objLib_OBJ_TIMEOUT) { taskIdCurrent->events.sysflags &= ~EVENTS_SYSFLAGS_WAITING; /* * errno will be set to S_objLib_OBJ_TIMEOUT in windTickAnnounce() * but events are not an object so change it to eventLib's timeout */ errnoSet (S_eventLib_TIMEOUT); } } /* * fill return variable with events received only if the user provided * a valid container */ level = intLock (); if (pEventsReceived != NULL) { if (options & EVENTS_RETURN_ALL) *pEventsReceived = taskIdCurrent->events.received; else *pEventsReceived = events & taskIdCurrent->events.received; } /* task has finished receiving events: clear events */ taskIdCurrent->events.received = 0x0; intUnlock (level); return (status); }/********************************************************************************* eventSend - Send event(s)** Sends specified event(s) to specified task. Passing a taskId of NULL sends * events to the calling task.** RETURNS:* OK on success or ERROR.** ERRNO* .iP "S_objLib_OBJ_ID_ERROR"* Task ID is invalid.* .iP "S_eventLib_NULL_TASKID_AT_INT_LEVEL"* Routine was called from ISR with a taskId of NULL.** SEE ALSO: eventReceive()*/STATUS eventSend ( int taskId, /* task events will be sent to */ UINT32 events /* events to send */ ) { WIND_TCB *pTcb; UINT8 options; UINT32 wanted; UINT32 received; int level; if ((INT_CONTEXT()) && (taskId == (int)NULL)) { errnoSet (S_eventLib_NULL_TASKID_AT_INT_LEVEL); return (ERROR); } pTcb = (taskId == (int)NULL) ? taskIdCurrent : (WIND_TCB*)taskId; level = intLock (); if (TASK_ID_VERIFY (pTcb) != OK) { intUnlock (level); return (ERROR); /* errno is set by TASK_ID_VERIFY */ }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_EVENT(EVENT_EVENTSEND, 2, taskId, events, 0);#endif /* WV_INSTRUMENTATION */ pTcb->events.received |= events; /* if task is not waiting for events, work is done */ if (!(pTcb->events.sysflags & EVENTS_SYSFLAGS_WAITING)) { intUnlock (level); return (OK); } /* helps readability of code */ received = pTcb->events.received; wanted = pTcb->events.wanted; options = pTcb->events.options; /* * look for one of two scenarios: * (1) all events wanted have been received; or * (2) some events received and waiting for any of them. */ if (((wanted & received) == wanted) || (((options & EVENTS_WAIT_MASK) == EVENTS_WAIT_ANY) && ((wanted & received) != 0x0))) { /* received correct events: task is not waiting anymore... */ pTcb->events.sysflags &= ~EVENTS_SYSFLAGS_WAITING; /* ...then put it back on the ready queue */ if (kernelState) { intUnlock (level); workQAdd1 ((FUNCPTR)eventPendQRemove, (int)pTcb); return (OK); } kernelState = TRUE; intUnlock (level); windPendQRemove (pTcb);#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_0(EVENT_OBJ_EVENTSEND);#endif /* WV_INSTRUMENTATION */ windReadyQPut (pTcb); windExit (); return (OK); } /* task is still waiting but everything went fine */ intUnlock (level); return (OK); }/********************************************************************************* eventPendQRemove - remove task from the pend Q and put it on ready Q** Deferred removal from vxEventPendQ. Only executed as draining of the work Q.** NOMANUAL*/LOCAL void eventPendQRemove ( WIND_TCB * pTcb ) { windPendQRemove (pTcb);#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_0(EVENT_OBJ_EVENTSEND);#endif /* WV_INSTRUMENTATION */ windReadyQPut (pTcb); }/********************************************************************************* eventRsrcSend - Send event(s) from a resource** Sends specified event(s) to specified task.** WARNING: Routine must be called with kernelState == TRUE.** RETURNS:* OK on success or ERROR.** ERRNO* .iP "S_objLib_OBJ_ID_ERROR"* Task ID is invalid.** NOMANUAL*/STATUS eventRsrcSend ( int taskId, /* task events will be sent to */ UINT32 events /* events to send */ ) { WIND_TCB *pTcb; UINT8 options; UINT32 wanted; UINT32 received; int level; pTcb = (WIND_TCB*)taskId; level = intLock (); if (TASK_ID_VERIFY (pTcb) != OK) { intUnlock (level); return (ERROR); /* errno is set by TASK_ID_VERIFY */ }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_EVENT(EVENT_EVENTSEND, 2, taskId, events, 0);#endif /* WV_INSTRUMENTATION */ pTcb->events.received |= events; /* if task is not waiting for events, work is done */ if ((pTcb->events.sysflags & EVENTS_SYSFLAGS_WAITING) == 0x0) { intUnlock (level); return (OK); } /* helps readability of code */ received = pTcb->events.received; wanted = pTcb->events.wanted; options = pTcb->events.options; /* * look for one of two scenarios: * (1) all events wanted have been received; or * (2) some events received and waiting for any of them. */ if (((wanted & received) == wanted) || (((options & EVENTS_WAIT_MASK) == EVENTS_WAIT_ANY) && ((wanted & received) != 0x0))) { /* received correct events: task is not waiting anymore... */ pTcb->events.sysflags &= ~EVENTS_SYSFLAGS_WAITING; /* ...then put it back on the ready queue */ intUnlock (level); windPendQRemove (pTcb);#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_0(EVENT_OBJ_EVENTSEND);#endif /* WV_INSTRUMENTATION */ windReadyQPut (pTcb); return (OK); } /* task is still waiting but everything went fine */ intUnlock (level); return (OK); }/********************************************************************************* eventClear - Clear all events for current task.** This function clears all received events for the calling task.** RETURNS: OK on success or ERROR.** ERRNO* .iP "S_intLib_NOT_ISR_CALLABLE"* Routine has been called from interrupt level.** SEE ALSO: */STATUS eventClear ( void ) { if (INT_RESTRICT () != OK) return (ERROR); /* errno set by INT_RESTRICT() */ /* if task is currently receiving events, abort */ taskIdCurrent->events.received = 0x0; return (OK); }/********************************************************************************* eventStart - Common code for resource registration** NOTE: Routine must be called with TASK_LOCK() already done. This function is* responsible for doing the TASK_UNLOCK().** RETURNS: OK on success or ERROR.** ERRNO* .iP "S_eventLib_ALREADY_REGISTERED"* A task is already registered.* .iP "S_eventLib_EVENTSEND_FAILED"* A bad taskId was passed to eventSend().** NOMANUAL*/STATUS eventStart ( OBJ_ID objId, /* resource on which to register events */ EVENTS_RSRC * pRsrc,/* ptr to resource control block */ FUNCPTR isRsrcFree, /* ptr to fcn determining if rsrc is free*/ UINT32 events, /* 32 possible events to register */ UINT8 options /* event-related resource options */ ) { int level; /* interrupt lock level */ /* * Refuse to register if another task has already done so, but only if * the EVENTS_ALLOW_OVERWRITE option is not in use AND if the task trying * to do the registration is not the one currently registered. */ if ((pRsrc->options & EVENTS_ALLOW_OVERWRITE) != EVENTS_ALLOW_OVERWRITE) { if ((pRsrc->taskId!=(int)NULL) && (pRsrc->taskId != (int)taskIdCurrent)) { TASK_UNLOCK (); errnoSet (S_eventLib_ALREADY_REGISTERED); return (ERROR); } } /* check if user wants to send events */ level = intLock (); if ((options & EVENTS_SEND_IF_FREE) == EVENTS_SEND_IF_FREE) { /* find out if resource is free */ if (isRsrcFree (objId)) { intUnlock (level); /* only register if user didn't choose one shot */ if ((options & EVENTS_SEND_ONCE) != EVENTS_SEND_ONCE) { pRsrc->registered = events; pRsrc->options = options; pRsrc->taskId = (int)taskIdCurrent; } else pRsrc->taskId = (int) NULL; TASK_UNLOCK (); if (eventSend ((int)taskIdCurrent, events) != OK) { errnoSet (S_eventLib_EVENTSEND_FAILED); return (ERROR); } else return (OK); } } /* * resource not free or user chose not to send events right away: * register needed info */ pRsrc->registered = events; pRsrc->options = options; pRsrc->taskId = (int)taskIdCurrent; intUnlock (level); TASK_UNLOCK (); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -