]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/tst-tls-manydynamic.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / elf / tst-tls-manydynamic.c
CommitLineData
01b23a30 1/* Test with many dynamic TLS variables.
bfff8b1b 2 Copyright (C) 2016-2017 Free Software Foundation, Inc.
01b23a30
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
17 <http://www.gnu.org/licenses/>. */
18
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). */
24
25#include "tst-tls-manydynamic.h"
26
27#include <dlfcn.h>
28#include <pthread.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33static int do_test (void);
34#define TEST_FUNCTION do_test ()
35#include "../test-skeleton.c"
36
37void *handles[COUNT];
38set_value_func set_value_funcs[COUNT];
39get_value_func get_value_funcs[COUNT];
40
41static void
42init_functions (void)
43{
44 for (int i = 0; i < COUNT; ++i)
45 {
46 /* Open the module. */
47 {
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)
52 {
53 printf ("error: dlopen failed: %s\n", dlerror ());
54 exit (1);
55 }
56 }
57
58 /* Obtain the setter function. */
59 {
60 char fname[100];
61 snprintf (fname, sizeof (fname), "set_value_%02d", i);
62 void *func = dlsym (handles[i], fname);
63 if (func == NULL)
64 {
65 printf ("error: dlsym: %s\n", dlerror ());
66 exit (1);
67 }
68 set_value_funcs[i] = func;
69 }
70
71 /* Obtain the getter function. */
72 {
73 char fname[100];
74 snprintf (fname, sizeof (fname), "get_value_%02d", i);
75 void *func = dlsym (handles[i], fname);
76 if (func == NULL)
77 {
78 printf ("error: dlsym: %s\n", dlerror ());
79 exit (1);
80 }
81 get_value_funcs[i] = func;
82 }
83 }
84}
85
86static pthread_barrier_t barrier;
87
88/* Running thread which forces real TLS initialization. */
89static void *
90blocked_thread_func (void *closure)
91{
92 xpthread_barrier_wait (&barrier);
93
94 /* TLS test runs here in the main thread. */
95
96 xpthread_barrier_wait (&barrier);
97 return NULL;
98}
99
100static int
101do_test (void)
102{
103 {
104 int ret = pthread_barrier_init (&barrier, NULL, 2);
105 if (ret != 0)
106 {
107 errno = ret;
108 printf ("error: pthread_barrier_init: %m\n");
109 exit (1);
110 }
111 }
112
113 pthread_t blocked_thread = xpthread_create (NULL, blocked_thread_func, NULL);
114 xpthread_barrier_wait (&barrier);
115
116 init_functions ();
117
118 struct value values[COUNT];
119 /* Initialze the TLS variables. */
120 for (int i = 0; i < COUNT; ++i)
121 {
122 for (int j = 0; j < PER_VALUE_COUNT; ++j)
123 values[i].num[j] = rand ();
124 set_value_funcs[i] (&values[i]);
125 }
126
127 /* Read back their values to check that they do not overlap. */
128 for (int i = 0; i < COUNT; ++i)
129 {
130 struct value actual;
131 get_value_funcs[i] (&actual);
132
133 for (int j = 0; j < PER_VALUE_COUNT; ++j)
134 if (actual.num[j] != values[i].num[j])
135 {
136 printf ("error: mismatch at variable %d/%d: %d != %d\n",
137 i, j, actual.num[j], values[i].num[j]);
138 exit (1);
139 }
140 }
141
142 xpthread_barrier_wait (&barrier);
143 xpthread_join (blocked_thread);
144
145 /* Close the modules. */
146 for (int i = 0; i < COUNT; ++i)
147 dlclose (handles[i]);
148
149 return 0;
150}