Bump to m4 1.4.19
[platform/upstream/m4.git] / tests / pthread-thread.c
1 /* Creating and controlling POSIX threads.
2    Copyright (C) 2010-2021 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8
9    This program 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
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, see <https://www.gnu.org/licenses/>.  */
16
17 /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019.  */
18
19 #include <config.h>
20
21 /* Specification.  */
22 #include <pthread.h>
23
24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
25 # include "windows-thread.h"
26 #else
27 # include <stdlib.h>
28 #endif
29
30 typedef void * (* pthread_main_function_t) (void *);
31
32 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
33
34 int
35 pthread_attr_init (pthread_attr_t *attr)
36 {
37   *attr = PTHREAD_CREATE_JOINABLE;
38   return 0;
39 }
40
41 int
42 pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstatep)
43 {
44   *detachstatep = *attr & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED);
45   return 0;
46 }
47
48 int
49 pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
50 {
51   if (!(detachstate == PTHREAD_CREATE_JOINABLE
52         || detachstate == PTHREAD_CREATE_DETACHED))
53     return EINVAL;
54   *attr ^= (*attr ^ detachstate)
55            & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED);
56   return 0;
57 }
58
59 int
60 pthread_attr_destroy (pthread_attr_t *attr _GL_UNUSED)
61 {
62   return 0;
63 }
64
65 #endif
66
67 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
68 /* Use Windows threads.  */
69
70 int
71 pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
72                 pthread_main_function_t mainfunc, void *arg)
73 {
74   unsigned int glwthread_attr =
75     (attr != NULL
76      && (*attr & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED))
77         != PTHREAD_CREATE_JOINABLE
78      ? GLWTHREAD_ATTR_DETACHED
79      : 0);
80   return glwthread_thread_create (threadp, glwthread_attr, mainfunc, arg);
81 }
82
83 pthread_t
84 pthread_self (void)
85 {
86   return glwthread_thread_self ();
87 }
88
89 int
90 pthread_equal (pthread_t thread1, pthread_t thread2)
91 {
92   return thread1 == thread2;
93 }
94
95 int
96 pthread_detach (pthread_t thread)
97 {
98   return glwthread_thread_detach (thread);
99 }
100
101 int
102 pthread_join (pthread_t thread, void **valuep)
103 {
104   return glwthread_thread_join (thread, valuep);
105 }
106
107 void
108 pthread_exit (void *value)
109 {
110   glwthread_thread_exit (value);
111 }
112
113 #elif HAVE_PTHREAD_H
114 /* Provide workarounds for POSIX threads.  */
115
116 # if PTHREAD_CREATE_IS_INLINE
117 int
118 pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
119                 pthread_main_function_t mainfunc, void *arg)
120 #  undef pthread_create
121 {
122   return pthread_create (threadp, attr, mainfunc, arg);
123 }
124
125 int
126 pthread_attr_init (pthread_attr_t *attr)
127 #  undef pthread_attr_init
128 {
129   return pthread_attr_init (attr);
130 }
131
132 # endif
133
134 #else
135 /* Provide a dummy implementation for single-threaded applications.  */
136
137 int
138 pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
139                 pthread_main_function_t mainfunc, void *arg)
140 {
141   /* The maximum number of threads is reached.  Do not create a thread.  */
142   return EAGAIN;
143 }
144
145 pthread_t
146 pthread_self (void)
147 {
148   return 42;
149 }
150
151 int
152 pthread_equal (pthread_t thread1, pthread_t thread2)
153 {
154   return thread1 == thread2;
155 }
156
157 int
158 pthread_detach (pthread_t thread)
159 {
160   /* There are no joinable threads.  */
161   return EINVAL;
162 }
163
164 int
165 pthread_join (pthread_t thread, void **valuep)
166 {
167   /* There are no joinable threads.  */
168   return EINVAL;
169 }
170
171 void
172 pthread_exit (void *value)
173 {
174   /* There is just one thread, so the process exits.  */
175   exit (0);
176 }
177
178 #endif