1
/* Copyright (C) 2000 MySQL AB
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.
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.
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 */
16
/* Defines to make different thread packages compatible */
22
#define ETIME ETIMEDOUT /* For FreeBSD */
26
#define EXTERNC extern "C"
30
#endif /* __cplusplus */
32
#ifdef HAVE_rts_threads
33
#define sigwait org_sigwait
41
#ifdef HAVE_THR_SETCONCURRENCY
42
#include <thread.h> /* Probably solaris */
51
extern int my_pthread_getprio(pthread_t thread_id);
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 *);
60
/* Test first for RTS or FSU threads */
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) */
72
#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
73
int sigwait(sigset_t *set, int *sig);
76
#ifndef HAVE_NONPOSIX_SIGWAIT
77
#define my_sigwait(A,B) sigwait((A),(B))
79
int my_sigwait(const sigset_t *set,int *sig);
82
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
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 */
93
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
94
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
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 */
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.
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; \
115
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
116
DBUG_ASSERT(l_rc == 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))
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))
130
extern void my_pthread_setprio(pthread_t thread_id,int prior);
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))
138
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
142
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE)
143
#define pthread_attr_setscope(A,B)
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))
153
#if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
154
#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B))
156
#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
157
void *my_pthread_getspecific_imp(pthread_key_t key);
160
#ifndef HAVE_LOCALTIME_R
161
struct tm *localtime_r(const time_t *clock, struct tm *res);
164
#ifndef HAVE_GMTIME_R
165
struct tm *gmtime_r(const time_t *clock, struct tm *res);
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
175
#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
176
#define pthread_key_delete(A) pthread_dummy(0)
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); }
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); }
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))
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); }
223
#define HAVE_PTHREAD_KILL
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);
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()
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
246
#ifdef HAVE_TIMESPEC_TS_SEC
248
#define set_timespec(ABSTIME,SEC) \
250
(ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
251
(ABSTIME).ts_nsec=0; \
253
#endif /* !set_timespec */
254
#ifndef set_timespec_nsec
255
#define set_timespec_nsec(ABSTIME,NSEC) \
257
ulonglong now= my_getsystime() + (NSEC/100); \
258
(ABSTIME).ts_sec= (now / ULL(10000000)); \
259
(ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
261
#endif /* !set_timespec_nsec */
264
#define set_timespec(ABSTIME,SEC) \
267
gettimeofday(&tv,0);\
268
(ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
269
(ABSTIME).tv_nsec=tv.tv_usec*1000;\
271
#endif /* !set_timespec */
272
#ifndef set_timespec_nsec
273
#define set_timespec_nsec(ABSTIME,NSEC) \
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)); \
279
#endif /* !set_timespec_nsec */
280
#endif /* HAVE_TIMESPEC_TS_SEC */
282
/* safe_mutex adds checking to mutex for easier debugging */
284
typedef struct st_safe_mutex_t
286
pthread_mutex_t global,mutex;
290
#ifdef SAFE_MUTEX_DETECT_DESTROY
291
struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */
295
#ifdef SAFE_MUTEX_DETECT_DESTROY
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.
302
typedef struct st_safe_mutex_info_t
304
struct st_safe_mutex_info_t *next;
305
struct st_safe_mutex_info_t *prev;
306
const char *init_file;
309
#endif /* SAFE_MUTEX_DETECT_DESTROY */
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,
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);
323
/* Wrappers if safe mutex is actually used */
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))
350
#define safe_mutex_assert_owner(mp)
351
#define safe_mutex_assert_not_owner(mp)
352
#endif /* SAFE_MUTEX */
354
#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
355
typedef struct st_my_pthread_fastmutex_t
357
pthread_mutex_t mutex;
359
} my_pthread_fastmutex_t;
360
void fastmutex_global_init(void);
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);
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) */
386
/* READ-WRITE thread locking */
388
#ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */
389
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
390
#undef HAVE_RWLOCK_INIT
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
417
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
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 */
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))
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 */
445
#ifndef HAVE_THR_SETCONCURRENCY
446
#define thr_setconcurrency(A) pthread_dummy(0)
448
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
449
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
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
458
#define MY_MUTEX_INIT_FAST NULL
460
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
461
extern pthread_mutexattr_t my_errorcheck_mutexattr;
462
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
464
#define MY_MUTEX_INIT_ERRCHK NULL
468
/* Define it to something */
472
typedef ulong my_thread_id;
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);
483
/* All thread specific variables are in the following struct */
485
#define THREAD_NAME_SIZE 10
486
#ifndef DEFAULT_THREAD_STACK
489
MySQL can survive with 32K, but some glibc libraries require > 128K stack
490
To resolve hostnames. Also recursive stored procedures needs stack.
492
#define DEFAULT_THREAD_STACK (256*1024L)
494
#define DEFAULT_THREAD_STACK (192*1024)
498
struct st_my_thread_var
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;
510
struct st_my_thread_var *next,**prev;
514
char name[THREAD_NAME_SIZE+1];
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
523
Keep track of shutdown,signal, and main threads so that my_end() will not
524
report errors with them
527
/* Which kind of thread library is in use */
529
#define THD_LIB_OTHER 1
530
#define THD_LIB_NPTL 2
533
extern uint thd_lib_detected;
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.
545
When compiling without threads, this file is not included.
546
See the *other* declarations of thread_safe_xxx in include/my_global.h
549
See include/config-win.h, for yet another implementation.
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)))
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)))
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.
574
When compiling without SAFE_STATISTICS:
575
- race conditions can occur, making the result slightly inaccurate.
576
- the lock given is not honored.
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))
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 */
591
No locking needed, the counter is owned by the thread
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)
601
#endif /* _my_ptread_h */