+# ifdef OLD_PTHREADS_API /* Here be dragons. */
+# define DETACH(t) \
+ STMT_START { \
+ int _eC_; \
+ if ((_eC_ = pthread_detach(&(t)->self))) { \
+ MUTEX_UNLOCK(&(t)->mutex); \
+ Perl_croak_nocontext("panic: DETACH (%d) [%s:%d]", \
+ _eC_, __FILE__, __LINE__); \
+ } \
+ } STMT_END
+
+# define PERL_GET_CONTEXT Perl_get_context()
+# define PERL_SET_CONTEXT(t) Perl_set_context((void*)t)
+
+# define PTHREAD_GETSPECIFIC_INT
+# ifdef DJGPP
+# define pthread_addr_t any_t
+# define NEED_PTHREAD_INIT
+# define PTHREAD_CREATE_JOINABLE (1)
+# endif
+# ifdef __OPEN_VM
+# define pthread_addr_t void *
+# endif
+# ifdef OEMVS
+# define pthread_addr_t void *
+# define pthread_create(t,a,s,d) pthread_create(t,&(a),s,d)
+# define pthread_keycreate pthread_key_create
+# endif
+# ifdef VMS
+# define pthread_attr_init(a) pthread_attr_create(a)
+# define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_setdetach_np(a,s)
+# define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
+# define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
+# define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
+# define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
+# endif
+# if defined(__hpux) && defined(__ux_version) && __ux_version <= 1020
+# define pthread_attr_init(a) pthread_attr_create(a)
+ /* XXX pthread_setdetach_np() missing in DCE threads on HP-UX 10.20 */
+# define PTHREAD_ATTR_SETDETACHSTATE(a,s) (0)
+# define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
+# define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
+# define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
+# define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
+# endif
+# if defined(DJGPP) || defined(__OPEN_VM) || defined(OEMVS)
+# define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,&(s))
+# define YIELD pthread_yield(NULL)
+# endif
+# endif
+# if !defined(__hpux) || !defined(__ux_version) || __ux_version > 1020
+# define pthread_mutexattr_default NULL
+# define pthread_condattr_default NULL
+# endif
+#endif /* NETWARE */
+#endif
+
+#ifndef PTHREAD_CREATE
+/* You are not supposed to pass NULL as the 2nd arg of PTHREAD_CREATE(). */
+# define PTHREAD_CREATE(t,a,s,d) pthread_create(t,&(a),s,d)
+#endif
+
+#ifndef PTHREAD_ATTR_SETDETACHSTATE
+# define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
+#endif
+
+#ifndef PTHREAD_CREATE_JOINABLE
+# ifdef OLD_PTHREAD_CREATE_JOINABLE
+# define PTHREAD_CREATE_JOINABLE OLD_PTHREAD_CREATE_JOINABLE
+# else
+# define PTHREAD_CREATE_JOINABLE 0 /* Panic? No, guess. */
+# endif
+#endif
+
+#ifdef DGUX
+# define THREAD_CREATE_NEEDS_STACK (32*1024)
+#endif
+
+#ifdef __VMS
+ /* Default is 1024 on VAX, 8192 otherwise */
+# define THREAD_CREATE_NEEDS_STACK (32*1024)
+#endif
+
+#ifdef I_MACH_CTHREADS
+
+/* cthreads interface */
+
+/* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
+
+#define MUTEX_INIT(m) \
+ STMT_START { \
+ *m = mutex_alloc(); \
+ if (*m) { \
+ mutex_init(*m); \
+ } else { \
+ Perl_croak_nocontext("panic: MUTEX_INIT [%s:%d]", \
+ __FILE__, __LINE__); \
+ } \
+ } STMT_END
+
+#define MUTEX_LOCK(m) mutex_lock(*m)
+#define MUTEX_UNLOCK(m) mutex_unlock(*m)
+#define MUTEX_DESTROY(m) \
+ STMT_START { \
+ mutex_free(*m); \
+ *m = 0; \
+ } STMT_END
+
+#define COND_INIT(c) \
+ STMT_START { \
+ *c = condition_alloc(); \
+ if (*c) { \
+ condition_init(*c); \
+ } \
+ else { \
+ Perl_croak_nocontext("panic: COND_INIT [%s:%d]", \
+ __FILE__, __LINE__); \
+ } \
+ } STMT_END
+
+#define COND_SIGNAL(c) condition_signal(*c)
+#define COND_BROADCAST(c) condition_broadcast(*c)
+#define COND_WAIT(c, m) condition_wait(*c, *m)
+#define COND_DESTROY(c) \
+ STMT_START { \
+ condition_free(*c); \
+ *c = 0; \
+ } STMT_END
+
+#define THREAD_CREATE(thr, f) (thr->self = cthread_fork(f, thr), 0)
+#define THREAD_POST_CREATE(thr)
+
+#define THREAD_RET_TYPE any_t
+#define THREAD_RET_CAST(x) ((any_t) x)
+
+#define DETACH(t) cthread_detach(t->self)
+#define JOIN(t, avp) (*(avp) = (AV *)cthread_join(t->self))
+
+#define PERL_SET_CONTEXT(t) cthread_set_data(cthread_self(), t)
+#define PERL_GET_CONTEXT cthread_data(cthread_self())
+
+#define INIT_THREADS cthread_init()
+#define YIELD cthread_yield()
+#define ALLOC_THREAD_KEY NOOP
+#define FREE_THREAD_KEY NOOP
+#define SET_THREAD_SELF(thr) (thr->self = cthread_self())
+
+#endif /* I_MACH_CTHREADS */