MINOR: threads: add flags to know if a thread is started and/or running

Several times during debugging it has been difficult to find a way to
reliably indicate if a thread had been started and if it was still
running. It's really not easy because the elements we look at are not
necessarily reliable (e.g. harmless bit or idle bit might not reflect
what we think during a signal). And such notions can be subjective
anyway.

Here we define two thread flags, TH_FL_STARTED which is set as soon as
a thread enters run_thread_poll_loop() and drops the idle bit, and
another one, TH_FL_IN_LOOP, which is set when entering run_poll_loop()
and cleared when leaving it. This should help init/deinit code know
whether it's called from a non-initialized thread (i.e. tid must not
be trusted), or shared functions know if they're being called from a
running thread or from init/deinit code outside of the polling loop.
This commit is contained in:
Willy Tarreau 2023-02-17 08:36:42 +01:00
parent ba4c7a1597
commit 3e820a1056
2 changed files with 7 additions and 0 deletions

View File

@ -60,6 +60,8 @@ enum {
#define TH_FL_TASK_PROFILING 0x00000002
#define TH_FL_NOTIFIED 0x00000004 /* task was notified about the need to wake up */
#define TH_FL_SLEEPING 0x00000008 /* thread won't check its task list before next wakeup */
#define TH_FL_STARTED 0x00000010 /* set once the thread starts */
#define TH_FL_IN_LOOP 0x00000020 /* set only inside the polling loop */
/* Thread group information. This defines a base and a count of global thread

View File

@ -2922,6 +2922,8 @@ void run_poll_loop()
{
int next, wake;
_HA_ATOMIC_OR(&th_ctx->flags, TH_FL_IN_LOOP);
clock_update_date(0,1);
while (1) {
wake_expired_tasks();
@ -3010,6 +3012,8 @@ void run_poll_loop()
activity[tid].loops++;
}
_HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_IN_LOOP);
}
static void *run_thread_poll_loop(void *data)
@ -3028,6 +3032,7 @@ static void *run_thread_poll_loop(void *data)
/* thread is started, from now on it is not idle nor harmless */
thread_harmless_end();
thread_idle_end();
_HA_ATOMIC_OR(&th_ctx->flags, TH_FL_STARTED);
/* Now, initialize one thread init at a time. This is better since
* some init code is a bit tricky and may release global resources