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_WIN32_H
00031 #define GCC_GTHR_WIN32_H
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #define __GTHREADS 1
00065
00066 #include <errno.h>
00067 #ifdef __MINGW32__
00068 #include <_mingw.h>
00069 #endif
00070
00071 #ifdef _LIBOBJC
00072
00073
00074
00075 #ifndef __OBJC__
00076 #define __OBJC__
00077 #endif
00078 #include <windows.h>
00079
00080 #undef BOOL
00081
00082
00083 static DWORD __gthread_objc_data_tls = (DWORD) -1;
00084
00085
00086
00087
00088 int
00089 __gthread_objc_init_thread_system (void)
00090 {
00091
00092 if ((__gthread_objc_data_tls = TlsAlloc ()) != (DWORD) -1)
00093 return 0;
00094 else
00095 return -1;
00096 }
00097
00098
00099 int
00100 __gthread_objc_close_thread_system (void)
00101 {
00102 if (__gthread_objc_data_tls != (DWORD) -1)
00103 TlsFree (__gthread_objc_data_tls);
00104 return 0;
00105 }
00106
00107
00108
00109
00110 objc_thread_t
00111 __gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
00112 {
00113 DWORD thread_id = 0;
00114 HANDLE win32_handle;
00115
00116 if (!(win32_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) func,
00117 arg, 0, &thread_id)))
00118 thread_id = 0;
00119
00120 return (objc_thread_t) thread_id;
00121 }
00122
00123
00124 int
00125 __gthread_objc_thread_set_priority (int priority)
00126 {
00127 int sys_priority = 0;
00128
00129 switch (priority)
00130 {
00131 case OBJC_THREAD_INTERACTIVE_PRIORITY:
00132 sys_priority = THREAD_PRIORITY_NORMAL;
00133 break;
00134 default:
00135 case OBJC_THREAD_BACKGROUND_PRIORITY:
00136 sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
00137 break;
00138 case OBJC_THREAD_LOW_PRIORITY:
00139 sys_priority = THREAD_PRIORITY_LOWEST;
00140 break;
00141 }
00142
00143
00144 if (SetThreadPriority (GetCurrentThread (), sys_priority))
00145 return 0;
00146 else
00147 return -1;
00148 }
00149
00150
00151 int
00152 __gthread_objc_thread_get_priority (void)
00153 {
00154 int sys_priority;
00155
00156 sys_priority = GetThreadPriority (GetCurrentThread ());
00157
00158 switch (sys_priority)
00159 {
00160 case THREAD_PRIORITY_HIGHEST:
00161 case THREAD_PRIORITY_TIME_CRITICAL:
00162 case THREAD_PRIORITY_ABOVE_NORMAL:
00163 case THREAD_PRIORITY_NORMAL:
00164 return OBJC_THREAD_INTERACTIVE_PRIORITY;
00165
00166 default:
00167 case THREAD_PRIORITY_BELOW_NORMAL:
00168 return OBJC_THREAD_BACKGROUND_PRIORITY;
00169
00170 case THREAD_PRIORITY_IDLE:
00171 case THREAD_PRIORITY_LOWEST:
00172 return OBJC_THREAD_LOW_PRIORITY;
00173 }
00174
00175
00176 return -1;
00177 }
00178
00179
00180 void
00181 __gthread_objc_thread_yield (void)
00182 {
00183 Sleep (0);
00184 }
00185
00186
00187 int
00188 __gthread_objc_thread_exit (void)
00189 {
00190
00191 ExitThread (__objc_thread_exit_status);
00192
00193
00194 return -1;
00195 }
00196
00197
00198 objc_thread_t
00199 __gthread_objc_thread_id (void)
00200 {
00201 return (objc_thread_t) GetCurrentThreadId ();
00202 }
00203
00204
00205 int
00206 __gthread_objc_thread_set_data (void *value)
00207 {
00208 if (TlsSetValue (__gthread_objc_data_tls, value))
00209 return 0;
00210 else
00211 return -1;
00212 }
00213
00214
00215 void *
00216 __gthread_objc_thread_get_data (void)
00217 {
00218 DWORD lasterror;
00219 void *ptr;
00220
00221 lasterror = GetLastError ();
00222
00223 ptr = TlsGetValue (__gthread_objc_data_tls);
00224
00225 SetLastError (lasterror);
00226
00227 return ptr;
00228 }
00229
00230
00231
00232
00233 int
00234 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00235 {
00236 if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
00237 return -1;
00238 else
00239 return 0;
00240 }
00241
00242
00243 int
00244 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00245 {
00246 CloseHandle ((HANDLE) (mutex->backend));
00247 return 0;
00248 }
00249
00250
00251 int
00252 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00253 {
00254 int status;
00255
00256 status = WaitForSingleObject ((HANDLE) (mutex->backend), INFINITE);
00257 if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
00258 return -1;
00259 else
00260 return 0;
00261 }
00262
00263
00264 int
00265 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00266 {
00267 int status;
00268
00269 status = WaitForSingleObject ((HANDLE) (mutex->backend), 0);
00270 if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
00271 return -1;
00272 else
00273 return 0;
00274 }
00275
00276
00277 int
00278 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00279 {
00280 if (ReleaseMutex ((HANDLE) (mutex->backend)) == 0)
00281 return -1;
00282 else
00283 return 0;
00284 }
00285
00286
00287
00288
00289 int
00290 __gthread_objc_condition_allocate (objc_condition_t condition)
00291 {
00292
00293 return -1;
00294 }
00295
00296
00297 int
00298 __gthread_objc_condition_deallocate (objc_condition_t condition)
00299 {
00300
00301 return -1;
00302 }
00303
00304
00305 int
00306 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00307 {
00308
00309 return -1;
00310 }
00311
00312
00313 int
00314 __gthread_objc_condition_broadcast (objc_condition_t condition)
00315 {
00316
00317 return -1;
00318 }
00319
00320
00321 int
00322 __gthread_objc_condition_signal (objc_condition_t condition)
00323 {
00324
00325 return -1;
00326 }
00327
00328 #else
00329
00330 #ifdef __cplusplus
00331 extern "C" {
00332 #endif
00333
00334 typedef unsigned long __gthread_key_t;
00335
00336 typedef struct {
00337 int done;
00338 long started;
00339 } __gthread_once_t;
00340
00341 typedef struct {
00342 long counter;
00343 void *sema;
00344 } __gthread_mutex_t;
00345
00346 typedef struct {
00347 long counter;
00348 long depth;
00349 unsigned long owner;
00350 void *sema;
00351 } __gthread_recursive_mutex_t;
00352
00353 #define __GTHREAD_ONCE_INIT {0, -1}
00354 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
00355 #define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0}
00356 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION \
00357 __gthread_recursive_mutex_init_function
00358 #define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
00359
00360 #if __MINGW32_MAJOR_VERSION >= 1 || \
00361 (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
00362 #define MINGW32_SUPPORTS_MT_EH 1
00363
00364
00365
00366 extern int _CRT_MT;
00367 extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
00368 #endif
00369
00370
00371
00372
00373
00374
00375 #ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
00376 static inline long
00377 __gthr_i486_lock_cmp_xchg(long *dest, long xchg, long comperand)
00378 {
00379 long result;
00380 __asm__ __volatile__ ("\n\
00381 lock\n\
00382 cmpxchg{l} {%4, %1|%1, %4}\n"
00383 : "=a" (result), "=m" (*dest)
00384 : "0" (comperand), "m" (*dest), "r" (xchg)
00385 : "cc");
00386 return result;
00387 }
00388 #define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg
00389 #else
00390 #define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange
00391 #endif
00392
00393 static inline int
00394 __gthread_active_p (void)
00395 {
00396 #ifdef MINGW32_SUPPORTS_MT_EH
00397 return _CRT_MT;
00398 #else
00399 return 1;
00400 #endif
00401 }
00402
00403 #if __GTHREAD_HIDE_WIN32API
00404
00405
00406
00407
00408
00409 extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
00410 extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
00411 extern int __gthr_win32_key_delete (__gthread_key_t);
00412 extern void * __gthr_win32_getspecific (__gthread_key_t);
00413 extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
00414 extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
00415 extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
00416 extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
00417 extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);
00418 extern void
00419 __gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *);
00420 extern int __gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *);
00421 extern int
00422 __gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *);
00423 extern int __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *);
00424
00425 static inline int
00426 __gthread_once (__gthread_once_t *once, void (*func) (void))
00427 {
00428 if (__gthread_active_p ())
00429 return __gthr_win32_once (once, func);
00430 else
00431 return -1;
00432 }
00433
00434 static inline int
00435 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00436 {
00437 return __gthr_win32_key_create (key, dtor);
00438 }
00439
00440 static inline int
00441 __gthread_key_delete (__gthread_key_t key)
00442 {
00443 return __gthr_win32_key_delete (key);
00444 }
00445
00446 static inline void *
00447 __gthread_getspecific (__gthread_key_t key)
00448 {
00449 return __gthr_win32_getspecific (key);
00450 }
00451
00452 static inline int
00453 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00454 {
00455 return __gthr_win32_setspecific (key, ptr);
00456 }
00457
00458 static inline void
00459 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
00460 {
00461 __gthr_win32_mutex_init_function (mutex);
00462 }
00463
00464 static inline int
00465 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00466 {
00467 if (__gthread_active_p ())
00468 return __gthr_win32_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 __gthr_win32_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 __gthr_win32_mutex_unlock (mutex);
00487 else
00488 return 0;
00489 }
00490
00491 static inline void
00492 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00493 {
00494 __gthr_win32_recursive_mutex_init_function (mutex);
00495 }
00496
00497 static inline int
00498 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00499 {
00500 if (__gthread_active_p ())
00501 return __gthr_win32_recursive_mutex_lock (mutex);
00502 else
00503 return 0;
00504 }
00505
00506 static inline int
00507 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00508 {
00509 if (__gthread_active_p ())
00510 return __gthr_win32_recursive_mutex_trylock (mutex);
00511 else
00512 return 0;
00513 }
00514
00515 static inline int
00516 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00517 {
00518 if (__gthread_active_p ())
00519 return __gthr_win32_recursive_mutex_unlock (mutex);
00520 else
00521 return 0;
00522 }
00523
00524 #else
00525
00526 #include <windows.h>
00527 #include <errno.h>
00528
00529 static inline int
00530 __gthread_once (__gthread_once_t *once, void (*func) (void))
00531 {
00532 if (! __gthread_active_p ())
00533 return -1;
00534 else if (once == NULL || func == NULL)
00535 return EINVAL;
00536
00537 if (! once->done)
00538 {
00539 if (InterlockedIncrement (&(once->started)) == 0)
00540 {
00541 (*func) ();
00542 once->done = TRUE;
00543 }
00544 else
00545 {
00546
00547
00548
00549
00550
00551 while (! once->done)
00552 Sleep (0);
00553 }
00554 }
00555
00556 return 0;
00557 }
00558
00559
00560
00561
00562 static inline int
00563 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00564 {
00565 int status = 0;
00566 DWORD tls_index = TlsAlloc ();
00567 if (tls_index != 0xFFFFFFFF)
00568 {
00569 *key = tls_index;
00570 #ifdef MINGW32_SUPPORTS_MT_EH
00571
00572
00573 status = __mingwthr_key_dtor (*key, dtor);
00574 #endif
00575 }
00576 else
00577 status = (int) GetLastError ();
00578 return status;
00579 }
00580
00581 static inline int
00582 __gthread_key_delete (__gthread_key_t key)
00583 {
00584 return (TlsFree (key) != 0) ? 0 : (int) GetLastError ();
00585 }
00586
00587 static inline void *
00588 __gthread_getspecific (__gthread_key_t key)
00589 {
00590 DWORD lasterror;
00591 void *ptr;
00592
00593 lasterror = GetLastError ();
00594
00595 ptr = TlsGetValue (key);
00596
00597 SetLastError (lasterror);
00598
00599 return ptr;
00600 }
00601
00602 static inline int
00603 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00604 {
00605 return (TlsSetValue (key, (void*) ptr) != 0) ? 0 : (int) GetLastError ();
00606 }
00607
00608 static inline void
00609 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
00610 {
00611 mutex->counter = -1;
00612 mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
00613 }
00614
00615 static inline int
00616 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00617 {
00618 int status = 0;
00619
00620 if (__gthread_active_p ())
00621 {
00622 if (InterlockedIncrement (&mutex->counter) == 0 ||
00623 WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
00624 status = 0;
00625 else
00626 {
00627
00628
00629 InterlockedDecrement (&mutex->counter);
00630 status = 1;
00631 }
00632 }
00633 return status;
00634 }
00635
00636 static inline int
00637 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00638 {
00639 int status = 0;
00640
00641 if (__gthread_active_p ())
00642 {
00643 if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
00644 status = 0;
00645 else
00646 status = 1;
00647 }
00648 return status;
00649 }
00650
00651 static inline int
00652 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00653 {
00654 if (__gthread_active_p ())
00655 {
00656 if (InterlockedDecrement (&mutex->counter) >= 0)
00657 return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
00658 }
00659 return 0;
00660 }
00661
00662 static inline void
00663 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00664 {
00665 mutex->counter = -1;
00666 mutex->depth = 0;
00667 mutex->owner = 0;
00668 mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
00669 }
00670
00671 static inline int
00672 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00673 {
00674 if (__gthread_active_p ())
00675 {
00676 DWORD me = GetCurrentThreadId();
00677 if (InterlockedIncrement (&mutex->counter) == 0)
00678 {
00679 mutex->depth = 1;
00680 mutex->owner = me;
00681 }
00682 else if (mutex->owner == me)
00683 {
00684 InterlockedDecrement (&mutex->counter);
00685 ++(mutex->depth);
00686 }
00687 else if (WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
00688 {
00689 mutex->depth = 1;
00690 mutex->owner = me;
00691 }
00692 else
00693 {
00694
00695
00696 InterlockedDecrement (&mutex->counter);
00697 return 1;
00698 }
00699 }
00700 return 0;
00701 }
00702
00703 static inline int
00704 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00705 {
00706 if (__gthread_active_p ())
00707 {
00708 DWORD me = GetCurrentThreadId();
00709 if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
00710 {
00711 mutex->depth = 1;
00712 mutex->owner = me;
00713 }
00714 else if (mutex->owner == me)
00715 ++(mutex->depth);
00716 else
00717 return 1;
00718 }
00719 return 0;
00720 }
00721
00722 static inline int
00723 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00724 {
00725 if (__gthread_active_p ())
00726 {
00727 --(mutex->depth);
00728 if (mutex->depth == 0)
00729 {
00730 mutex->owner = 0;
00731
00732 if (InterlockedDecrement (&mutex->counter) >= 0)
00733 return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
00734 }
00735 }
00736 return 0;
00737 }
00738
00739 #endif
00740
00741 #ifdef __cplusplus
00742 }
00743 #endif
00744
00745 #endif
00746
00747 #endif