1/* This file is automatically generated. DO NOT EDIT! */ 2/* Generated from: NetBSD: mknative-gcc,v 1.45 2009/12/17 15:48:13 uebayasi Exp */ 3/* Generated from: NetBSD: mknative.common,v 1.9 2007/02/05 18:26:01 apb Exp */ 4 5/* Threads compatibility routines for libgcc2 and libobjc. */ 6/* Compile this one with gcc. */ 7/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 8 Free Software Foundation, Inc. 9 10This file is part of GCC. 11 12GCC is free software; you can redistribute it and/or modify it under 13the terms of the GNU General Public License as published by the Free 14Software Foundation; either version 2, or (at your option) any later 15version. 16 17GCC is distributed in the hope that it will be useful, but WITHOUT ANY 18WARRANTY; without even the implied warranty of MERCHANTABILITY or 19FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20for more details. 21 22You should have received a copy of the GNU General Public License 23along with GCC; see the file COPYING. If not, write to the Free 24Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2502110-1301, USA. */ 26 27/* As a special exception, if you link this library with other files, 28 some of which are compiled with GCC, to produce an executable, 29 this library does not by itself cause the resulting executable 30 to be covered by the GNU General Public License. 31 This exception does not however invalidate any other reasons why 32 the executable file might be covered by the GNU General Public License. */ 33 34#ifndef _GLIBCXX_GCC_GTHR_POSIX_H 35#define _GLIBCXX_GCC_GTHR_POSIX_H 36 37/* POSIX threads specific definitions. 38 Easy, since the interface is just one-to-one mapping. */ 39 40#define __GTHREADS 1 41 42/* Some implementations of <pthread.h> require this to be defined. */ 43#if !defined(_REENTRANT) && defined(__osf__) 44#define _REENTRANT 1 45#endif 46 47#include <pthread.h> 48#include <unistd.h> 49 50typedef pthread_key_t __gthread_key_t; 51typedef pthread_once_t __gthread_once_t; 52typedef pthread_mutex_t __gthread_mutex_t; 53typedef pthread_mutex_t __gthread_recursive_mutex_t; 54 55#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 56#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 57#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 58#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER 59#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 60#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 61#else 62#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 63#endif 64 65#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 66# ifndef __gthrw_pragma 67# define __gthrw_pragma(pragma) 68# endif 69# ifdef __clang__ 70# define __gthrw2(name,name2,type) \ 71 static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 72 __gthrw_pragma(weak type) 73# else 74# define __gthrw2(name,name2,type) \ 75 extern __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 76 __gthrw_pragma(weak type) 77# endif 78# define __gthrw_(name) __gthrw_ ## name 79#else 80# define __gthrw2(name,name2,type) 81# define __gthrw_(name) name 82#endif 83 84/* Typically, __gthrw_foo is a weak reference to symbol foo. */ 85#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) 86 87/* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to 88 map a subset of the POSIX pthread API to mangled versions of their 89 names. */ 90#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 91#define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name) 92__gthrw3(pthread_once) 93__gthrw3(pthread_getspecific) 94__gthrw3(pthread_setspecific) 95__gthrw3(pthread_create) 96__gthrw3(pthread_cancel) 97__gthrw3(pthread_mutex_lock) 98__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