2 #ifndef ROSE_threadSupport_H
3 #define ROSE_threadSupport_H
25 #include "rosePublicConfig.h"
35 #ifdef ROSE_HAVE_PTHREAD_H
36 # define ROSE_THREADS_ENABLED
37 # define ROSE_THREADS_POSIX
40 # undef ROSE_THREADS_ENABLED
52 #ifndef ROSE_THREADS_ENABLED
54 # pragma message("Multi-thread support is not enabled. ROSE will not be thread safe even for functions that advertise safety.")
56 # warning "Multi-thread support is not enabled. ROSE will not be thread safe even for functions that advertise safety."
62 #define __attribute__(x)
63 #define __attribute(x)
161 #ifdef ROSE_THREADS_ENABLED
162 # define RTS_MUTEX(MUTEX) \
164 RTS_mutex_t *RTS_Mp_mutex = &(MUTEX); \
165 int RTS_Mp_err = RTS_mutex_lock(RTS_Mp_mutex); \
166 assert(0==RTS_Mp_err); \
171 # define RTS_MUTEX_END \
173 RTS_Mp_err = RTS_mutex_unlock(RTS_Mp_mutex); \
174 assert(0==RTS_Mp_err); \
178 RTS_Mp_err = RTS_mutex_unlock(RTS_Mp_mutex); \
179 assert(0==RTS_Mp_err); \
182 # define RTS_MUTEX(MUTEX) \
184 # define RTS_MUTEX_END \
192 #define RTS_MUTEX_MAGIC 0x1a95a713
194 #ifdef ROSE_THREADS_ENABLED
206 #define RTS_MUTEX_INITIALIZER(LAYER) { RTS_MUTEX_MAGIC, (LAYER), PTHREAD_MUTEX_INITIALIZER }
217 #define RTS_MUTEX_INITIALIZER(LAYER) { 0 }
319 #ifdef ROSE_THREADS_ENABLED
320 # define RTS_RWLOCK(RWLOCK, HOW) \
322 RTS_rwlock_t *RTS_Wp_rwlock = &(RWLOCK); \
323 int RTS_Wp_err = RTS_rwlock_##HOW(RTS_Wp_rwlock); \
324 assert(0==RTS_Wp_err); \
328 # define RTS_RWLOCK_END \
330 RTS_Wp_err = RTS_rwlock_unlock(RTS_Wp_rwlock); \
331 assert(0==RTS_Wp_err); \
335 RTS_Wp_err = RTS_rwlock_unlock(RTS_Wp_rwlock); \
336 assert(0==RTS_Wp_err); \
340 # define RTS_RWLOCK(RWLOCK, HOW) \
342 # define RTS_RWLOCK_END \
346 #define RTS_READ(RWLOCK) RTS_RWLOCK(RWLOCK, rdlock)
347 #define RTS_READ_END RTS_RWLOCK_END
348 #define RTS_WRITE(RWLOCK) RTS_RWLOCK(RWLOCK, wrlock)
349 #define RTS_WRITE_END RTS_RWLOCK_END
362 #ifdef ROSE_THREADS_ENABLED
377 #define RTS_RWLOCK_MAGIC 0x20e7f3f4
380 #ifdef ROSE_THREADS_ENABLED
381 # define RTS_RWLOCK_INITIALIZER(LAYER) { RTS_RWLOCK_MAGIC, \
383 PTHREAD_RWLOCK_INITIALIZER, \
384 RTS_MUTEX_INITIALIZER(RTS_LAYER_DONTCARE), \
388 # define RTS_RWLOCK_INITIALIZER(LAYER) { 0 }
391 #ifdef ROSE_THREADS_ENABLED
486 #ifdef ROSE_THREADS_ENABLED
487 # define RTS_INIT(MUTEX, ALLOW_RECURSION) \
489 static bool RTS_Is_initialized=false, RTS_Is_initializing=false; \
490 static pthread_t RTS_Is_initializer; \
491 static pthread_cond_t RTS_Is_condition=PTHREAD_COND_INITIALIZER; \
492 RTS_mutex_t *RTS_Ip_mutex = &(MUTEX); \
493 bool RTS_Ip_initialized, RTS_Ip_initializing; \
494 bool RTS_Ip_allow_recursion = (ALLOW_RECURSION); \
500 if (!(RTS_Ip_initialized=RTS_Is_initialized) && !(RTS_Ip_initializing=RTS_Is_initializing)) { \
501 RTS_Is_initializing = true; \
502 RTS_Is_initializer = pthread_self(); \
506 if (!RTS_Ip_initialized) { \
507 if (!RTS_Ip_initializing) { \
513 # define RTS_INIT_END \
516 RTS_MUTEX(*RTS_Ip_mutex) { \
517 RTS_Is_initialized = true; \
518 RTS_Is_initializing = false; \
519 pthread_cond_broadcast(&RTS_Is_condition); \
524 RTS_MUTEX(*RTS_Ip_mutex) { \
525 RTS_Is_initialized = true; \
526 RTS_Is_initializing = false; \
527 pthread_cond_broadcast(&RTS_Is_condition); \
529 } else if (pthread_equal(pthread_self(), RTS_Is_initializer)) { \
534 if (!RTS_Ip_allow_recursion) { \
535 fprintf(stderr, "RTS_I_LOCK body made a recursive call. Aborting...\n"); \
541 RTS_MUTEX(*RTS_Ip_mutex) { \
542 while (!RTS_Is_initialized) \
543 pthread_cond_wait(&RTS_Is_condition, &(RTS_Ip_mutex->mutex)); \
549 # define RTS_INIT(MUTEX, ALLOW_RECURSION) \
551 static bool RTS_Is_initialized=false; \
552 if (!RTS_Is_initialized) { \
553 RTS_Is_initialized = true; \
555 # define RTS_INIT_END \
561 #define RTS_INIT_RECURSIVE(MUTEX) RTS_INIT(MUTEX, true)
562 #define RTS_INIT_NONRECURSIVE(MUTEX) RTS_INIT(MUTEX, false)
726 void format(
const char *fmt, va_list, va_list);
777 #ifdef ROSE_THREADS_ENABLED
778 # define RTS_MESSAGE(MESG) \
780 RTS_Message *RTS_Mp_mesg = &(MESG); \
781 int RTS_Mp_err = RTS_Mp_mesg->lock(); \
782 assert(0==RTS_Mp_err); \
786 # define RTS_MESSAGE_END(SOL) \
788 RTS_Mp_err = RTS_Mp_mesg->unlock((SOL)); \
789 assert(0==RTS_Mp_err); \
793 RTS_Mp_err = RTS_Mp_mesg->unlock((SOL)); \
794 assert(0==RTS_Mp_err); \
797 # define RTS_MESSAGE(MESG) \
799 # define RTS_MESSAGE_END(SOL) \