~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to include/my_pthread.h

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
21
#ifndef ETIME
 
22
#define ETIME ETIMEDOUT                         /* For FreeBSD */
 
23
#endif
 
24
 
 
25
#ifdef  __cplusplus
 
26
#define EXTERNC extern "C"
 
27
extern "C" {
 
28
#else
 
29
#define EXTERNC
 
30
#endif /* __cplusplus */ 
 
31
 
 
32
#ifdef HAVE_rts_threads
 
33
#define sigwait org_sigwait
 
34
#include <signal.h>
 
35
#undef sigwait
 
36
#endif
 
37
#include <pthread.h>
 
38
#ifndef _REENTRANT
 
39
#define _REENTRANT
 
40
#endif
 
41
#ifdef HAVE_THR_SETCONCURRENCY
 
42
#include <thread.h>                     /* Probably solaris */
 
43
#endif
 
44
#ifdef HAVE_SCHED_H
 
45
#include <sched.h>
 
46
#endif
 
47
#ifdef HAVE_SYNCH_H
 
48
#include <synch.h>
 
49
#endif
 
50
 
 
51
extern int my_pthread_getprio(pthread_t thread_id);
 
52
 
 
53
#define pthread_key(T,V) pthread_key_t V
 
54
#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
 
55
#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
 
56
#define pthread_detach_this_thread()
 
57
#define pthread_handler_t EXTERNC void *
 
58
typedef void *(* pthread_handler)(void *);
 
59
 
 
60
/* Test first for RTS or FSU threads */
 
61
 
 
62
#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
 
63
#define HAVE_rts_threads
 
64
extern int my_pthread_create_detached;
 
65
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
 
66
#define PTHREAD_CREATE_DETACHED &my_pthread_create_detached
 
67
#define PTHREAD_SCOPE_SYSTEM  PTHREAD_SCOPE_GLOBAL
 
68
#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
 
69
#define USE_ALARM_THREAD
 
70
#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */
 
71
 
 
72
#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
 
73
int sigwait(sigset_t *set, int *sig);
 
74
#endif
 
75
 
 
76
#ifndef HAVE_NONPOSIX_SIGWAIT
 
77
#define my_sigwait(A,B) sigwait((A),(B))
 
78
#else
 
79
int my_sigwait(const sigset_t *set,int *sig);
 
80
#endif
 
81
 
 
82
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
 
83
#ifndef SAFE_MUTEX
 
84
#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
 
85
extern int my_pthread_mutex_init(pthread_mutex_t *mp,
 
86
                                 const pthread_mutexattr_t *attr);
 
87
#endif /* SAFE_MUTEX */
 
88
#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b))
 
89
extern int my_pthread_cond_init(pthread_cond_t *mp,
 
90
                                const pthread_condattr_t *attr);
 
91
#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
 
92
 
 
93
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
 
94
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
 
95
#endif
 
96
 
 
97
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT)
 
98
int sigwait(sigset_t *setp, int *sigp);         /* Use our implemention */
 
99
#endif
 
100
 
 
101
 
 
102
/*
 
103
  We define my_sigset() and use that instead of the system sigset() so that
 
104
  we can favor an implementation based on sigaction(). On some systems, such
 
105
  as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
 
106
  we want to make sure that no such flags are set.
 
107
*/
 
108
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
 
109
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
 
110
                            DBUG_ASSERT((A) != 0);                          \
 
111
                            sigemptyset(&l_set);                            \
 
112
                            l_s.sa_handler = (B);                           \
 
113
                            l_s.sa_mask   = l_set;                          \
 
114
                            l_s.sa_flags   = 0;                             \
 
115
                            l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
 
116
                            DBUG_ASSERT(l_rc == 0);                         \
 
117
                          } while (0)
 
118
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
 
119
#define my_sigset(A,B) sigset((A),(B))
 
120
#elif !defined(my_sigset)
 
121
#define my_sigset(A,B) signal((A),(B))
 
122
#endif
 
