]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tasklet: support an optional set of wakeup flags to tasklet_wakeup_on()
authorWilly Tarreau <w@1wt.eu>
Tue, 19 Nov 2024 14:56:59 +0000 (15:56 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 19 Nov 2024 19:13:41 +0000 (20:13 +0100)
tasklet_wakeup_on() and its derivates (tasklet_wakeup_after() and
tasklet_wakeup()) do not support passing a wakeup cause like
task_wakeup(). This is essentially due to an API limitation cause by
the fact that for a very long time the only reason for waking up was
to process pending I/O. But with the growing complexity of mux tasks,
it is becoming important to be able to skip certain heavy processing
when not strictly needed.

One possibility is to permit the caller of tasklet_wakeup() to pass
flags like task_wakeup(). Instead of going with a complex naming scheme,
let's simply make the flags optional and be zero when not specified. This
means that tasklet_wakeup_on() now takes either 2 or 3 args, and that the
third one is the optional flags to be passed to the callee. Eligible flags
are essentially the non-persistent ones (TASK_F_UEVT* and TASK_WOKEN_*)
which are cleared when the tasklet is executed. This way the handler
will find them in its <state> argument and will be able to distinguish
various causes for the call.

doc/internals/api/scheduler.txt
include/haproxy/task.h

index 0b4459817d6408e7b0d2ffea9314b2b230281878..4a1540df526ed0c94ec7ac474543e36e2396d3f7 100644 (file)
@@ -98,12 +98,14 @@ void task_set_thread(t, id)
         indicate "any thread". It's ignored and replaced by zero when threads
         are disabled.
 
-void tasklet_wakeup(tl)
+void tasklet_wakeup(tl, [flags])
         Make sure that tasklet <tl> will wake up, that is, will execute at
         least once. The tasklet will run on its assigned thread, or on any
-        thread if its TID is negative.
+        thread if its TID is negative. An optional <flags> value may be passed
+        to set a wakeup cause on the tasklet's flags, typically TASK_WOKEN_* or
+        TASK_F_UEVT*. When not set, 0 is passed (i.e. no flags are changed).
 
-struct list *tasklet_wakeup_after(head, tl)
+struct list *tasklet_wakeup_after(head, tl, [flags])
         Schedule tasklet <tl> to run immediately the current one if <head> is
         NULL, or after the last queued one if <head> is non-null. The new head
         is returned, to be passed to the next call. The purpose here is to
@@ -113,15 +115,20 @@ struct list *tasklet_wakeup_after(head, tl)
         already queued tasklets. This may induce extra latencies for pending
         jobs and must only be used extremely carefully when it's certain that
         the processing will benefit from using fresh data from the L1 cache.
+        An optional <flags> value may be passed to set a wakeup cause on the
+        tasklet's flags, typically TASK_WOKEN_* or TASK_F_UEVT*. When not set,
+        0 is passed (i.e. no flags are changed).
 
-void tasklet_wakeup_on(tl, thr)
+void tasklet_wakeup_on(tl, thr, [flags])
         Make sure that tasklet <tl> will wake up on thread <thr>, that is, will
         execute at least once. The designated thread may only differ from the
         calling one if the tasklet is already configured to run on another
         thread, and it is not permitted to self-assign a tasklet if its tid is
         negative, as it may already be scheduled to run somewhere else. Just in
         case, only use tasklet_wakeup() which will pick the tasklet's assigned
-        thread ID.
+        thread ID. An optional <flags> value may be passed to set a wakeup
+        cause on the tasklet's flags, typically TASK_WOKEN_* or TASK_F_UEVT*.
+        When not set, 0 is passed (i.e. no flags are changed).
 
 struct tasklet *tasklet_new()
         Allocate a new tasklet and set it to run by default on the calling
index 3c4163b2795b1d0e4f487508a30971049d397e26..5749253037626b325abd3eccb7359de659964977 100644 (file)
@@ -373,9 +373,14 @@ static inline void task_set_thread(struct task *t, int thr)
  * at least once scheduled on a specific thread. With DEBUG_TASK, the
  * <file>:<line> from the call place are stored into the tasklet for tracing
  * purposes.
+ *
+ * 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).
  */
-#define tasklet_wakeup_on(tl, thr) \
-       _tasklet_wakeup_on(tl, thr, 0, MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
+#define tasklet_wakeup_on(tl, thr, ...)                                        \
+       _tasklet_wakeup_on(tl, thr, DEFZERO(__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)
 {
@@ -405,9 +410,14 @@ static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const
  * is either its owner thread if >= 0 or the current thread if < 0. When
  * DEBUG_TASK is set, the <file>:<line> from the call place are stored into the
  * task for tracing purposes.
+ *
+ * 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).
  */
-#define tasklet_wakeup(tl) \
-       _tasklet_wakeup_on(tl, (tl)->tid, 0, MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
+#define tasklet_wakeup(tl, ...)                                                \
+       _tasklet_wakeup_on(tl, (tl)->tid, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
 
 /* instantly wakes up task <t> 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
@@ -466,9 +476,14 @@ static inline void _task_instant_wakeup(struct task *t, unsigned int f, const st
  * thread will be used.
  * With DEBUG_TASK, the <file>:<line> from the call place are stored into the tasklet
  * for tracing purposes.
+ *
+ * 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).
  */
-#define tasklet_wakeup_after(head, tl) \
-       _tasklet_wakeup_after(head, tl, 0, MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, 0, 0))
+#define tasklet_wakeup_after(head, tl, ...)                                    \
+       _tasklet_wakeup_after(head, tl, DEFZERO(__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)