This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
integarte malloc.c changes from mainline change#1807,2112,2133
[perl5.git] / thread.h
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 #ifndef YIELD
39 #  ifdef HAS_SCHED_YIELD
40 #    define YIELD sched_yield()
41 #  else
42 #    ifdef HAS_PTHREAD_YIELD
43 #      define YIELD pthread_yield()
44 #    endif
45 #  endif
46 #endif
47
48 #ifndef MUTEX_INIT
49 #define MUTEX_INIT(m)                                           \
50     STMT_START {                                                \
51         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
52             croak("panic: MUTEX_INIT");                         \
53     } STMT_END
54 #define MUTEX_LOCK(m)                           \
55     STMT_START {                                \
56         if (pthread_mutex_lock((m)))            \
57             croak("panic: MUTEX_LOCK");         \
58     } STMT_END
59 #define MUTEX_UNLOCK(m)                         \
60     STMT_START {                                \
61         if (pthread_mutex_unlock((m)))          \
62             croak("panic: MUTEX_UNLOCK");       \
63     } STMT_END
64 #define MUTEX_DESTROY(m)                        \
65     STMT_START {                                \
66         if (pthread_mutex_destroy((m)))         \
67             croak("panic: MUTEX_DESTROY");      \
68     } STMT_END
69 #endif /* MUTEX_INIT */
70
71 #ifndef COND_INIT
72 #define COND_INIT(c)                                            \
73     STMT_START {                                                \
74         if (pthread_cond_init((c), pthread_condattr_default))   \
75             croak("panic: COND_INIT");                          \
76     } STMT_END
77 #define COND_SIGNAL(c)                          \
78     STMT_START {                                \
79         if (pthread_cond_signal((c)))           \
80             croak("panic: COND_SIGNAL");        \
81     } STMT_END
82 #define COND_BROADCAST(c)                       \
83     STMT_START {                                \
84         if (pthread_cond_broadcast((c)))        \
85             croak("panic: COND_BROADCAST");     \
86     } STMT_END
87 #define COND_WAIT(c, m)                         \
88     STMT_START {                                \
89         if (pthread_cond_wait((c), (m)))        \
90             croak("panic: COND_WAIT");          \
91     } STMT_END
92 #define COND_DESTROY(c)                         \
93     STMT_START {                                \
94         if (pthread_cond_destroy((c)))          \
95             croak("panic: COND_DESTROY");       \
96     } STMT_END
97 #endif /* COND_INIT */
98
99 /* DETACH(t) must only be called while holding t->mutex */
100 #ifndef DETACH
101 #define DETACH(t)                               \
102     STMT_START {                                \
103         if (pthread_detach((t)->self)) {        \
104             MUTEX_UNLOCK(&(t)->mutex);          \
105             croak("panic: DETACH");             \
106         }                                       \
107     } STMT_END
108 #endif /* DETACH */
109
110 #ifndef JOIN
111 #define JOIN(t, avp)                                    \
112     STMT_START {                                        \
113         if (pthread_join((t)->self, (void**)(avp)))     \
114             croak("panic: pthread_join");               \
115     } STMT_END
116 #endif /* JOIN */
117
118 #ifndef SET_THR
119 #define SET_THR(t)                                      \
120     STMT_START {                                        \
121         if (pthread_setspecific(PL_thr_key, (void *) (t)))      \
122             croak("panic: pthread_setspecific");        \
123     } STMT_END
124 #endif /* SET_THR */
125
126 #ifndef THR
127 #  ifdef OLD_PTHREADS_API
128 struct perl_thread *getTHR _((void));
129 #    define THR getTHR()
130 #  else
131 #    define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
132 #  endif /* OLD_PTHREADS_API */
133 #endif /* THR */
134
135 /*
136  * dTHR is performance-critical. Here, we only do the pthread_get_specific
137  * if there may be more than one thread in existence, otherwise we get thr
138  * from thrsv which is cached in the per-interpreter structure.
139  * Systems with very fast pthread_get_specific (which should be all systems
140  * but unfortunately isn't) may wish to simplify to "...*thr = THR".
141  */
142 #ifndef dTHR
143 #  define dTHR \
144     struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
145 #endif /* dTHR */
146
147 #ifndef INIT_THREADS
148 #  ifdef NEED_PTHREAD_INIT
149 #    define INIT_THREADS pthread_init()
150 #  else
151 #    define INIT_THREADS NOOP
152 #  endif
153 #endif
154
155 /* Accessor for per-thread SVs */
156 #define THREADSV(i) (thr->threadsvp[i])
157
158 /*
159  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
160  * try only locking them if there may be more than one thread in existence.
161  * Systems with very fast mutexes (and/or slow conditionals) may wish to
162  * remove the "if (threadnum) ..." test.
163  */
164 #define LOCK_SV_MUTEX                           \
165     STMT_START {                                \
166         if (PL_threadnum)                       \
167             MUTEX_LOCK(&PL_sv_mutex);           \
168     } STMT_END
169
170 #define UNLOCK_SV_MUTEX                         \
171     STMT_START {                                \
172         if (PL_threadnum)                       \
173             MUTEX_UNLOCK(&PL_sv_mutex);         \
174     } STMT_END
175
176 /* Likewise for strtab_mutex */
177 #define LOCK_STRTAB_MUTEX                       \
178     STMT_START {                                \
179         if (PL_threadnum)                       \
180             MUTEX_LOCK(&PL_strtab_mutex);       \
181     } STMT_END
182
183 #define UNLOCK_STRTAB_MUTEX                     \
184     STMT_START {                                \
185         if (PL_threadnum)                       \
186             MUTEX_UNLOCK(&PL_strtab_mutex);     \
187     } STMT_END
188
189 #ifndef THREAD_RET_TYPE
190 #  define THREAD_RET_TYPE       void *
191 #  define THREAD_RET_CAST(p)    ((void *)(p))
192 #endif /* THREAD_RET */
193
194
195 /* Values and macros for thr->flags */
196 #define THRf_STATE_MASK 7
197 #define THRf_R_JOINABLE 0
198 #define THRf_R_JOINED   1
199 #define THRf_R_DETACHED 2
200 #define THRf_ZOMBIE     3
201 #define THRf_DEAD       4
202
203 #define THRf_DID_DIE    8
204
205 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
206 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
207 #define ThrSETSTATE(t, s) STMT_START {          \
208         (t)->flags &= ~THRf_STATE_MASK;         \
209         (t)->flags |= (s);                      \
210         DEBUG_S(PerlIO_printf(PerlIO_stderr(),  \
211                               "thread %p set to state %d\n", (t), (s))); \
212     } STMT_END
213
214 typedef struct condpair {
215     perl_mutex  mutex;          /* Protects all other fields */
216     perl_cond   owner_cond;     /* For when owner changes at all */
217     perl_cond   cond;           /* For cond_signal and cond_broadcast */
218     Thread      owner;          /* Currently owning thread */
219 } condpair_t;
220
221 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
222 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
223 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
224 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
225
226 #else
227 /* USE_THREADS is not defined */
228 #define MUTEX_LOCK(m)
229 #define MUTEX_UNLOCK(m)
230 #define MUTEX_INIT(m)
231 #define MUTEX_DESTROY(m)
232 #define COND_INIT(c)
233 #define COND_SIGNAL(c)
234 #define COND_BROADCAST(c)
235 #define COND_WAIT(c, m)
236 #define COND_DESTROY(c)
237 #define LOCK_SV_MUTEX
238 #define UNLOCK_SV_MUTEX
239 #define LOCK_STRTAB_MUTEX
240 #define UNLOCK_STRTAB_MUTEX
241
242 #define THR
243 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */
244 #ifdef WIN32
245 #define dTHR extern int Perl___notused
246 #else
247 #define dTHR extern int errno
248 #endif
249 #endif /* USE_THREADS */