From 7cbcc178e04602b673c1c86abf16b34668983abd Mon Sep 17 00:00:00 2001 From: Pedro Falcato Date: Fri, 9 Jun 2023 17:55:19 +0100 Subject: [PATCH] main: Fix deadlocks on _threads exit See issue (https://github.com/antonblanchard/will-it-scale/issues/33). Since async pthread_cancel on threads that do hold locks is wrong, we instead create a separate process that holds the threads. On exit, the holding process just exits, and the parent wait()'s for it, and cleans up the testcase. Signed-off-by: Pedro Falcato --- main.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/main.c b/main.c index c16e0cf..efb5ed2 100644 --- a/main.c +++ b/main.c @@ -113,6 +113,8 @@ static bool use_affinity = true; static pthread_t threads[2*MAX_TASKS]; static int nr_threads; +static pid_t thread_controller = 0; + void new_task(void *(func)(void *), void *arg) { pthread_create(&threads[nr_threads++], NULL, func, arg); @@ -313,6 +315,19 @@ int main(int argc, char *argv[]) testcase_prepare(opt_tasks); +#ifdef THREADS + thread_controller = fork(); + + if (thread_controller < 0) { + perror("fork"); + exit(1); + } else if (thread_controller > 0) { + pid_t wpid = wait(NULL); + assert(wpid == thread_controller); + goto out; + } +#endif + #if HAVE_HWLOC hwloc_topology_init(&topology); hwloc_topology_load(topology); @@ -437,7 +452,11 @@ int main(int argc, char *argv[]) if (opt_iterations && (iterations > (opt_iterations + WARMUP_ITERATIONS))) { printf("average:%llu\n", total / opt_iterations); +#ifdef THREADS + exit(0); +#else break; +#endif } } @@ -450,6 +469,9 @@ int main(int argc, char *argv[]) } #endif free(args); +#ifdef THREADS +out: +#endif testcase_cleanup(); exit(0);