From 80408cac1637c8452c3b9f3a227d701b9d40641f Mon Sep 17 00:00:00 2001 From: Wu Yongwei Date: Tue, 27 Apr 2004 21:38:05 +0000 Subject: [PATCH] gthr-win32.h (__gthread_mutex_t): Change typedef to new structure. 2004-04-27 Wu Yongwei * gthr-win32.h (__gthread_mutex_t): Change typedef to new structure. (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust. (__gthread_mutex_init_function): Replace CreateMutex with initialization of custom mutex using CreateSemaphore. (__gthread_mutex_lock): Use InterlockedIncrement. (__gthread_mutex_trylock): Use InterlockedCompareExchange. (__gthread_mutex_unlock): Use InterlockedDecrement and ReleaseSemaphore to unlock * config/i386/gthr-win32.c (__gthread_mutex_init_function, __gthread_mutex_lock, __gthread_mutex_trylock, __gthread_mutex_unlock): Adjust to match inline versions in gthr-win32.h. From-SVN: r81227 --- gcc/ChangeLog | 15 ++++++++++++++ gcc/config/i386/gthr-win32.c | 28 ++++++++++++++++--------- gcc/gthr-win32.h | 40 ++++++++++++++++++++++-------------- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ddc303c9b58..7bd874a42f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-04-27 Wu Yongwei + + * gthr-win32.h (__gthread_mutex_t): Change typedef to new structure. + (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust. + (__gthread_mutex_init_function): Replace CreateMutex with + initialization of custom mutex using CreateSemaphore. + (__gthread_mutex_lock): Use InterlockedIncrement. + (__gthread_mutex_trylock): Use InterlockedCompareExchange. + (__gthread_mutex_unlock): Use InterlockedDecrement and + ReleaseSemaphore to unlock + * config/i386/gthr-win32.c (__gthread_mutex_init_function, + __gthread_mutex_lock, __gthread_mutex_trylock, + __gthread_mutex_unlock): Adjust to match inline versions in + gthr-win32.h. + 2004-04-27 Paul Brook * config/arm/arm.c (arm_promote_prototypes): New function. diff --git a/gcc/config/i386/gthr-win32.c b/gcc/config/i386/gthr-win32.c index 4e2b282251d..e4852afef80 100644 --- a/gcc/config/i386/gthr-win32.c +++ b/gcc/config/i386/gthr-win32.c @@ -61,10 +61,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA This may cause incorrect error return due to truncation values on hw where sizeof (DWORD) > sizeof (int). - 3. We might consider using Critical Sections instead of Windows32 - mutexes for better performance, but emulating __gthread_mutex_trylock - interface becomes more complicated (Win9x does not support - TryEnterCriticalSectioni, while NT does). + 3. We are currently using a special mutex instead of the Critical + Sections, since Win9x does not support TryEnterCriticalSection + (while NT does). The basic framework should work well enough. In the long term, GCC needs to use Structured Exception Handling on Windows32. */ @@ -145,23 +144,29 @@ __gthr_win32_setspecific (__gthread_key_t key, const void *ptr) void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { - /* Create unnamed mutex with default security attr and no initial owner. */ - *mutex = CreateMutex (NULL, 0, NULL); + mutex->counter = 0; + mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); } int __gthr_win32_mutex_lock (__gthread_mutex_t *mutex) { - if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0) + if (InterlockedIncrement (&mutex->counter) == 1 || + WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) return 0; else - return 1; + { + // WaitForSingleObject returns WAIT_FAILED, and we can only do + // some best-effort cleanup here. + InterlockedDecrement (&mutex->counter); + return 1; + } } int __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex) { - if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0) + if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0) return 0; else return 1; @@ -170,5 +175,8 @@ __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex) int __gthr_win32_mutex_unlock (__gthread_mutex_t *mutex) { - return (ReleaseMutex (*mutex) != 0) ? 0 : 1; + if (InterlockedDecrement (&mutex->counter)) + return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; + else + return 0; } diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h index 93f157481a3..e399047e485 100644 --- a/gcc/gthr-win32.h +++ b/gcc/gthr-win32.h @@ -1,6 +1,6 @@ /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ -/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Mumit Khan . This file is part of GCC. @@ -54,10 +54,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA This may cause incorrect error return due to truncation values on hw where sizeof (DWORD) > sizeof (int). - 3. We might consider using Critical Sections instead of Windows32 - mutexes for better performance, but emulating __gthread_mutex_trylock - interface becomes more complicated (Win9x does not support - TryEnterCriticalSectioni, while NT does). + 3. We are currently using a special mutex instead of the Critical + Sections, since Win9x does not support TryEnterCriticalSection + (while NT does). The basic framework should work well enough. In the long term, GCC needs to use Structured Exception Handling on Windows32. */ @@ -339,11 +338,14 @@ typedef struct { long started; } __gthread_once_t; -typedef void* __gthread_mutex_t; +typedef struct { + long counter; + void *sema; +} __gthread_mutex_t; #define __GTHREAD_ONCE_INIT {0, -1} #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function -#define __GTHREAD_MUTEX_INIT_DEFAULT 0 +#define __GTHREAD_MUTEX_INIT_DEFAULT {0, 0} #if __MINGW32_MAJOR_VERSION >= 1 || \ (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2) @@ -534,8 +536,8 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr) static inline void __gthread_mutex_init_function (__gthread_mutex_t *mutex) { - /* Create unnamed mutex with default security attr and no initial owner. */ - *mutex = CreateMutex (NULL, 0, NULL); + mutex->counter = 0; + mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); } static inline int @@ -545,10 +547,16 @@ __gthread_mutex_lock (__gthread_mutex_t *mutex) if (__gthread_active_p ()) { - if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0) + if (InterlockedIncrement (&mutex->counter) == 1 || + WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) status = 0; else - status = 1; + { + // WaitForSingleObject returns WAIT_FAILED, and we can only do + // some best-effort cleanup here. + InterlockedDecrement (&mutex->counter); + status = 1; + } } return status; } @@ -560,7 +568,7 @@ __gthread_mutex_trylock (__gthread_mutex_t *mutex) if (__gthread_active_p ()) { - if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0) + if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0) status = 0; else status = 1; @@ -572,9 +580,11 @@ static inline int __gthread_mutex_unlock (__gthread_mutex_t *mutex) { if (__gthread_active_p ()) - return (ReleaseMutex (*mutex) != 0) ? 0 : 1; - else - return 0; + { + if (InterlockedDecrement (&mutex->counter)) + return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; + } + return 0; } #endif /* __GTHREAD_HIDE_WIN32API */ -- 2.30.2