mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-16 02:26:54 +00:00
MEDIUM: threads: automatically assign threads to groups
This takes care of unassigned threads groups and places unassigned threads there, in a more or less balanced way. Too sparse allocations may still fail though. For now with a maximum group number fixed to 1 nothing can really fail.
This commit is contained in:
parent
fc69e410e6
commit
e6806ebecc
@ -43,6 +43,7 @@ int parse_nbthread(const char *arg, char **err);
|
||||
void ha_tkill(unsigned int thr, int sig);
|
||||
void ha_tkillall(int sig);
|
||||
void ha_thread_relax(void);
|
||||
int thread_map_to_groups();
|
||||
extern int thread_cpus_enabled_at_boot;
|
||||
|
||||
|
||||
|
@ -2439,6 +2439,11 @@ int check_config_validity()
|
||||
if (!global.nbtgroups)
|
||||
global.nbtgroups = 1;
|
||||
|
||||
if (thread_map_to_groups() < 0) {
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
|
||||
|
||||
pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
|
||||
|
76
src/thread.c
76
src/thread.c
@ -1001,6 +1001,82 @@ REGISTER_BUILD_OPTS("Built without multi-threading support (USE_THREAD not set).
|
||||
#endif // USE_THREAD
|
||||
|
||||
|
||||
/* scans the configured thread mapping and establishes the final one. Returns <0
|
||||
* on failure, >=0 on success.
|
||||
*/
|
||||
int thread_map_to_groups()
|
||||
{
|
||||
int t, g, ut, ug;
|
||||
int q, r;
|
||||
|
||||
ut = ug = 0; // unassigned threads & groups
|
||||
|
||||
for (t = 0; t < global.nbthread; t++) {
|
||||
if (!ha_thread_info[t].tg)
|
||||
ut++;
|
||||
}
|
||||
|
||||
for (g = 0; g < global.nbtgroups; g++) {
|
||||
if (!ha_tgroup_info[g].count)
|
||||
ug++;
|
||||
}
|
||||
|
||||
if (ug > ut) {
|
||||
ha_alert("More unassigned thread-groups (%d) than threads (%d). Please reduce thread-groups\n", ug, ut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look for first unassigned thread */
|
||||
for (t = 0; t < global.nbthread && ha_thread_info[t].tg; t++)
|
||||
;
|
||||
|
||||
/* assign threads to empty groups */
|
||||
for (g = 0; ug && ut; ) {
|
||||
/* due to sparse thread assignment we can end up with more threads
|
||||
* per group on last assigned groups than former ones, so we must
|
||||
* always try to pack the maximum remaining ones together first.
|
||||
*/
|
||||
q = ut / ug;
|
||||
r = ut % ug;
|
||||
if ((q + !!r) > MAX_THREADS_PER_GROUP) {
|
||||
ha_alert("Too many remaining unassigned threads (%d) for thread groups (%d). Please increase thread-groups or make sure to keep thread numbers contiguous\n", ug, ut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* thread <t> is the next unassigned one. Let's look for next
|
||||
* unassigned group, we know there are some left
|
||||
*/
|
||||
while (ut >= ug && ha_tgroup_info[g].count)
|
||||
g++;
|
||||
|
||||
/* group g is unassigned, try to fill it with consecutive threads */
|
||||
while (ut && ut >= ug && ha_tgroup_info[g].count < q + !!r &&
|
||||
(!ha_tgroup_info[g].count || t == ha_tgroup_info[g].base + ha_tgroup_info[g].count)) {
|
||||
|
||||
if (!ha_tgroup_info[g].count) {
|
||||
/* assign new group */
|
||||
ha_tgroup_info[g].base = t;
|
||||
ug--;
|
||||
}
|
||||
|
||||
ha_tgroup_info[g].count++;
|
||||
ha_thread_info[t].tg = &ha_tgroup_info[g];
|
||||
|
||||
ut--;
|
||||
/* switch to next unassigned thread */
|
||||
while (++t < global.nbthread && ha_thread_info[t].tg)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (ut) {
|
||||
ha_alert("Remaining unassigned threads found (%d) because all groups are in use. Please increase 'thread-groups', reduce 'nbthreads' or remove or extend 'thread-group' enumerations.\n", ut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse the "nbthread" global directive, which takes an integer argument that
|
||||
* contains the desired number of threads.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user