~drizzle-trunk/drizzle/development

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