Fix powerpc fmax, fmin sNaN handling (bug 20947).
[glibc.git] / elf / tst-tls-manydynamic.c
blob29bf1394d8dd44d5400acf56bcf42612ee239bc7
1 /* Test with many dynamic TLS variables.
2 Copyright (C) 2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* This test intends to exercise dynamic TLS variable allocation. It
20 achieves this by combining dlopen (to avoid static TLS allocation
21 after static TLS resizing), many DSOs with a large variable (to
22 exceed the static TLS reserve), and an already-running thread (to
23 force full dynamic TLS initialization). */
25 #include "tst-tls-manydynamic.h"
27 #include <dlfcn.h>
28 #include <pthread.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 static int do_test (void);
34 #define TEST_FUNCTION do_test ()
35 #include "../test-skeleton.c"
37 void *handles[COUNT];
38 set_value_func set_value_funcs[COUNT];
39 get_value_func get_value_funcs[COUNT];
41 static void
42 init_functions (void)
44 for (int i = 0; i < COUNT; ++i)
46 /* Open the module. */
48 char soname[100];
49 snprintf (soname, sizeof (soname), "tst-tls-manydynamic%02dmod.so", i);
50 handles[i] = dlopen (soname, RTLD_LAZY);
51 if (handles[i] == NULL)
53 printf ("error: dlopen failed: %s\n", dlerror ());
54 exit (1);
58 /* Obtain the setter function. */
60 char fname[100];
61 snprintf (fname, sizeof (fname), "set_value_%02d", i);
62 void *func = dlsym (handles[i], fname);
63 if (func == NULL)
65 printf ("error: dlsym: %s\n", dlerror ());
66 exit (1);
68 set_value_funcs[i] = func;
71 /* Obtain the getter function. */
73 char fname[100];
74 snprintf (fname, sizeof (fname), "get_value_%02d", i);
75 void *func = dlsym (handles[i], fname);
76 if (func == NULL)
78 printf ("error: dlsym: %s\n", dlerror ());
79 exit (1);
81 get_value_funcs[i] = func;
86 static pthread_barrier_t barrier;
88 /* Running thread which forces real TLS initialization. */
89 static void *
90 blocked_thread_func (void *closure)
92 xpthread_barrier_wait (&barrier);
94 /* TLS test runs here in the main thread. */
96 xpthread_barrier_wait (&barrier);
97 return NULL;
100 static int
101 do_test (void)
104 int ret = pthread_barrier_init (&barrier, NULL, 2);
105 if (ret != 0)
107 errno = ret;
108 printf ("error: pthread_barrier_init: %m\n");
109 exit (1);
113 pthread_t blocked_thread = xpthread_create (NULL, blocked_thread_func, NULL);
114 xpthread_barrier_wait (&barrier);
116 init_functions ();
118 struct value values[COUNT];
119 /* Initialze the TLS variables. */
120 for (int i = 0; i < COUNT; ++i)
122 for (int j = 0; j < PER_VALUE_COUNT; ++j)
123 values[i].num[j] = rand ();
124 set_value_funcs[i] (&values[i]);
127 /* Read back their values to check that they do not overlap. */
128 for (int i = 0; i < COUNT; ++i)
130 struct value actual;
131 get_value_funcs[i] (&actual);
133 for (int j = 0; j < PER_VALUE_COUNT; ++j)
134 if (actual.num[j] != values[i].num[j])
136 printf ("error: mismatch at variable %d/%d: %d != %d\n",
137 i, j, actual.num[j], values[i].num[j]);
138 exit (1);
142 xpthread_barrier_wait (&barrier);
143 xpthread_join (blocked_thread);
145 /* Close the modules. */
146 for (int i = 0; i < COUNT; ++i)
147 dlclose (handles[i]);
149 return 0;