summaryrefslogtreecommitdiff
path: root/sol_compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'sol_compat.h')
-rw-r--r--sol_compat.h55
1 files changed, 53 insertions, 2 deletions
diff --git a/sol_compat.h b/sol_compat.h
index 215296a..b2e3e25 100644
--- a/sol_compat.h
+++ b/sol_compat.h
@@ -59,7 +59,7 @@ static INLINE hrtime_t gethrtime(void) {
static INLINE thread_t _thr_self(void) {
return thr_self();
}
-#if defined(_MACH_PORT_T)
+#if defined(__MACH__)
#define CPUHINT() (pthread_mach_thread_np(pthread_self()))
#endif
# define thr_sigsetmask pthread_sigmask
@@ -114,6 +114,12 @@ static INLINE int thr_create(void *stack_base,
# ifdef _WIN32
# define ec_atomic_inc(a) InterlockedIncrement(a)
# define ec_atomic_inc64(a) InterlockedIncrement64(a)
+# elif defined(__MACH__)
+# include <libkern/OSAtomic.h>
+# define ec_atomic_inc(x) OSAtomicIncrement32Barrier((int32_t*)x)
+# if !defined(__ppc__)
+# define ec_atomic_inc64(x) OSAtomicIncrement64Barrier((int64_t*)x)
+# endif
# elif (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp)
{
@@ -124,6 +130,40 @@ static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp)
: "memory");
return prev;
}
+static INLINE uint64_t ec_atomic_cas64(uint64_t *mem, uint64_t with,
+ uint64_t cmp)
+{
+ uint64_t prev;
+# if defined(__x86_64__)
+ __asm__ volatile ("lock; cmpxchgq %1, %2"
+ : "=a" (prev)
+ : "r" (with), "m" (*(mem)), "0" (cmp)
+ : "memory");
+# else
+ __asm__ volatile (
+ "pushl %%ebx;"
+ "mov 4+%1,%%ecx;"
+ "mov %1,%%ebx;"
+ "lock;"
+ "cmpxchg8b (%3);"
+ "popl %%ebx"
+ : "=A" (prev)
+ : "m" (with), "A" (cmp), "r" (mem)
+ : "%ecx", "memory");
+# endif
+ return prev;
+}
+static INLINE uint64_t ec_atomic_inc64(uint64_t *mem)
+{
+ register uint64_t last;
+ do {
+ last = *mem;
+ } while (ec_atomic_cas64(mem, last+1, last) != last);
+ return ++last;
+}
+# define ec_atomic_inc64 ec_atomic_inc64
+# else
+# error no atomic solution for your platform
# endif
# ifndef ec_atomic_inc
@@ -139,7 +179,18 @@ static INLINE uint_t ec_atomic_inc(uint_t *mem)
# ifndef ec_atomic_inc64
/* yeah, it's not great. It's only used to bump failed allocation
* counts, so it is not critical right now. */
-# define ec_atomic_inc64(a) (*a)++
+extern pthread_mutex_t umem_ppc_64inc_lock;
+static INLINE uint64_t ec_atomic_inc64(uint64_t *val)
+{
+ uint64_t rval;
+ pthread_mutex_lock(&umem_ppc_64inc_lock);
+ rval = *val + 1;
+ *val = rval;
+ pthread_mutex_unlock(&umem_ppc_64inc_lock);
+ return rval;
+}
+# define ec_atomic_inc64 ec_atomic_inc64
+# define NEED_64_LOCK 1
# endif
#endif