From e6f4f15929064457c16f31634509bb18f10c3470 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 28 Nov 2024 19:42:22 +0100 Subject: [PATCH] MINOR: tasklet: set TASK_WOKEN_OTHER on tasklets by default Now when tasklets are woken up via tasklet_wakeup(), tasklet_wakeup_on() or tasklet_wakeup_after(), either the optional wakeup flags will be used, or TASK_WOKEN_OTHER will be used. This allows tasklet handlers waking up for any given cause to notice whether or not they were also woken for another reason. For example, a mux handler could skip heavy parts when seeing that TASK_WOKEN_OTHER is absent, proving that no standard tasklet_wakeup() was done, for example in response to a subscribe(). The benefit of the TASK_WOKEN_* flags is that they're purged during the wakeup, and that they're easy to check for using TASK_WOKEN_ANY. TASK_F_UEVT1 and TASK_F_UEVT2 are also usable for private use (e.g. wakeup from a stream to a connection inside a mux). Probably that in the future, code dealing with subscribe events should start to place TASK_WOKEN_IO like is done for upper layers. --- include/haproxy/task.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/haproxy/task.h b/include/haproxy/task.h index 5749253037626..bd2ca60f0dae5 100644 --- a/include/haproxy/task.h +++ b/include/haproxy/task.h @@ -380,7 +380,7 @@ static inline void task_set_thread(struct task *t, int thr) * flag is added). */ #define tasklet_wakeup_on(tl, thr, ...) \ - _tasklet_wakeup_on(tl, thr, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0)) + _tasklet_wakeup_on(tl, thr, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0)) static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const struct ha_caller *caller) { @@ -417,7 +417,7 @@ static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const * flag is added). */ #define tasklet_wakeup(tl, ...) \ - _tasklet_wakeup_on(tl, (tl)->tid, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0)) + _tasklet_wakeup_on(tl, (tl)->tid, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0)) /* instantly wakes up task on its owner thread even if it's not the current * one, bypassing the run queue. The purpose is to be able to avoid contention @@ -479,11 +479,14 @@ static inline void _task_instant_wakeup(struct task *t, unsigned int f, const st * * The macro accepts an optional 3rd argument that is passed as a set of flags * to be set on the tasklet, among TASK_WOKEN_*, TASK_F_UEVT* etc to indicate a - * wakeup cause to the tasklet. When not set, the arg defaults to zero (i.e. no - * flag is added). + * wakeup cause to the tasklet. When not set, the arg defaults to + * TASK_WOKEN_OTHER, so that tasklets can differentiate a unique explicit wakeup + * cause from a wakeup cause combined with other implicit ones. I.e. that may be + * used by muxes to decide whether or not to perform a short path for certain + * operations, or a complete one that also covers regular I/O. */ #define tasklet_wakeup_after(head, tl, ...) \ - _tasklet_wakeup_after(head, tl, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, 0, 0)) + _tasklet_wakeup_after(head, tl, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, 0, 0)) static inline struct list *_tasklet_wakeup_after(struct list *head, struct tasklet *tl, uint f, const struct ha_caller *caller)