malloc: Add threaded variants of single-threaded malloc tests

Single-threaded malloc tests exercise only the SINGLE_THREAD_P paths in
the malloc implementation.  This commit runs variants of these tests in
a multi-threaded environment in order to exercise the alternate code
paths in the same test scenarios, thus potentially improving coverage.

$(test)-threaded-main and $(test)-threaded-worker variants are
introduced for most single-threaded malloc tests (with a small number of
exceptions).  The -main variants run the base test in a main thread
while the test environment has an alternate thread running, whereas the
-worker variants run the test in an alternate thread while the main
thread waits on it.

The tests themselves are unmodified, and the change is accomplished by
using -DTEST_IN_THREAD at compile time, which instructs support/
infrastructure to run the test while an alternate thread waits on it.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
Arjun Shankar 2025-11-14 18:31:46 +01:00
parent bd0e88f05c
commit 244c404ae8
1 changed files with 66 additions and 6 deletions

View File

@ -297,10 +297,57 @@ $(addprefix $(objpfx), $(tests-link-with-libpthread)): $(shared-thread-library)
$(tests-link-with-libpthread:%=$(objpfx)%-malloc-largetcache): \
$(shared-thread-library)
# 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.
# List of tests which don't have threaded-{main,worker} copies:
# already multithreaded tests,
# static copies of some regular tests,
# tst-compathooks-on: hook/call counts mismatch due to threading allocations
# tst-interpose-nothread: interposes malloc without locking
tests-exclude-threaded = \
$(tests-link-with-libpthread) \
$(tests-static) \
tst-compathooks-on \
tst-interpose-nothread \
# tests-exclude-threaded
tests-threaded-main = $(addsuffix -threaded-main, \
$(filter-out $(tests-exclude-threaded), \
$(tests)))
$(addprefix $(objpfx), $(tests-threaded-main)): $(shared-thread-library)
tests-threaded-worker = $(addsuffix -threaded-worker, \
$(filter-out $(tests-exclude-threaded), \
$(tests)))
$(addprefix $(objpfx), $(tests-threaded-worker)): $(shared-thread-library)
tests += $(tests-threaded-main) $(tests-threaded-worker)
# This avoids a test combination explosion with two threaded copies of each
# of these variants:
tests-exclude-malloc-check += $(tests-threaded-main) $(tests-threaded-worker)
tests-exclude-mcheck += $(tests-threaded-main) $(tests-threaded-worker)
tests-exclude-hugetlb1 += $(tests-threaded-main) $(tests-threaded-worker)
tests-exclude-hugetlb2 += $(tests-threaded-main) $(tests-threaded-worker)
tests-exclude-largetcache += $(tests-threaded-main) $(tests-threaded-worker)
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
others-extras = mcheck-init.o
# Compile threaded-{main,worker} tests from their corresponding base
# sources, but with -DTEST_IN_THREAD appropriately defined so that support
# infrastructure runs them in a multi-threaded program.
$(objpfx)%-threaded-main.o: CPPFLAGS += -DTEST_IN_THREAD=TEST_THREAD_MAIN
$(objpfx)%-threaded-main.o: %.c $(before-compile)
$(compile-command.c)
$(objpfx)%-threaded-worker.o: CPPFLAGS += -DTEST_IN_THREAD=TEST_THREAD_WORKER
$(objpfx)%-threaded-worker.o: %.c $(before-compile)
$(compile-command.c)
# Include the cleanup handler.
aux := set-freeres thread-freeres
@ -384,13 +431,22 @@ endif
endif
endif
tst-malloc-check-ENV = MALLOC_CHECK_=3 \
malloc-check-env = \
MALLOC_CHECK_=3 \
LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
tst-malloc-usable-ENV = MALLOC_CHECK_=3 \
LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
malloc-check-tunables-env = \
GLIBC_TUNABLES=glibc.malloc.check=3 \
LD_PRELOAD=$(objpfx)/libc_malloc_debug.so
tst-malloc-check-ENV = $(malloc-check-env)
tst-malloc-usable-ENV = $(malloc-check-env)
tst-malloc-usable-threaded-main-ENV = $(malloc-check-env)
tst-malloc-usable-threaded-worker-ENV = $(malloc-check-env)
tst-malloc-usable-tunables-ENV = $(malloc-check-tunables-env)
tst-malloc-usable-tunables-threaded-main-ENV = $(malloc-check-tunables-env)
tst-malloc-usable-tunables-threaded-worker-ENV = $(malloc-check-tunables-env)
tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
CPPFLAGS-malloc-debug.c += -DUSE_TCACHE=0
@ -455,6 +511,10 @@ tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
# libc_malloc_debug.so.
$(objpfx)tst-mallocstate: $(objpfx)libc_malloc_debug.so
$(objpfx)tst-mallocstate-malloc-check: $(objpfx)libc_malloc_debug.so
tst-mallocstate-threaded-main-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
$(objpfx)tst-mallocstate-threaded-main: $(objpfx)libc_malloc_debug.so
tst-mallocstate-threaded-worker-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
$(objpfx)tst-mallocstate-threaded-worker: $(objpfx)libc_malloc_debug.so
$(objpfx)tst-aligned-alloc-random.out: $(objpfx)tst-aligned_alloc-lib.so
$(objpfx)tst-aligned-alloc-random-thread.out: $(objpfx)tst-aligned_alloc-lib.so