gthr-win32.h (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust.
authorWu Yongwei <adah@sh163.net>
Wed, 23 Jun 2004 23:57:27 +0000 (23:57 +0000)
committerDanny Smith <dannysmith@gcc.gnu.org>
Wed, 23 Jun 2004 23:57:27 +0000 (23:57 +0000)
2004-06-23  Wu Yongwei  <adah@sh163.net>

* 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
gcc/config/i386/gthr-win32.c
gcc/gthr-win32.h

index 14598abb7a1ca2782360085f42a256ab7eb60581..214eec74acfbe63d4e2dcab5d6d009b444382d57 100644 (file)
@@ -1,3 +1,21 @@
+2004-06-23  Wu Yongwei  <adah@sh163.net>
+
+       * 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  <edelsohn@gnu.org>
 
        * config/rs6000/rs6000.c (rs6000_use_dfa_pipeline_interface): Delete.
index e4852afef8010d752972911e5aefb669bbc571d6..c53369bca50c4c81cf1a3dcf957d06e8a21389cb 100644 (file)
@@ -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 <windows.h>
 #ifndef __GTHREAD_HIDE_WIN32API
 # define __GTHREAD_HIDE_WIN32API 1
 #endif
+#undef  __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
+#define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
 #include <gthr-win32.h>
-#include <windows.h>
 
 /* 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;
index e399047e485d2f661af637c360c7fb3c01a18d7e..b7618048430107b85106efdc428797f9d8f84f0f 100644 (file)
@@ -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;