123
 
 
124
#ifndef my_pthread_setprio
 
125
#if defined(HAVE_PTHREAD_SETPRIO_NP)            /* FSU threads */
 
126
#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
 
127
#elif defined(HAVE_PTHREAD_SETPRIO)
 
128
#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
 
129
#else
 
130
extern void my_pthread_setprio(pthread_t thread_id,int prior);
 
131
#endif
 
132
#endif
 
133
 
 
134
#ifndef my_pthread_attr_setprio
 
135
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
 
136
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
 
137
#else
 
138
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
 
139
#endif
 
140
#endif
 
141
 
 
142
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE)
 
143
#define pthread_attr_setscope(A,B)
 
144
#endif
 
145
 
 
146
#if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX)
 
147
extern int my_pthread_cond_timedwait(pthread_cond_t *cond,
 
148
                                     pthread_mutex_t *mutex,
 
149
                                     struct timespec *abstime);
 
150
#define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
 
151
#endif
 
152
 
 
153
#if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
 
154
#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B))
 
155
#else
 
156
#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
 
157
void *my_pthread_getspecific_imp(pthread_key_t key);
 
158
#endif
 
159
 
 
160
#ifndef HAVE_LOCALTIME_R
 
161
struct tm *localtime_r(const time_t *clock, struct tm *res);
 
162
#endif
 
163
 
 
164
#ifndef HAVE_GMTIME_R
 
165
struct tm *gmtime_r(const time_t *clock, struct tm *res);
 
166
#endif
 
167
 
 
168
#ifdef HAVE_PTHREAD_CONDATTR_CREATE
 
169
/* DCE threads on HPUX 10.20 */
 
170
#define pthread_condattr_init pthread_condattr_create
 
171
#define pthread_condattr_destroy pthread_condattr_delete
 
172
#endif
 
173
 
 
174
/* FSU THREADS */
 
175
#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
 
176
#define pthread_key_delete(A) pthread_dummy(0)
 
177
#endif
 
178
 
 
179
#ifdef HAVE_CTHREADS_WRAPPER                    /* For MacOSX */
 
180
#define pthread_cond_destroy(A) pthread_dummy(0)
 
181
#define pthread_mutex_destroy(A) pthread_dummy(0)
 
182
#define pthread_attr_delete(A) pthread_dummy(0)
 
183
#define pthread_condattr_delete(A) pthread_dummy(0)
 
184
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
 
185
#define pthread_equal(A,B) ((A) == (B))
 
186
#define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b))
 
187
#define pthread_attr_init(A) pthread_attr_create(A)
 
188
#define pthread_attr_destroy(A) pthread_attr_delete(A)
 
189
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
 
190
#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
 
191
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
 
192
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
 
193
#undef  pthread_detach_this_thread
 
194
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
 
195
#endif
 
196
 
 
197
#ifdef HAVE_DARWIN5_THREADS
 
198
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
 
199
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
 
200
#define pthread_condattr_init(A) pthread_dummy(0)
 
201
#define pthread_condattr_destroy(A) pthread_dummy(0)
 
202
#undef  pthread_detach_this_thread
 
203
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
 
204
#endif
 
205
 
 
206
#if (defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT))
 
207
/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
 
208
#define pthread_key_create(A,B) \
 
209
                pthread_keycreate(A,(B) ?\
 
210
                                  (pthread_destructor_t) (B) :\
 
211
                                  (pthread_destructor_t) pthread_dummy)
 
212
#define pthread_attr_init(A) pthread_attr_create(A)
 
213
#define pthread_attr_destroy(A) pthread_attr_delete(A)
 
214
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
 
215
#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
 
216
#ifndef pthread_sigmask
 
217
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
 
218
#endif
 
219
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
 
220
#undef  pthread_detach_this_thread
 
221
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
 
222
#else
 
223
#define HAVE_PTHREAD_KILL
 
224
#endif
 
225
 
 
226
#if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
 
227
#undef pthread_mutex_trylock
 
