[PATCH v2] Add threaded variants of single-threaded malloc tests
Florian Weimer
fweimer@redhat.com
Tue Nov 11 11:32:01 GMT 2025
* Arjun Shankar:
> +# tests-threaded-{main,worker} are variants of base malloc tests that are
> +# run in a multi-threaded program. The main variant is run in the main
> +# thread while an alternate thread exists, and the worker variant is run in
> +# a worker thread while the main thread waits on it.
> +
> +tests-exclude-threaded = \
> + $(tests-link-with-libpthread) \
> + $(tests-static) \
> + tst-compathooks-off \
> + tst-compathooks-on \
> + tst-interpose-nothread \
> + tst-malloc-usable \
> + tst-malloc-usable-tunables \
> + tst-mallocstate \
> + tst-memalign-2 \
> + tst-mxfast \
> + tst-safe-linking \
> +# tests-exclude-threaded
Please add comments why these tests are excluded.
> +
> +tests-threaded-main = $(addsuffix -threaded-main, \
> + $(filter-out $(tests-exclude-threaded), \
> + $(tests)))
> +$(addprefix $(objpfx), $(tests-threaded-main)): $(shared-thread-library)
> +$(addprefix $(objpfx), $(tests-threaded-main:%=%-malloc-check)): $(shared-thread-library)
> +$(addprefix $(objpfx), $(tests-threaded-main:%=%-malloc-hugetlb1)): $(shared-thread-library)
> +$(addprefix $(objpfx), $(tests-threaded-main:%=%-malloc-hugetlb2)): $(shared-thread-library)
> +$(addprefix $(objpfx), $(tests-threaded-main:%=%-mcheck)): $(shared-thread-library)
> +$(addprefix $(objpfx), $(tests-threaded-main:%=%-malloc-largetcache)): $(shared-thread-library)
I think it would be sufficient to add the two threading tests in
parallel to -check, -hugetlb1, etc. So two more test variants instead
of tripling the number of tests.
> +tests-threaded-worker = $(addsuffix -threaded-worker, \
> + $(filter-out $(tests-exclude-threaded) \
> + tst-free-errno \
> + tst-mallocfork, \
> + $(tests)))
Likewise why are tst-free-errno, tst-mallocfork excluded?
> diff --git a/support/Makefile b/support/Makefile
> index 2043e4e590..a7b1b39782 100644
> --- a/support/Makefile
> +++ b/support/Makefile
> @@ -98,6 +98,7 @@ libsupport-routines = \
> support_test_compare_failure \
> support_test_compare_string \
> support_test_compare_string_wide \
> + support_test_in_thread_wrapper \
> support_test_main \
> support_test_verify_impl \
> support_wait_for_thread_exit \
I think the support changes should be in a separate patch.
> diff --git a/support/support_test_in_thread_wrapper.c b/support/support_test_in_thread_wrapper.c
> new file mode 100644
> index 0000000000..a4d5df0c12
> --- /dev/null
> +++ b/support/support_test_in_thread_wrapper.c
> @@ -0,0 +1,90 @@
> +/* Test-in-thread wrapper function for the test driver.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
Please add a comment here explaining the need for separate compilation
(both for Hurd and for static linking).
> +pthread_barrier_t barrier;
This needs to be static.
> +static void *
> +empty_thread (void *closure)
> +{
> + /* Make sure that the alternate thread waits (and exists) till the main
> + thread finishes running the test. */
> + xpthread_barrier_wait (&barrier);
> +
> + return NULL;
> +}
> +
> +int
> +support_test_in_thread_wrapper (int argc, char **argv,
> + const struct test_config *config)
> +{
> + pthread_t thread;
> + struct test_thread_args closure = {.argc = argc,
> + .argv = argv,
> + .config = config};
> +
> + if (config->test_in_thread == THREAD_MAIN)
> + {
> + xpthread_barrier_init (&barrier, NULL, 2);
> + thread = xpthread_create (NULL, empty_thread, NULL);
> +
> + /* Run the test in the main thread. */
> + test_thread (&closure);
> +
> + /* Signal to the alternate thread that it can return. */
> + xpthread_barrier_wait (&barrier);
> + xpthread_join (thread);
> + }
> + else /* config->test_in_thread == THREAD_WORKER. */
> + {
> + /* Run the test in an alternate thread. */
> + thread = xpthread_create (NULL, test_thread, &closure);
> + xpthread_join (thread);
> + }
> +
> + return closure.ret;
> +}
> diff --git a/support/test-driver.c b/support/test-driver.c
> index 40e2bc0ee2..cb65b9f078 100644
> --- a/support/test-driver.c
> +++ b/support/test-driver.c
> @@ -168,5 +168,13 @@ main (int argc, char **argv)
> test_config.optstring = "+";
> #endif
>
> +#ifdef TEST_IN_THREAD
> + test_config.test_in_thread = TEST_IN_THREAD;
> + test_config.test_in_thread_wrapper = support_test_in_thread_wrapper;
> +#else
> + test_config.test_in_thread = 0;
> + test_config.test_in_thread_wrapper = NULL;
> +#endif
> +
> return support_test_main (argc, argv, &test_config);
> }
> diff --git a/support/test-driver.h b/support/test-driver.h
> index 9291611fbf..2d76ba4aab 100644
> --- a/support/test-driver.h
> +++ b/support/test-driver.h
> @@ -38,6 +38,8 @@ struct test_config
> char no_setvbuf; /* Boolean flag to disable setvbuf. */
> char run_command_mode; /* Boolean flag to indicate run-command-mode. */
> const char *optstring; /* Short command line options. */
> + int test_in_thread; /* 0 => no threading, MAIN, WORKER. */
> + int (*test_in_thread_wrapper) (int, char **, const struct test_config *);
> };
>
> enum
> @@ -54,6 +56,11 @@ enum
> /* Used for command line argument parsing. */
> OPT_DIRECT = 1000,
> OPT_TESTDIR,
> +
> + /* Used for TEST_IN_THREAD to run single-threaded tests in a
> + multi-threaded environment. */
> + THREAD_MAIN = 1,
> + THREAD_WORKER = 2,
> };
I would add a prefix, something like TEST_THREAD_MAIN.
> /* Options provided by the test driver. */
> @@ -78,6 +85,9 @@ extern unsigned int test_verbose;
> printf (__VA_ARGS__); \
> } while (0);
>
> +extern int support_test_in_thread_wrapper (int argc, char **argv,
> + const struct test_config *config);
> +
This should have a comment.
Thanks,
Florian
More information about the Libc-alpha
mailing list