diff options
| author | Benoit Germain <bnt.germain@gmail.com> | 2013-05-20 18:35:15 +0200 |
|---|---|---|
| committer | Benoit Germain <bnt.germain@gmail.com> | 2013-05-20 18:35:15 +0200 |
| commit | df29f9fc22fb7a2827ae5396aeb8127636f6ece4 (patch) | |
| tree | 72325d423784ea478088845283e5738d4f94b77b /src | |
| parent | 894803c8982d7d08fad487fd55c7f18d03a20fd2 (diff) | |
| download | lanes-df29f9fc22fb7a2827ae5396aeb8127636f6ece4.tar.gz lanes-df29f9fc22fb7a2827ae5396aeb8127636f6ece4.tar.bz2 lanes-df29f9fc22fb7a2827ae5396aeb8127636f6ece4.zip | |
version 3.6.2
* WIN32 builds use condition variables instead of PulseEvent() when available.
* first steps toward fixing make-vc.cmd
Diffstat (limited to 'src')
| -rw-r--r-- | src/lanes.c | 2 | ||||
| -rw-r--r-- | src/threading.c | 65 | ||||
| -rw-r--r-- | src/threading.h | 30 |
3 files changed, 88 insertions, 9 deletions
diff --git a/src/lanes.c b/src/lanes.c index 2c6a3ba..08bdb9a 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
| @@ -52,7 +52,7 @@ | |||
| 52 | * ... | 52 | * ... |
| 53 | */ | 53 | */ |
| 54 | 54 | ||
| 55 | char const* VERSION = "3.6.1"; | 55 | char const* VERSION = "3.6.2"; |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | =============================================================================== | 58 | =============================================================================== |
diff --git a/src/threading.c b/src/threading.c index 754b6d1..43e5f46 100644 --- a/src/threading.c +++ b/src/threading.c | |||
| @@ -243,6 +243,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
| 243 | #endif | 243 | #endif |
| 244 | 244 | ||
| 245 | #if THREADAPI == THREADAPI_WINDOWS | 245 | #if THREADAPI == THREADAPI_WINDOWS |
| 246 | |||
| 247 | #if WINVER <= 0x0400 // Windows NT4: Use Mutexes with Events | ||
| 246 | // | 248 | // |
| 247 | void MUTEX_INIT( MUTEX_T *ref ) { | 249 | void MUTEX_INIT( MUTEX_T *ref ) { |
| 248 | *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); | 250 | *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); |
| @@ -260,6 +262,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
| 260 | if (!ReleaseMutex(*ref)) | 262 | if (!ReleaseMutex(*ref)) |
| 261 | FAIL( "ReleaseMutex", GetLastError() ); | 263 | FAIL( "ReleaseMutex", GetLastError() ); |
| 262 | } | 264 | } |
| 265 | #endif // Windows NT4 | ||
| 266 | |||
| 263 | /* MSDN: "If you would like to use the CRT in ThreadProc, use the | 267 | /* MSDN: "If you would like to use the CRT in ThreadProc, use the |
| 264 | _beginthreadex function instead (of CreateThread)." | 268 | _beginthreadex function instead (of CreateThread)." |
| 265 | MSDN: "you can create at most 2028 threads" | 269 | MSDN: "you can create at most 2028 threads" |
| @@ -354,6 +358,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 354 | #endif // !__GNUC__ | 358 | #endif // !__GNUC__ |
| 355 | } | 359 | } |
| 356 | 360 | ||
| 361 | #if WINVER <= 0x0400 // Windows NT4: Use PulseEvent, although it is unreliable, but then... | ||
| 357 | 362 | ||
| 358 | // | 363 | // |
| 359 | void SIGNAL_INIT( SIGNAL_T *ref ) { | 364 | void SIGNAL_INIT( SIGNAL_T *ref ) { |
| @@ -426,6 +431,66 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
| 426 | if (!PulseEvent( *ref )) | 431 | if (!PulseEvent( *ref )) |
| 427 | FAIL( "PulseEvent", GetLastError() ); | 432 | FAIL( "PulseEvent", GetLastError() ); |
| 428 | } | 433 | } |
| 434 | |||
| 435 | #else // Windows Vista and above: condition variables exist, use them | ||
| 436 | |||
| 437 | // | ||
| 438 | void SIGNAL_INIT( SIGNAL_T *ref ) | ||
| 439 | { | ||
| 440 | InitializeConditionVariable( ref); | ||
| 441 | } | ||
| 442 | |||
| 443 | void SIGNAL_FREE( SIGNAL_T *ref ) | ||
| 444 | { | ||
| 445 | // nothing to do | ||
| 446 | ref; | ||
| 447 | } | ||
| 448 | |||
| 449 | bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs) | ||
| 450 | { | ||
| 451 | long ms; | ||
| 452 | |||
| 453 | if( abs_secs < 0.0) | ||
| 454 | ms = INFINITE; | ||
| 455 | else if( abs_secs == 0.0) | ||
| 456 | ms = 0; | ||
| 457 | else | ||
| 458 | { | ||
| 459 | ms = (long) ((abs_secs - now_secs())*1000.0 + 0.5); | ||
| 460 | |||
| 461 | // If the time already passed, still try once (ms==0). A short timeout | ||
| 462 | // may have turned negative or 0 because of the two time samples done. | ||
| 463 | // | ||
| 464 | if( ms < 0) | ||
| 465 | ms = 0; | ||
| 466 | } | ||
| 467 | |||
| 468 | if( !SleepConditionVariableCS( ref, mu_ref, ms)) | ||
| 469 | { | ||
| 470 | if( GetLastError() == ERROR_TIMEOUT) | ||
| 471 | { | ||
| 472 | return FALSE; | ||
| 473 | } | ||
| 474 | else | ||
| 475 | { | ||
| 476 | FAIL( "SleepConditionVariableCS", GetLastError()); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | return TRUE; | ||
| 480 | } | ||
| 481 | |||
| 482 | void SIGNAL_ONE( SIGNAL_T *ref ) | ||
| 483 | { | ||
| 484 | WakeConditionVariable( ref); | ||
| 485 | } | ||
| 486 | |||
| 487 | void SIGNAL_ALL( SIGNAL_T *ref ) | ||
| 488 | { | ||
| 489 | WakeAllConditionVariable( ref); | ||
| 490 | } | ||
| 491 | |||
| 492 | #endif // Windows Vista and above | ||
| 493 | |||
| 429 | #else // THREADAPI == THREADAPI_PTHREAD | 494 | #else // THREADAPI == THREADAPI_PTHREAD |
| 430 | // PThread (Linux, OS X, ...) | 495 | // PThread (Linux, OS X, ...) |
| 431 | // | 496 | // |
diff --git a/src/threading.h b/src/threading.h index 1b218b9..e559910 100644 --- a/src/threading.h +++ b/src/threading.h | |||
| @@ -64,7 +64,7 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
| 64 | #else // !PLATFORM_XBOX | 64 | #else // !PLATFORM_XBOX |
| 65 | #define WIN32_LEAN_AND_MEAN | 65 | #define WIN32_LEAN_AND_MEAN |
| 66 | // 'SignalObjectAndWait' needs this (targets Windows 2000 and above) | 66 | // 'SignalObjectAndWait' needs this (targets Windows 2000 and above) |
| 67 | #define _WIN32_WINNT 0x0400 | 67 | //#define _WIN32_WINNT 0x0500 Let the compiler decide depending on the host OS |
| 68 | #include <windows.h> | 68 | #include <windows.h> |
| 69 | #endif // !PLATFORM_XBOX | 69 | #endif // !PLATFORM_XBOX |
| 70 | #include <process.h> | 70 | #include <process.h> |
| @@ -74,17 +74,31 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
| 74 | // CRITICAL_SECTION can be used for simple code protection. Mutexes are | 74 | // CRITICAL_SECTION can be used for simple code protection. Mutexes are |
| 75 | // needed for use with the SIGNAL system. | 75 | // needed for use with the SIGNAL system. |
| 76 | // | 76 | // |
| 77 | #define MUTEX_T HANDLE | 77 | |
| 78 | void MUTEX_INIT( MUTEX_T *ref ); | 78 | #if WINVER <= 0x0400 // Windows NT4: use a signal |
| 79 | |||
| 80 | #define SIGNAL_T HANDLE | ||
| 81 | #define MUTEX_T HANDLE | ||
| 82 | void MUTEX_INIT( MUTEX_T* ref); | ||
| 83 | void MUTEX_FREE( MUTEX_T* ref); | ||
| 84 | void MUTEX_LOCK( MUTEX_T* ref); | ||
| 85 | void MUTEX_UNLOCK( MUTEX_T* ref); | ||
| 86 | |||
| 87 | #else // Vista and above: use a condition variable | ||
| 88 | |||
| 89 | #define SIGNAL_T CONDITION_VARIABLE | ||
| 90 | #define MUTEX_T CRITICAL_SECTION | ||
| 91 | #define MUTEX_INIT( ref) InitializeCriticalSection( ref) | ||
| 92 | #define MUTEX_FREE( ref) DeleteCriticalSection( ref) | ||
| 93 | #define MUTEX_LOCK( ref) EnterCriticalSection( ref) | ||
| 94 | #define MUTEX_UNLOCK( ref) LeaveCriticalSection( ref) | ||
| 95 | |||
| 96 | #endif // // Vista and above | ||
| 97 | |||
| 79 | #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */ | 98 | #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */ |
| 80 | void MUTEX_FREE( MUTEX_T *ref ); | ||
| 81 | void MUTEX_LOCK( MUTEX_T *ref ); | ||
| 82 | void MUTEX_UNLOCK( MUTEX_T *ref ); | ||
| 83 | 99 | ||
| 84 | typedef unsigned int THREAD_RETURN_T; | 100 | typedef unsigned int THREAD_RETURN_T; |
| 85 | 101 | ||
| 86 | #define SIGNAL_T HANDLE | ||
| 87 | |||
| 88 | #define YIELD() Sleep(0) | 102 | #define YIELD() Sleep(0) |
| 89 | #define THREAD_CALLCONV __stdcall | 103 | #define THREAD_CALLCONV __stdcall |
| 90 | #else // THREADAPI == THREADAPI_PTHREAD | 104 | #else // THREADAPI == THREADAPI_PTHREAD |
