#ifdef USE_THREAD
if (task->tid < 0) {
- int was_running;
/*
- * Make sure the task is not already running before changing
- * its expire, otherwise it could overwrite our modification
+ * If the task is already running, then just wake it up, just
+ * in case it did not notice it should reschedule itself.
+ * There is nothing else we can do, if it runs it may
+ * overwrite the expire field, so we can't just set it, and
+ * we can afford to wait until it is no longer running, just
+ * in case we are currently holding a lock, and the running
+ * task tries to acquire that lock.
+ * Tasks are supposed to take care of their own scheduling if
+ * needed anyway, we already do nothing if the task is in the
+ * runqueue, so it should be okay.
*/
- if (task == th_ctx->current)
- was_running = 1;
- else {
- was_running = 0;
- while (HA_ATOMIC_FETCH_OR(&task->state, TASK_RUNNING) & TASK_RUNNING)
- __ha_cpu_relax();
+ if (HA_ATOMIC_FETCH_OR(&task->state, TASK_RUNNING) & TASK_RUNNING) {
+ task_wakeup(task, TASK_WOKEN_OTHER);
+ return;
}
/* FIXME: is it really needed to lock the WQ during the check ? */
when = tick_first(when, task->expire);
task->expire = when;
- if (!was_running)
- task_drop_running(task, 0);
+ task_drop_running(task, 0);
if (!task_in_wq(task) || tick_is_lt(task->expire, task->wq.key)) {
if (likely(caller)) {
caller = HA_ATOMIC_XCHG(&task->caller, caller);