mirror of
https://github.com/haproxy/haproxy.git
synced 2026-03-14 14:42:13 -04:00
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:
parent
fb7e5e1696
commit
b7c8fab507
2 changed files with 53 additions and 2 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue