diff --git a/configure b/configure index 2b46ab8367..3d1519f075 100755 --- a/configure +++ b/configure @@ -343,6 +343,7 @@ CYGWIN*) # Flags below are still necessary mostly for MinGW. socklen_t="yes" sfaa="yes" + svcas="yes" rusage_thread="yes" fdatasync="yes" clock_gettime="yes" # clock_monotonic probe has dependency on this @@ -706,6 +707,30 @@ if compile_prog "" "" "__sync_fetch_and_add()" ; then fi print_config "__sync_fetch_and_add" "$sfaa" +########################################## +# __sync_val_compare_and_swap test +if test "$svcas" != "yes" ; then + svcas="no" +fi +cat > $TMPC << EOF +#include +static int svcas(uint32_t *ptr) +{ + return __sync_val_compare_and_swap(ptr, 0, 0); +} + +int main(int argc, char **argv) +{ + uint32_t val = 42; + svcas(&val); + return val; +} +EOF +if compile_prog "" "" "__sync_val_compare_and_swap()" ; then + svcas="yes" +fi +print_config "__sync_val_compare_and_swap" "$svcas" + ########################################## # libverbs probe if test "$libverbs" != "yes" ; then @@ -2108,6 +2133,9 @@ fi if test "$sfaa" = "yes" ; then output_sym "CONFIG_SFAA" fi +if test "$svcas" = "yes" ; then + output_sym "CONFIG_SVCAS" +fi if test "$libverbs" = "yes" -a "$rdmacm" = "yes" ; then output_sym "CONFIG_RDMA" fi diff --git a/gettime.c b/gettime.c index 390d2e70b7..49d55718a7 100644 --- a/gettime.c +++ b/gettime.c @@ -547,8 +547,8 @@ uint64_t time_since_now(const struct timespec *s) return mtime_since_now(s) / 1000; } -#if defined(FIO_HAVE_CPU_AFFINITY) && defined(ARCH_HAVE_CPU_CLOCK) && \ - defined(CONFIG_SFAA) +#if defined(FIO_HAVE_CPU_AFFINITY) && defined(ARCH_HAVE_CPU_CLOCK) && \ + defined(CONFIG_SFAA) && defined(CONFIG_SVCAS) #define CLOCK_ENTRIES_DEBUG 100000 #define CLOCK_ENTRIES_TEST 1000 @@ -570,11 +570,19 @@ struct clock_thread { struct clock_entry *entries; }; +/* Note: the following acts as a full barrier */ static inline uint32_t atomic32_inc_return(uint32_t *seq) { return 1 + __sync_fetch_and_add(seq, 1); } +/* Note: the following acts as a full barrier */ +static inline uint32_t atomic32_cas_return(uint32_t *ptr, uint32_t old, + uint32_t new) +{ + return __sync_val_compare_and_swap(ptr, old, new); +} + static void *clock_thread_fn(void *data) { struct clock_thread *t = data; @@ -607,16 +615,18 @@ static void *clock_thread_fn(void *data) last_seq = 0; c = &t->entries[0]; for (i = 0; i < t->nr_entries; i++, c++) { - uint32_t seq; + uint32_t seq, end_seq; uint64_t tsc; c->cpu = t->cpu; do { seq = atomic32_inc_return(t->seq); + tsc = get_cpu_clock(); + end_seq = atomic32_cas_return(t->seq, seq, seq); if (seq < last_seq) break; - tsc = get_cpu_clock(); - } while (seq != *t->seq); + last_seq = end_seq; + } while (seq != end_seq); c->seq = seq; c->tsc = tsc; @@ -778,7 +788,8 @@ int fio_monotonic_clocktest(int debug) return !!failed; } -#else /* defined(FIO_HAVE_CPU_AFFINITY) && defined(ARCH_HAVE_CPU_CLOCK) */ +#else /* defined(FIO_HAVE_CPU_AFFINITY) && defined(ARCH_HAVE_CPU_CLOCK) && + * defined(CONFIG_SFAA) && defined(CONFIG_SVCAS)*/ int fio_monotonic_clocktest(int debug) { @@ -787,4 +798,5 @@ int fio_monotonic_clocktest(int debug) return 1; } -#endif +#endif /* defined(FIO_HAVE_CPU_AFFINITY) && defined(ARCH_HAVE_CPU_CLOCK) && + * defined(CONFIG_SFAA) && defined(CONFIG_SVCAS)*/