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