From cdafe3a7d8483ac586e2c16487e2a09164e0f65c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 5 Jun 2012 16:34:49 -0400 Subject: [PATCH] Add gcc intrinsics implementations for atomic and mutex --- configure.ac | 4 ++-- src/hb-atomic-private.hh | 11 +++++++++-- src/hb-mutex-private.hh | 51 +++++++++++++++++++++++++++++++++++++++++------- src/hb-object-private.hh | 4 +++- src/hb-warning.cc | 14 ++++++------- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 44b0df4..edb8820 100644 --- a/configure.ac +++ b/configure.ac @@ -52,8 +52,8 @@ AC_SUBST(HB_LIBTOOL_VERSION_INFO) dnl GTK_DOC_CHECK([1.15],[--flavour no-tmpl]) # Functions and headers -AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap _setmode isatty) -AC_CHECK_HEADERS(unistd.h sys/mman.h io.h) +AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize sched_yield mmap _setmode isatty) +AC_CHECK_HEADERS(unistd.h sys/mman.h sched.h io.h) # Compiler flags AC_CANONICAL_HOST diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh index 29e4146..3394afc 100644 --- a/src/hb-atomic-private.hh +++ b/src/hb-atomic-private.hh @@ -72,13 +72,20 @@ typedef int hb_atomic_int_t; #endif -#else +#elif !defined(HB_NO_MT) + +#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ +typedef volatile int hb_atomic_int_t; +#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) + + +#else /* HB_NO_MT */ -#define HB_ATOMIC_INT_NIL 1 typedef int hb_atomic_int_t; #define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) #endif +/* TODO Add tracing. */ #endif /* HB_ATOMIC_PRIVATE_HH */ diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index 9e061b9..9278643 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -1,7 +1,7 @@ /* * Copyright © 2007 Chris Wilson * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2011 Google, Inc. + * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -53,7 +53,7 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -#elif !defined(HB_NO_MT) && defined(__APPLE__) +#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__)) #include typedef pthread_mutex_t hb_mutex_impl_t; @@ -75,15 +75,50 @@ typedef GStaticMutex hb_mutex_impl_t; #define hb_mutex_impl_finish(M) g_static_mutex_free (M) +#elif !defined(HB_NO_MT) && defined(__GNUC__) + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) +# include +# define HB_SCHED_YIELD() sched_yield () #else +# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END +#endif -#define HB_MUTEX_IMPL_NIL 1 +/* This actually is not a totally awful implementation. */ typedef volatile int hb_mutex_impl_t; #define HB_MUTEX_IMPL_INIT 0 -#define hb_mutex_impl_init(M) ((void) (*(M) = 0)) -#define hb_mutex_impl_lock(M) ((void) (*(M) = 1)) -#define hb_mutex_impl_unlock(M) ((void) (*(M) = 0)) -#define hb_mutex_impl_finish(M) ((void) (*(M) = 2)) +#define hb_mutex_impl_init(M) *(M) = 0 +#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END +#define hb_mutex_impl_unlock(M) __sync_lock_release (M) +#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END + + +#elif !defined(HB_NO_MT) + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) +# include +# define HB_SCHED_YIELD() sched_yield () +#else +# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END +#endif + +#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */ +typedef volatile int hb_mutex_impl_t; +#define HB_MUTEX_IMPL_INIT 0 +#define hb_mutex_impl_init(M) *(M) = 0 +#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END +#define hb_mutex_impl_unlock(M) (*(M))--; +#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END + + +#else /* HB_NO_MT */ + +typedef int hb_mutex_impl_t; +#define HB_MUTEX_IMPL_INIT 0 +#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END +#define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END +#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END +#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END #endif @@ -91,6 +126,8 @@ typedef volatile int hb_mutex_impl_t; #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} struct hb_mutex_t { + /* TODO Add tracing. */ + hb_mutex_impl_t m; inline void init (void) { hb_mutex_impl_init (&m); } diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index cad4426..e86a38d 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -1,7 +1,7 @@ /* * Copyright © 2007 Chris Wilson * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2011 Google, Inc. + * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -68,6 +68,8 @@ struct hb_reference_count_t #define HB_USER_DATA_ARRAY_INIT {HB_LOCKABLE_SET_INIT} struct hb_user_data_array_t { + /* TODO Add tracing. */ + struct hb_user_data_item_t { hb_user_data_key_t *key; void *data; diff --git a/src/hb-warning.cc b/src/hb-warning.cc index c13731b..4f1f65f 100644 --- a/src/hb-warning.cc +++ b/src/hb-warning.cc @@ -28,23 +28,23 @@ #include "hb-mutex-private.hh" -#if !defined(HB_NO_MT) && defined(HB_ATOMIC_INT_NIL) +#if defined(HB_ATOMIC_INT_NIL) #ifdef _MSC_VER -#pragma message("Could not find any system to define atomic_int macros, library will NOT be thread-safe") +#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe") #else -#warning "Could not find any system to define atomic_int macros, library will NOT be thread-safe" +#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe" #endif #endif -#if !defined(HB_NO_MT) && defined(HB_MUTEX_IMPL_NIL) +#if defined(HB_MUTEX_IMPL_NIL) #ifdef _MSC_VER -#pragma message("Could not find any system to define mutex macros, library will NOT be thread-safe") +#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe") #else -#warning "Could not find any system to define mutex macros, library will NOT be thread-safe" +#warning "Could not find any system to define mutex macros, library may NOT be thread-safe" #endif #endif -#if !defined(HB_NO_MT) && (defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL)) +#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL) #ifdef _MSC_VER #pragma message("To suppress these warnings, define HB_NO_MT") #else -- 2.7.4