From df29f9fc22fb7a2827ae5396aeb8127636f6ece4 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 20 May 2013 18:35:15 +0200 Subject: version 3.6.2 * WIN32 builds use condition variables instead of PulseEvent() when available. * first steps toward fixing make-vc.cmd --- src/lanes.c | 2 +- src/threading.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/threading.h | 30 +++++++++++++++++++------- 3 files changed, 88 insertions(+), 9 deletions(-) (limited to 'src') 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 @@ * ... */ -char const* VERSION = "3.6.1"; +char const* VERSION = "3.6.2"; /* =============================================================================== 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 ) { #endif #if THREADAPI == THREADAPI_WINDOWS + +#if WINVER <= 0x0400 // Windows NT4: Use Mutexes with Events // void MUTEX_INIT( MUTEX_T *ref ) { *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); @@ -260,6 +262,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { if (!ReleaseMutex(*ref)) FAIL( "ReleaseMutex", GetLastError() ); } +#endif // Windows NT4 + /* MSDN: "If you would like to use the CRT in ThreadProc, use the _beginthreadex function instead (of CreateThread)." MSDN: "you can create at most 2028 threads" @@ -354,6 +358,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) #endif // !__GNUC__ } +#if WINVER <= 0x0400 // Windows NT4: Use PulseEvent, although it is unreliable, but then... // void SIGNAL_INIT( SIGNAL_T *ref ) { @@ -426,6 +431,66 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) if (!PulseEvent( *ref )) FAIL( "PulseEvent", GetLastError() ); } + +#else // Windows Vista and above: condition variables exist, use them + + // + void SIGNAL_INIT( SIGNAL_T *ref ) + { + InitializeConditionVariable( ref); + } + + void SIGNAL_FREE( SIGNAL_T *ref ) + { + // nothing to do + ref; + } + + bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs) + { + long ms; + + if( abs_secs < 0.0) + ms = INFINITE; + else if( abs_secs == 0.0) + ms = 0; + else + { + ms = (long) ((abs_secs - now_secs())*1000.0 + 0.5); + + // If the time already passed, still try once (ms==0). A short timeout + // may have turned negative or 0 because of the two time samples done. + // + if( ms < 0) + ms = 0; + } + + if( !SleepConditionVariableCS( ref, mu_ref, ms)) + { + if( GetLastError() == ERROR_TIMEOUT) + { + return FALSE; + } + else + { + FAIL( "SleepConditionVariableCS", GetLastError()); + } + } + return TRUE; + } + + void SIGNAL_ONE( SIGNAL_T *ref ) + { + WakeConditionVariable( ref); + } + + void SIGNAL_ALL( SIGNAL_T *ref ) + { + WakeAllConditionVariable( ref); + } + +#endif // Windows Vista and above + #else // THREADAPI == THREADAPI_PTHREAD // PThread (Linux, OS X, ...) // 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 }; #else // !PLATFORM_XBOX #define WIN32_LEAN_AND_MEAN // 'SignalObjectAndWait' needs this (targets Windows 2000 and above) - #define _WIN32_WINNT 0x0400 + //#define _WIN32_WINNT 0x0500 Let the compiler decide depending on the host OS #include #endif // !PLATFORM_XBOX #include @@ -74,17 +74,31 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; // CRITICAL_SECTION can be used for simple code protection. Mutexes are // needed for use with the SIGNAL system. // - #define MUTEX_T HANDLE - void MUTEX_INIT( MUTEX_T *ref ); + + #if WINVER <= 0x0400 // Windows NT4: use a signal + + #define SIGNAL_T HANDLE + #define MUTEX_T HANDLE + void MUTEX_INIT( MUTEX_T* ref); + void MUTEX_FREE( MUTEX_T* ref); + void MUTEX_LOCK( MUTEX_T* ref); + void MUTEX_UNLOCK( MUTEX_T* ref); + + #else // Vista and above: use a condition variable + + #define SIGNAL_T CONDITION_VARIABLE + #define MUTEX_T CRITICAL_SECTION + #define MUTEX_INIT( ref) InitializeCriticalSection( ref) + #define MUTEX_FREE( ref) DeleteCriticalSection( ref) + #define MUTEX_LOCK( ref) EnterCriticalSection( ref) + #define MUTEX_UNLOCK( ref) LeaveCriticalSection( ref) + + #endif // // Vista and above + #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */ - void MUTEX_FREE( MUTEX_T *ref ); - void MUTEX_LOCK( MUTEX_T *ref ); - void MUTEX_UNLOCK( MUTEX_T *ref ); typedef unsigned int THREAD_RETURN_T; - #define SIGNAL_T HANDLE - #define YIELD() Sleep(0) #define THREAD_CALLCONV __stdcall #else // THREADAPI == THREADAPI_PTHREAD -- cgit v1.2.3-55-g6feb