kernel: Introduce k_work_poll

This commit adds new k_work_poll interface. It allows to
submit given work to a workqueue automatically when one of the
watched pollable objects changes its state.

Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
Piotr Zięcik 2019-09-27 09:16:25 +02:00 committed by Carles Cufí
commit 19d8349aa5
9 changed files with 1042 additions and 53 deletions

View file

@ -2681,8 +2681,9 @@ __syscall int k_stack_pop(struct k_stack *stack, stack_data_t *data, s32_t timeo
/** @} */
struct k_work;
struct k_work_poll;
/* private, used by k_poll */
/* private, used by k_poll and k_work_poll */
typedef int (*_poller_cb_t)(struct k_poll_event *event, u32_t state);
struct _poller {
volatile bool is_polling;
@ -2734,6 +2735,16 @@ struct k_delayed_work {
struct k_work_q *work_q;
};
struct k_work_poll {
struct k_work work;
struct _poller poller;
struct k_poll_event *events;
int num_events;
k_work_handler_t real_handler;
struct _timeout timeout;
int poll_result;
};
extern struct k_work_q k_sys_work_q;
/**
@ -3066,6 +3077,116 @@ static inline s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
return __ticks_to_ms(z_timeout_remaining(&work->timeout));
}
/**
* @brief Initialize a triggered work item.
*
* This routine initializes a workqueue triggered work item, prior to
* its first use.
*
* @param work Address of triggered work item.
* @param handler Function to invoke each time work item is processed.
*
* @return N/A
*/
extern void k_work_poll_init(struct k_work_poll *work,
k_work_handler_t handler);
/**
* @brief Submit a triggered work item.
*
* This routine schedules work item @a work to be processed by workqueue
* @a work_q when one of the given @a events is signaled. The routine
* initiates internal poller for the work item and then returns to the caller.
* Only when one of the watched events happen the work item is actually
* submitted to the workqueue and becomes pending.
*
* Submitting a previously submitted triggered work item that is still
* waiting for the event cancels the existing submission and reschedules it
* the using the new event list. Note that this behavior is inherently subject
* to race conditions with the pre-existig triggered work item and work queue,
* so care must be taken to synchronize such resubmissions externally.
*
* @note Can be called by ISRs.
*
* @warning
* Provided array of events as well as a triggered work item must be placed
* in persistent memory (valid until work handler execution or work
* cancellation) and cannot be modified after submission.
*
* @param work_q Address of workqueue.
* @param work Address of delayed work item.
* @param events An array of pointers to events which trigger the work.
* @param num_events The number of events in the array.
* @param timeout Timeout after which the work will be scheduled for
* execution even if not triggered.
*
*
* @retval 0 Work item started watching for events.
* @retval -EINVAL Work item is being processed or has completed its work.
* @retval -EADDRINUSE Work item is pending on a different workqueue.
*/
extern int k_work_poll_submit_to_queue(struct k_work_q *work_q,
struct k_work_poll *work,
struct k_poll_event *events,
int num_events,
s32_t timeout);
/**
* @brief Submit a triggered work item to the system workqueue.
*
* This routine schedules work item @a work to be processed by system
* workqueue when one of the given @a events is signaled. The routine
* initiates internal poller for the work item and then returns to the caller.
* Only when one of the watched events happen the work item is actually
* submitted to the workqueue and becomes pending.
*
* Submitting a previously submitted triggered work item that is still
* waiting for the event cancels the existing submission and reschedules it
* the using the new event list. Note that this behavior is inherently subject
* to race conditions with the pre-existig triggered work item and work queue,
* so care must be taken to synchronize such resubmissions externally.
*
* @note Can be called by ISRs.
*
* @warning
* Provided array of events as well as a triggered work item must not be
* modified until the item has been processed by the workqueue.
*
* @param work Address of delayed work item.
* @param events An array of pointers to events which trigger the work.
* @param num_events The number of events in the array.
* @param timeout Timeout after which the work will be scheduled for
* execution even if not triggered.
*
* @retval 0 Work item started watching for events.
* @retval -EINVAL Work item is being processed or has completed its work.
* @retval -EADDRINUSE Work item is pending on a different workqueue.
*/
static inline int k_work_poll_submit(struct k_work_poll *work,
struct k_poll_event *events,
int num_events,
s32_t timeout)
{
return k_work_poll_submit_to_queue(&k_sys_work_q, work,
events, num_events, timeout);
}
/**
* @brief Cancel a triggered work item.
*
* This routine cancels the submission of triggered work item @a work.
* A triggered work item can only be canceled if no event triggered work
* submission.
*
* @note Can be called by ISRs.
*
* @param work Address of delayed work item.
*
* @retval 0 Work tiem canceled.
* @retval -EINVAL Work item is being processed or has completed its work.
*/
extern int k_work_poll_cancel(struct k_work_poll *work);
/** @} */
/**
* @defgroup mutex_apis Mutex APIs