mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-26 04:48:03 +00:00
REORG: thread/sched: move the thread_info flags to the thread_ctx
The TI_FL_STUCK flag is manipulated by the watchdog and scheduler and describes the apparent life/death of a thread so it changes all the time and it makes sense to move it to the thread's context for an active thread.
This commit is contained in:
parent
45c38e22bf
commit
a0b99536c8
@ -35,15 +35,13 @@ enum {
|
|||||||
TL_CLASSES /* must be last */
|
TL_CLASSES /* must be last */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* thread info flags, for ha_thread_info[].flags */
|
/* thread_ctx flags, for ha_thread_ctx[].flags */
|
||||||
#define TI_FL_STUCK 0x00000001
|
#define TH_FL_STUCK 0x00000001
|
||||||
|
|
||||||
/* This structure describes all the per-thread info we need. When threads are
|
/* This structure describes all the per-thread info we need. When threads are
|
||||||
* disabled, it contains the same info for the single running thread.
|
* disabled, it contains the same info for the single running thread.
|
||||||
*/
|
*/
|
||||||
struct thread_info {
|
struct thread_info {
|
||||||
unsigned int flags; /* thread info flags, TI_FL_* */
|
|
||||||
|
|
||||||
#ifdef CONFIG_HAP_POOLS
|
#ifdef CONFIG_HAP_POOLS
|
||||||
struct list pool_lru_head; /* oldest objects */
|
struct list pool_lru_head; /* oldest objects */
|
||||||
#endif
|
#endif
|
||||||
@ -68,9 +66,10 @@ struct thread_ctx {
|
|||||||
unsigned int rqueue_ticks; /* Insertion counter for the run queue */
|
unsigned int rqueue_ticks; /* Insertion counter for the run queue */
|
||||||
int current_queue; /* points to current tasklet list being run, -1 if none */
|
int current_queue; /* points to current tasklet list being run, -1 if none */
|
||||||
unsigned int nb_tasks; /* number of tasks allocated on this thread */
|
unsigned int nb_tasks; /* number of tasks allocated on this thread */
|
||||||
|
uint flags; /* thread flags, TH_FL_* */
|
||||||
uint8_t tl_class_mask; /* bit mask of non-empty tasklets classes */
|
uint8_t tl_class_mask; /* bit mask of non-empty tasklets classes */
|
||||||
|
|
||||||
// 11 bytes hole here
|
// 7 bytes hole here
|
||||||
ALWAYS_ALIGN(2*sizeof(void*));
|
ALWAYS_ALIGN(2*sizeof(void*));
|
||||||
struct list tasklets[TL_CLASSES]; /* tasklets (and/or tasks) to run, by class */
|
struct list tasklets[TL_CLASSES]; /* tasklets (and/or tasks) to run, by class */
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void ha_thread_dump(struct buffer *buf, int thr, int calling_tid)
|
|||||||
unsigned long thr_bit = 1UL << thr;
|
unsigned long thr_bit = 1UL << thr;
|
||||||
unsigned long long p = ha_thread_ctx[thr].prev_cpu_time;
|
unsigned long long p = ha_thread_ctx[thr].prev_cpu_time;
|
||||||
unsigned long long n = now_cpu_time_thread(thr);
|
unsigned long long n = now_cpu_time_thread(thr);
|
||||||
int stuck = !!(ha_thread_info[thr].flags & TI_FL_STUCK);
|
int stuck = !!(ha_thread_ctx[thr].flags & TH_FL_STUCK);
|
||||||
|
|
||||||
chunk_appendf(buf,
|
chunk_appendf(buf,
|
||||||
"%c%cThread %-2u: id=0x%llx act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n"
|
"%c%cThread %-2u: id=0x%llx act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n"
|
||||||
@ -1145,7 +1145,7 @@ void debug_handler(int sig, siginfo_t *si, void *arg)
|
|||||||
* if it didn't move.
|
* if it didn't move.
|
||||||
*/
|
*/
|
||||||
if (!((threads_harmless_mask|sleeping_thread_mask) & tid_bit))
|
if (!((threads_harmless_mask|sleeping_thread_mask) & tid_bit))
|
||||||
ti->flags |= TI_FL_STUCK;
|
th_ctx->flags |= TH_FL_STUCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_debug_per_thread()
|
static int init_debug_per_thread()
|
||||||
|
2
src/fd.c
2
src/fd.c
@ -437,7 +437,7 @@ int fd_update_events(int fd, uint evts)
|
|||||||
uint new_flags, must_stop;
|
uint new_flags, must_stop;
|
||||||
ulong rmask, tmask;
|
ulong rmask, tmask;
|
||||||
|
|
||||||
ti->flags &= ~TI_FL_STUCK; // this thread is still running
|
th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
|
||||||
|
|
||||||
/* do nothing if the FD was taken over under us */
|
/* do nothing if the FD was taken over under us */
|
||||||
do {
|
do {
|
||||||
|
@ -1047,7 +1047,7 @@ void listener_accept(struct listener *l)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ti->flags &= ~TI_FL_STUCK; // this thread is still running
|
th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
|
||||||
} /* end of for (max_accept--) */
|
} /* end of for (max_accept--) */
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -529,7 +529,7 @@ unsigned int run_tasks_from_lists(unsigned int budgets[])
|
|||||||
t = (struct task *)LIST_ELEM(tl_queues[queue].n, struct tasklet *, list);
|
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);
|
state = t->state & (TASK_SHARED_WQ|TASK_SELF_WAKING|TASK_HEAVY|TASK_F_TASKLET|TASK_KILLED|TASK_F_USR1|TASK_KILLED);
|
||||||
|
|
||||||
ti->flags &= ~TI_FL_STUCK; // this thread is still running
|
th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
|
||||||
activity[tid].ctxsw++;
|
activity[tid].ctxsw++;
|
||||||
ctx = t->context;
|
ctx = t->context;
|
||||||
process = t->process;
|
process = t->process;
|
||||||
@ -685,7 +685,7 @@ void process_runnable_tasks()
|
|||||||
int heavy_queued = 0;
|
int heavy_queued = 0;
|
||||||
int budget;
|
int budget;
|
||||||
|
|
||||||
ti->flags &= ~TI_FL_STUCK; // this thread is still running
|
th_ctx->flags &= ~TH_FL_STUCK; // this thread is still running
|
||||||
|
|
||||||
if (!thread_has_tasks()) {
|
if (!thread_has_tasks()) {
|
||||||
activity[tid].empty_rq++;
|
activity[tid].empty_rq++;
|
||||||
|
@ -92,13 +92,13 @@ void wdt_handler(int sig, siginfo_t *si, void *arg)
|
|||||||
* certain that we're not witnessing an exceptional spike of
|
* certain that we're not witnessing an exceptional spike of
|
||||||
* CPU usage due to a configuration issue (like running tens
|
* CPU usage due to a configuration issue (like running tens
|
||||||
* of thousands of tasks in a single loop), we'll check if the
|
* of thousands of tasks in a single loop), we'll check if the
|
||||||
* scheduler is still alive by setting the TI_FL_STUCK flag
|
* scheduler is still alive by setting the TH_FL_STUCK flag
|
||||||
* that the scheduler clears when switching to the next task.
|
* that the scheduler clears when switching to the next task.
|
||||||
* If it's already set, then it's our second call with no
|
* If it's already set, then it's our second call with no
|
||||||
* progress and the thread is dead.
|
* progress and the thread is dead.
|
||||||
*/
|
*/
|
||||||
if (!(ha_thread_info[thr].flags & TI_FL_STUCK)) {
|
if (!(ha_thread_ctx[thr].flags & TH_FL_STUCK)) {
|
||||||
_HA_ATOMIC_OR(&ha_thread_info[thr].flags, TI_FL_STUCK);
|
_HA_ATOMIC_OR(&ha_thread_ctx[thr].flags, TH_FL_STUCK);
|
||||||
goto update_and_leave;
|
goto update_and_leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user