MINOR: tinfo: start to add basic thread_exec_ctx

We have the struct made of a type and a pointer in the th_ctx and a
function to switch it for the current thread. Two macros are provided
to enclose a callee within a temporary context. For now only type OTHER
is supported (only a generic pointer).
This commit is contained in:
Willy Tarreau 2026-03-03 09:37:10 +01:00
parent fb7e5e1696
commit b7c8fab507
2 changed files with 53 additions and 2 deletions

View file

@ -75,6 +75,20 @@ enum {
/* we have 4 buffer-wait queues, in highest to lowest emergency order */
#define DYNBUF_NBQ 4
/* execution context, for tracing resource usage or warning origins */
enum thread_exec_ctx_type {
TH_EX_CTX_NONE = 0, /* context not filled */
TH_EX_CTX_OTHER, /* context only known by a generic pointer */
};
struct thread_exec_ctx {
enum thread_exec_ctx_type type;
/* 32-bit hole here on 64-bit platforms */
union {
const void *pointer; /* generic pointer (for other) */
};
};
/* Thread group information. This defines a base and a count of global thread
* IDs which belong to it, and which can be looked up into thread_info/ctx. It
* is set up during parsing and is stable during operation. Thread groups start
@ -172,8 +186,7 @@ struct thread_ctx {
uint64_t curr_mono_time; /* latest system wide monotonic time (leaving poll) */
ulong lock_history; /* history of used locks, see thread.h for more details */
/* around 56 unused bytes here */
struct thread_exec_ctx exec_ctx; /* current execution context when known, or NULL */
// fourth cache line here on 64 bits: accessed mostly using atomic ops
ALWAYS_ALIGN(64);

View file

@ -117,4 +117,42 @@ static inline void thread_set_pin_grp1(struct thread_set *ts, ulong mask)
ts->rel[i] = 0;
}
/* switches the current execution context to <ctx> and returns the previous one
* so that this may even be used to save and restore. Setting EXEC_CTX_NONE
* resets it. It's efficient because it uses a pair of registers on input and
* output.
*/
static inline struct thread_exec_ctx switch_exec_ctx(const struct thread_exec_ctx ctx)
{
const struct thread_exec_ctx prev = th_ctx->exec_ctx;
th_ctx->exec_ctx = ctx;
return prev;
}
/* used to reset the execution context */
#define EXEC_CTX_NONE ((struct thread_exec_ctx){ .type = 0, .pointer = NULL })
/* make an execution context from a type and a pointer */
#define EXEC_CTX_MAKE(_type, _pointer) ((struct thread_exec_ctx){ .type = (_type), .pointer = (_pointer) })
/* execute expression <expr> under context <new_ctx> then restore the previous
* one, and return the expression's return value.
*/
#define EXEC_CTX_WITH_RET(new_ctx, expr) ({ \
const struct thread_exec_ctx __prev_ctx = switch_exec_ctx(new_ctx); \
typeof(expr) __ret = (expr); \
switch_exec_ctx(__prev_ctx); \
__ret; \
})
/* execute expression <expr> under context <new_ctx> then restore the previous
* one. This one has no return value.
*/
#define EXEC_CTX_NO_RET(new_ctx, expr) do { \
const struct thread_exec_ctx __prev_ctx = switch_exec_ctx(new_ctx); \
do { expr; } while (0); \
switch_exec_ctx(__prev_ctx); \
} while (0)
#endif /* _HAPROXY_TINFO_H */