home *** CD-ROM | disk | FTP | other *** search
/ Chip: Windows 2000 Professional Resource Kit / W2KPRK.iso / apps / perl / ActivePerl.exe / data.z / thread.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-14  |  8.7 KB  |  325 lines

  1. #ifdef USE_THREADS
  2.  
  3. #ifdef WIN32
  4. #  include <win32thread.h>
  5. #else
  6.  
  7. #ifndef DJGPP
  8. /* POSIXish threads */
  9. #ifdef OLD_PTHREADS_API
  10. #  define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
  11. #  define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
  12. #  define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
  13. #  define YIELD pthread_yield()
  14. #  define DETACH(t)                \
  15.     STMT_START {                \
  16.     if (pthread_detach(&(t)->self)) {    \
  17.         MUTEX_UNLOCK(&(t)->mutex);        \
  18.         croak("panic: DETACH");        \
  19.     }                    \
  20.     } STMT_END
  21. #else
  22. #  define pthread_mutexattr_default NULL
  23. #  define pthread_condattr_default NULL
  24. #endif /* OLD_PTHREADS_API */
  25. #endif
  26. #endif
  27.  
  28. #ifdef PTHREADS_CREATED_JOINABLE
  29. #  define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
  30. #else
  31. #  ifdef PTHREAD_CREATE_UNDETACHED
  32. #    define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
  33. #  else
  34. #    define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
  35. #  endif
  36. #endif
  37.  
  38. #ifdef I_MACH_CTHREADS
  39.  
  40. /* cthreads interface */
  41.  
  42. /* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
  43.  
  44. #define MUTEX_INIT(m)                    \
  45.     STMT_START {                    \
  46.         *m = mutex_alloc();            \
  47.         if (*m) {                \
  48.             mutex_init(*m);            \
  49.         } else {                \
  50.             croak("panic: MUTEX_INIT");    \
  51.         }                    \
  52.     } STMT_END
  53.  
  54. #define MUTEX_LOCK(m)        mutex_lock(*m)
  55. #define MUTEX_UNLOCK(m)        mutex_unlock(*m)
  56. #define MUTEX_DESTROY(m)                \
  57.     STMT_START {                    \
  58.         mutex_free(*m);                \
  59.         *m = 0;                    \
  60.     } STMT_END
  61.  
  62. #define COND_INIT(c)                    \
  63.     STMT_START {                    \
  64.         *c = condition_alloc();            \
  65.         if (*c) {                \
  66.             condition_init(*c);        \
  67.         } else {                \
  68.             croak("panic: COND_INIT");    \
  69.         }                    \
  70.     } STMT_END
  71.  
  72. #define COND_SIGNAL(c)        condition_signal(*c)
  73. #define COND_BROADCAST(c)    condition_broadcast(*c)
  74. #define COND_WAIT(c, m)        condition_wait(*c, *m)
  75. #define COND_DESTROY(c)                \
  76.     STMT_START {                \
  77.         condition_free(*c);        \
  78.         *c = 0;                \
  79.     } STMT_END
  80.  
  81. #define THREAD_CREATE(thr, f)    (thr->self = cthread_fork(f, thr), 0)
  82. #define THREAD_POST_CREATE(thr)
  83.  
  84. #define THREAD_RET_TYPE        any_t
  85. #define THREAD_RET_CAST(x)    ((any_t) x)
  86.  
  87. #define DETACH(t)        cthread_detach(t->self)
  88. #define JOIN(t, avp)        (*(avp) = (AV *)cthread_join(t->self))
  89.  
  90. #define SET_THR(thr)        cthread_set_data(cthread_self(), thr)
  91. #define THR            cthread_data(cthread_self())
  92.  
  93. #define INIT_THREADS        cthread_init()
  94. #define YIELD            cthread_yield()
  95. #define ALLOC_THREAD_KEY
  96. #define SET_THREAD_SELF(thr)    (thr->self = cthread_self())
  97.  
  98. #endif /* I_MACH_CTHREADS */
  99.  
  100. #ifndef YIELD
  101. #  ifdef HAS_SCHED_YIELD
  102. #    define YIELD sched_yield()
  103. #  else
  104. #    ifdef HAS_PTHREAD_YIELD
  105. #      define YIELD pthread_yield()
  106. #    endif
  107. #  endif
  108. #endif
  109.  
  110. #ifdef __hpux
  111. #  define MUTEX_INIT_NEEDS_MUTEX_ZEROED
  112. #endif
  113.  
  114. #ifndef MUTEX_INIT
  115. #ifdef MUTEX_INIT_NEEDS_MUTEX_ZEROED
  116.     /* Temporary workaround, true bug is deeper. --jhi 1999-02-25 */
  117. #define MUTEX_INIT(m)                        \
  118.     STMT_START {                        \
  119.     Zero((m), 1, perl_mutex);                               \
  120.      if (pthread_mutex_init((m), pthread_mutexattr_default))    \
  121.         croak("panic: MUTEX_INIT");                \
  122.     } STMT_END
  123. #else
  124. #define MUTEX_INIT(m)                        \
  125.     STMT_START {                        \
  126.     if (pthread_mutex_init((m), pthread_mutexattr_default))    \
  127.         croak("panic: MUTEX_INIT");                \
  128.     } STMT_END
  129. #endif
  130. #define MUTEX_LOCK(m)                \
  131.     STMT_START {                \
  132.     if (pthread_mutex_lock((m)))        \
  133.         croak("panic: MUTEX_LOCK");        \
  134.     } STMT_END
  135. #define MUTEX_UNLOCK(m)                \
  136.     STMT_START {                \
  137.     if (pthread_mutex_unlock((m)))        \
  138.         croak("panic: MUTEX_UNLOCK");    \
  139.     } STMT_END
  140. #define MUTEX_DESTROY(m)            \
  141.     STMT_START {                \
  142.     if (pthread_mutex_destroy((m)))        \
  143.         croak("panic: MUTEX_DESTROY");    \
  144.     } STMT_END
  145. #endif /* MUTEX_INIT */
  146.  
  147. #ifndef COND_INIT
  148. #define COND_INIT(c)                        \
  149.     STMT_START {                        \
  150.     if (pthread_cond_init((c), pthread_condattr_default))    \
  151.         croak("panic: COND_INIT");                \
  152.     } STMT_END
  153. #define COND_SIGNAL(c)                \
  154.     STMT_START {                \
  155.     if (pthread_cond_signal((c)))        \
  156.         croak("panic: COND_SIGNAL");    \
  157.     } STMT_END
  158. #define COND_BROADCAST(c)            \
  159.     STMT_START {                \
  160.     if (pthread_cond_broadcast((c)))    \
  161.         croak("panic: COND_BROADCAST");    \
  162.     } STMT_END
  163. #define COND_WAIT(c, m)                \
  164.     STMT_START {                \
  165.     if (pthread_cond_wait((c), (m)))    \
  166.         croak("panic: COND_WAIT");        \
  167.     } STMT_END
  168. #define COND_DESTROY(c)                \
  169.     STMT_START {                \
  170.     if (pthread_cond_destroy((c)))        \
  171.         croak("panic: COND_DESTROY");    \
  172.     } STMT_END
  173. #endif /* COND_INIT */
  174.  
  175. /* DETACH(t) must only be called while holding t->mutex */
  176. #ifndef DETACH
  177. #define DETACH(t)                \
  178.     STMT_START {                \
  179.     if (pthread_detach((t)->self)) {    \
  180.         MUTEX_UNLOCK(&(t)->mutex);        \
  181.         croak("panic: DETACH");        \
  182.     }                    \
  183.     } STMT_END
  184. #endif /* DETACH */
  185.  
  186. #ifndef JOIN
  187. #define JOIN(t, avp)                     \
  188.     STMT_START {                    \
  189.     if (pthread_join((t)->self, (void**)(avp)))    \
  190.         croak("panic: pthread_join");        \
  191.     } STMT_END
  192. #endif /* JOIN */
  193.  
  194. #ifndef SET_THR
  195. #define SET_THR(t)                    \
  196.     STMT_START {                    \
  197.     if (pthread_setspecific(PL_thr_key, (void *) (t)))    \
  198.         croak("panic: pthread_setspecific");    \
  199.     } STMT_END
  200. #endif /* SET_THR */
  201.  
  202. #ifndef THR
  203. #  ifdef OLD_PTHREADS_API
  204. struct perl_thread *getTHR _((void));
  205. #    define THR getTHR()
  206. #  else
  207. #    define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
  208. #  endif /* OLD_PTHREADS_API */
  209. #endif /* THR */
  210.  
  211. /*
  212.  * dTHR is performance-critical. Here, we only do the pthread_get_specific
  213.  * if there may be more than one thread in existence, otherwise we get thr
  214.  * from thrsv which is cached in the per-interpreter structure.
  215.  * Systems with very fast pthread_get_specific (which should be all systems
  216.  * but unfortunately isn't) may wish to simplify to "...*thr = THR".
  217.  *
  218.  * The use of PL_threadnum should be safe here.
  219.  */
  220. #ifndef dTHR
  221. #  define dTHR \
  222.     struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
  223. #endif /* dTHR */
  224.  
  225. #ifndef INIT_THREADS
  226. #  ifdef NEED_PTHREAD_INIT
  227. #    define INIT_THREADS pthread_init()
  228. #  else
  229. #    define INIT_THREADS NOOP
  230. #  endif
  231. #endif
  232.  
  233. /* Accessor for per-thread SVs */
  234. #define THREADSV(i) (thr->threadsvp[i])
  235.  
  236. /*
  237.  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
  238.  * try only locking them if there may be more than one thread in existence.
  239.  * Systems with very fast mutexes (and/or slow conditionals) may wish to
  240.  * remove the "if (threadnum) ..." test.
  241.  * XXX do NOT use C<if (PL_threadnum) ...> -- it sets up race conditions!
  242.  */
  243. #define LOCK_SV_MUTEX                \
  244.     STMT_START {                \
  245.     MUTEX_LOCK(&PL_sv_mutex);        \
  246.     } STMT_END
  247.  
  248. #define UNLOCK_SV_MUTEX                \
  249.     STMT_START {                \
  250.     MUTEX_UNLOCK(&PL_sv_mutex);        \
  251.     } STMT_END
  252.  
  253. /* Likewise for strtab_mutex */
  254. #define LOCK_STRTAB_MUTEX            \
  255.     STMT_START {                \
  256.     MUTEX_LOCK(&PL_strtab_mutex);    \
  257.     } STMT_END
  258.  
  259. #define UNLOCK_STRTAB_MUTEX            \
  260.     STMT_START {                \
  261.     MUTEX_UNLOCK(&PL_strtab_mutex);    \
  262.     } STMT_END
  263.  
  264. #ifndef THREAD_RET_TYPE
  265. #  define THREAD_RET_TYPE    void *
  266. #  define THREAD_RET_CAST(p)    ((void *)(p))
  267. #endif /* THREAD_RET */
  268.  
  269.  
  270. /* Values and macros for thr->flags */
  271. #define THRf_STATE_MASK    7
  272. #define THRf_R_JOINABLE    0
  273. #define THRf_R_JOINED    1
  274. #define THRf_R_DETACHED    2
  275. #define THRf_ZOMBIE    3
  276. #define THRf_DEAD    4
  277.  
  278. #define THRf_DID_DIE    8
  279.  
  280. /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
  281. #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
  282. #define ThrSETSTATE(t, s) STMT_START {        \
  283.     (t)->flags &= ~THRf_STATE_MASK;        \
  284.     (t)->flags |= (s);            \
  285.     DEBUG_S(PerlIO_printf(PerlIO_stderr(),    \
  286.                   "thread %p set to state %d\n", (t), (s))); \
  287.     } STMT_END
  288.  
  289. typedef struct condpair {
  290.     perl_mutex    mutex;        /* Protects all other fields */
  291.     perl_cond    owner_cond;    /* For when owner changes at all */
  292.     perl_cond    cond;        /* For cond_signal and cond_broadcast */
  293.     Thread    owner;        /* Currently owning thread */
  294. } condpair_t;
  295.  
  296. #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
  297. #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
  298. #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
  299. #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
  300.  
  301. #else
  302. /* USE_THREADS is not defined */
  303. #define MUTEX_LOCK(m)
  304. #define MUTEX_UNLOCK(m)
  305. #define MUTEX_INIT(m)
  306. #define MUTEX_DESTROY(m)
  307. #define COND_INIT(c)
  308. #define COND_SIGNAL(c)
  309. #define COND_BROADCAST(c)
  310. #define COND_WAIT(c, m)
  311. #define COND_DESTROY(c)
  312. #define LOCK_SV_MUTEX
  313. #define UNLOCK_SV_MUTEX
  314. #define LOCK_STRTAB_MUTEX
  315. #define UNLOCK_STRTAB_MUTEX
  316.  
  317. #define THR
  318. /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
  319. #ifdef WIN32
  320. #define dTHR extern int Perl___notused
  321. #else
  322. #define dTHR extern int errno
  323. #endif
  324. #endif /* USE_THREADS */
  325.