source: trunk/third/perl/thread.h @ 18450

Revision 18450, 12.4 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18449, which included commits to RCS files with non-trunk default branches.
Line 
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
371typedef 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
Note: See TracBrowser for help on using the repository browser.