home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2006 December / PCpro_2006_12.ISO / ossdvd / server / Perl2 / lib / core / thread.h < prev    next >
Encoding:
C/C++ Source or Header  |  2002-06-19  |  12.9 KB  |  478 lines

  1. /*    thread.h
  2.  *
  3.  *    Copyright (c) 1997-2002, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  */
  9.  
  10. #if defined(USE_5005THREADS) || defined(USE_ITHREADS)
  11.  
  12. #if defined(VMS)
  13. #include <builtins.h>
  14. #endif
  15.  
  16. #ifdef WIN32
  17. #  include <win32thread.h>
  18. #else
  19. #ifdef NETWARE
  20. #  include <nw5thread.h>
  21. #else
  22. #  ifdef OLD_PTHREADS_API /* Here be dragons. */
  23. #    define DETACH(t) \
  24.     STMT_START {                        \
  25.     if (pthread_detach(&(t)->self)) {            \
  26.         MUTEX_UNLOCK(&(t)->mutex);                \
  27.         Perl_croak_nocontext("panic: DETACH");        \
  28.     }                            \
  29.     } STMT_END
  30.  
  31. #    define PERL_GET_CONTEXT    Perl_get_context()
  32. #    define PERL_SET_CONTEXT(t)    Perl_set_context((void*)t)
  33.  
  34. #    define PTHREAD_GETSPECIFIC_INT
  35. #    ifdef DJGPP
  36. #      define pthread_addr_t any_t
  37. #      define NEED_PTHREAD_INIT
  38. #      define PTHREAD_CREATE_JOINABLE (1)
  39. #    endif
  40. #    ifdef __OPEN_VM
  41. #      define pthread_addr_t void *
  42. #    endif
  43. #    ifdef VMS
  44. #      define pthread_attr_init(a) pthread_attr_create(a)
  45. #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_setdetach_np(a,s)
  46. #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
  47. #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
  48. #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
  49. #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
  50. #    endif
  51. #    if defined(__hpux) && defined(__ux_version) && __ux_version <= 1020
  52. #      define pthread_attr_init(a) pthread_attr_create(a)
  53.        /* XXX pthread_setdetach_np() missing in DCE threads on HP-UX 10.20 */
  54. #      define PTHREAD_ATTR_SETDETACHSTATE(a,s)    (0)
  55. #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
  56. #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
  57. #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
  58. #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
  59. #    endif
  60. #    if defined(DJGPP) || defined(__OPEN_VM)
  61. #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,&(s))
  62. #      define YIELD pthread_yield(NULL)
  63. #    endif
  64. #  endif
  65. #  if !defined(__hpux) || !defined(__ux_version) || __ux_version > 1020
  66. #    define pthread_mutexattr_default NULL
  67. #    define pthread_condattr_default  NULL
  68. #  endif
  69. #endif    /* NETWARE */
  70. #endif
  71.  
  72. #ifndef PTHREAD_CREATE
  73. /* You are not supposed to pass NULL as the 2nd arg of PTHREAD_CREATE(). */
  74. #  define PTHREAD_CREATE(t,a,s,d) pthread_create(t,&(a),s,d)
  75. #endif
  76.  
  77. #ifndef PTHREAD_ATTR_SETDETACHSTATE
  78. #  define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
  79. #endif
  80.  
  81. #ifndef PTHREAD_CREATE_JOINABLE
  82. #  ifdef OLD_PTHREAD_CREATE_JOINABLE
  83. #    define PTHREAD_CREATE_JOINABLE OLD_PTHREAD_CREATE_JOINABLE
  84. #  else
  85. #    define PTHREAD_CREATE_JOINABLE 0 /* Panic?  No, guess. */
  86. #  endif
  87. #endif
  88.  
  89. #ifdef DGUX
  90. #  define THREAD_CREATE_NEEDS_STACK (32*1024)
  91. #endif
  92.  
  93. #ifdef I_MACH_CTHREADS
  94.  
  95. /* cthreads interface */
  96.  
  97. /* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
  98.  
  99. #define MUTEX_INIT(m) \
  100.     STMT_START {                        \
  101.     *m = mutex_alloc();                    \
  102.     if (*m) {                        \
  103.         mutex_init(*m);                    \
  104.     } else {                        \
  105.         Perl_croak_nocontext("panic: MUTEX_INIT");        \
  106.     }                            \
  107.     } STMT_END
  108.  
  109. #define MUTEX_LOCK(m)            mutex_lock(*m)
  110. #define MUTEX_UNLOCK(m)            mutex_unlock(*m)
  111. #define MUTEX_DESTROY(m) \
  112.     STMT_START {                        \
  113.     mutex_free(*m);                        \
  114.     *m = 0;                            \
  115.     } STMT_END
  116.  
  117. #define COND_INIT(c) \
  118.     STMT_START {                        \
  119.     *c = condition_alloc();                    \
  120.     if (*c) {                        \
  121.         condition_init(*c);                    \
  122.     }                            \
  123.     else {                            \
  124.         Perl_croak_nocontext("panic: COND_INIT");        \
  125.     }                            \
  126.     } STMT_END
  127.  
  128. #define COND_SIGNAL(c)        condition_signal(*c)
  129. #define COND_BROADCAST(c)    condition_broadcast(*c)
  130. #define COND_WAIT(c, m)        condition_wait(*c, *m)
  131. #define COND_DESTROY(c) \
  132.     STMT_START {                        \
  133.     condition_free(*c);                    \
  134.     *c = 0;                            \
  135.     } STMT_END
  136.  
  137. #define THREAD_CREATE(thr, f)    (thr->self = cthread_fork(f, thr), 0)
  138. #define THREAD_POST_CREATE(thr)
  139.  
  140. #define THREAD_RET_TYPE        any_t
  141. #define THREAD_RET_CAST(x)    ((any_t) x)
  142.  
  143. #define DETACH(t)        cthread_detach(t->self)
  144. #define JOIN(t, avp)        (*(avp) = (AV *)cthread_join(t->self))
  145.  
  146. #define PERL_SET_CONTEXT(t)    cthread_set_data(cthread_self(), t)
  147. #define PERL_GET_CONTEXT    cthread_data(cthread_self())
  148.  
  149. #define INIT_THREADS        cthread_init()
  150. #define YIELD            cthread_yield()
  151. #define ALLOC_THREAD_KEY    NOOP
  152. #define FREE_THREAD_KEY        NOOP
  153. #define SET_THREAD_SELF(thr)    (thr->self = cthread_self())
  154.  
  155. #endif /* I_MACH_CTHREADS */
  156.  
  157. #ifndef YIELD
  158. #  ifdef SCHED_YIELD
  159. #    define YIELD SCHED_YIELD
  160. #  else
  161. #    ifdef HAS_SCHED_YIELD
  162. #      define YIELD sched_yield()
  163. #    else
  164. #      ifdef HAS_PTHREAD_YIELD
  165.     /* pthread_yield(NULL) platforms are expected
  166.      * to have #defined YIELD for themselves. */
  167. #        define YIELD pthread_yield()
  168. #      endif
  169. #    endif
  170. #  endif
  171. #endif
  172.  
  173. #ifdef __hpux
  174. #  define MUTEX_INIT_NEEDS_MUTEX_ZEROED
  175. #endif
  176.  
  177. #ifndef MUTEX_INIT
  178.  
  179. #  ifdef MUTEX_INIT_NEEDS_MUTEX_ZEROED
  180.     /* Temporary workaround, true bug is deeper. --jhi 1999-02-25 */
  181. #    define MUTEX_INIT(m) \
  182.     STMT_START {                        \
  183.     Zero((m), 1, perl_mutex);                               \
  184.      if (pthread_mutex_init((m), pthread_mutexattr_default))    \
  185.         Perl_croak_nocontext("panic: MUTEX_INIT");        \
  186.     } STMT_END
  187. #  else
  188. #    define MUTEX_INIT(m) \
  189.     STMT_START {                        \
  190.     if (pthread_mutex_init((m), pthread_mutexattr_default))    \
  191.         Perl_croak_nocontext("panic: MUTEX_INIT");        \
  192.     } STMT_END
  193. #  endif
  194.  
  195. #  define MUTEX_LOCK(m) \
  196.     STMT_START {                        \
  197.     if (pthread_mutex_lock((m)))                \
  198.         Perl_croak_nocontext("panic: MUTEX_LOCK");        \
  199.     } STMT_END
  200.  
  201. #  define MUTEX_UNLOCK(m) \
  202.     STMT_START {                        \
  203.     if (pthread_mutex_unlock((m)))                \
  204.         Perl_croak_nocontext("panic: MUTEX_UNLOCK");    \
  205.     } STMT_END
  206.  
  207. #  define MUTEX_DESTROY(m) \
  208.     STMT_START {                        \
  209.     if (pthread_mutex_destroy((m)))                \
  210.         Perl_croak_nocontext("panic: MUTEX_DESTROY");    \
  211.     } STMT_END
  212. #endif /* MUTEX_INIT */
  213.  
  214. #ifndef COND_INIT
  215. #  define COND_INIT(c) \
  216.     STMT_START {                        \
  217.     if (pthread_cond_init((c), pthread_condattr_default))    \
  218.         Perl_croak_nocontext("panic: COND_INIT");        \
  219.     } STMT_END
  220.  
  221. #  define COND_SIGNAL(c) \
  222.     STMT_START {                        \
  223.     if (pthread_cond_signal((c)))                \
  224.         Perl_croak_nocontext("panic: COND_SIGNAL");        \
  225.     } STMT_END
  226.  
  227. #  define COND_BROADCAST(c) \
  228.     STMT_START {                        \
  229.     if (pthread_cond_broadcast((c)))            \
  230.         Perl_croak_nocontext("panic: COND_BROADCAST");    \
  231.     } STMT_END
  232.  
  233. #  define COND_WAIT(c, m) \
  234.     STMT_START {                        \
  235.     if (pthread_cond_wait((c), (m)))            \
  236.         Perl_croak_nocontext("panic: COND_WAIT");        \
  237.     } STMT_END
  238.  
  239. #  define COND_DESTROY(c) \
  240.     STMT_START {                        \
  241.     if (pthread_cond_destroy((c)))                \
  242.         Perl_croak_nocontext("panic: COND_DESTROY");    \
  243.     } STMT_END
  244. #endif /* COND_INIT */
  245.  
  246. /* DETACH(t) must only be called while holding t->mutex */
  247. #ifndef DETACH
  248. #  define DETACH(t) \
  249.     STMT_START {                        \
  250.     if (pthread_detach((t)->self)) {            \
  251.         MUTEX_UNLOCK(&(t)->mutex);                \
  252.         Perl_croak_nocontext("panic: DETACH");        \
  253.     }                            \
  254.     } STMT_END
  255. #endif /* DETACH */
  256.  
  257. #ifndef JOIN
  258. #  define JOIN(t, avp) \
  259.     STMT_START {                        \
  260.     if (pthread_join((t)->self, (void**)(avp)))        \
  261.         Perl_croak_nocontext("panic: pthread_join");    \
  262.     } STMT_END
  263. #endif /* JOIN */
  264.  
  265. /* Use an unchecked fetch of thread-specific data instead of a checked one.
  266.  * It would fail if the key were bogus, but if the key were bogus then
  267.  * Really Bad Things would be happening anyway. --dan */
  268. #if (defined(__ALPHA) && (__VMS_VER >= 70000000)) || \
  269.     (defined(__alpha) && defined(__osf__)) /* Available only on >= 4.0 */
  270. #  define HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP /* Configure test needed */
  271. #endif
  272.  
  273. #ifdef HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP
  274. #  define PTHREAD_GETSPECIFIC(key) pthread_unchecked_getspecific_np(key)
  275. #else
  276. #  define PTHREAD_GETSPECIFIC(key) pthread_getspecific(key)
  277. #endif
  278.  
  279. #ifndef PERL_GET_CONTEXT
  280. #  define PERL_GET_CONTEXT    PTHREAD_GETSPECIFIC(PL_thr_key)
  281. #endif
  282.  
  283. #ifndef PERL_SET_CONTEXT
  284. #  define PERL_SET_CONTEXT(t) \
  285.     STMT_START {                        \
  286.     if (pthread_setspecific(PL_thr_key, (void *)(t)))    \
  287.         Perl_croak_nocontext("panic: pthread_setspecific");    \
  288.     } STMT_END
  289. #endif /* PERL_SET_CONTEXT */
  290.  
  291. #ifndef INIT_THREADS
  292. #  ifdef NEED_PTHREAD_INIT
  293. #    define INIT_THREADS pthread_init()
  294. #  endif
  295. #endif
  296.  
  297. #ifndef ALLOC_THREAD_KEY
  298. #  define ALLOC_THREAD_KEY \
  299.     STMT_START {                        \
  300.     if (pthread_key_create(&PL_thr_key, 0))    {        \
  301.         PerlIO_printf(PerlIO_stderr(), "panic: pthread_key_create");    \
  302.         exit(1);                        \
  303.     }                            \
  304.     } STMT_END
  305. #endif
  306.  
  307. #ifndef FREE_THREAD_KEY
  308. #  define FREE_THREAD_KEY \
  309.     STMT_START {                        \
  310.     pthread_key_delete(PL_thr_key);                \
  311.     } STMT_END
  312. #endif
  313.  
  314. #ifndef PTHREAD_ATFORK
  315. #  ifdef HAS_PTHREAD_ATFORK
  316. #    define PTHREAD_ATFORK(prepare,parent,child)        \
  317.     pthread_atfork(prepare,parent,child)
  318. #  else
  319. #    define PTHREAD_ATFORK(prepare,parent,child)        \
  320.     NOOP
  321. #  endif
  322. #endif
  323.  
  324. #ifndef THREAD_RET_TYPE
  325. #  define THREAD_RET_TYPE    void *
  326. #  define THREAD_RET_CAST(p)    ((void *)(p))
  327. #endif /* THREAD_RET */
  328.  
  329. #if defined(USE_5005THREADS)
  330.  
  331. /* Accessor for per-thread SVs */
  332. #  define THREADSV(i) (thr->threadsvp[i])
  333.  
  334. /*
  335.  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
  336.  * try only locking them if there may be more than one thread in existence.
  337.  * Systems with very fast mutexes (and/or slow conditionals) may wish to
  338.  * remove the "if (threadnum) ..." test.
  339.  * XXX do NOT use C<if (PL_threadnum) ...> -- it sets up race conditions!
  340.  */
  341. #  define LOCK_SV_MUTEX        MUTEX_LOCK(&PL_sv_mutex)
  342. #  define UNLOCK_SV_MUTEX    MUTEX_UNLOCK(&PL_sv_mutex)
  343. #  define LOCK_STRTAB_MUTEX    MUTEX_LOCK(&PL_strtab_mutex)
  344. #  define UNLOCK_STRTAB_MUTEX    MUTEX_UNLOCK(&PL_strtab_mutex)
  345. #  define LOCK_CRED_MUTEX    MUTEX_LOCK(&PL_cred_mutex)
  346. #  define UNLOCK_CRED_MUTEX    MUTEX_UNLOCK(&PL_cred_mutex)
  347. #  define LOCK_FDPID_MUTEX    MUTEX_LOCK(&PL_fdpid_mutex)
  348. #  define UNLOCK_FDPID_MUTEX    MUTEX_UNLOCK(&PL_fdpid_mutex)
  349. #  define LOCK_SV_LOCK_MUTEX    MUTEX_LOCK(&PL_sv_lock_mutex)
  350. #  define UNLOCK_SV_LOCK_MUTEX    MUTEX_UNLOCK(&PL_sv_lock_mutex)
  351.  
  352. /* Values and macros for thr->flags */
  353. #define THRf_STATE_MASK    7
  354. #define THRf_R_JOINABLE    0
  355. #define THRf_R_JOINED    1
  356. #define THRf_R_DETACHED    2
  357. #define THRf_ZOMBIE    3
  358. #define THRf_DEAD    4
  359.  
  360. #define THRf_DID_DIE    8
  361.  
  362. /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
  363. #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
  364. #define ThrSETSTATE(t, s) STMT_START {        \
  365.     (t)->flags &= ~THRf_STATE_MASK;        \
  366.     (t)->flags |= (s);            \
  367.     DEBUG_S(PerlIO_printf(Perl_debug_log,    \
  368.                   "thread %p set to state %d\n", (t), (s))); \
  369.     } STMT_END
  370.  
  371. typedef struct condpair {
  372.     perl_mutex    mutex;        /* Protects all other fields */
  373.     perl_cond    owner_cond;    /* For when owner changes at all */
  374.     perl_cond    cond;        /* For cond_signal and cond_broadcast */
  375.     Thread    owner;        /* Currently owning thread */
  376. } condpair_t;
  377.  
  378. #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
  379. #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
  380. #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
  381. #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
  382.  
  383. #endif /* USE_5005THREADS */
  384. #endif /* USE_5005THREADS || USE_ITHREADS */
  385.  
  386. #ifndef MUTEX_LOCK
  387. #  define MUTEX_LOCK(m)
  388. #endif
  389.  
  390. #ifndef MUTEX_UNLOCK
  391. #  define MUTEX_UNLOCK(m)
  392. #endif
  393.  
  394. #ifndef MUTEX_INIT
  395. #  define MUTEX_INIT(m)
  396. #endif
  397.  
  398. #ifndef MUTEX_DESTROY
  399. #  define MUTEX_DESTROY(m)
  400. #endif
  401.  
  402. #ifndef COND_INIT
  403. #  define COND_INIT(c)
  404. #endif
  405.  
  406. #ifndef COND_SIGNAL
  407. #  define COND_SIGNAL(c)
  408. #endif
  409.  
  410. #ifndef COND_BROADCAST
  411. #  define COND_BROADCAST(c)
  412. #endif
  413.  
  414. #ifndef COND_WAIT
  415. #  define COND_WAIT(c, m)
  416. #endif
  417.  
  418. #ifndef COND_DESTROY
  419. #  define COND_DESTROY(c)
  420. #endif
  421.  
  422. #ifndef LOCK_SV_MUTEX
  423. #  define LOCK_SV_MUTEX
  424. #endif
  425.  
  426. #ifndef UNLOCK_SV_MUTEX
  427. #  define UNLOCK_SV_MUTEX
  428. #endif
  429.  
  430. #ifndef LOCK_STRTAB_MUTEX
  431. #  define LOCK_STRTAB_MUTEX
  432. #endif
  433.  
  434. #ifndef UNLOCK_STRTAB_MUTEX
  435. #  define UNLOCK_STRTAB_MUTEX
  436. #endif
  437.  
  438. #ifndef LOCK_CRED_MUTEX
  439. #  define LOCK_CRED_MUTEX
  440. #endif
  441.  
  442. #ifndef UNLOCK_CRED_MUTEX
  443. #  define UNLOCK_CRED_MUTEX
  444. #endif
  445.  
  446. #ifndef LOCK_FDPID_MUTEX
  447. #  define LOCK_FDPID_MUTEX
  448. #endif
  449.  
  450. #ifndef UNLOCK_FDPID_MUTEX
  451. #  define UNLOCK_FDPID_MUTEX
  452. #endif
  453.  
  454. #ifndef LOCK_SV_LOCK_MUTEX
  455. #  define LOCK_SV_LOCK_MUTEX
  456. #endif
  457.  
  458. #ifndef UNLOCK_SV_LOCK_MUTEX
  459. #  define UNLOCK_SV_LOCK_MUTEX
  460. #endif
  461.  
  462. /* THR, SET_THR, and dTHR are there for compatibility with old versions */
  463. #ifndef THR
  464. #  define THR        PERL_GET_THX
  465. #endif
  466.  
  467. #ifndef SET_THR
  468. #  define SET_THR(t)    PERL_SET_THX(t)
  469. #endif
  470.  
  471. #ifndef dTHR
  472. #  define dTHR dNOOP
  473. #endif
  474.  
  475. #ifndef INIT_THREADS
  476. #  define INIT_THREADS NOOP
  477. #endif
  478.