228
#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
 
229
int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
 
230
#endif
 
231
 
 
232
#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
 
233
/* no pthread_yield() available */
 
234
#ifdef HAVE_SCHED_YIELD
 
235
#define pthread_yield() sched_yield()
 
236
#elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */
 
237
#define pthread_yield() pthread_yield_np()
 
238
#endif
 
239
#endif
 
240
 
 
241
/*
 
242
  The defines set_timespec and set_timespec_nsec should be used
 
243
  for calculating an absolute time at which
 
244
  pthread_cond_timedwait should timeout
 
245
*/
 
246
#ifdef HAVE_TIMESPEC_TS_SEC
 
247
#ifndef set_timespec
 
248
#define set_timespec(ABSTIME,SEC) \
 
249
{ \
 
250
  (ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
 
251
  (ABSTIME).ts_nsec=0; \
 
252
}
 
253
#endif /* !set_timespec */
 
254
#ifndef set_timespec_nsec
 
255
#define set_timespec_nsec(ABSTIME,NSEC) \
 
256
{ \
 
257
  ulonglong now= my_getsystime() + (NSEC/100); \
 
258
  (ABSTIME).ts_sec=  (now / ULL(10000000)); \
 
259
  (ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
 
260
}
 
261
#endif /* !set_timespec_nsec */
 
262
#else
 
263
#ifndef set_timespec
 
264
#define set_timespec(ABSTIME,SEC) \
 
265
{\
 
266
  struct timeval tv;\
 
267
  gettimeofday(&tv,0);\
 
268
  (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
 
269
  (ABSTIME).tv_nsec=tv.tv_usec*1000;\
 
270
}
 
271
#endif /* !set_timespec */
 
272
#ifndef set_timespec_nsec
 
273
#define set_timespec_nsec(ABSTIME,NSEC) \
 
274
{\
 
275
  ulonglong now= my_getsystime() + (NSEC/100); \
 
276
  (ABSTIME).tv_sec=  (time_t) (now / ULL(10000000));                  \
 
277
  (ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
 
278
}
 
279
#endif /* !set_timespec_nsec */
 
280
#endif /* HAVE_TIMESPEC_TS_SEC */
 
281
 
 
282
        /* safe_mutex adds checking to mutex for easier debugging */
 
283
 
 
284
typedef struct st_safe_mutex_t
 
285
{
 
286
  pthread_mutex_t global,mutex;
 
287
  const char *file;
 
288
  uint line,count;
 
289
  pthread_t thread;
 
290
#ifdef SAFE_MUTEX_DETECT_DESTROY
 
291
  struct st_safe_mutex_info_t *info;    /* to track destroying of mutexes */
 
292
#endif
 
293
} safe_mutex_t;
 
294
 
 
295
#ifdef SAFE_MUTEX_DETECT_DESTROY
 
296
/*
 
297
  Used to track the destroying of mutexes. This needs to be a seperate
 
298
  structure because the safe_mutex_t structure could be freed before
 
299
  the mutexes are destroyed.
 
300
*/
 
301
 
 
302
typedef struct st_safe_mutex_info_t
 
303
{
 
304
  struct st_safe_mutex_info_t *next;
 
305
  struct st_safe_mutex_info_t *prev;
 
306
  const char *init_file;
 
307
  uint32 init_line;
 
308
} safe_mutex_info_t;
 
309
#endif /* SAFE_MUTEX_DETECT_DESTROY */
 
310
 
 
311
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
 
312
                    const char *file, uint line);
 
313
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
 
314
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
 
315
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
 
316
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
 
317
                   uint line);
 
318
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
 
319
                        struct timespec *abstime, const char *file, uint line);
 
320
void safe_mutex_global_init(void);
 
321
void safe_mutex_end(FILE *file);
 
322
 
 
323
        /* Wrappers if safe mutex is actually used */
 
324
#ifdef SAFE_MUTEX
 
325
#undef pthread_mutex_init
 
326
#undef pthread_mutex_lock
 
327
#undef pthread_mutex_unlock
 
328
#undef pthread_mutex_destroy
 
329
#undef pthread_mutex_wait
 
330
#undef pthread_mutex_timedwait
 
331
#undef pthread_mutex_t
 
332
#undef pthread_cond_wait
 
333
#undef pthread_cond_timedwait
 
334
#undef pthread_mutex_trylock
 
335
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
 
336
#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__)
 
337
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
 
338
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
 
339
#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
 
340
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
 
341
#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__)
 
342
#define pthread_mutex_t safe_mutex_t
 
343
#define safe_mutex_assert_owner(mp) \
 
344
          DBUG_ASSERT((mp)->count > 0 && \
 
345
                      pthread_equal(pthread_self(), (mp)->thread))
 
346
#define safe_mutex_assert_not_owner(mp) \
 
347
          DBUG_ASSERT(! (mp)->count || \
 
348
                      ! pthread_equal(pthread_self(), (mp)->thread))
 
349
#else
 
350
#define safe_mutex_assert_owner(mp)
 
351
#define safe_mutex_assert_not_owner(mp)
 
352
#endif /* SAFE_MUTEX */
 
353
 
 
354
#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
 
355
typedef struct st_my_pthread_fastmutex_t
 
356
{
 
357
  pthread_mutex_t mutex;
 
358
  uint spins;
 
359
} my_pthread_fastmutex_t;
 
360
void fastmutex_global_init(void);
 
361
 
 
362
int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, 
 
363
                              const pthread_mutexattr_t *attr);
 
