Add support for atomic int and mutex on Apple systems

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.
This commit is contained in:
Behdad Esfahbod 2012-02-24 13:51:09 -05:00
parent 8004429102
commit a1970d9afc
2 changed files with 19 additions and 10 deletions

View File

@ -43,7 +43,6 @@
#if !defined(HB_NO_MT) && defined(HAVE_GLIB) #if !defined(HB_NO_MT) && defined(HAVE_GLIB)
#include <glib.h> #include <glib.h>
typedef GStaticMutex hb_mutex_impl_t; typedef GStaticMutex hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT G_STATIC_MUTEX_INIT #define HB_MUTEX_IMPL_INIT G_STATIC_MUTEX_INIT
#define hb_mutex_impl_init(M) g_static_mutex_init (M) #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_unlock(M) g_static_mutex_unlock (M)
#define hb_mutex_impl_free(M) g_static_mutex_free (M) #define hb_mutex_impl_free(M) g_static_mutex_free (M)
#elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) #elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__)
#include <windows.h> #include <windows.h>
typedef CRITICAL_SECTION hb_mutex_impl_t; typedef CRITICAL_SECTION hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 } #define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 }
#define hb_mutex_impl_init(M) InitializeCriticalSection (M) #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_unlock(M) LeaveCriticalSection (M)
#define hb_mutex_impl_free(M) DeleteCriticalSection (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 #else
#define HB_MUTEX_IMPL_NIL 1 #define HB_MUTEX_IMPL_NIL 1
typedef volatile int hb_mutex_impl_t; typedef volatile int hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT 0 #define HB_MUTEX_IMPL_INIT 0
#define hb_mutex_impl_init(M) ((void) (*(M) = 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_unlock(M) ((void) (*(M) = 0))
#define hb_mutex_impl_free(M) ((void) (*(M) = 2)) #define hb_mutex_impl_free(M) ((void) (*(M) = 2))
#endif #endif

View File

@ -52,7 +52,6 @@
#if !defined(HB_NO_MT) && defined(HAVE_GLIB) #if !defined(HB_NO_MT) && defined(HAVE_GLIB)
#include <glib.h> #include <glib.h>
typedef volatile int hb_atomic_int_t; typedef volatile int hb_atomic_int_t;
#if GLIB_CHECK_VERSION(2,29,5) #if GLIB_CHECK_VERSION(2,29,5)
#define hb_atomic_int_add(AI, V) g_atomic_int_add (&(AI), V) #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 #elif !defined(HB_NO_MT) && defined(_MSC_VER) && _MSC_VER >= 1600
#include <intrin.h> #include <intrin.h>
typedef long hb_atomic_int_t; typedef long hb_atomic_int_t;
#define hb_atomic_int_add(AI, V) _InterlockedExchangeAdd (&(AI), V) #define hb_atomic_int_add(AI, V) _InterlockedExchangeAdd (&(AI), V)
#define hb_atomic_int_get(AI) (_ReadBarrier (), (AI)) #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 #else
@ -96,8 +100,9 @@ typedef struct {
inline int inc (void) { return hb_atomic_int_add (ref_count, 1); } 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 dec (void) { return hb_atomic_int_add (ref_count, -1); }
inline int get (void) const { return hb_atomic_int_get (ref_count); } inline int get (void) { return hb_atomic_int_get (ref_count); }
inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; } 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; } hb_reference_count_t;
@ -193,7 +198,7 @@ struct _hb_object_header_t {
inline void trace (const char *function) const { inline void trace (const char *function) const {
DEBUG_MSG (OBJECT, (void *) this, DEBUG_MSG (OBJECT, (void *) this,
"refcount=%d %s", "refcount=%d %s",
this ? ref_count.get () : 0, this ? ref_count.get_unsafe () : 0,
function); function);
} }