00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef GCC_GTHR_SOLARIS_H
00031 #define GCC_GTHR_SOLARIS_H
00032
00033
00034
00035
00036
00037 #define __GTHREADS 1
00038
00039 #include <thread.h>
00040 #include <errno.h>
00041
00042 #ifdef __cplusplus
00043 #define UNUSED(x)
00044 #else
00045 #define UNUSED(x) x __attribute__((unused))
00046 #endif
00047
00048 typedef thread_key_t __gthread_key_t;
00049 typedef struct {
00050 mutex_t mutex;
00051 int once;
00052 } __gthread_once_t;
00053 typedef mutex_t __gthread_mutex_t;
00054
00055 typedef struct {
00056 long depth;
00057 thread_t owner;
00058 mutex_t actual;
00059 } __gthread_recursive_mutex_t;
00060
00061 #define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 }
00062 #define __GTHREAD_MUTEX_INIT DEFAULTMUTEX
00063 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
00064
00065 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
00066 # define __gthrw(name) \
00067 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
00068 # define __gthrw_(name) __gthrw_ ## name
00069 #else
00070 # define __gthrw(name)
00071 # define __gthrw_(name) name
00072 #endif
00073
00074 __gthrw(thr_keycreate)
00075 __gthrw(thr_getspecific)
00076 __gthrw(thr_setspecific)
00077 __gthrw(thr_create)
00078 __gthrw(thr_self)
00079
00080 __gthrw(mutex_init)
00081 __gthrw(mutex_destroy)
00082 __gthrw(mutex_lock)
00083 __gthrw(mutex_trylock)
00084 __gthrw(mutex_unlock)
00085
00086 #ifdef _LIBOBJC
00087 __gthrw(thr_exit)
00088 __gthrw(thr_getprio)
00089 __gthrw(thr_setprio)
00090 __gthrw(thr_yield)
00091
00092 __gthrw(cond_init)
00093 __gthrw(cond_destroy)
00094 __gthrw(cond_wait)
00095 __gthrw(cond_broadcast)
00096 __gthrw(cond_signal)
00097
00098 #endif
00099
00100 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
00101
00102
00103
00104
00105 static inline int
00106 __gthread_active_p (void)
00107 {
00108 static void *const __gthread_active_ptr = (void *) &__gthrw_(thr_create);
00109 return __gthread_active_ptr != 0;
00110 }
00111
00112 #else
00113
00114 static inline int
00115 __gthread_active_p (void)
00116 {
00117 return 1;
00118 }
00119
00120 #endif
00121
00122 #ifdef _LIBOBJC
00123
00124
00125 static thread_key_t _objc_thread_storage;
00126
00127
00128 static void *thread_local_storage = NULL;
00129
00130
00131
00132
00133 static inline int
00134 __gthread_objc_init_thread_system (void)
00135 {
00136
00137 if (__gthread_active_p ()
00138 && __gthrw_(thr_keycreate) (&_objc_thread_storage, NULL) == 0)
00139 return 0;
00140
00141 return -1;
00142 }
00143
00144
00145 static inline int
00146 __gthread_objc_close_thread_system (void)
00147 {
00148 if (__gthread_active_p ())
00149 return 0;
00150 else
00151 return -1;
00152 }
00153
00154
00155
00156
00157 static inline objc_thread_t
00158 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00159 {
00160 objc_thread_t thread_id;
00161 thread_t new_thread_id = 0;
00162
00163 if (!__gthread_active_p ())
00164 return NULL;
00165
00166 if (__gthrw_(thr_create) (NULL, 0, (void *) func, arg,
00167 THR_DETACHED | THR_NEW_LWP,
00168 &new_thread_id) == 0)
00169 thread_id = *(objc_thread_t *) &new_thread_id;
00170 else
00171 thread_id = NULL;
00172
00173 return thread_id;
00174 }
00175
00176
00177 static inline int
00178 __gthread_objc_thread_set_priority (int priority)
00179 {
00180 int sys_priority = 0;
00181
00182 if (!__gthread_active_p ())
00183 return -1;
00184
00185 switch (priority)
00186 {
00187 case OBJC_THREAD_INTERACTIVE_PRIORITY:
00188 sys_priority = 300;
00189 break;
00190 default:
00191 case OBJC_THREAD_BACKGROUND_PRIORITY:
00192 sys_priority = 200;
00193 break;
00194 case OBJC_THREAD_LOW_PRIORITY:
00195 sys_priority = 1000;
00196 break;
00197 }
00198
00199
00200 if (__gthrw_(thr_setprio) (__gthrw_(thr_self) (), sys_priority) == 0)
00201 return 0;
00202 else
00203 return -1;
00204 }
00205
00206
00207 static inline int
00208 __gthread_objc_thread_get_priority (void)
00209 {
00210 int sys_priority;
00211
00212 if (!__gthread_active_p ())
00213 return OBJC_THREAD_INTERACTIVE_PRIORITY;
00214
00215 if (__gthrw_(thr_getprio) (__gthrw_(thr_self) (), &sys_priority) == 0)
00216 {
00217 if (sys_priority >= 250)
00218 return OBJC_THREAD_INTERACTIVE_PRIORITY;
00219 else if (sys_priority >= 150)
00220 return OBJC_THREAD_BACKGROUND_PRIORITY;
00221 return OBJC_THREAD_LOW_PRIORITY;
00222 }
00223
00224
00225 return -1;
00226 }
00227
00228
00229 static inline void
00230 __gthread_objc_thread_yield (void)
00231 {
00232 if (__gthread_active_p ())
00233 __gthrw_(thr_yield) ();
00234 }
00235
00236
00237 static inline int
00238 __gthread_objc_thread_exit (void)
00239 {
00240 if (__gthread_active_p ())
00241
00242 __gthrw_(thr_exit) (&__objc_thread_exit_status);
00243
00244
00245 return -1;
00246 }
00247
00248
00249 static inline objc_thread_t
00250 __gthread_objc_thread_id (void)
00251 {
00252 if (__gthread_active_p ())
00253 return (objc_thread_t) __gthrw_(thr_self) ();
00254 else
00255 return (objc_thread_t) 1;
00256 }
00257
00258
00259 static inline int
00260 __gthread_objc_thread_set_data (void *value)
00261 {
00262 if (__gthread_active_p ())
00263 {
00264 if (__gthrw_(thr_setspecific) (_objc_thread_storage, value) == 0)
00265 return 0;
00266 else
00267 return -1;
00268 }
00269 else
00270 {
00271 thread_local_storage = value;
00272 return 0;
00273 }
00274 }
00275
00276
00277 static inline void *
00278 __gthread_objc_thread_get_data (void)
00279 {
00280 void *value = NULL;
00281
00282 if (__gthread_active_p ())
00283 {
00284 if (__gthrw_(thr_getspecific) (_objc_thread_storage, &value) == 0)
00285 return value;
00286 else
00287 return NULL;
00288 }
00289 else
00290 return thread_local_storage;
00291 }
00292
00293
00294
00295
00296 static inline int
00297 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00298 {
00299 if (__gthread_active_p ()
00300 && __gthrw_(mutex_init) ((mutex_t *) (&(mutex->backend)), USYNC_THREAD, 0))
00301 return -1;
00302
00303 return 0;
00304 }
00305
00306
00307 static inline int
00308 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00309 {
00310 if (__gthread_active_p ())
00311 __gthrw_(mutex_destroy) ((mutex_t *) (&(mutex->backend)));
00312
00313 return 0;
00314 }
00315
00316
00317 static inline int
00318 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00319 {
00320 if (__gthread_active_p ()
00321 && __gthrw_(mutex_lock) ((mutex_t *) (&(mutex->backend))) != 0)
00322 return -1;
00323
00324 return 0;
00325 }
00326
00327
00328 static inline int
00329 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00330 {
00331 if (__gthread_active_p ()
00332 && __gthrw_(mutex_trylock) ((mutex_t *) (&(mutex->backend))) != 0)
00333 return -1;
00334
00335 return 0;
00336 }
00337
00338
00339 static inline int
00340 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00341 {
00342 if (__gthread_active_p ()
00343 && __gthrw_(mutex_unlock) ((mutex_t *) (&(mutex->backend))) != 0)
00344 return -1;
00345
00346 return 0;
00347 }
00348
00349
00350
00351
00352 static inline int
00353 __gthread_objc_condition_allocate (objc_condition_t condition)
00354 {
00355 if (__gthread_active_p ())
00356 return __gthrw_(cond_init) ((cond_t *) (&(condition->backend)), USYNC_THREAD,
00357 NULL);
00358 else
00359 return 0;
00360 }
00361
00362
00363 static inline int
00364 __gthread_objc_condition_deallocate (objc_condition_t condition)
00365 {
00366 if (__gthread_active_p ())
00367 return __gthrw_(cond_destroy) ((cond_t *) (&(condition->backend)));
00368 else
00369 return 0;
00370 }
00371
00372
00373 static inline int
00374 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00375 {
00376 if (__gthread_active_p ())
00377 return __gthrw_(cond_wait) ((cond_t *) (&(condition->backend)),
00378 (mutex_t *) (&(mutex->backend)));
00379 else
00380 return 0;
00381 }
00382
00383
00384 static inline int
00385 __gthread_objc_condition_broadcast (objc_condition_t condition)
00386 {
00387 if (__gthread_active_p ())
00388 return __gthrw_(cond_broadcast) ((cond_t *) (&(condition->backend)));
00389 else
00390 return 0;
00391 }
00392
00393
00394 static inline int
00395 __gthread_objc_condition_signal (objc_condition_t condition)
00396 {
00397 if (__gthread_active_p ())
00398 return __gthrw_(cond_signal) ((cond_t *) (&(condition->backend)));
00399 else
00400 return 0;
00401 }
00402
00403 #else
00404
00405 static inline int
00406 __gthread_once (__gthread_once_t *once, void (*func) (void))
00407 {
00408 if (! __gthread_active_p ())
00409 return -1;
00410
00411 if (once == 0 || func == 0)
00412 return EINVAL;
00413
00414 if (once->once == 0)
00415 {
00416 int status = __gthrw_(mutex_lock) (&once->mutex);
00417 if (status != 0)
00418 return status;
00419 if (once->once == 0)
00420 {
00421 (*func) ();
00422 once->once++;
00423 }
00424 __gthrw_(mutex_unlock) (&once->mutex);
00425 }
00426 return 0;
00427 }
00428
00429 static inline int
00430 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00431 {
00432
00433
00434 *key = (__gthread_key_t)-1;
00435 if (__gthrw_(thr_keycreate) (key, dtor) != 0 || *key == (__gthread_key_t)-1)
00436 return -1;
00437 else
00438 return 0;
00439 }
00440
00441 static inline int
00442 __gthread_key_delete (__gthread_key_t UNUSED (key))
00443 {
00444
00445 return -1;
00446 }
00447
00448 static inline void *
00449 __gthread_getspecific (__gthread_key_t key)
00450 {
00451 void *ptr;
00452 if (__gthrw_(thr_getspecific) (key, &ptr) == 0)
00453 return ptr;
00454 else
00455 return 0;
00456 }
00457
00458 static inline int
00459 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00460 {
00461 return __gthrw_(thr_setspecific) (key, (void *) ptr);
00462 }
00463
00464 static inline int
00465 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00466 {
00467 if (__gthread_active_p ())
00468 return __gthrw_(mutex_lock) (mutex);
00469 else
00470 return 0;
00471 }
00472
00473 static inline int
00474 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00475 {
00476 if (__gthread_active_p ())
00477 return __gthrw_(mutex_trylock) (mutex);
00478 else
00479 return 0;
00480 }
00481
00482 static inline int
00483 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00484 {
00485 if (__gthread_active_p ())
00486 return __gthrw_(mutex_unlock) (mutex);
00487 else
00488 return 0;
00489 }
00490
00491 static inline int
00492 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00493 {
00494 mutex->depth = 0;
00495 mutex->owner = (thread_t) 0;
00496 return __gthrw_(mutex_init) (&mutex->actual, USYNC_THREAD, 0);
00497 }
00498
00499 static inline int
00500 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00501 {
00502 if (__gthread_active_p ())
00503 {
00504 thread_t me = __gthrw_(thr_self) ();
00505
00506 if (mutex->owner != me)
00507 {
00508 __gthrw_(mutex_lock) (&mutex->actual);
00509 mutex->owner = me;
00510 }
00511
00512 mutex->depth++;
00513 }
00514 return 0;
00515 }
00516
00517 static inline int
00518 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00519 {
00520 if (__gthread_active_p ())
00521 {
00522 thread_t me = __gthrw_(thr_self) ();
00523
00524 if (mutex->owner != me)
00525 {
00526 if (__gthrw_(mutex_trylock) (&mutex->actual))
00527 return 1;
00528 mutex->owner = me;
00529 }
00530
00531 mutex->depth++;
00532 }
00533 return 0;
00534 }
00535
00536 static inline int
00537 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00538 {
00539 if (__gthread_active_p ())
00540 {
00541 if (--mutex->depth == 0)
00542 {
00543 mutex->owner = (thread_t) 0;
00544 __gthrw_(mutex_unlock) (&mutex->actual);
00545 }
00546 }
00547 return 0;
00548 }
00549
00550 #endif
00551
00552 #undef UNUSED
00553
00554 #endif