364
int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
 
365
 
 
366
#undef pthread_mutex_init
 
367
#undef pthread_mutex_lock
 
368
#undef pthread_mutex_unlock
 
369
#undef pthread_mutex_destroy
 
370
#undef pthread_mutex_wait
 
371
#undef pthread_mutex_timedwait
 
372
#undef pthread_mutex_t
 
373
#undef pthread_cond_wait
 
374
#undef pthread_cond_timedwait
 
375
#undef pthread_mutex_trylock
 
376
#define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B))
 
377
#define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A)
 
378
#define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex)
 
379
#define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex)
 
380
#define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex)
 
381
#define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C))
 
382
#define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex)
 
383
#define pthread_mutex_t my_pthread_fastmutex_t
 
384
#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
 
385
 
 
386
        /* READ-WRITE thread locking */
 
387
 
 
388
#ifdef HAVE_BROKEN_RWLOCK                       /* For OpenUnix */
 
389
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
 
390
#undef HAVE_RWLOCK_INIT
 
391
#undef HAVE_RWLOCK_T
 
392
#endif
 
393
 
 
394
#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
 
395
/* use these defs for simple mutex locking */
 
396
#define rw_lock_t pthread_mutex_t
 
397
#define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
 
398
#define rw_rdlock(A) pthread_mutex_lock((A))
 
399
#define rw_wrlock(A) pthread_mutex_lock((A))
 
400
#define rw_tryrdlock(A) pthread_mutex_trylock((A))
 
401
#define rw_trywrlock(A) pthread_mutex_trylock((A))
 
402
#define rw_unlock(A) pthread_mutex_unlock((A))
 
403
#define rwlock_destroy(A) pthread_mutex_destroy((A))
 
404
#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
 
405
#define rw_lock_t pthread_rwlock_t
 
406
#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
 
407
#define rw_rdlock(A) pthread_rwlock_rdlock(A)
 
408
#define rw_wrlock(A) pthread_rwlock_wrlock(A)
 
409
#define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
 
410
#define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
 
411
#define rw_unlock(A) pthread_rwlock_unlock(A)
 
412
#define rwlock_destroy(A) pthread_rwlock_destroy(A)
 
413
#elif defined(HAVE_RWLOCK_INIT)
 
414
#ifdef HAVE_RWLOCK_T                            /* For example Solaris 2.6-> */
 
415
#define rw_lock_t rwlock_t
 
416
#endif
 
