mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-19 12:10:46 +00:00
MINOR: listener: pre-compute some thread counts per bind_conf
In order to quickly pick a thread ID when accepting a connection, we'll need to know certain pre-computed values derived from the thread mask, which are counts of bits per position multiples of 1, 2, 4, 8, 16 and 32. In practice it is sufficient to compute only the 4 first ones and store them in the bind_conf. We update the count every time the bind_thread value is adjusted. The fields in the bind_conf struct have been moved around a little bit to make it easier to group all thread bit values into the same cache line. The function used to return a thread number is bind_map_thread_id(), and it maps a number between 0 and 31/63 to a thread ID between 0 and 31/63, starting from the left.
This commit is contained in:
parent
f3241115e7
commit
b2b50a7784
@ -127,6 +127,9 @@ struct bind_kw *bind_find_kw(const char *kw);
|
||||
/* Dumps all registered "bind" keywords to the <out> string pointer. */
|
||||
void bind_dump_kws(char **out);
|
||||
|
||||
void bind_recount_thread_bits(struct bind_conf *conf);
|
||||
unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r);
|
||||
|
||||
/* allocate an bind_conf struct for a bind line, and chain it to the frontend <fe>.
|
||||
* If <arg> is not NULL, it is duplicated into ->arg to store useful config
|
||||
* information for error reporting.
|
||||
|
@ -165,21 +165,23 @@ struct bind_conf {
|
||||
struct xprt_ops *xprt; /* transport-layer operations for all listeners */
|
||||
int is_ssl; /* SSL is required for these listeners */
|
||||
int generate_certs; /* 1 if generate-certificates option is set, else 0 */
|
||||
int level; /* stats access level (ACCESS_LVL_*) */
|
||||
int severity_output; /* default severity output format in cli feedback messages */
|
||||
struct list listeners; /* list of listeners using this bind config */
|
||||
unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
|
||||
unsigned long bind_thread; /* bitmask of threads allowed to use these listeners */
|
||||
unsigned long thr_2, thr_4, thr_8, thr_16; /* intermediate values for bind_thread counting */
|
||||
unsigned int thr_count; /* #threads bound */
|
||||
uint32_t ns_cip_magic; /* Excepted NetScaler Client IP magic number */
|
||||
struct list by_fe; /* next binding for the same frontend, or NULL */
|
||||
char *arg; /* argument passed to "bind" for better error reporting */
|
||||
char *file; /* file where the section appears */
|
||||
int line; /* line where the section appears */
|
||||
struct { /* UNIX socket permissions */
|
||||
uid_t uid; /* -1 to leave unchanged */
|
||||
gid_t gid; /* -1 to leave unchanged */
|
||||
mode_t mode; /* 0 to leave unchanged */
|
||||
} ux;
|
||||
int level; /* stats access level (ACCESS_LVL_*) */
|
||||
int severity_output; /* default severity output format in cli feedback messages */
|
||||
struct list by_fe; /* next binding for the same frontend, or NULL */
|
||||
struct list listeners; /* list of listeners using this bind config */
|
||||
uint32_t ns_cip_magic; /* Excepted NetScaler Client IP magic number */
|
||||
char *arg; /* argument passed to "bind" for better error reporting */
|
||||
char *file; /* file where the section appears */
|
||||
int line; /* line where the section appears */
|
||||
};
|
||||
|
||||
/* The listener will be directly referenced by the fdtab[] which holds its
|
||||
|
@ -2318,6 +2318,8 @@ int check_config_validity()
|
||||
curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
|
||||
}
|
||||
|
||||
bind_recount_thread_bits(bind_conf);
|
||||
|
||||
/* detect process and nbproc affinity inconsistencies */
|
||||
mask = proc_mask(bind_conf->bind_proc) & proc_mask(curproxy->bind_proc);
|
||||
if (!(mask & all_proc_mask)) {
|
||||
|
@ -802,6 +802,33 @@ void bind_dump_kws(char **out)
|
||||
}
|
||||
}
|
||||
|
||||
/* recompute the bit counts per parity for the bind_thread value. This will be
|
||||
* used to quickly map a thread number from 1 to #thread to a thread ID among
|
||||
* the ones bound. This is the preparation phase of the bit rank counting algo
|
||||
* described here: https://graphics.stanford.edu/~seander/bithacks.html
|
||||
*/
|
||||
void bind_recount_thread_bits(struct bind_conf *conf)
|
||||
{
|
||||
unsigned long m;
|
||||
|
||||
m = thread_mask(conf->bind_thread);
|
||||
conf->thr_count = my_popcountl(m);
|
||||
mask_prep_rank_map(m, &conf->thr_2, &conf->thr_4, &conf->thr_8, &conf->thr_16);
|
||||
}
|
||||
|
||||
/* Report the ID of thread <r> in bind_conf <conf> according to its thread_mask.
|
||||
* <r> must be between 0 and LONGBITS-1. This makes use of the pre-computed
|
||||
* bits resulting from bind_recount_thread_bits. See this function for more
|
||||
* info.
|
||||
*/
|
||||
unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r)
|
||||
{
|
||||
unsigned long m;
|
||||
|
||||
m = thread_mask(conf->bind_thread);
|
||||
return mask_find_rank_bit_fast(r, m, conf->thr_2, conf->thr_4, conf->thr_8, conf->thr_16);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* All supported sample and ACL keywords must be declared here. */
|
||||
/************************************************************************/
|
||||
@ -1012,6 +1039,7 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct
|
||||
|
||||
conf->bind_proc |= proc;
|
||||
conf->bind_thread |= thread;
|
||||
bind_recount_thread_bits(conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user