📄 event.c
字号:
* * Waits for one or more events on the specified event group, either * in conjunctive or disjunctive mode. * If the specified set of bits is not set, the calling task is * blocked. The task is not resumed until the request is fulfilled. * The event bits are NOT cleared from the event group when a request * is satisfied; rt_event_wait() will return immediately with success * for the same event mask until rt_event_clear() is called to clear * those bits. * * @param event The descriptor address of the affected event group. * * @param mask The set of bits to wait for. Passing zero causes this * service to return immediately with a success value; the current * value of the event mask is also copied to @a mask_r. * * @param mask_r The value of the event mask at the time the task was * readied. * * @param mode The pend mode. The following flags can be OR'ed into * this bitmask, each of them affecting the operation: * * - EV_ANY makes the task pend in disjunctive mode (i.e. OR); this * means that the request is fulfilled when at least one bit set into * @a mask is set in the current event mask. * * - EV_ALL makes the task pend in conjunctive mode (i.e. AND); this * means that the request is fulfilled when at all bits set into @a * mask are set in the current event mask. * * @param timeout The number of clock ticks to wait for fulfilling the * request (see note). Passing TM_INFINITE causes the caller to block * indefinitely until the request is fulfilled. Passing TM_NONBLOCK * causes the service to return immediately without waiting if the * request cannot be satisfied immediately. * * @return 0 is returned upon success. Otherwise: * * - -EINVAL is returned if @a event is not a event group descriptor. * * - -EIDRM is returned if @a event is a deleted event group * descriptor, including if the deletion occurred while the caller was * sleeping on it before the request has been satisfied. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and the current event mask value does not satisfy the request. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before the request has been satisfied. * * - -ETIMEDOUT is returned if the request has not been satisfied * within the specified amount of time. * * - -EPERM is returned if this service should block, but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code or Interrupt service * routine only if @a timeout is equal to TM_NONBLOCK. * - Kernel-based task * - User-space task (switches to primary mode) * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. */int rt_event_wait (RT_EVENT *event, unsigned long mask, unsigned long *mask_r, int mode, RTIME timeout){ RT_TASK *task; int err = 0; spl_t s; xnlock_get_irqsave(&nklock,s); event = xeno_h2obj_validate(event,XENO_EVENT_MAGIC,RT_EVENT); if (!event) { err = xeno_handle_error(event,XENO_EVENT_MAGIC,RT_EVENT); goto unlock_and_exit; } if (!mask) { *mask_r = event->value; goto unlock_and_exit; } if (timeout == TM_NONBLOCK) { unsigned long bits = (event->value & mask); *mask_r = bits; if (mode & EV_ANY) { if (!bits) err = -EWOULDBLOCK; } else if (bits != mask) err = -EWOULDBLOCK; goto unlock_and_exit; } if (((mode & EV_ANY) && (mask & event->value) != 0) || (!(mode & EV_ANY) && ((mask & event->value) == mask))) { *mask_r = (event->value & mask); goto unlock_and_exit; } if (xnpod_unblockable_p()) { err = -EPERM; goto unlock_and_exit; } task = xeno_current_task(); task->wait_args.event.mode = mode; task->wait_args.event.mask = mask; xnsynch_sleep_on(&event->synch_base,timeout); /* The returned mask is only significant if the operation has succeeded, but do always write it back anyway. */ *mask_r = task->wait_args.event.mask; if (xnthread_test_flags(&task->thread_base,XNRMID)) err = -EIDRM; /* Event group deleted while pending. */ else if (xnthread_test_flags(&task->thread_base,XNTIMEO)) err = -ETIMEDOUT; /* Timeout.*/ else if (xnthread_test_flags(&task->thread_base,XNBREAK)) err = -EINTR; /* Unblocked.*/ unlock_and_exit: xnlock_put_irqrestore(&nklock,s); return err;}/** * @fn int rt_event_clear(RT_EVENT *event,unsigned long mask,unsigned long *mask_r) * @brief Clear an event group. * * Clears a set of flags from an event mask. * * @param event The descriptor address of the affected event. * * @param mask The set of events to be cleared. * * @param mask_r If non-NULL, @a mask_r is the address of a memory * location which will be written upon success with the previous value * of the event group before the flags are cleared. * * @return 0 is returned upon success. Otherwise: * * - -EINVAL is returned if @a event is not an event group descriptor. * * - -EIDRM is returned if @a event is a deleted event group descriptor. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine * - Kernel-based task * - User-space task * * Rescheduling: never. */int rt_event_clear (RT_EVENT *event, unsigned long mask, unsigned long *mask_r){ int err = 0; spl_t s; xnlock_get_irqsave(&nklock,s); event = xeno_h2obj_validate(event,XENO_EVENT_MAGIC,RT_EVENT); if (!event) { err = xeno_handle_error(event,XENO_EVENT_MAGIC,RT_EVENT); goto unlock_and_exit; } if (mask_r) *mask_r = event->value; /* Clear the flags. */ event->value &= ~mask; unlock_and_exit: xnlock_put_irqrestore(&nklock,s); return err;}/** * @fn int rt_event_inquire(RT_EVENT *event, RT_EVENT_INFO *info) * @brief Inquire about an event group. * * Return various information about the status of a specified * event group. * * @param event The descriptor address of the inquired event group. * * @param info The address of a structure the event group information * will be written to. * @return 0 is returned and status information is written to the * structure pointed at by @a info upon success. Otherwise: * * - -EINVAL is returned if @a event is not a event group descriptor. * * - -EIDRM is returned if @a event is a deleted event group * descriptor. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine * - Kernel-based task * - User-space task * * Rescheduling: never. */int rt_event_inquire (RT_EVENT *event, RT_EVENT_INFO *info){ int err = 0; spl_t s; xnlock_get_irqsave(&nklock,s); event = xeno_h2obj_validate(event,XENO_EVENT_MAGIC,RT_EVENT); if (!event) { err = xeno_handle_error(event,XENO_EVENT_MAGIC,RT_EVENT); goto unlock_and_exit; } strcpy(info->name,event->name); info->value = event->value; info->nwaiters = xnsynch_nsleepers(&event->synch_base); unlock_and_exit: xnlock_put_irqrestore(&nklock,s); return err;}/** * @fn int rt_event_bind(RT_EVENT *event,const char *name,RTIME timeout) * @brief Bind to an event flag group. * * This user-space only service retrieves the uniform descriptor of a * given Xenomai event flag group identified by its symbolic name. If the * event flag group does not exist on entry, this service blocks the * caller until a event flag group of the given name is created. * * @param name A valid NULL-terminated name which identifies the * event flag group to bind to. * * @param event The address of an event flag group descriptor * retrieved by the operation. Contents of this memory is undefined * upon failure. * * @param timeout The number of clock ticks to wait for the * registration to occur (see note). Passing TM_INFINITE causes the * caller to block indefinitely until the object is * registered. Passing TM_NONBLOCK causes the service to return * immediately without waiting if the object is not registered on * entry. * * @return 0 is returned upon success. Otherwise: * * - -EFAULT is returned if @a event or @a name is referencing invalid * memory. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before the retrieval has completed. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and the searched object is not registered on entry. * * - -ETIMEDOUT is returned if the object cannot be retrieved within * the specified amount of time. * * - -EPERM is returned if this service should block, but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * Environments: * * This service can be called from: * * - User-space task (switches to primary mode) * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. *//** * @fn int rt_event_unbind(RT_EVENT *event) * * @brief Unbind from an event flag group. * * This user-space only service unbinds the calling task from the * event flag group object previously retrieved by a call to * rt_event_bind(). * * @param event The address of an event flag group descriptor to * unbind from. * * @return 0 is always returned. * * This service can be called from: * * - User-space task. * * Rescheduling: never. */int __native_event_pkg_init (void){ return 0;}void __native_event_pkg_cleanup (void){}/*@}*/EXPORT_SYMBOL(rt_event_create);EXPORT_SYMBOL(rt_event_delete);EXPORT_SYMBOL(rt_event_signal);EXPORT_SYMBOL(rt_event_wait);EXPORT_SYMBOL(rt_event_clear);EXPORT_SYMBOL(rt_event_inquire);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -