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