aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lanes.c2
-rw-r--r--src/threading.c65
-rw-r--r--src/threading.h30
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
55char const* VERSION = "3.6.1"; 55char 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