From 8f49909e9e5245782bbb14d6468f1c7684229f76 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sat, 9 Feb 2013 23:18:28 +0000 Subject: [PATCH] Fix #1608 - atomic: add workaround for missing intrinsic atomic ops. --- configure | 5 +++++ src/atomic.h | 30 ++++++++++++++++++++++++------ src/main.c | 2 ++ src/tvheadend.h | 1 + 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 1b618cea..3d3ec68f 100755 --- a/configure +++ b/configure @@ -54,6 +54,11 @@ check_cc_option sse2 check_cc_snippet getloadavg '#include void test() { getloadavg(NULL,0); }' +check_cc_snippet atomic64 '#include +uint64_t test(uint64_t *ptr){ +return __sync_fetch_and_add(ptr, 1); +}' + # # Python # diff --git a/src/atomic.h b/src/atomic.h index f4b8c991..db68ca7e 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -33,13 +33,31 @@ atomic_exchange(volatile int *ptr, int new) static inline uint64_t atomic_add_u64(volatile uint64_t *ptr, uint64_t incr) { +#if ENABLE_ATOMIC64 return __sync_fetch_and_add(ptr, incr); -} - -static inline uint64_t -atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr) -{ - return __sync_add_and_fetch(ptr, incr); +#else + uint64_t ret; + pthread_mutex_lock(&atomic_lock); + ret = *ptr; + *ptr += incr; + pthread_mutex_unlock(&atomic_lock); + return ret; +#endif +} + +static inline uint64_t +atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr) +{ +#if ENABLE_ATOMIC64 + return __sync_add_and_fetch(ptr, incr); +#else + uint64_t ret; + pthread_mutex_lock(&atomic_lock); + *ptr += incr; + ret = *ptr; + pthread_mutex_unlock(&atomic_lock); + return ret; +#endif } static inline uint64_t diff --git a/src/main.c b/src/main.c index a9a50651..60c4cc1c 100644 --- a/src/main.c +++ b/src/main.c @@ -139,6 +139,7 @@ time_t dispatch_clock; pthread_mutex_t global_lock; pthread_mutex_t ffmpeg_lock; pthread_mutex_t fork_lock; +pthread_mutex_t atomic_lock; /* * Locals @@ -574,6 +575,7 @@ main(int argc, char **argv) pthread_mutex_init(&ffmpeg_lock, NULL); pthread_mutex_init(&fork_lock, NULL); pthread_mutex_init(&global_lock, NULL); + pthread_mutex_init(&atomic_lock, NULL); pthread_mutex_lock(&global_lock); time(&dispatch_clock); diff --git a/src/tvheadend.h b/src/tvheadend.h index 6b0f3ab5..d2f2b4e5 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -63,6 +63,7 @@ static inline htsmsg_t *tvheadend_capabilities_list(int check) extern pthread_mutex_t global_lock; extern pthread_mutex_t ffmpeg_lock; extern pthread_mutex_t fork_lock; +extern pthread_mutex_t atomic_lock; extern int tvheadend_webui_port; extern int tvheadend_webui_debug;