Add support for atomic int and mutex on Apple systems
authorBehdad Esfahbod <behdad@behdad.org>
Fri, 24 Feb 2012 18:51:09 +0000 (13:51 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Fri, 24 Feb 2012 21:19:52 +0000 (16:19 -0500)
So, apparently there's no atomic int 'get' method on Apple.  You have to
add(0) to get.  And that's not const-friendly.  So switch inert-object
checking to a non-atomic get.  This, however, is safe, and a negligible
performance boost too.

src/hb-mutex-private.hh
src/hb-object-private.hh

index 88442d1..7b960c5 100644 (file)
@@ -43,7 +43,6 @@
 #if !defined(HB_NO_MT) && defined(HAVE_GLIB)
 
 #include <glib.h>
-
 typedef GStaticMutex hb_mutex_impl_t;
 #define HB_MUTEX_IMPL_INIT     G_STATIC_MUTEX_INIT
 #define hb_mutex_impl_init(M)  g_static_mutex_init (M)
@@ -51,11 +50,9 @@ typedef GStaticMutex hb_mutex_impl_t;
 #define hb_mutex_impl_unlock(M)        g_static_mutex_unlock (M)
 #define hb_mutex_impl_free(M)  g_static_mutex_free (M)
 
-
 #elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__)
 
 #include <windows.h>
-
 typedef CRITICAL_SECTION hb_mutex_impl_t;
 #define HB_MUTEX_IMPL_INIT     { NULL, 0, 0, NULL, NULL, 0 }
 #define hb_mutex_impl_init(M)  InitializeCriticalSection (M)
@@ -63,11 +60,19 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
 #define hb_mutex_impl_unlock(M)        LeaveCriticalSection (M)
 #define hb_mutex_impl_free(M)  DeleteCriticalSection (M)
 
+#elif !defined(HB_NO_MT) && defined(__APPLE__)
+
+#include <pthread.h>
+typedef pthread_mutex_t hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT     PTHREAD_MUTEX_INITIALIZER
+#define hb_mutex_impl_init(M)  pthread_mutex_init (M, NULL)
+#define hb_mutex_impl_lock(M)  pthread_mutex_lock (M)
+#define hb_mutex_impl_unlock(M)        pthread_mutex_unlock (M)
+#define hb_mutex_impl_free(M)  pthread_mutex_destroy (M)
 
 #else
 
 #define HB_MUTEX_IMPL_NIL 1
-
 typedef volatile int hb_mutex_impl_t;
 #define HB_MUTEX_IMPL_INIT     0
 #define hb_mutex_impl_init(M)  ((void) (*(M) = 0))
@@ -75,7 +80,6 @@ typedef volatile int hb_mutex_impl_t;
 #define hb_mutex_impl_unlock(M)        ((void) (*(M) = 0))
 #define hb_mutex_impl_free(M)  ((void) (*(M) = 2))
 
-
 #endif
 
 
index 1ade549..b96f6d8 100644 (file)
@@ -52,7 +52,6 @@
 #if !defined(HB_NO_MT) && defined(HAVE_GLIB)
 
 #include <glib.h>
-
 typedef volatile int hb_atomic_int_t;
 #if GLIB_CHECK_VERSION(2,29,5)
 #define hb_atomic_int_add(AI, V)       g_atomic_int_add (&(AI), V)
@@ -65,11 +64,16 @@ typedef volatile int hb_atomic_int_t;
 #elif !defined(HB_NO_MT) && defined(_MSC_VER) && _MSC_VER >= 1600
 
 #include <intrin.h>
-
 typedef long hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)       _InterlockedExchangeAdd (&(AI), V)
 #define hb_atomic_int_get(AI)          (_ReadBarrier (), (AI))
 
+#elif !defined(HB_NO_MT) && defined(__APPLE__)
+
+#include <libkern/OSAtomic.h>
+typedef int32_t hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V)       OSAtomicAdd32Barrier(V, &(AI))
+#define hb_atomic_int_get(AI)          OSAtomicAdd32Barrier(0, &(AI))
 
 #else
 
@@ -96,8 +100,9 @@ typedef struct {
   inline int inc (void) { return hb_atomic_int_add (ref_count,  1); }
   inline int dec (void) { return hb_atomic_int_add (ref_count, -1); }
 
-  inline int get (void) const { return hb_atomic_int_get (ref_count); }
-  inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
+  inline int get (void) { return hb_atomic_int_get (ref_count); }
+  inline int get_unsafe (void) const { return ref_count; }
+  inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
 
 } hb_reference_count_t;
 
@@ -193,7 +198,7 @@ struct _hb_object_header_t {
   inline void trace (const char *function) const {
     DEBUG_MSG (OBJECT, (void *) this,
               "refcount=%d %s",
-              this ? ref_count.get () : 0,
+              this ? ref_count.get_unsafe () : 0,
               function);
   }