[glib] gatomic: use pthread mutexes instead of GMutex



commit e2ae75ad4be9107ee172c644c096e5949598c4a8
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Sep 16 17:50:13 2011 -0400

    gatomic: use pthread mutexes instead of GMutex
    
    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 |   85 +++++++++++++++++++++++++++++++++----------------------
 1 files changed, 51 insertions(+), 34 deletions(-)
---
diff --git a/glib/gatomic.c b/glib/gatomic.c
index 1e83f19..5b354c4 100644
--- a/glib/gatomic.c
+++ b/glib/gatomic.c
@@ -82,6 +82,17 @@
  * 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;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]