Linux: Make generic fcntl.h the default one
[glibc.git] / nptl / tst-cleanup4.c
blobbc58b074fe542790330306cde23a0feba45044da
1 /* Copyright (C) 2003-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <pthread.h>
19 #include <shlib-compat.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
24 /* LinuxThreads pthread_cleanup_{push,pop} helpers. */
25 extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
26 void (*__routine) (void *),
27 void *__arg);
28 compat_symbol_reference (libpthread, _pthread_cleanup_push,
29 _pthread_cleanup_push, GLIBC_2_0);
30 extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
31 int __execute);
32 compat_symbol_reference (libpthread, _pthread_cleanup_pop,
33 _pthread_cleanup_pop, GLIBC_2_0);
35 static int fds[2];
36 static pthread_barrier_t b2;
37 static int global;
39 /* Defined in tst-cleanup4aux.c, never compiled with -fexceptions. */
40 extern void fn5 (void);
41 extern void fn7 (void);
42 extern void fn9 (void);
44 void
45 clh (void *arg)
47 int val = (long int) arg;
49 printf ("clh (%d)\n", val);
51 global *= val;
52 global += val;
56 static __attribute__((noinline)) void
57 fn_read (void)
59 int r = pthread_barrier_wait (&b2);
60 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
62 printf ("%s: barrier_wait failed\n", __FUNCTION__);
63 exit (1);
66 char c;
67 read (fds[0], &c, 1);
71 __attribute__((noinline)) void
72 fn0 (void)
74 pthread_cleanup_push (clh, (void *) 1l);
76 fn_read ();
78 pthread_cleanup_pop (1);
82 __attribute__((noinline)) void
83 fn1 (void)
85 /* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
86 struct _pthread_cleanup_buffer b;
87 _pthread_cleanup_push (&b, clh, (void *) 2l);
89 fn0 ();
91 _pthread_cleanup_pop (&b, 1);
95 static __attribute__((noinline)) void
96 fn2 (void)
98 pthread_cleanup_push (clh, (void *) 3l);
100 fn1 ();
102 pthread_cleanup_pop (1);
106 static void *
107 tf (void *a)
109 switch ((long) a)
111 case 0:
112 fn2 ();
113 break;
114 case 1:
115 fn5 ();
116 break;
117 case 2:
118 fn7 ();
119 break;
120 case 3:
121 fn9 ();
122 break;
125 return NULL;
130 do_test (void)
132 int result = 0;
134 if (pipe (fds) != 0)
136 puts ("pipe failed");
137 exit (1);
140 if (pthread_barrier_init (&b2, NULL, 2) != 0)
142 puts ("b2 init failed");
143 exit (1);
146 const int expect[] =
148 15, /* 1 2 3 */
149 276, /* 1 4 5 6 */
150 120, /* 1 7 8 */
151 460 /* 1 2 9 10 */
154 long i;
155 for (i = 0; i < 4; ++i)
157 global = 0;
159 printf ("test %ld\n", i);
161 pthread_t th;
162 if (pthread_create (&th, NULL, tf, (void *) i) != 0)
164 puts ("create failed");
165 exit (1);
168 int e = pthread_barrier_wait (&b2);
169 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
171 printf ("%s: barrier_wait failed\n", __FUNCTION__);
172 exit (1);
175 pthread_cancel (th);
177 void *r;
178 if ((e = pthread_join (th, &r)) != 0)
180 printf ("join failed: %d\n", e);
181 _exit (1);
184 if (r != PTHREAD_CANCELED)
186 puts ("thread not canceled");
187 exit (1);
190 if (global != expect[i])
192 printf ("global = %d, expected %d\n", global, expect[i]);
193 result = 1;
197 return result;
200 #define TEST_FUNCTION do_test ()
201 #include "../test-skeleton.c"