#define TASK_F_USR1 0x00010000 /* preserved user flag 1, application-specific, def:0 */
/* unused: 0x20000..0x80000000 */
+/* These flags are persistent across scheduler calls */
+#define TASK_PERSISTENT (TASK_SHARED_WQ | TASK_SELF_WAKING | TASK_KILLED | \
+ TASK_HEAVY | TASK_F_TASKLET | TASK_F_USR1)
struct notification {
struct list purge_me; /* Part of the list of signals to be purged in the
}
budgets[queue]--;
- t = (struct task *)LIST_ELEM(tl_queues[queue].n, struct tasklet *, list);
- state = t->state & (TASK_SHARED_WQ|TASK_SELF_WAKING|TASK_HEAVY|TASK_F_TASKLET|TASK_KILLED|TASK_F_USR1|TASK_KILLED);
-
- th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
activity[tid].ctxsw++;
+
+ t = (struct task *)LIST_ELEM(tl_queues[queue].n, struct tasklet *, list);
ctx = t->context;
process = t->process;
t->calls++;
th_ctx->current = t;
+ th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
_HA_ATOMIC_DEC(&th_ctx->rq_total);
- if (state & TASK_F_TASKLET) {
+ if (t->state & TASK_F_TASKLET) {
uint64_t before = 0;
LIST_DEL_INIT(&((struct tasklet *)t)->list);
#endif
}
- state = _HA_ATOMIC_XCHG(&t->state, state);
+ state = _HA_ATOMIC_FETCH_AND(&t->state, TASK_PERSISTENT);
__ha_barrier_atomic_store();
if (likely(!(state & TASK_KILLED))) {
LIST_DEL_INIT(&((struct tasklet *)t)->list);
__ha_barrier_store();
- state = _HA_ATOMIC_XCHG(&t->state, state|TASK_RUNNING|TASK_F_USR1);
+
+ state = t->state;
+ while (!_HA_ATOMIC_CAS(&t->state, &state, (state & TASK_PERSISTENT) | TASK_RUNNING))
+ ;
+
__ha_barrier_atomic_store();
/* OK then this is a regular task */