Fix perl_os_thread typedef for pthreads. Tweak SvTAINT so that
[p5sagit/p5-mst-13.2.git] / thread.h
1 #ifdef USE_THREADS
2
3 #ifdef WIN32
4 #  include <win32thread.h>
5 #else
6
7 /* POSIXish threads */
8 #ifdef OLD_PTHREADS_API
9 #  define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
10 #  define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
11 #  define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
12 #  define YIELD pthread_yield()
13 #  define DETACH(t)                             \
14     STMT_START {                                \
15         if (pthread_detach(&(t)->self)) {       \
16             MUTEX_UNLOCK(&(t)->mutex);          \
17             croak("panic: DETACH");             \
18         }                                       \
19     } STMT_END
20 #else
21 #  define pthread_mutexattr_default NULL
22 #  define pthread_condattr_default NULL
23 #  define pthread_attr_default NULL
24 #endif /* OLD_PTHREADS_API */
25 #endif
26
27 #ifndef YIELD
28 #  ifdef HAS_PTHREAD_YIELD
29 #    define YIELD pthread_yield()
30 #  else
31 #    define YIELD sched_yield()
32 #  endif
33 #endif
34
35 #ifndef MUTEX_INIT
36 #define MUTEX_INIT(m)                                           \
37     STMT_START {                                                \
38         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
39             croak("panic: MUTEX_INIT");                         \
40     } STMT_END
41 #define MUTEX_LOCK(m)                           \
42     STMT_START {                                \
43         if (pthread_mutex_lock((m)))            \
44             croak("panic: MUTEX_LOCK");         \
45     } STMT_END
46 #define MUTEX_UNLOCK(m)                         \
47     STMT_START {                                \
48         if (pthread_mutex_unlock((m)))          \
49             croak("panic: MUTEX_UNLOCK");       \
50     } STMT_END
51 #define MUTEX_DESTROY(m)                        \
52     STMT_START {                                \
53         if (pthread_mutex_destroy((m)))         \
54             croak("panic: MUTEX_DESTROY");      \
55     } STMT_END
56 #endif /* MUTEX_INIT */
57
58 #ifndef COND_INIT
59 #define COND_INIT(c)                                            \
60     STMT_START {                                                \
61         if (pthread_cond_init((c), pthread_condattr_default))   \
62             croak("panic: COND_INIT");                          \
63     } STMT_END
64 #define COND_SIGNAL(c)                          \
65     STMT_START {                                \
66         if (pthread_cond_signal((c)))           \
67             croak("panic: COND_SIGNAL");        \
68     } STMT_END
69 #define COND_BROADCAST(c)                       \
70     STMT_START {                                \
71         if (pthread_cond_broadcast((c)))        \
72             croak("panic: COND_BROADCAST");     \
73     } STMT_END
74 #define COND_WAIT(c, m)                         \
75     STMT_START {                                \
76         if (pthread_cond_wait((c), (m)))        \
77             croak("panic: COND_WAIT");          \
78     } STMT_END
79 #define COND_DESTROY(c)                         \
80     STMT_START {                                \
81         if (pthread_cond_destroy((c)))          \
82             croak("panic: COND_DESTROY");       \
83     } STMT_END
84 #endif /* COND_INIT */
85
86 /* DETACH(t) must only be called while holding t->mutex */
87 #ifndef DETACH
88 #define DETACH(t)                               \
89     STMT_START {                                \
90         if (pthread_detach((t)->self)) {        \
91             MUTEX_UNLOCK(&(t)->mutex);          \
92             croak("panic: DETACH");             \
93         }                                       \
94     } STMT_END
95 #endif /* DETACH */
96
97 #ifndef JOIN
98 #define JOIN(t, avp)                                    \
99     STMT_START {                                        \
100         if (pthread_join((t)->self, (void**)(avp)))     \
101             croak("panic: pthread_join");               \
102     } STMT_END
103 #endif /* JOIN */
104
105 #ifndef SET_THR
106 #define SET_THR(t)                                      \
107     STMT_START {                                        \
108         if (pthread_setspecific(thr_key, (void *) (t))) \
109             croak("panic: pthread_setspecific");        \
110     } STMT_END
111 #endif /* SET_THR */
112
113 #ifndef THR
114 #  ifdef OLD_PTHREADS_API
115 struct perl_thread *getTHR _((void));
116 #    define THR getTHR()
117 #  else
118 #    define THR ((struct perl_thread *) pthread_getspecific(thr_key))
119 #  endif /* OLD_PTHREADS_API */
120 #endif /* THR */
121
122 #ifndef dTHR
123 #  define dTHR struct perl_thread *thr = THR
124 #endif /* dTHR */
125
126 #ifndef INIT_THREADS
127 #  ifdef NEED_PTHREAD_INIT
128 #    define INIT_THREADS pthread_init()
129 #  else
130 #    define INIT_THREADS NOOP
131 #  endif
132 #endif
133
134
135 #ifndef THREAD_RET_TYPE
136 #  define THREAD_RET_TYPE       void *
137 #  define THREAD_RET_CAST(p)    ((void *)(p))
138 #endif /* THREAD_RET */
139
140
141 /* Values and macros for thr->flags */
142 #define THRf_STATE_MASK 7
143 #define THRf_R_JOINABLE 0
144 #define THRf_R_JOINED   1
145 #define THRf_R_DETACHED 2
146 #define THRf_ZOMBIE     3
147 #define THRf_DEAD       4
148
149 #define THRf_DID_DIE    8
150
151 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
152 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
153 #define ThrSETSTATE(t, s) STMT_START {          \
154         (t)->flags &= ~THRf_STATE_MASK;         \
155         (t)->flags |= (s);                      \
156         DEBUG_L(PerlIO_printf(PerlIO_stderr(),  \
157                               "thread %p set to state %d\n", (t), (s))); \
158     } STMT_END
159
160 typedef struct condpair {
161     perl_mutex  mutex;          /* Protects all other fields */
162     perl_cond   owner_cond;     /* For when owner changes at all */
163     perl_cond   cond;           /* For cond_signal and cond_broadcast */
164     Thread      owner;          /* Currently owning thread */
165 } condpair_t;
166
167 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
168 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
169 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
170 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
171
172 #else
173 /* USE_THREADS is not defined */
174 #define MUTEX_LOCK(m)
175 #define MUTEX_UNLOCK(m)
176 #define MUTEX_INIT(m)
177 #define MUTEX_DESTROY(m)
178 #define COND_INIT(c)
179 #define COND_SIGNAL(c)
180 #define COND_BROADCAST(c)
181 #define COND_WAIT(c, m)
182 #define COND_DESTROY(c)
183
184 #define THR
185 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
186 #define dTHR extern int errno
187 #endif /* USE_THREADS */