Skip to content

Commit f0c0567

Browse files
FlorianWeber1018dkalowsk
authored andcommitted
lib: os: p4wq: add done handler
Add an optional handler to the p4wq to give the submitting code (e.g. rtio workq) a possibility execute code after the work was succesfully executed. Signed-off-by: Florian Weber <[email protected]> (cherry picked from commit 093b29f)
1 parent b40cacb commit f0c0567

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

include/zephyr/sys/p4wq.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ struct k_p4wq_work;
1818
*/
1919
typedef void (*k_p4wq_handler_t)(struct k_p4wq_work *work);
2020

21+
/**
22+
* Optional P4 Queue done callback.
23+
* Will be called after the memory structure is not used anymore by the p4wq.
24+
* If it is not used it must be set to NULL.
25+
*/
26+
typedef void (*k_p4wq_done_handler_t)(struct k_p4wq_work *work);
27+
2128
/**
2229
* @brief P4 Queue Work Item
2330
*
@@ -74,6 +81,11 @@ struct k_p4wq {
7481

7582
/* K_P4WQ_* flags above */
7683
uint32_t flags;
84+
85+
/* done handler which is called every time after work was successfully executed
86+
* and k_p4wq_work is not needed by p4wq anymore
87+
*/
88+
k_p4wq_done_handler_t done_handler;
7789
};
7890

7991
struct k_p4wq_initparam {
@@ -83,6 +95,7 @@ struct k_p4wq_initparam {
8395
struct k_thread *threads;
8496
struct z_thread_stack_element *stacks;
8597
uint32_t flags;
98+
k_p4wq_done_handler_t done_handler;
8699
};
87100

88101
/**
@@ -95,8 +108,9 @@ struct k_p4wq_initparam {
95108
* @param name Symbol name of the struct k_p4wq that will be defined
96109
* @param n_threads Number of threads in the work queue pool
97110
* @param stack_sz Requested stack size of each thread, in bytes
111+
* @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t
98112
*/
99-
#define K_P4WQ_DEFINE(name, n_threads, stack_sz) \
113+
#define K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, dn_handler) \
100114
static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name, \
101115
n_threads, stack_sz); \
102116
static struct k_thread _p4threads_##name[n_threads]; \
@@ -109,8 +123,19 @@ struct k_p4wq_initparam {
109123
.stacks = &(_p4stacks_##name[0][0]), \
110124
.queue = &name, \
111125
.flags = 0, \
126+
.done_handler = dn_handler, \
112127
}
113128

129+
/**
130+
* @brief Statically initialize a P4 Work Queue
131+
*
132+
* Same like K_P4WQ_DEFINE_WITH_DONE_HANDLER but without an
133+
* optional handler which is called everytime when work is executed
134+
* and not used anymore by the p4wq
135+
*/
136+
#define K_P4WQ_DEFINE(name, n_threads, stack_sz) \
137+
K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, NULL)
138+
114139
/**
115140
* @brief Statically initialize an array of P4 Work Queues
116141
*
@@ -122,8 +147,9 @@ struct k_p4wq_initparam {
122147
* @param n_threads Number of threads and work queues
123148
* @param stack_sz Requested stack size of each thread, in bytes
124149
* @param flg Flags
150+
* @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t
125151
*/
126-
#define K_P4WQ_ARRAY_DEFINE(name, n_threads, stack_sz, flg) \
152+
#define K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, dn_handler) \
127153
static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name, \
128154
n_threads, stack_sz); \
129155
static struct k_thread _p4threads_##name[n_threads]; \
@@ -136,8 +162,19 @@ struct k_p4wq_initparam {
136162
.stacks = &(_p4stacks_##name[0][0]), \
137163
.queue = name, \
138164
.flags = K_P4WQ_QUEUE_PER_THREAD | flg, \
165+
.done_handler = dn_handler, \
139166
}
140167

168+
/**
169+
* @brief Statically initialize an array of P4 Work Queues
170+
*
171+
* Same like K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER but without an
172+
* optional handler which is called everytime when work is executed
173+
* and not used anymore by the p4wq
174+
*/
175+
#define K_P4WQ_ARRAY_DEFINE(name, n_threads, stack_sz, flg) \
176+
K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, NULL)
177+
141178
/**
142179
* @brief Initialize P4 Queue
143180
*

lib/os/p4wq.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,14 @@ static FUNC_NORETURN void p4wq_loop(void *p0, void *p1, void *p2)
104104
if (!thread_was_requeued(_current)) {
105105
sys_dlist_remove(&w->dlnode);
106106
w->thread = NULL;
107-
k_sem_give(&w->done_sem);
107+
108+
if (queue->done_handler) {
109+
k_spin_unlock(&queue->lock, k);
110+
queue->done_handler(w);
111+
k = k_spin_lock(&queue->lock);
112+
} else {
113+
k_sem_give(&w->done_sem);
114+
}
108115
}
109116
} else {
110117
z_pend_curr(&queue->lock, k, &queue->waitq, K_FOREVER);
@@ -152,6 +159,7 @@ static int static_init(void)
152159

153160
if (!i || (pp->flags & K_P4WQ_QUEUE_PER_THREAD)) {
154161
k_p4wq_init(q);
162+
q->done_handler = pp->done_handler;
155163
}
156164

157165
q->flags = pp->flags;
@@ -301,7 +309,14 @@ bool k_p4wq_cancel(struct k_p4wq *queue, struct k_p4wq_work *item)
301309

302310
if (ret) {
303311
rb_remove(&queue->queue, &item->rbnode);
304-
k_sem_give(&item->done_sem);
312+
313+
if (queue->done_handler) {
314+
k_spin_unlock(&queue->lock, k);
315+
queue->done_handler(item);
316+
k = k_spin_lock(&queue->lock);
317+
} else {
318+
k_sem_give(&item->done_sem);
319+
}
305320
}
306321

307322
k_spin_unlock(&queue->lock, k);

0 commit comments

Comments
 (0)