1 /* Check that __pthread_destroy_specific works correctly if it has to skip
2    unused slots.
3    Copyright (C) 2000-2022 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5 
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10 
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library;  if not, see
18    <https://www.gnu.org/licenses/>.  */
19 
20 #define _GNU_SOURCE
21 
22 #include <error.h>
23 #include <pthread.h>
24 #include <stdio.h>
25 
26 
27 #define N_k 42
28 
29 static volatile int v;
30 
31 static void
d(void * x)32 d (void *x)
33 {
34   int *i = (int *) x;
35 
36   if (v != *i)
37     error (1, 0, "FAILED %d %d", v, *i);
38   v += 2;
39 
40   printf ("%s %d\n", __FUNCTION__, *i);
41   fflush (stdout);
42 }
43 
44 static void *
test(void * x)45 test (void *x)
46 {
47   pthread_key_t k[N_k];
48   static int k_v[N_k];
49 
50   int err, i;
51 
52   for (i = 0; i < N_k; i += 1)
53     {
54       err = pthread_key_create (&k[i], &d);
55       if (err != 0)
56 	error (1, err, "pthread_key_create %d", i);
57     }
58 
59   for (i = 0; i < N_k; i += 1)
60     {
61       k_v[i] = i;
62       err = pthread_setspecific (k[i], &k_v[i]);
63       if (err != 0)
64 	error (1, err, "pthread_setspecific %d", i);
65     }
66 
67   /* Delete every even key.  */
68   for (i = 0; i < N_k; i += 2)
69     {
70       err = pthread_key_delete (k[i]);
71       if (err != 0)
72 	error (1, err, "pthread_key_delete %d", i);
73     }
74 
75   v = 1;
76   pthread_exit (NULL);
77 
78   return NULL;
79 }
80 
81 
82 int
main(void)83 main (void)
84 {
85   pthread_t tid;
86   int err;
87 
88   err = pthread_create (&tid, 0, test, NULL);
89   if (err != 0)
90     error (1, err, "pthread_create");
91 
92   err = pthread_join (tid, NULL);
93   if (err)
94     error (1, err, "pthread_join");
95 
96   if (v != N_k + 1)
97     error (1, 0, "FAILED END %d %d", v, N_k + 1);
98 
99   return 0;
100 }
101