mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MAJOR: threads: Start threads to experiment multithreading
[WARNING] For now, HAProxy is not thread-safe, so from this commit, it will be broken for a while, when compiled with threads. When nbthread parameter is greater than 1, HAProxy will create the corresponding number of threads. If nbthread is set to 1, nothing should be done. So if there are concurrency issues (and be sure there will be, unfortunatly), an obvious workaround is to disable the multithreading... Each created threads will run a polling loop. So, in a certain way, it is pretty similar to the nbproc mode ("outside" the bugs and the lock contention). Nevertheless, there are an init and a deinit steps for each thread to deal with per-thread allocation. Each thread has a tid (thread-id), numbered from 0 to (nbtread-1). It is used in many place to do bitwise operations or to improve debugging information.
This commit is contained in:
parent
339fff8a18
commit
1d17c10d8b
@ -2237,6 +2237,32 @@ static void run_poll_loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_THREAD
|
||||||
|
static void *run_thread_poll_loop(void *data)
|
||||||
|
{
|
||||||
|
struct per_thread_init_fct *ptif;
|
||||||
|
struct per_thread_deinit_fct *ptdf;
|
||||||
|
|
||||||
|
tid = *((unsigned int *)data);
|
||||||
|
tid_bit = (1UL << tid);
|
||||||
|
tv_update_date(-1,-1);
|
||||||
|
|
||||||
|
list_for_each_entry(ptif, &per_thread_init_list, list) {
|
||||||
|
if (!ptif->fct()) {
|
||||||
|
Alert("failed to initialize thread %u.\n", tid);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run_poll_loop();
|
||||||
|
|
||||||
|
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
|
||||||
|
ptdf->fct();
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is the global management task for listeners. It enables listeners waiting
|
/* This is the global management task for listeners. It enables listeners waiting
|
||||||
* for global resources when there are enough free resource, or at least once in
|
* for global resources when there are enough free resource, or at least once in
|
||||||
* a while. It is designed to be called as a task.
|
* a while. It is designed to be called as a task.
|
||||||
@ -2755,7 +2781,28 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* That's it : the central polling loop. Run until we stop.
|
* That's it : the central polling loop. Run until we stop.
|
||||||
*/
|
*/
|
||||||
|
if (global.nbthread > 1) {
|
||||||
|
#ifdef USE_THREAD
|
||||||
|
unsigned int *tids = calloc(global.nbthread, sizeof(unsigned int));
|
||||||
|
pthread_t *threads = calloc(global.nbthread, sizeof(pthread_t));
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < global.nbthread; i++) {
|
||||||
|
tids[i] = i;
|
||||||
|
pthread_create(&threads[i], NULL, &run_thread_poll_loop, &tids[i]);
|
||||||
|
}
|
||||||
|
for (i = 0; i < global.nbthread; i++)
|
||||||
|
pthread_join(threads[i], NULL);
|
||||||
|
|
||||||
|
free(tids);
|
||||||
|
free(threads);
|
||||||
|
|
||||||
|
#endif /* USE_THREAD */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tid = 0;
|
||||||
run_poll_loop();
|
run_poll_loop();
|
||||||
|
}
|
||||||
|
|
||||||
/* Do some cleanup */
|
/* Do some cleanup */
|
||||||
deinit();
|
deinit();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user