1 /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23 /* Defines to make different thread packages compatible */
24
25 #ifndef MY_THREAD_INCLUDED
26 #define MY_THREAD_INCLUDED
27
28 #include "my_global.h" /* my_bool */
29
30 #if !defined(_WIN32)
31 #include <pthread.h>
32 #endif
33
34 #ifndef ETIME
35 #define ETIME ETIMEDOUT /* For FreeBSD */
36 #endif
37
38 #ifndef ETIMEDOUT
39 #define ETIMEDOUT 145 /* Win32 doesn't have this */
40 #endif
41
42 /*
43 MySQL can survive with 32K, but some glibc libraries require > 128K stack
44 To resolve hostnames. Also recursive stored procedures needs stack.
45 */
46 #if defined(__sparc) && (defined(__SUNPRO_CC) || defined(__SUNPRO_C))
47 #define STACK_MULTIPLIER 2UL
48 #else
49 #define STACK_MULTIPLIER 1UL
50 #endif
51
52 #if SIZEOF_CHARP > 4
53 #define DEFAULT_THREAD_STACK (STACK_MULTIPLIER * 256UL * 1024UL)
54 #else
55 #define DEFAULT_THREAD_STACK (STACK_MULTIPLIER * 192UL * 1024UL)
56 #endif
57
58 #ifdef __cplusplus
59 #define EXTERNC extern "C"
60 #else
61 #define EXTERNC
62 #endif
63
64 C_MODE_START
65
66 #ifdef _WIN32
67 typedef volatile LONG my_thread_once_t;
68 typedef DWORD my_thread_t;
69 typedef struct thread_attr
70 {
71 DWORD dwStackSize;
72 int detachstate;
73 } my_thread_attr_t;
74 #define MY_THREAD_CREATE_JOINABLE 0
75 #define MY_THREAD_CREATE_DETACHED 1
76 typedef void * (__cdecl *my_start_routine)(void *);
77 #define MY_THREAD_ONCE_INIT 0
78 #define MY_THREAD_ONCE_INPROGRESS 1
79 #define MY_THREAD_ONCE_DONE 2
80 #else
81 typedef pthread_once_t my_thread_once_t;
82 typedef pthread_t my_thread_t;
83 typedef pthread_attr_t my_thread_attr_t;
84 #define MY_THREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
85 #define MY_THREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
86 typedef void *(* my_start_routine)(void *);
87 #define MY_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
88 #endif
89
90 typedef struct st_my_thread_handle
91 {
92 my_thread_t thread;
93 #ifdef _WIN32
94 HANDLE handle;
95 #endif
96 } my_thread_handle;
97
98 int my_thread_once(my_thread_once_t *once_control, void (*init_routine)(void));
99
my_thread_self()100 static inline my_thread_t my_thread_self()
101 {
102 #ifdef _WIN32
103 return GetCurrentThreadId();
104 #else
105 return pthread_self();
106 #endif
107 }
108
my_thread_equal(my_thread_t t1,my_thread_t t2)109 static inline int my_thread_equal(my_thread_t t1, my_thread_t t2)
110 {
111 #ifdef _WIN32
112 return t1 == t2;
113 #else
114 return pthread_equal(t1, t2);
115 #endif
116 }
117
my_thread_attr_init(my_thread_attr_t * attr)118 static inline int my_thread_attr_init(my_thread_attr_t *attr)
119 {
120 #ifdef _WIN32
121 attr->dwStackSize= 0;
122 /* Set to joinable by default to match Linux */
123 attr->detachstate= MY_THREAD_CREATE_JOINABLE;
124 return 0;
125 #else
126 return pthread_attr_init(attr);
127 #endif
128 }
129
my_thread_attr_destroy(my_thread_attr_t * attr)130 static inline int my_thread_attr_destroy(my_thread_attr_t *attr)
131 {
132 #ifdef _WIN32
133 attr->dwStackSize= 0;
134 /* Set to joinable by default to match Linux */
135 attr->detachstate= MY_THREAD_CREATE_JOINABLE;
136 return 0;
137 #else
138 return pthread_attr_destroy(attr);
139 #endif
140 }
141
my_thread_attr_setstacksize(my_thread_attr_t * attr,size_t stacksize)142 static inline int my_thread_attr_setstacksize(my_thread_attr_t *attr,
143 size_t stacksize)
144 {
145 #ifdef _WIN32
146 attr->dwStackSize= (DWORD)stacksize;
147 return 0;
148 #else
149 return pthread_attr_setstacksize(attr, stacksize);
150 #endif
151 }
152
my_thread_attr_setdetachstate(my_thread_attr_t * attr,int detachstate)153 static inline int my_thread_attr_setdetachstate(my_thread_attr_t *attr,
154 int detachstate)
155 {
156 #ifdef _WIN32
157 attr->detachstate= detachstate;
158 return 0;
159 #else
160 return pthread_attr_setdetachstate(attr, detachstate);
161 #endif
162 }
163
my_thread_attr_getstacksize(my_thread_attr_t * attr,size_t * stacksize)164 static inline int my_thread_attr_getstacksize(my_thread_attr_t *attr,
165 size_t *stacksize)
166 {
167 #ifdef _WIN32
168 *stacksize= (size_t)attr->dwStackSize;
169 return 0;
170 #else
171 return pthread_attr_getstacksize(attr, stacksize);
172 #endif
173 }
174
my_thread_yield()175 static inline void my_thread_yield()
176 {
177 #ifdef _WIN32
178 SwitchToThread();
179 #else
180 sched_yield();
181 #endif
182 }
183
184 int my_thread_create(my_thread_handle *thread, const my_thread_attr_t *attr,
185 my_start_routine func, void *arg);
186 int my_thread_join(my_thread_handle *thread, void **value_ptr);
187 int my_thread_cancel(my_thread_handle *thread);
188 void my_thread_exit(void *value_ptr);
189
190
191 extern my_bool my_thread_global_init();
192 extern void my_thread_global_reinit();
193 extern void my_thread_global_end();
194 extern my_bool my_thread_init();
195 extern void my_thread_end();
196
197 C_MODE_END
198
199 #endif /* MY_THREAD_INCLUDED */
200