/* a few exported variables */
extern volatile unsigned long global_tasks_mask; /* Mask of threads with tasks in the global runqueue */
-extern unsigned int grq_total; /* total number of entries in the global run queue */
+extern unsigned int grq_total; /* total number of entries in the global run queue, atomic */
extern unsigned int niced_tasks; /* number of niced tasks in the run queue */
extern struct pool_head *pool_head_task;
extern struct pool_head *pool_head_tasklet;
if (likely(task_in_rq(t))) {
eb32sc_delete(&t->rq);
- if (is_global) {
- grq_total--;
done = 1;
}
HA_SPIN_UNLOCK(TASK_RQ_LOCK, &rq_lock);
if (done) {
- if (is_global)
+ if (is_global) {
_HA_ATOMIC_AND(&t->state, ~TASK_GLOBAL);
+ _HA_ATOMIC_SUB(&grq_total, 1);
+ }
else
_HA_ATOMIC_SUB(&sched->rq_total, 1);
if (t->nice)
#ifdef USE_THREAD
struct eb_root timers; /* sorted timers tree, global, accessed under wq_lock */
struct eb_root rqueue; /* tree constituting the global run queue, accessed under rq_lock */
-unsigned int grq_total; /* total number of entries in the global run queue, use grq_lock */
+unsigned int grq_total; /* total number of entries in the global run queue, atomic */
static unsigned int global_rqueue_ticks; /* insertion count in the grq, use rq_lock */
#endif
if (t->thread_mask != tid_bit && global.nbthread != 1) {
root = &rqueue;
+ _HA_ATOMIC_ADD(&grq_total, 1);
HA_SPIN_LOCK(TASK_RQ_LOCK, &rq_lock);
global_tasks_mask |= t->thread_mask;
- grq_total++;
t->rq.key = ++global_rqueue_ticks;
__ha_barrier_store();
} else
else {
t = eb32sc_entry(grq, struct task, rq);
grq = eb32sc_next(grq, tid_bit);
- grq_total--;
_HA_ATOMIC_AND(&t->state, ~TASK_GLOBAL);
eb32sc_delete(&t->rq);
if (lpicked + gpicked) {
tt->tl_class_mask |= 1 << TL_NORMAL;
_HA_ATOMIC_ADD(&tt->tasks_in_list, lpicked + gpicked);
- if (gpicked)
+ if (gpicked) {
+ _HA_ATOMIC_SUB(&grq_total, gpicked);
_HA_ATOMIC_ADD(&tt->rq_total, gpicked);
+ }
activity[tid].tasksw += lpicked + gpicked;
}