~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_pthread.h

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:59 UTC
  • mfrom: (518 drizzle)
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063259-fwbqogq7lnezct0l
Merged with trunk.

Show diffs side-by-side

added added

removed removed

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