diff options
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 |