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