417
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
 
418
#else
 
419
/* Use our own version of read/write locks */
 
420
typedef struct _my_rw_lock_t {
 
421
        pthread_mutex_t lock;           /* lock for structure           */
 
422
        pthread_cond_t  readers;        /* waiting readers              */
 
423
        pthread_cond_t  writers;        /* waiting writers              */
 
424
        int             state;          /* -1:writer,0:free,>0:readers  */
 
425
        int             waiters;        /* number of waiting writers    */
 
426
} my_rw_lock_t;
 
427
 
 
428
#define rw_lock_t my_rw_lock_t
 
429
#define rw_rdlock(A) my_rw_rdlock((A))
 
430
#define rw_wrlock(A) my_rw_wrlock((A))
 
431
#define rw_tryrdlock(A) my_rw_tryrdlock((A))
 
432
#define rw_trywrlock(A) my_rw_trywrlock((A))
 
433
#define rw_unlock(A) my_rw_unlock((A))
 
434
#define rwlock_destroy(A) my_rwlock_destroy((A))
 
435
 
 
436
extern int my_rwlock_init(my_rw_lock_t *, void *);
 
437
extern int my_rwlock_destroy(my_rw_lock_t *);
 
438
extern int my_rw_rdlock(my_rw_lock_t *);
 
439
extern int my_rw_wrlock(my_rw_lock_t *);
 
440
extern int my_rw_unlock(my_rw_lock_t *);
 
441
extern int my_rw_tryrdlock(my_rw_lock_t *);
 
442
extern int my_rw_trywrlock(my_rw_lock_t *);
 
443
#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
 
444
 
 
445
#ifndef HAVE_THR_SETCONCURRENCY
 
446
#define thr_setconcurrency(A) pthread_dummy(0)
 
447
#endif
 
448
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
 
449
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
 
450
#endif
 
451
 
 
452
/* Define mutex types, see my_thr_init.c */
 
453
#define MY_MUTEX_INIT_SLOW   NULL
 
454
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
455
extern pthread_mutexattr_t my_fast_mutexattr;
 
456
#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
 
457
#else
 
458
#define MY_MUTEX_INIT_FAST   NULL
 
459
#endif
 
460
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
461
extern pthread_mutexattr_t my_errorcheck_mutexattr;
 
462
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
 
463
#else
 
464
#define MY_MUTEX_INIT_ERRCHK   NULL
 
465
#endif
 
466
 
 
467
#ifndef ESRCH
 
468
/* Define it to something */
 
469
#define ESRCH 1
 
470
#endif
 
471
 
 
472
typedef ulong my_thread_id;
 
473
 
 
474
extern my_bool my_thread_global_init(void);
 
475
extern void my_thread_global_end(void);
 
476
extern my_bool my_thread_init(void);
 
477
extern void my_thread_end(void);
 
478
extern const char *my_thread_name(void);
 
479
extern my_thread_id my_thread_dbug_id(void);
 
480
extern int pthread_no_free(void *);
 
481
extern int pthread_dummy(int);
 
482
 
 
483
/* All thread specific variables are in the following struct */
 
484
 
 
485
#define THREAD_NAME_SIZE 10
 
486
#ifndef DEFAULT_THREAD_STACK
 
487
#if SIZEOF_CHARP > 4
 
488
/*
 
489
  MySQL can survive with 32K, but some glibc libraries require > 128K stack
 
490
  To resolve hostnames. Also recursive stored procedures needs stack.
 
491
*/
 
492
#define DEFAULT_THREAD_STACK    (256*1024L)
 
493
#else
 
494
#define DEFAULT_THREAD_STACK    (192*1024)
 
495
#endif
 
496
#endif
 
497
 
 
498
struct st_my_thread_var
 
