From 42dfcf84c26960bcc9c0d2f77f9c9ab4ce424927 Mon Sep 17 00:00:00 2001 From: Wu Yongwei Date: Wed, 23 Jun 2004 23:57:27 +0000 Subject: [PATCH] gthr-win32.h (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust. 2004-06-23 Wu Yongwei * gthr-win32.h (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust. (__gthr_i486_lock_cmp_xchg): New inline assembly function. (__GTHR_W32_InterlockedCompareExchange): New macro to choose a suitable function for interlocked compare-and-exchange. (__gthread_mutex_trylock): Use __GTHR_W32_InterlockedCompareExchange. (__gthread_mutex_init_function, __gthread_mutex_lock, __gthread_mutex_trylock, __gthread_mutex_unlock): Adjust the initial counter value to work correctly under Windows 95. * config/i386/gthr-win32.c: Adjust include order. Define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES before including gthr-win32.h. (__gthr_win32_mutex_init_function, __gthr_win32_mutex_lock, __gthr_win32_mutex_trylock, __gthr_win32_mutex_unlock): Adjust to match inline versions in gthr-win32.h. From-SVN: r83569 --- gcc/ChangeLog | 18 ++++++++++++++++++ gcc/config/i386/gthr-win32.c | 16 +++++++++------- gcc/gthr-win32.h | 37 +++++++++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14598abb7a1..214eec74acf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2004-06-23 Wu Yongwei + + * gthr-win32.h (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust. + (__gthr_i486_lock_cmp_xchg): New inline assembly function. + (__GTHR_W32_InterlockedCompareExchange): New macro to choose a + suitable function for interlocked compare-and-exchange. + (__gthread_mutex_trylock): Use + __GTHR_W32_InterlockedCompareExchange. + (__gthread_mutex_init_function, __gthread_mutex_lock, + __gthread_mutex_trylock, __gthread_mutex_unlock): Adjust the + initial counter value to work correctly under Windows 95. + * config/i386/gthr-win32.c: Adjust include order. + Define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES before including + gthr-win32.h. + (__gthr_win32_mutex_init_function, __gthr_win32_mutex_lock, + __gthr_win32_mutex_trylock, __gthr_win32_mutex_unlock): Adjust + to match inline versions in gthr-win32.h. + 2004-06-23 David Edelsohn * config/rs6000/rs6000.c (rs6000_use_dfa_pipeline_interface): Delete. diff --git a/gcc/config/i386/gthr-win32.c b/gcc/config/i386/gthr-win32.c index e4852afef80..c53369bca50 100644 --- a/gcc/config/i386/gthr-win32.c +++ b/gcc/config/i386/gthr-win32.c @@ -31,11 +31,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA the executable file might be covered by the GNU General Public License. */ +#include #ifndef __GTHREAD_HIDE_WIN32API # define __GTHREAD_HIDE_WIN32API 1 #endif +#undef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES +#define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES #include -#include /* Windows32 threads specific definitions. The windows32 threading model does not map well into pthread-inspired gcc's threading model, and so @@ -144,20 +146,20 @@ __gthr_win32_setspecific (__gthread_key_t key, const void *ptr) void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { - mutex->counter = 0; + mutex->counter = -1; mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); } int __gthr_win32_mutex_lock (__gthread_mutex_t *mutex) { - if (InterlockedIncrement (&mutex->counter) == 1 || + if (InterlockedIncrement (&mutex->counter) == 0 || WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) return 0; else { - // WaitForSingleObject returns WAIT_FAILED, and we can only do - // some best-effort cleanup here. + /* WaitForSingleObject returns WAIT_FAILED, and we can only do + some best-effort cleanup here. */ InterlockedDecrement (&mutex->counter); return 1; } @@ -166,7 +168,7 @@ __gthr_win32_mutex_lock (__gthread_mutex_t *mutex) int __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex) { - if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0) + if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0) return 0; else return 1; @@ -175,7 +177,7 @@ __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex) int __gthr_win32_mutex_unlock (__gthread_mutex_t *mutex) { - if (InterlockedDecrement (&mutex->counter)) + if (InterlockedDecrement (&mutex->counter) >= 0) return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; else return 0; diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h index e399047e485..b7618048430 100644 --- a/gcc/gthr-win32.h +++ b/gcc/gthr-win32.h @@ -345,7 +345,7 @@ typedef struct { #define __GTHREAD_ONCE_INIT {0, -1} #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function -#define __GTHREAD_MUTEX_INIT_DEFAULT {0, 0} +#define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0} #if __MINGW32_MAJOR_VERSION >= 1 || \ (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2) @@ -357,6 +357,29 @@ extern int _CRT_MT; extern int __mingwthr_key_dtor (unsigned long, void (*) (void *)); #endif /* __MINGW32__ version */ +/* The Windows95 kernel does not export InterlockedCompareExchange. + This provides a substitute. When building apps that reference + gthread_mutex_try_lock, the __GTHREAD_I486_INLINE_LOCK_PRIMITIVES + macro must be defined if Windows95 is a target. Currently + gthread_mutex_try_lock is not referenced by libgcc or libstdc++. */ +#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES +static inline long +__gthr_i486_lock_cmp_xchg(long *dest, long xchg, long comperand) +{ + long result; + __asm__ __volatile__ ("\n\ + lock\n\ + cmpxchg{l} {%4, %1|%1, %4}\n" + : "=a" (result), "=m" (*dest) + : "0" (comperand), "m" (*dest), "r" (xchg) + : "cc"); + return result; +} +#define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg +#else /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */ +#define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange +#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */ + static inline int __gthread_active_p (void) { @@ -536,7 +559,7 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr) static inline void __gthread_mutex_init_function (__gthread_mutex_t *mutex) { - mutex->counter = 0; + mutex->counter = -1; mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); } @@ -547,13 +570,13 @@ __gthread_mutex_lock (__gthread_mutex_t *mutex) if (__gthread_active_p ()) { - if (InterlockedIncrement (&mutex->counter) == 1 || + if (InterlockedIncrement (&mutex->counter) == 0 || WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) status = 0; else { - // WaitForSingleObject returns WAIT_FAILED, and we can only do - // some best-effort cleanup here. + /* WaitForSingleObject returns WAIT_FAILED, and we can only do + some best-effort cleanup here. */ InterlockedDecrement (&mutex->counter); status = 1; } @@ -568,7 +591,7 @@ __gthread_mutex_trylock (__gthread_mutex_t *mutex) if (__gthread_active_p ()) { - if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0) + if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0) status = 0; else status = 1; @@ -581,7 +604,7 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) { if (__gthread_active_p ()) { - if (InterlockedDecrement (&mutex->counter)) + if (InterlockedDecrement (&mutex->counter) >= 0) return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; } return 0; -- 2.30.2