gatomic: use pthread mutexes instead of GMutex
authorRyan Lortie <desrt@desrt.ca>
Fri, 16 Sep 2011 21:50:13 +0000 (17:50 -0400)
committerRyan Lortie <desrt@desrt.ca>
Fri, 16 Sep 2011 21:51:27 +0000 (17:51 -0400)
GStaticMutex makes use of atomic operations to initialise itself.  We
were using GStaticMutex from the emulated case of gatomic.  Use pthreads
directly to avoid unbounded recursion in this case.

glib/gatomic.c

index 1e83f19..5b354c4 100644 (file)
  * perform the operations normally and then release the lock.
  **/
 
+/* NOTE CAREFULLY:
+ *
+ * This file is the lowest-level part of GLib.
+ *
+ * Other lowlevel parts of GLib (threads, slice allocator, g_malloc,
+ * messages, etc) call into these functions and macros to get work done.
+ *
+ * As such, these functions can not call back into any part of GLib
+ * without risking recursion.
+ */
+
 #ifdef G_ATOMIC_OP_USE_GCC_BUILTINS
 
 #ifndef __GNUC__
@@ -604,18 +615,24 @@ gsize
 
 #else
 
-#include "gthread.h"
+/* We are not permitted to call into any GLib functions from here, so we
+ * can not use GMutex.
+ *
+ * Fortunately, we already take care of the Windows case above, and all
+ * non-Windows platforms on which glib runs have pthreads.  Use those.
+ */
+#include <pthread.h>
 
-static GStaticMutex g_atomic_lock;
+static pthread_mutex_t g_atomic_lock = PTHREAD_MUTEX_INITIALIZER;
 
 gint
 (g_atomic_int_get) (volatile gint *atomic)
 {
   gint value;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   value = *atomic;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return value;
 }
@@ -624,17 +641,17 @@ void
 (g_atomic_int_set) (volatile gint *atomic,
                     gint           value)
 {
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   *atomic = value;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 }
 
 void
 (g_atomic_int_inc) (volatile gint *atomic)
 {
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   (*atomic)++;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 }
 
 gboolean
@@ -642,9 +659,9 @@ gboolean
 {
   gboolean is_zero;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   is_zero = --(*atomic) == 0;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return is_zero;
 }
@@ -656,12 +673,12 @@ gboolean
 {
   gboolean success;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
 
   if ((success = (*atomic == oldval)))
     *atomic = newval;
 
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return success;
 }
@@ -672,10 +689,10 @@ gint
 {
   gint oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *atomic;
   *atomic = oldval + val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -686,10 +703,10 @@ guint
 {
   guint oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *atomic;
   *atomic = oldval & val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -700,10 +717,10 @@ guint
 {
   guint oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *atomic;
   *atomic = oldval | val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -714,10 +731,10 @@ guint
 {
   guint oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *atomic;
   *atomic = oldval ^ val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -729,9 +746,9 @@ gpointer
   volatile gpointer *ptr = atomic;
   gpointer value;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   value = *ptr;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return value;
 }
@@ -742,9 +759,9 @@ void
 {
   volatile gpointer *ptr = atomic;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   *ptr = newval;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 }
 
 gboolean
@@ -755,12 +772,12 @@ gboolean
   volatile gpointer *ptr = atomic;
   gboolean success;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
 
   if ((success = (*ptr == oldval)))
     *ptr = newval;
 
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return success;
 }
@@ -772,10 +789,10 @@ gssize
   volatile gssize *ptr = atomic;
   gssize oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *ptr;
   *ptr = oldval + val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -787,10 +804,10 @@ gsize
   volatile gsize *ptr = atomic;
   gsize oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *ptr;
   *ptr = oldval & val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -802,10 +819,10 @@ gsize
   volatile gsize *ptr = atomic;
   gsize oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *ptr;
   *ptr = oldval | val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }
@@ -817,10 +834,10 @@ gsize
   volatile gsize *ptr = atomic;
   gsize oldval;
 
-  g_static_mutex_lock (&g_atomic_lock);
+  pthread_mutex_lock (&g_atomic_lock);
   oldval = *ptr;
   *ptr = oldval ^ val;
-  g_static_mutex_unlock (&g_atomic_lock);
+  pthread_mutex_unlock (&g_atomic_lock);
 
   return oldval;
 }