499
{
 
500
  int thr_errno;
 
501
  pthread_cond_t suspend;
 
502
  pthread_mutex_t mutex;
 
503
  pthread_mutex_t * volatile current_mutex;
 
504
  pthread_cond_t * volatile current_cond;
 
505
  pthread_t pthread_self;
 
506
  my_thread_id id;
 
507
  int cmp_length;
 
508
  int volatile abort;
 
509
  my_bool init;
 
510
  struct st_my_thread_var *next,**prev;
 
511
  void *opt_info;
 
512
#ifndef DBUG_OFF
 
513
  void *dbug;
 
514
  char name[THREAD_NAME_SIZE+1];
 
515
#endif
 
516
};
 
517
 
 
518
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
 
519
extern uint my_thread_end_wait_time;
 
520
#define my_thread_var (_my_thread_var())
 
521
#define my_errno my_thread_var->thr_errno
 
522
/*
 
523
  Keep track of shutdown,signal, and main threads so that my_end() will not
 
524
  report errors with them
 
525
*/
 
526
 
 
527
/* Which kind of thread library is in use */
 
528
 
 
529
#define THD_LIB_OTHER 1
 
530
#define THD_LIB_NPTL  2
 
531
#define THD_LIB_LT    4
 
532
 
 
533
extern uint thd_lib_detected;
 
534
 
 
535
/*
 
536
  thread_safe_xxx functions are for critical statistic or counters.
 
537
  The implementation is guaranteed to be thread safe, on all platforms.
 
538
  Note that the calling code should *not* assume the counter is protected
 
539
  by the mutex given, as the implementation of these helpers may change
 
540
  to use my_atomic operations instead.
 
541
*/
 
542
 
 
543
/*
 
544
  Warning:
 
545
  When compiling without threads, this file is not included.
 
546
  See the *other* declarations of thread_safe_xxx in include/my_global.h
 
547
 
 
548
  Second warning:
 
549
  See include/config-win.h, for yet another implementation.
 
550
*/
 
551
#ifdef THREAD
 
552
#ifndef thread_safe_increment
 
553
#define thread_safe_increment(V,L) \
 
554
        (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
 
555
#define thread_safe_decrement(V,L) \
 
556
        (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
 
557
#endif
 
558
 
 
559
#ifndef thread_safe_add
 
560
#define thread_safe_add(V,C,L) \
 
561
        (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
 
562
#define thread_safe_sub(V,C,L) \
 
563
        (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
 
564
#endif
 
565
#endif
 
566
 
 
567
/*
 
568
  statistics_xxx functions are for non critical statistic,
 
569
  maintained in global variables.
 
570
  When compiling with SAFE_STATISTICS:
 
571
  - race conditions can not occur.
 
572
  - some locking occurs, which may cause performance degradation.
 
573
 
 
574
  When compiling without SAFE_STATISTICS:
 
575
  - race conditions can occur, making the result slightly inaccurate.
 
576
  - the lock given is not honored.
 
577
*/
 
578
#ifdef SAFE_STATISTICS
 
579
#define statistic_increment(V,L) thread_safe_increment((V),(L))
 
580
#define statistic_decrement(V,L) thread_safe_decrement((V),(L))
 
581
#define statistic_add(V,C,L)     thread_safe_add((V),(C),(L))
 
582
#define statistic_sub(V,C,L)     thread_safe_sub((V),(C),(L))
 
583
#else
 
584
#define statistic_decrement(V,L) (V)--
 
585
#define statistic_increment(V,L) (V)++
 
586
#define statistic_add(V,C,L)     (V)+=(C)
 
587
#define statistic_sub(V,C,L)     (V)-=(C)
 
588
#endif /* SAFE_STATISTICS */
 
589
 
 
590
/*
 
591
  No locking needed, the counter is owned by the thread
 
592
*/
 
593
#define status_var_increment(V) (V)++
 
594
#define status_var_decrement(V) (V)--
 
595
#define status_var_add(V,C)     (V)+=(C)
 
596
#define status_var_sub(V,C)     (V)-=(C)
 
597
 
 
598
#ifdef  __cplusplus
 
599
}
 
600
#endif
 
601
#endif /* _my_ptread_h */