/* 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.
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 */
- unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
- unsigned long bind_thread; /* bitmask of threads allowed to use these listeners */
- 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 */
+ 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;
};
/* The listener will be directly referenced by the fdtab[] which holds its
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)) {
}
}
+/* 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. */
/************************************************************************/
conf->bind_proc |= proc;
conf->bind_thread |= thread;
+ bind_recount_thread_bits(conf);
return 0;
}