1
by brian
clean slate |
1 |
/* Copyright (C) 2000 MySQL AB
|
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 as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
14 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
16 |
/* Defines to make different thread packages compatible */
|
|
17 |
||
18 |
#ifndef _my_pthread_h
|
|
19 |
#define _my_pthread_h
|
|
20 |
||
549
by Monty Taylor
Took gettext.h out of header files. |
21 |
#include <stdint.h> |
520.8.3
by Monty Taylor
Moved hash back to mysys. |
22 |
#include <stdbool.h> |
549
by Monty Taylor
Took gettext.h out of header files. |
23 |
#include <unistd.h> |
24 |
||
1
by brian
clean slate |
25 |
#ifndef ETIME
|
26 |
#define ETIME ETIMEDOUT /* For FreeBSD */ |
|
27 |
#endif
|
|
28 |
||
29 |
#ifdef __cplusplus
|
|
30 |
#define EXTERNC extern "C"
|
|
31 |
extern "C" { |
|
32 |
#else
|
|
33 |
#define EXTERNC
|
|
34 |
#endif /* __cplusplus */ |
|
35 |
||
36 |
#include <pthread.h> |
|
37 |
#ifndef _REENTRANT
|
|
38 |
#define _REENTRANT
|
|
39 |
#endif
|
|
40 |
#ifdef HAVE_SCHED_H
|
|
41 |
#include <sched.h> |
|
42 |
#endif
|
|
43 |
#ifdef HAVE_SYNCH_H
|
|
44 |
#include <synch.h> |
|
45 |
#endif
|
|
46 |
||
47 |
#define pthread_key(T,V) pthread_key_t V
|
|
48 |
#define pthread_detach_this_thread()
|
|
49 |
#define pthread_handler_t EXTERNC void *
|
|
50 |
typedef void *(* pthread_handler)(void *); |
|
51 |
||
52 |
/* Test first for RTS or FSU threads */
|
|
53 |
||
54 |
#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
|
|
55 |
#define HAVE_rts_threads
|
|
56 |
extern int my_pthread_create_detached; |
|
57 |
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
|
|
58 |
#define PTHREAD_CREATE_DETACHED &my_pthread_create_detached
|
|
59 |
#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL
|
|
60 |
#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
|
|
61 |
#define USE_ALARM_THREAD
|
|
62 |
#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ |
|
63 |
||
64 |
#ifndef HAVE_NONPOSIX_SIGWAIT
|
|
65 |
#define my_sigwait(A,B) sigwait((A),(B))
|
|
66 |
#else
|
|
67 |
int my_sigwait(const sigset_t *set,int *sig); |
|
68 |
#endif
|
|
69 |
||
70 |
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
|
|
71 |
#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
|
|
72 |
extern int my_pthread_mutex_init(pthread_mutex_t *mp, |
|
73 |
const pthread_mutexattr_t *attr); |
|
74 |
#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b))
|
|
75 |
extern int my_pthread_cond_init(pthread_cond_t *mp, |
|
76 |
const pthread_condattr_t *attr); |
|
77 |
#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ |
|
78 |
||
79 |
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
|
|
80 |
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
|
|
81 |
#endif
|
|
82 |
||
83 |
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT)
|
|
84 |
int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ |
|
85 |
#endif
|
|
86 |
||
87 |
||
88 |
/*
|
|
89 |
We define my_sigset() and use that instead of the system sigset() so that
|
|
90 |
we can favor an implementation based on sigaction(). On some systems, such
|
|
91 |
as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
|
|
92 |
we want to make sure that no such flags are set.
|
|
93 |
*/
|
|
94 |
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
|
|
95 |
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
|
|
51.3.28
by Jay Pipes
DBUG entirely removed from server and client |
96 |
assert((A) != 0); \
|
1
by brian
clean slate |
97 |
sigemptyset(&l_set); \
|
98 |
l_s.sa_handler = (B); \
|
|
99 |
l_s.sa_mask = l_set; \
|
|
100 |
l_s.sa_flags = 0; \
|
|
101 |
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
|
|
51.3.28
by Jay Pipes
DBUG entirely removed from server and client |
102 |
assert(l_rc == 0); \
|
1
by brian
clean slate |
103 |
} while (0)
|
104 |
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
|
|
105 |
#define my_sigset(A,B) sigset((A),(B))
|
|
106 |
#elif !defined(my_sigset)
|
|
107 |
#define my_sigset(A,B) signal((A),(B))
|
|
108 |
#endif
|
|
109 |
||
110 |
#ifndef my_pthread_attr_setprio
|
|
111 |
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
|
|
112 |
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
|
|
113 |
#else
|
|
114 |
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority); |
|
115 |
#endif
|
|
116 |
#endif
|
|
117 |
||
118 |
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE)
|
|
119 |
#define pthread_attr_setscope(A,B)
|
|
120 |
#endif
|
|
121 |
||
7
by Brian Aker
Further cleanup on pthreads. |
122 |
#if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
|
1
by brian
clean slate |
123 |
extern int my_pthread_cond_timedwait(pthread_cond_t *cond, |
124 |
pthread_mutex_t *mutex, |
|
125 |
struct timespec *abstime); |
|
126 |
#define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
|
|
127 |
#endif
|
|
128 |
||
129 |
/* FSU THREADS */
|
|
130 |
#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
|
|
131 |
#define pthread_key_delete(A) pthread_dummy(0)
|
|
132 |
#endif
|
|
133 |
||
134 |
#ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */ |
|
135 |
#define pthread_cond_destroy(A) pthread_dummy(0)
|
|
136 |
#define pthread_mutex_destroy(A) pthread_dummy(0)
|
|
137 |
#define pthread_attr_delete(A) pthread_dummy(0)
|
|
138 |
#define pthread_condattr_delete(A) pthread_dummy(0)
|
|
139 |
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
|
|
140 |
#define pthread_equal(A,B) ((A) == (B))
|
|
141 |
#define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b))
|
|
142 |
#define pthread_attr_init(A) pthread_attr_create(A)
|
|
143 |
#define pthread_attr_destroy(A) pthread_attr_delete(A)
|
|
144 |
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
|
|
145 |
#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
|
|
146 |
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
|
|
147 |
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
|
|
148 |
#undef pthread_detach_this_thread
|
|
149 |
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
|
|
150 |
#endif
|
|
151 |
||
152 |
#ifdef HAVE_DARWIN5_THREADS
|
|
153 |
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
|
|
154 |
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
|
|
155 |
#define pthread_condattr_init(A) pthread_dummy(0)
|
|
156 |
#define pthread_condattr_destroy(A) pthread_dummy(0)
|
|
157 |
#undef pthread_detach_this_thread
|
|
158 |
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
|
|
159 |
#endif
|
|
160 |
||
161 |
#if (defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT))
|
|
162 |
/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
|
|
163 |
#define pthread_key_create(A,B) \
|
|
164 |
pthread_keycreate(A,(B) ?\
|
|
165 |
(pthread_destructor_t) (B) :\
|
|
166 |
(pthread_destructor_t) pthread_dummy)
|
|
167 |
#define pthread_attr_init(A) pthread_attr_create(A)
|
|
168 |
#define pthread_attr_destroy(A) pthread_attr_delete(A)
|
|
169 |
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
|
|
170 |
#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
|
|
171 |
#ifndef pthread_sigmask
|
|
172 |
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
|
|
173 |
#endif
|
|
174 |
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
|
|
175 |
#undef pthread_detach_this_thread
|
|
176 |
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
|
|
177 |
#else
|
|
178 |
#define HAVE_PTHREAD_KILL
|
|
179 |
#endif
|
|
180 |
||
181 |
#if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
|
|
182 |
#undef pthread_mutex_trylock
|
|
183 |
#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
|
|
184 |
int my_pthread_mutex_trylock(pthread_mutex_t *mutex); |
|
185 |
#endif
|
|
186 |
||
187 |
#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
|
|
188 |
/* no pthread_yield() available */
|
|
189 |
#ifdef HAVE_SCHED_YIELD
|
|
190 |
#define pthread_yield() sched_yield()
|
|
191 |
#elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */ |
|
192 |
#define pthread_yield() pthread_yield_np()
|
|
193 |
#endif
|
|
194 |
#endif
|
|
195 |
||
196 |
/*
|
|
197 |
The defines set_timespec and set_timespec_nsec should be used
|
|
198 |
for calculating an absolute time at which
|
|
199 |
pthread_cond_timedwait should timeout
|
|
200 |
*/
|
|
201 |
#ifdef HAVE_TIMESPEC_TS_SEC
|
|
202 |
#ifndef set_timespec
|
|
203 |
#define set_timespec(ABSTIME,SEC) \
|
|
204 |
{ \
|
|
205 |
(ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
|
|
206 |
(ABSTIME).ts_nsec=0; \
|
|
207 |
}
|
|
208 |
#endif /* !set_timespec */ |
|
209 |
#ifndef set_timespec_nsec
|
|
210 |
#define set_timespec_nsec(ABSTIME,NSEC) \
|
|
211 |
{ \
|
|
151
by Brian Aker
Ulonglong to uint64_t |
212 |
uint64_t now= my_getsystime() + (NSEC/100); \
|
398.1.8
by Monty Taylor
Enabled -Wlong-long. |
213 |
(ABSTIME).ts_sec= (now / 10000000UL); \
|
214 |
(ABSTIME).ts_nsec= (now % 10000000UL * 100 + ((NSEC) % 100)); \
|
|
1
by brian
clean slate |
215 |
}
|
216 |
#endif /* !set_timespec_nsec */ |
|
217 |
#else
|
|
218 |
#ifndef set_timespec
|
|
219 |
#define set_timespec(ABSTIME,SEC) \
|
|
220 |
{\
|
|
221 |
struct timeval tv;\
|
|
222 |
gettimeofday(&tv,0);\
|
|
223 |
(ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
|
|
224 |
(ABSTIME).tv_nsec=tv.tv_usec*1000;\
|
|
225 |
}
|
|
226 |
#endif /* !set_timespec */ |
|
227 |
#ifndef set_timespec_nsec
|
|
228 |
#define set_timespec_nsec(ABSTIME,NSEC) \
|
|
229 |
{\
|
|
151
by Brian Aker
Ulonglong to uint64_t |
230 |
uint64_t now= my_getsystime() + (NSEC/100); \
|
398.1.8
by Monty Taylor
Enabled -Wlong-long. |
231 |
(ABSTIME).tv_sec= (time_t) (now / 10000000UL); \
|
232 |
(ABSTIME).tv_nsec= (long) (now % 10000000UL * 100 + ((NSEC) % 100)); \
|
|
1
by brian
clean slate |
233 |
}
|
234 |
#endif /* !set_timespec_nsec */ |
|
235 |
#endif /* HAVE_TIMESPEC_TS_SEC */ |
|
236 |
||
237 |
/* safe_mutex adds checking to mutex for easier debugging */
|
|
238 |
||
239 |
typedef struct st_safe_mutex_t |
|
240 |
{
|
|
241 |
pthread_mutex_t global,mutex; |
|
242 |
const char *file; |
|
411
by Brian Aker
Removed legacy bits around enum. |
243 |
uint32_t line,count; |
1
by brian
clean slate |
244 |
pthread_t thread; |
245 |
} safe_mutex_t; |
|
246 |
||
247 |
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr, |
|
411
by Brian Aker
Removed legacy bits around enum. |
248 |
const char *file, uint32_t line); |
249 |
int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file, uint32_t line); |
|
250 |
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint32_t line); |
|
251 |
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint32_t line); |
|
1
by brian
clean slate |
252 |
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, |
411
by Brian Aker
Removed legacy bits around enum. |
253 |
uint32_t line); |
1
by brian
clean slate |
254 |
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, |
411
by Brian Aker
Removed legacy bits around enum. |
255 |
struct timespec *abstime, const char *file, uint32_t line); |
1
by brian
clean slate |
256 |
void safe_mutex_global_init(void); |
549
by Monty Taylor
Took gettext.h out of header files. |
257 |
void safe_mutex_end(void); |
1
by brian
clean slate |
258 |
|
259 |
/* Wrappers if safe mutex is actually used */
|
|
260 |
#define safe_mutex_assert_owner(mp)
|
|
261 |
#define safe_mutex_assert_not_owner(mp)
|
|
262 |
||
7
by Brian Aker
Further cleanup on pthreads. |
263 |
#if defined(MY_PTHREAD_FASTMUTEX)
|
1
by brian
clean slate |
264 |
typedef struct st_my_pthread_fastmutex_t |
265 |
{
|
|
266 |
pthread_mutex_t mutex; |
|
411
by Brian Aker
Removed legacy bits around enum. |
267 |
uint32_t spins; |
1
by brian
clean slate |
268 |
} my_pthread_fastmutex_t; |
269 |
void fastmutex_global_init(void); |
|
270 |
||
271 |
int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, |
|
272 |
const pthread_mutexattr_t *attr); |
|
273 |
int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); |
|
274 |
||
275 |
#undef pthread_mutex_init
|
|
276 |
#undef pthread_mutex_lock
|
|
277 |
#undef pthread_mutex_unlock
|
|
278 |
#undef pthread_mutex_destroy
|
|
279 |
#undef pthread_mutex_wait
|
|
280 |
#undef pthread_mutex_timedwait
|
|
281 |
#undef pthread_mutex_t
|
|
282 |
#undef pthread_cond_wait
|
|
283 |
#undef pthread_cond_timedwait
|
|
284 |
#undef pthread_mutex_trylock
|
|
285 |
#define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B))
|
|
286 |
#define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A)
|
|
287 |
#define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex)
|
|
288 |
#define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex)
|
|
289 |
#define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex)
|
|
290 |
#define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C))
|
|
291 |
#define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex)
|
|
292 |
#define pthread_mutex_t my_pthread_fastmutex_t
|
|
7
by Brian Aker
Further cleanup on pthreads. |
293 |
#endif /* defined(MY_PTHREAD_FASTMUTEX) */ |
1
by brian
clean slate |
294 |
|
295 |
/* READ-WRITE thread locking */
|
|
296 |
||
297 |
#ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */ |
|
298 |
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
|
|
299 |
#undef HAVE_RWLOCK_INIT
|
|
300 |
#undef HAVE_RWLOCK_T
|
|
301 |
#endif
|
|
302 |
||
303 |
#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
|
|
304 |
/* use these defs for simple mutex locking */
|
|
305 |
#define rw_lock_t pthread_mutex_t
|
|
306 |
#define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
|
|
307 |
#define rw_rdlock(A) pthread_mutex_lock((A))
|
|
308 |
#define rw_wrlock(A) pthread_mutex_lock((A))
|
|
309 |
#define rw_tryrdlock(A) pthread_mutex_trylock((A))
|
|
310 |
#define rw_trywrlock(A) pthread_mutex_trylock((A))
|
|
311 |
#define rw_unlock(A) pthread_mutex_unlock((A))
|
|
312 |
#define rwlock_destroy(A) pthread_mutex_destroy((A))
|
|
313 |
#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
|
|
314 |
#define rw_lock_t pthread_rwlock_t
|
|
315 |
#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
|
|
316 |
#define rw_rdlock(A) pthread_rwlock_rdlock(A)
|
|
317 |
#define rw_wrlock(A) pthread_rwlock_wrlock(A)
|
|
318 |
#define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
|
|
319 |
#define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
|
|
320 |
#define rw_unlock(A) pthread_rwlock_unlock(A)
|
|
321 |
#define rwlock_destroy(A) pthread_rwlock_destroy(A)
|
|
322 |
#elif defined(HAVE_RWLOCK_INIT)
|
|
323 |
#ifdef HAVE_RWLOCK_T /* For example Solaris 2.6-> */ |
|
324 |
#define rw_lock_t rwlock_t
|
|
325 |
#endif
|
|
326 |
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
|
|
327 |
#else
|
|
328 |
/* Use our own version of read/write locks */
|
|
329 |
typedef struct _my_rw_lock_t { |
|
330 |
pthread_mutex_t lock; /* lock for structure */ |
|
331 |
pthread_cond_t readers; /* waiting readers */ |
|
332 |
pthread_cond_t writers; /* waiting writers */ |
|
333 |
int state; /* -1:writer,0:free,>0:readers */ |
|
334 |
int waiters; /* number of waiting writers */ |
|
335 |
} my_rw_lock_t; |
|
336 |
||
337 |
#define rw_lock_t my_rw_lock_t
|
|
338 |
#define rw_rdlock(A) my_rw_rdlock((A))
|
|
339 |
#define rw_wrlock(A) my_rw_wrlock((A))
|
|
340 |
#define rw_tryrdlock(A) my_rw_tryrdlock((A))
|
|
341 |
#define rw_trywrlock(A) my_rw_trywrlock((A))
|
|
342 |
#define rw_unlock(A) my_rw_unlock((A))
|
|
343 |
#define rwlock_destroy(A) my_rwlock_destroy((A))
|
|
344 |
||
345 |
extern int my_rwlock_init(my_rw_lock_t *, void *); |
|
346 |
extern int my_rwlock_destroy(my_rw_lock_t *); |
|
347 |
extern int my_rw_rdlock(my_rw_lock_t *); |
|
348 |
extern int my_rw_wrlock(my_rw_lock_t *); |
|
349 |
extern int my_rw_unlock(my_rw_lock_t *); |
|
350 |
extern int my_rw_tryrdlock(my_rw_lock_t *); |
|
351 |
extern int my_rw_trywrlock(my_rw_lock_t *); |
|
352 |
#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ |
|
353 |
||
354 |
#ifndef HAVE_THR_SETCONCURRENCY
|
|
355 |
#define thr_setconcurrency(A) pthread_dummy(0)
|
|
356 |
#endif
|
|
357 |
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
|
|
358 |
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
|
|
359 |
#endif
|
|
360 |
||
361 |
/* Define mutex types, see my_thr_init.c */
|
|
362 |
#define MY_MUTEX_INIT_SLOW NULL
|
|
363 |
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
|
364 |
extern pthread_mutexattr_t my_fast_mutexattr; |
|
365 |
#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
|
|
366 |
#else
|
|
367 |
#define MY_MUTEX_INIT_FAST NULL
|
|
368 |
#endif
|
|
369 |
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
|
370 |
extern pthread_mutexattr_t my_errorcheck_mutexattr; |
|
371 |
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
|
|
372 |
#else
|
|
373 |
#define MY_MUTEX_INIT_ERRCHK NULL
|
|
374 |
#endif
|
|
375 |
||
376 |
#ifndef ESRCH
|
|
377 |
/* Define it to something */
|
|
378 |
#define ESRCH 1
|
|
379 |
#endif
|
|
380 |
||
553
by Monty Taylor
Changed my_thread_id type. |
381 |
typedef uint64_t my_thread_id; |
1
by brian
clean slate |
382 |
|
146
by Brian Aker
my_bool cleanup. |
383 |
extern bool my_thread_global_init(void); |
1
by brian
clean slate |
384 |
extern void my_thread_global_end(void); |
146
by Brian Aker
my_bool cleanup. |
385 |
extern bool my_thread_init(void); |
1
by brian
clean slate |
386 |
extern void my_thread_end(void); |
387 |
extern const char *my_thread_name(void); |
|
388 |
extern my_thread_id my_thread_dbug_id(void); |
|
389 |
||
390 |
/* All thread specific variables are in the following struct */
|
|
391 |
||
392 |
#define THREAD_NAME_SIZE 10
|
|
393 |
/*
|
|
481.1.21
by Monty Taylor
Got rid of some size testing. |
394 |
Drizzle can survive with 32K, but some glibc libraries require > 128K stack
|
395 |
to resolve hostnames. Also recursive stored procedures needs stack.
|
|
1
by brian
clean slate |
396 |
*/
|
481.1.21
by Monty Taylor
Got rid of some size testing. |
397 |
#define DEFAULT_THREAD_STACK (256*INT32_C(1024))
|
1
by brian
clean slate |
398 |
|
399 |
struct st_my_thread_var |
|
400 |
{
|
|
401 |
pthread_cond_t suspend; |
|
402 |
pthread_mutex_t mutex; |
|
403 |
pthread_mutex_t * volatile current_mutex; |
|
404 |
pthread_cond_t * volatile current_cond; |
|
405 |
pthread_t pthread_self; |
|
406 |
my_thread_id id; |
|
407 |
int cmp_length; |
|
408 |
int volatile abort; |
|
146
by Brian Aker
my_bool cleanup. |
409 |
bool init; |
1
by brian
clean slate |
410 |
struct st_my_thread_var *next,**prev; |
411 |
void *opt_info; |
|
412 |
};
|
|
413 |
||
520.4.43
by mordred
A set of Solaris fixes. |
414 |
extern struct st_my_thread_var *_my_thread_var(void); |
411
by Brian Aker
Removed legacy bits around enum. |
415 |
extern uint32_t my_thread_end_wait_time; |
1
by brian
clean slate |
416 |
#define my_thread_var (_my_thread_var())
|
417 |
/*
|
|
418 |
Keep track of shutdown,signal, and main threads so that my_end() will not
|
|
419 |
report errors with them
|
|
420 |
*/
|
|
421 |
||
422 |
/* Which kind of thread library is in use */
|
|
423 |
||
424 |
#define THD_LIB_OTHER 1
|
|
425 |
#define THD_LIB_NPTL 2
|
|
426 |
#define THD_LIB_LT 4
|
|
427 |
||
411
by Brian Aker
Removed legacy bits around enum. |
428 |
extern uint32_t thd_lib_detected; |
1
by brian
clean slate |
429 |
|
430 |
/*
|
|
431 |
thread_safe_xxx functions are for critical statistic or counters.
|
|
432 |
The implementation is guaranteed to be thread safe, on all platforms.
|
|
433 |
Note that the calling code should *not* assume the counter is protected
|
|
434 |
by the mutex given, as the implementation of these helpers may change
|
|
435 |
to use my_atomic operations instead.
|
|
436 |
*/
|
|
437 |
||
438 |
#ifndef thread_safe_increment
|
|
439 |
#define thread_safe_increment(V,L) \
|
|
440 |
(pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
|
|
441 |
#define thread_safe_decrement(V,L) \
|
|
442 |
(pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
|
|
443 |
#endif
|
|
444 |
||
445 |
#ifndef thread_safe_add
|
|
446 |
#define thread_safe_add(V,C,L) \
|
|
447 |
(pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
|
|
448 |
#define thread_safe_sub(V,C,L) \
|
|
449 |
(pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
|
|
450 |
#endif
|
|
451 |
||
452 |
/*
|
|
453 |
statistics_xxx functions are for non critical statistic,
|
|
454 |
maintained in global variables.
|
|
455 |
- race conditions can occur, making the result slightly inaccurate.
|
|
456 |
- the lock given is not honored.
|
|
457 |
*/
|
|
458 |
#define statistic_decrement(V,L) (V)--
|
|
459 |
#define statistic_increment(V,L) (V)++
|
|
460 |
#define statistic_add(V,C,L) (V)+=(C)
|
|
461 |
#define statistic_sub(V,C,L) (V)-=(C)
|
|
462 |
||
463 |
/*
|
|
464 |
No locking needed, the counter is owned by the thread
|
|
465 |
*/
|
|
466 |
#define status_var_increment(V) (V)++
|
|
467 |
#define status_var_decrement(V) (V)--
|
|
468 |
#define status_var_add(V,C) (V)+=(C)
|
|
469 |
#define status_var_sub(V,C) (V)-=(C)
|
|
470 |
||
471 |
#ifdef __cplusplus
|
|
472 |
}
|
|
473 |
#endif
|
|
474 |
#endif /* _my_ptread_h */ |