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
00065 #define __GTHREADS 1
00066
00067 #include <errno.h>
00068 #ifdef __MINGW32__
00069 #include <_mingw.h>
00070 #endif
00071
00072 #ifdef _LIBOBJC
00073
00074
00075
00076 #ifndef __OBJC__
00077 #define __OBJC__
00078 #endif
00079 #include <windows.h>
00080
00081 #undef BOOL
00082
00083
00084 static DWORD __gthread_objc_data_tls = (DWORD) -1;
00085
00086
00087
00088
00089 int
00090 __gthread_objc_init_thread_system (void)
00091 {
00092
00093 if ((__gthread_objc_data_tls = TlsAlloc ()) != (DWORD) -1)
00094 return 0;
00095 else
00096 return -1;
00097 }
00098
00099
00100 int
00101 __gthread_objc_close_thread_system (void)
00102 {
00103 if (__gthread_objc_data_tls != (DWORD) -1)
00104 TlsFree (__gthread_objc_data_tls);
00105 return 0;
00106 }
00107
00108
00109
00110
00111 objc_thread_t
00112 __gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
00113 {
00114 DWORD thread_id = 0;
00115 HANDLE win32_handle;
00116
00117 if (!(win32_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) func,
00118 arg, 0, &thread_id)))
00119 thread_id = 0;
00120
00121 return (objc_thread_t) thread_id;
00122 }
00123
00124
00125 int
00126 __gthread_objc_thread_set_priority (int priority)
00127 {
00128 int sys_priority = 0;
00129
00130 switch (priority)
00131 {
00132 case OBJC_THREAD_INTERACTIVE_PRIORITY:
00133 sys_priority = THREAD_PRIORITY_NORMAL;
00134 break;
00135 default:
00136 case OBJC_THREAD_BACKGROUND_PRIORITY:
00137 sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
00138 break;
00139 case OBJC_THREAD_LOW_PRIORITY:
00140 sys_priority = THREAD_PRIORITY_LOWEST;
00141 break;
00142 }
00143
00144
00145 if (SetThreadPriority (GetCurrentThread (), sys_priority))
00146 return 0;
00147 else
00148 return -1;
00149 }
00150
00151
00152 int
00153 __gthread_objc_thread_get_priority (void)
00154 {
00155 int sys_priority;
00156
00157 sys_priority = GetThreadPriority (GetCurrentThread ());
00158
00159 switch (sys_priority)
00160 {
00161 case THREAD_PRIORITY_HIGHEST:
00162 case THREAD_PRIORITY_TIME_CRITICAL:
00163 case THREAD_PRIORITY_ABOVE_NORMAL:
00164 case THREAD_PRIORITY_NORMAL:
00165 return OBJC_THREAD_INTERACTIVE_PRIORITY;
00166
00167 default:
00168 case THREAD_PRIORITY_BELOW_NORMAL:
00169 return OBJC_THREAD_BACKGROUND_PRIORITY;
00170
00171 case THREAD_PRIORITY_IDLE:
00172 case THREAD_PRIORITY_LOWEST:
00173 return OBJC_THREAD_LOW_PRIORITY;
00174 }
00175
00176
00177 return -1;
00178 }
00179
00180
00181 void
00182 __gthread_objc_thread_yield (void)
00183 {
00184 Sleep (0);
00185 }
00186
00187
00188 int
00189 __gthread_objc_thread_exit (void)
00190 {
00191
00192 ExitThread (__objc_thread_exit_status);
00193
00194
00195 return -1;
00196 }
00197
00198
00199 objc_thread_t
00200 __gthread_objc_thread_id (void)
00201 {
00202 return (objc_thread_t) GetCurrentThreadId ();
00203 }
00204
00205
00206 int
00207 __gthread_objc_thread_set_data (void *value)
00208 {
00209 if (TlsSetValue (__gthread_objc_data_tls, value))
00210 return 0;
00211 else
00212 return -1;
00213 }
00214
00215
00216 void *
00217 __gthread_objc_thread_get_data (void)
00218 {
00219 DWORD lasterror;
00220 void *ptr;
00221
00222 lasterror = GetLastError ();
00223
00224 ptr = TlsGetValue (__gthread_objc_data_tls);
00225
00226 SetLastError (lasterror);
00227
00228 return ptr;
00229 }
00230
00231
00232
00233
00234 int
00235 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00236 {
00237 if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
00238 return -1;
00239 else
00240 return 0;
00241 }
00242
00243
00244 int
00245 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00246 {
00247 CloseHandle ((HANDLE) (mutex->backend));
00248 return 0;
00249 }
00250
00251
00252 int
00253 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00254 {
00255 int status;
00256
00257 status = WaitForSingleObject ((HANDLE) (mutex->backend), INFINITE);
00258 if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
00259 return -1;
00260 else
00261 return 0;
00262 }
00263
00264
00265 int
00266 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00267 {
00268 int status;
00269
00270 status = WaitForSingleObject ((HANDLE) (mutex->backend), 0);
00271 if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
00272 return -1;
00273 else
00274 return 0;
00275 }
00276
00277
00278 int
00279 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00280 {
00281 if (ReleaseMutex ((HANDLE) (mutex->backend)) == 0)
00282 return -1;
00283 else
00284 return 0;
00285 }
00286
00287
00288
00289
00290 int
00291 __gthread_objc_condition_allocate (objc_condition_t condition)
00292 {
00293
00294 return -1;
00295 }
00296
00297
00298 int
00299 __gthread_objc_condition_deallocate (objc_condition_t condition)
00300 {
00301
00302 return -1;
00303 }
00304
00305
00306 int
00307 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00308 {
00309
00310 return -1;
00311 }
00312
00313
00314 int
00315 __gthread_objc_condition_broadcast (objc_condition_t condition)
00316 {
00317
00318 return -1;
00319 }
00320
00321
00322 int
00323 __gthread_objc_condition_signal (objc_condition_t condition)
00324 {
00325
00326 return -1;
00327 }
00328
00329 #else
00330
00331 #ifdef __cplusplus
00332 extern "C" {
00333 #endif
00334
00335 typedef unsigned long __gthread_key_t;
00336
00337 typedef struct {
00338 int done;
00339 long started;
00340 } __gthread_once_t;
00341
00342 typedef void* __gthread_mutex_t;
00343
00344 #define __GTHREAD_ONCE_INIT {0, -1}
00345 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
00346 #define __GTHREAD_MUTEX_INIT_DEFAULT 0
00347
00348 #if __MINGW32_MAJOR_VERSION >= 1 || \
00349 (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
00350 #define MINGW32_SUPPORTS_MT_EH 1
00351
00352
00353
00354 extern int _CRT_MT;
00355 extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
00356 #endif
00357
00358 static inline int
00359 __gthread_active_p (void)
00360 {
00361 #ifdef MINGW32_SUPPORTS_MT_EH
00362 return _CRT_MT;
00363 #else
00364 return 1;
00365 #endif
00366 }
00367
00368 #ifdef __GTHREAD_HIDE_WIN32API
00369
00370
00371
00372
00373
00374 extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
00375 extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
00376 extern int __gthr_win32_key_delete (__gthread_key_t);
00377 extern void * __gthr_win32_getspecific (__gthread_key_t);
00378 extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
00379 extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
00380 extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
00381 extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
00382 extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);
00383
00384 static inline int
00385 __gthread_once (__gthread_once_t *once, void (*func) (void))
00386 {
00387 if (__gthread_active_p ())
00388 return __gthr_win32_once (once, func);
00389 else
00390 return -1;
00391 }
00392
00393 static inline int
00394 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00395 {
00396 return __gthr_win32_key_create (key, dtor);
00397 }
00398
00399 static inline int
00400 __gthread_key_dtor (__gthread_key_t key, void *ptr)
00401 {
00402
00403 return 0;
00404 }
00405
00406 static inline int
00407 __gthread_key_delete (__gthread_key_t key)
00408 {
00409 return __gthr_win32_key_delete (key);
00410 }
00411
00412 static inline void *
00413 __gthread_getspecific (__gthread_key_t key)
00414 {
00415 return __gthr_win32_getspecific (key);
00416 }
00417
00418 static inline int
00419 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00420 {
00421 return __gthr_win32_setspecific (key, ptr);
00422 }
00423
00424 static inline void
00425 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
00426 {
00427 __gthr_win32_mutex_init_function (mutex);
00428 }
00429
00430 static inline int
00431 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00432 {
00433 if (__gthread_active_p ())
00434 return __gthr_win32_mutex_lock (mutex);
00435 else
00436 return 0;
00437 }
00438
00439 static inline int
00440 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00441 {
00442 if (__gthread_active_p ())
00443 return __gthr_win32_mutex_trylock (mutex);
00444 else
00445 return 0;
00446 }
00447
00448 static inline int
00449 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00450 {
00451 if (__gthread_active_p ())
00452 return __gthr_win32_mutex_unlock (mutex);
00453 else
00454 return 0;
00455 }
00456
00457 #else
00458
00459 #include <windows.h>
00460 #include <errno.h>
00461
00462 static inline int
00463 __gthread_once (__gthread_once_t *once, void (*func) (void))
00464 {
00465 if (! __gthread_active_p ())
00466 return -1;
00467 else if (once == NULL || func == NULL)
00468 return EINVAL;
00469
00470 if (! once->done)
00471 {
00472 if (InterlockedIncrement (&(once->started)) == 0)
00473 {
00474 (*func) ();
00475 once->done = TRUE;
00476 }
00477 else
00478 {
00479
00480
00481
00482
00483
00484 while (! once->done)
00485 Sleep (0);
00486 }
00487 }
00488
00489 return 0;
00490 }
00491
00492
00493
00494
00495 static inline int
00496 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00497 {
00498 int status = 0;
00499 DWORD tls_index = TlsAlloc ();
00500 if (tls_index != 0xFFFFFFFF)
00501 {
00502 *key = tls_index;
00503 #ifdef MINGW32_SUPPORTS_MT_EH
00504
00505
00506 status = __mingwthr_key_dtor (*key, dtor);
00507 #endif
00508 }
00509 else
00510 status = (int) GetLastError ();
00511 return status;
00512 }
00513
00514
00515
00516 static inline int
00517 __gthread_key_dtor (__gthread_key_t key, void *ptr)
00518 {
00519
00520 return 0;
00521 }
00522
00523 static inline int
00524 __gthread_key_delete (__gthread_key_t key)
00525 {
00526 return (TlsFree (key) != 0) ? 0 : (int) GetLastError ();
00527 }
00528
00529 static inline void *
00530 __gthread_getspecific (__gthread_key_t key)
00531 {
00532 DWORD lasterror;
00533 void *ptr;
00534
00535 lasterror = GetLastError ();
00536
00537 ptr = TlsGetValue (key);
00538
00539 SetLastError (lasterror);
00540
00541 return ptr;
00542 }
00543
00544 static inline int
00545 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00546 {
00547 return (TlsSetValue (key, (void*) ptr) != 0) ? 0 : (int) GetLastError ();
00548 }
00549
00550 static inline void
00551 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
00552 {
00553
00554 *mutex = CreateMutex (NULL, 0, NULL);
00555 }
00556
00557 static inline int
00558 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00559 {
00560 int status = 0;
00561
00562 if (__gthread_active_p ())
00563 {
00564 if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0)
00565 status = 0;
00566 else
00567 status = 1;
00568 }
00569 return status;
00570 }
00571
00572 static inline int
00573 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00574 {
00575 int status = 0;
00576
00577 if (__gthread_active_p ())
00578 {
00579 if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0)
00580 status = 0;
00581 else
00582 status = 1;
00583 }
00584 return status;
00585 }
00586
00587 static inline int
00588 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00589 {
00590 if (__gthread_active_p ())
00591 return (ReleaseMutex (*mutex) != 0) ? 0 : 1;
00592 else
00593 return 0;
00594 }
00595
00596 #endif
00597
00598 #ifdef __cplusplus
00599 }
00600 #endif
00601
00602 #endif
00603
00604 #endif