]> git.ipfire.org Git - thirdparty/glibc.git/blame - malloc/tst-malloc-thread-exit.c
Fix http: URL in 'configure'
[thirdparty/glibc.git] / malloc / tst-malloc-thread-exit.c
CommitLineData
3da825ce 1/* Test malloc with concurrent thread termination.
04277e02 2 Copyright (C) 2015-2019 Free Software Foundation, Inc.
3da825ce
FW
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
3da825ce
FW
18
19/* This thread spawns a number of outer threads, equal to the arena
20 limit. The outer threads run a loop which start and join two
21 different kinds of threads: the first kind allocates (attaching an
22 arena to the thread; malloc_first_thread) and waits, the second
23 kind waits and allocates (wait_first_threads). Both kinds of
24 threads exit immediately after waiting. The hope is that this will
25 exhibit races in thread termination and arena management,
26 particularly related to the arena free list. */
27
28#include <errno.h>
2a386889 29#include <malloc.h>
3da825ce
FW
30#include <pthread.h>
31#include <stdbool.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <unistd.h>
35
c23de0aa
FW
36#include <support/support.h>
37#include <support/xthread.h>
38#include <support/test-driver.h>
3da825ce
FW
39
40static bool termination_requested;
41static int inner_thread_count = 4;
42static size_t malloc_size = 32;
43
44static void
45__attribute__ ((noinline, noclone))
46unoptimized_free (void *ptr)
47{
48 free (ptr);
49}
50
51static void *
52malloc_first_thread (void * closure)
53{
54 pthread_barrier_t *barrier = closure;
c23de0aa
FW
55 void *ptr = xmalloc (malloc_size);
56 xpthread_barrier_wait (barrier);
3da825ce
FW
57 unoptimized_free (ptr);
58 return NULL;
59}
60
61static void *
62wait_first_thread (void * closure)
63{
64 pthread_barrier_t *barrier = closure;
c23de0aa
FW
65 xpthread_barrier_wait (barrier);
66 void *ptr = xmalloc (malloc_size);
3da825ce
FW
67 unoptimized_free (ptr);
68 return NULL;
69}
70
71static void *
72outer_thread (void *closure)
73{
c23de0aa 74 pthread_t *threads = xcalloc (sizeof (*threads), inner_thread_count);
3da825ce
FW
75 while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
76 {
77 pthread_barrier_t barrier;
c23de0aa 78 xpthread_barrier_init (&barrier, NULL, inner_thread_count + 1);
3da825ce
FW
79 for (int i = 0; i < inner_thread_count; ++i)
80 {
81 void *(*func) (void *);
82 if ((i % 2) == 0)
83 func = malloc_first_thread;
84 else
85 func = wait_first_thread;
c23de0aa 86 threads[i] = xpthread_create (NULL, func, &barrier);
3da825ce 87 }
c23de0aa 88 xpthread_barrier_wait (&barrier);
3da825ce 89 for (int i = 0; i < inner_thread_count; ++i)
c23de0aa
FW
90 xpthread_join (threads[i]);
91 xpthread_barrier_destroy (&barrier);
3da825ce
FW
92 }
93
94 free (threads);
95
96 return NULL;
97}
98
99static int
100do_test (void)
101{
2a386889
FW
102 /* The number of threads should be smaller than the number of
103 arenas, so that there will be some free arenas to add to the
104 arena free list. */
105 enum { outer_thread_count = 2 };
106 if (mallopt (M_ARENA_MAX, 8) == 0)
3da825ce 107 {
2a386889
FW
108 printf ("error: mallopt (M_ARENA_MAX) failed\n");
109 return 1;
3da825ce
FW
110 }
111
112 /* Leave some room for shutting down all threads gracefully. */
2a386889 113 int timeout = 3;
c23de0aa
FW
114 if (timeout > DEFAULT_TIMEOUT)
115 timeout = DEFAULT_TIMEOUT - 1;
3da825ce 116
c23de0aa 117 pthread_t *threads = xcalloc (sizeof (*threads), outer_thread_count);
3da825ce 118 for (long i = 0; i < outer_thread_count; ++i)
c23de0aa 119 threads[i] = xpthread_create (NULL, outer_thread, NULL);
3da825ce
FW
120
121 struct timespec ts = {timeout, 0};
122 if (nanosleep (&ts, NULL))
123 {
124 printf ("error: error: nanosleep: %m\n");
125 abort ();
126 }
127
128 __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);
129
130 for (long i = 0; i < outer_thread_count; ++i)
c23de0aa 131 xpthread_join (threads[i]);
3da825ce
FW
132 free (threads);
133
134 return 0;
135}
c23de0aa
FW
136
137#include <support/test-driver.c>