1281348Scy/* This file is automatically generated. DO NOT EDIT! */ 2281348Scy/* Generated from: NetBSD: mknative-gcc,v 1.45 2009/12/17 15:48:13 uebayasi Exp */ 3281348Scy/* Generated from: NetBSD: mknative.common,v 1.9 2007/02/05 18:26:01 apb Exp */ 4281348Scy 5281348Scy/* Threads compatibility routines for libgcc2 and libobjc. */ 6281348Scy/* Compile this one with gcc. */ 7281348Scy/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 8281348Scy Free Software Foundation, Inc. 9281348Scy 10281348ScyThis file is part of GCC. 11281348Scy 12281348ScyGCC is free software; you can redistribute it and/or modify it under 13281348Scythe terms of the GNU General Public License as published by the Free 14281348ScySoftware Foundation; either version 2, or (at your option) any later 15281348Scyversion. 16281348Scy 17281348ScyGCC is distributed in the hope that it will be useful, but WITHOUT ANY 18281348ScyWARRANTY; without even the implied warranty of MERCHANTABILITY or 19281348ScyFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20281348Scyfor more details. 21281348Scy 22281348ScyYou should have received a copy of the GNU General Public License 23281348Scyalong with GCC; see the file COPYING. If not, write to the Free 24281348ScySoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 25281348Scy02110-1301, USA. */ 26281348Scy 27281348Scy/* As a special exception, if you link this library with other files, 28281348Scy some of which are compiled with GCC, to produce an executable, 29281348Scy this library does not by itself cause the resulting executable 30281348Scy to be covered by the GNU General Public License. 31281348Scy This exception does not however invalidate any other reasons why 32281348Scy the executable file might be covered by the GNU General Public License. */ 33281348Scy 34281348Scy#ifndef _GLIBCXX_GCC_GTHR_POSIX_H 35290000Sglebius#define _GLIBCXX_GCC_GTHR_POSIX_H 36281348Scy 37281348Scy/* POSIX threads specific definitions. 38290000Sglebius Easy, since the interface is just one-to-one mapping. */ 39281348Scy 40281348Scy#define __GTHREADS 1 41281348Scy 42281348Scy/* Some implementations of <pthread.h> require this to be defined. */ 43281348Scy#if !defined(_REENTRANT) && defined(__osf__) 44281348Scy#define _REENTRANT 1 45281348Scy#endif 46281348Scy 47281348Scy#include <pthread.h> 48281348Scy#include <unistd.h> 49281348Scy 50281348Scytypedef pthread_key_t __gthread_key_t; 51281348Scytypedef pthread_once_t __gthread_once_t; 52281348Scytypedef pthread_mutex_t __gthread_mutex_t; 53281348Scytypedef pthread_mutex_t __gthread_recursive_mutex_t; 54281348Scy 55281348Scy#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 56281348Scy#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 57281348Scy#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 58281348Scy#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER 59281348Scy#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 60281348Scy#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 61281348Scy#else 62281348Scy#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 63281348Scy#endif 64281348Scy 65281348Scy#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 66281348Scy# ifndef __gthrw_pragma 67281348Scy# define __gthrw_pragma(pragma) 68281348Scy# endif 69281348Scy# ifdef __clang__ 70281348Scy# define __gthrw2(name,name2,type) \ 71281348Scy static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 72281348Scy __gthrw_pragma(weak type) 73281348Scy# else 74281348Scy# define __gthrw2(name,name2,type) \ 75281348Scy extern __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 76281348Scy __gthrw_pragma(weak type) 77281348Scy# endif 78281348Scy# define __gthrw_(name) __gthrw_ ## name 79281348Scy#else 80281348Scy# define __gthrw2(name,name2,type) 81281348Scy# define __gthrw_(name) name 82281348Scy#endif 83281348Scy 84281348Scy/* Typically, __gthrw_foo is a weak reference to symbol foo. */ 85281348Scy#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) 86281348Scy 87281348Scy/* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to 88281348Scy map a subset of the POSIX pthread API to mangled versions of their 89281348Scy names. */ 90281348Scy#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 91281348Scy#define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name) 92281348Scy__gthrw3(pthread_once) 93281348Scy__gthrw3(pthread_getspecific) 94281348Scy__gthrw3(pthread_setspecific) 95281348Scy__gthrw3(pthread_create) 96281348Scy__gthrw3(pthread_cancel) 97281348Scy__gthrw3(pthread_mutex_lock) 98281348Scy__gthrw3(pthread_mutex_trylock) 99__gthrw3(pthread_mutex_unlock) 100__gthrw3(pthread_mutex_init) 101#else 102__gthrw(pthread_once) 103__gthrw(pthread_getspecific) 104__gthrw(pthread_setspecific) 105__gthrw(pthread_create) 106__gthrw(pthread_cancel) 107__gthrw(pthread_mutex_lock) 108__gthrw(pthread_mutex_trylock) 109__gthrw(pthread_mutex_unlock) 110__gthrw(pthread_mutex_init) 111#endif 112 113__gthrw(pthread_key_create) 114__gthrw(pthread_key_delete) 115__gthrw(pthread_mutexattr_init) 116__gthrw(pthread_mutexattr_settype) 117__gthrw(pthread_mutexattr_destroy) 118 119 120#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) 121/* Objective-C. */ 122#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 123__gthrw3(pthread_cond_broadcast) 124__gthrw3(pthread_cond_destroy) 125__gthrw3(pthread_cond_init) 126__gthrw3(pthread_cond_signal) 127__gthrw3(pthread_cond_wait) 128__gthrw3(pthread_exit) 129__gthrw3(pthread_mutex_destroy) 130__gthrw3(pthread_self) 131#else 132__gthrw(pthread_cond_broadcast) 133__gthrw(pthread_cond_destroy) 134__gthrw(pthread_cond_init) 135__gthrw(pthread_cond_signal) 136__gthrw(pthread_cond_wait) 137__gthrw(pthread_exit) 138__gthrw(pthread_mutex_destroy) 139__gthrw(pthread_self) 140#endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */ 141#ifdef _POSIX_PRIORITY_SCHEDULING 142#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 143__gthrw(sched_get_priority_max) 144__gthrw(sched_get_priority_min) 145#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 146#endif /* _POSIX_PRIORITY_SCHEDULING */ 147__gthrw(sched_yield) 148__gthrw(pthread_attr_destroy) 149__gthrw(pthread_attr_init) 150__gthrw(pthread_attr_setdetachstate) 151#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 152__gthrw(pthread_getschedparam) 153__gthrw(pthread_setschedparam) 154#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 155#endif /* _LIBOBJC || _LIBOBJC_WEAK */ 156 157#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 158 159static inline int 160__gthread_active_p (void) 161{ 162 static void *const __gthread_active_ptr 163 = __extension__ (void *) &__gthrw_(pthread_cancel); 164 return __gthread_active_ptr != 0; 165} 166 167#else /* not __GXX_WEAK__ */ 168 169static inline int 170__gthread_active_p (void) 171{ 172 return 1; 173} 174 175#endif /* __GXX_WEAK__ */ 176 177#ifdef _LIBOBJC 178 179/* This is the config.h file in libobjc/ */ 180#include <config.h> 181 182#ifdef HAVE_SCHED_H 183# include <sched.h> 184#endif 185 186/* Key structure for maintaining thread specific storage */ 187static pthread_key_t _objc_thread_storage; 188static pthread_attr_t _objc_thread_attribs; 189 190/* Thread local storage for a single thread */ 191static void *thread_local_storage = NULL; 192 193/* Backend initialization functions */ 194 195/* Initialize the threads subsystem. */ 196static inline int 197__gthread_objc_init_thread_system (void) 198{ 199 if (__gthread_active_p ()) 200 { 201 /* Initialize the thread storage key. */ 202 if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) 203 { 204 /* The normal default detach state for threads is 205 * PTHREAD_CREATE_JOINABLE which causes threads to not die 206 * when you think they should. */ 207 if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 208 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, 209 PTHREAD_CREATE_DETACHED) == 0) 210 return 0; 211 } 212 } 213 214 return -1; 215} 216 217/* Close the threads subsystem. */ 218static inline int 219__gthread_objc_close_thread_system (void) 220{ 221 if (__gthread_active_p () 222 && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 223 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) 224 return 0; 225 226 return -1; 227} 228 229/* Backend thread functions */ 230 231/* Create a new thread of execution. */ 232static inline objc_thread_t 233__gthread_objc_thread_detach (void (*func)(void *), void *arg) 234{ 235 objc_thread_t thread_id; 236 pthread_t new_thread_handle; 237 238 if (!__gthread_active_p ()) 239 return NULL; 240 241 if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg))) 242 thread_id = (objc_thread_t) new_thread_handle; 243 else 244 thread_id = NULL; 245 246 return thread_id; 247} 248 249/* Set the current thread's priority. */ 250static inline int 251__gthread_objc_thread_set_priority (int priority) 252{ 253 if (!__gthread_active_p ()) 254 return -1; 255 else 256 { 257#ifdef _POSIX_PRIORITY_SCHEDULING 258#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 259 pthread_t thread_id = __gthrw_(pthread_self) (); 260 int policy; 261 struct sched_param params; 262 int priority_min, priority_max; 263 264 if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) 265 { 266 if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) 267 return -1; 268 269 if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) 270 return -1; 271 272 if (priority > priority_max) 273 priority = priority_max; 274 else if (priority < priority_min) 275 priority = priority_min; 276 params.sched_priority = priority; 277 278 /* 279 * The solaris 7 and several other man pages incorrectly state that 280 * this should be a pointer to policy but pthread.h is universally 281 * at odds with this. 282 */ 283 if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) 284 return 0; 285 } 286#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 287#endif /* _POSIX_PRIORITY_SCHEDULING */ 288 return -1; 289 } 290} 291 292/* Return the current thread's priority. */ 293static inline int 294__gthread_objc_thread_get_priority (void) 295{ 296#ifdef _POSIX_PRIORITY_SCHEDULING 297#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 298 if (__gthread_active_p ()) 299 { 300 int policy; 301 struct sched_param params; 302 303 if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) 304 return params.sched_priority; 305 else 306 return -1; 307 } 308 else 309#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 310#endif /* _POSIX_PRIORITY_SCHEDULING */ 311 return OBJC_THREAD_INTERACTIVE_PRIORITY; 312} 313 314/* Yield our process time to another thread. */ 315static inline void 316__gthread_objc_thread_yield (void) 317{ 318 if (__gthread_active_p ()) 319 __gthrw_(sched_yield) (); 320} 321 322/* Terminate the current thread. */ 323static inline int 324__gthread_objc_thread_exit (void) 325{ 326 if (__gthread_active_p ()) 327 /* exit the thread */ 328 __gthrw_(pthread_exit) (&__objc_thread_exit_status); 329 330 /* Failed if we reached here */ 331 return -1; 332} 333 334/* Returns an integer value which uniquely describes a thread. */ 335static inline objc_thread_t 336__gthread_objc_thread_id (void) 337{ 338 if (__gthread_active_p ()) 339 return (objc_thread_t) __gthrw_(pthread_self) (); 340 else 341 return (objc_thread_t) 1; 342} 343 344/* Sets the thread's local storage pointer. */ 345static inline int 346__gthread_objc_thread_set_data (void *value) 347{ 348 if (__gthread_active_p ()) 349 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); 350 else 351 { 352 thread_local_storage = value; 353 return 0; 354 } 355} 356 357/* Returns the thread's local storage pointer. */ 358static inline void * 359__gthread_objc_thread_get_data (void) 360{ 361 if (__gthread_active_p ()) 362 return __gthrw_(pthread_getspecific) (_objc_thread_storage); 363 else 364 return thread_local_storage; 365} 366 367/* Backend mutex functions */ 368 369/* Allocate a mutex. */ 370static inline int 371__gthread_objc_mutex_allocate (objc_mutex_t mutex) 372{ 373 if (__gthread_active_p ()) 374 { 375 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 376 377 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) 378 { 379 objc_free (mutex->backend); 380 mutex->backend = NULL; 381 return -1; 382 } 383 } 384 385 return 0; 386} 387 388/* Deallocate a mutex. */ 389static inline int 390__gthread_objc_mutex_deallocate (objc_mutex_t mutex) 391{ 392 if (__gthread_active_p ()) 393 { 394 int count; 395 396 /* 397 * Posix Threads specifically require that the thread be unlocked 398 * for __gthrw_(pthread_mutex_destroy) to work. 399 */ 400 401 do 402 { 403 count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); 404 if (count < 0) 405 return -1; 406 } 407 while (count); 408 409 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) 410 return -1; 411 412 objc_free (mutex->backend); 413 mutex->backend = NULL; 414 } 415 return 0; 416} 417 418/* Grab a lock on a mutex. */ 419static inline int 420__gthread_objc_mutex_lock (objc_mutex_t mutex) 421{ 422 if (__gthread_active_p () 423 && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) 424 { 425 return -1; 426 } 427 428 return 0; 429} 430 431/* Try to grab a lock on a mutex. */ 432static inline int 433__gthread_objc_mutex_trylock (objc_mutex_t mutex) 434{ 435 if (__gthread_active_p () 436 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) 437 { 438 return -1; 439 } 440 441 return 0; 442} 443 444/* Unlock the mutex */ 445static inline int 446__gthread_objc_mutex_unlock (objc_mutex_t mutex) 447{ 448 if (__gthread_active_p () 449 && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) 450 { 451 return -1; 452 } 453 454 return 0; 455} 456 457/* Backend condition mutex functions */ 458 459/* Allocate a condition. */ 460static inline int 461__gthread_objc_condition_allocate (objc_condition_t condition) 462{ 463 if (__gthread_active_p ()) 464 { 465 condition->backend = objc_malloc (sizeof (pthread_cond_t)); 466 467 if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) 468 { 469 objc_free (condition->backend); 470 condition->backend = NULL; 471 return -1; 472 } 473 } 474 475 return 0; 476} 477 478/* Deallocate a condition. */ 479static inline int 480__gthread_objc_condition_deallocate (objc_condition_t condition) 481{ 482 if (__gthread_active_p ()) 483 { 484 if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) 485 return -1; 486 487 objc_free (condition->backend); 488 condition->backend = NULL; 489 } 490 return 0; 491} 492 493/* Wait on the condition */ 494static inline int 495__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 496{ 497 if (__gthread_active_p ()) 498 return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, 499 (pthread_mutex_t *) mutex->backend); 500 else 501 return 0; 502} 503 504/* Wake up all threads waiting on this condition. */ 505static inline int 506__gthread_objc_condition_broadcast (objc_condition_t condition) 507{ 508 if (__gthread_active_p ()) 509 return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); 510 else 511 return 0; 512} 513 514/* Wake up one thread waiting on this condition. */ 515static inline int 516__gthread_objc_condition_signal (objc_condition_t condition) 517{ 518 if (__gthread_active_p ()) 519 return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); 520 else 521 return 0; 522} 523 524#else /* _LIBOBJC */ 525 526static inline int 527__gthread_once (__gthread_once_t *once, void (*func) (void)) 528{ 529 if (__gthread_active_p ()) 530 return __gthrw_(pthread_once) (once, func); 531 else 532 return -1; 533} 534 535static inline int 536__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) 537{ 538 return __gthrw_(pthread_key_create) (key, dtor); 539} 540 541static inline int 542__gthread_key_delete (__gthread_key_t key) 543{ 544 return __gthrw_(pthread_key_delete) (key); 545} 546 547static inline void * 548__gthread_getspecific (__gthread_key_t key) 549{ 550 return __gthrw_(pthread_getspecific) (key); 551} 552 553static inline int 554__gthread_setspecific (__gthread_key_t key, const void *ptr) 555{ 556 return __gthrw_(pthread_setspecific) (key, ptr); 557} 558 559static inline int 560__gthread_mutex_lock (__gthread_mutex_t *mutex) 561{ 562 if (__gthread_active_p ()) 563 return __gthrw_(pthread_mutex_lock) (mutex); 564 else 565 return 0; 566} 567 568static inline int 569__gthread_mutex_trylock (__gthread_mutex_t *mutex) 570{ 571 if (__gthread_active_p ()) 572 return __gthrw_(pthread_mutex_trylock) (mutex); 573 else 574 return 0; 575} 576 577static inline int 578__gthread_mutex_unlock (__gthread_mutex_t *mutex) 579{ 580 if (__gthread_active_p ()) 581 return __gthrw_(pthread_mutex_unlock) (mutex); 582 else 583 return 0; 584} 585 586#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 587static inline int 588__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) 589{ 590 if (__gthread_active_p ()) 591 { 592 pthread_mutexattr_t attr; 593 int r; 594 595 r = __gthrw_(pthread_mutexattr_init) (&attr); 596 if (!r) 597 r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE); 598 if (!r) 599 r = __gthrw_(pthread_mutex_init) (mutex, &attr); 600 if (!r) 601 r = __gthrw_(pthread_mutexattr_destroy) (&attr); 602 return r; 603 } 604 return 0; 605} 606#endif 607 608static inline int 609__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) 610{ 611 return __gthread_mutex_lock (mutex); 612} 613 614static inline int 615__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) 616{ 617 return __gthread_mutex_trylock (mutex); 618} 619 620static inline int 621__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) 622{ 623 return __gthread_mutex_unlock (mutex); 624} 625 626#endif /* _LIBOBJC */ 627 628#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ 629