From 8c4a41f9835d56437c44631d97ef592e948385d9 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 17 Nov 2012 03:43:57 -0800 Subject: fix spinlocks; add --disable-atomics cfg opt --- config.h.in | 3 +++ configure | 15 +++++++++++++++ pk/atomic.h | 49 ++++++++++++++++++++++++++++++++----------------- pk/frontend.c | 4 +++- pk/pk.ac | 5 +++++ 5 files changed, 58 insertions(+), 18 deletions(-) diff --git a/config.h.in b/config.h.in index 65b5df0..b06f0a9 100644 --- a/config.h.in +++ b/config.h.in @@ -21,6 +21,9 @@ /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef PK_ENABLED +/* Define if atomics are supported */ +#undef PK_ENABLE_ATOMICS + /* Define if floating-point emulation is enabled */ #undef PK_ENABLE_FP_EMULATION diff --git a/configure b/configure index c0def38..e9864a6 100755 --- a/configure +++ b/configure @@ -648,6 +648,7 @@ enable_stow enable_optional_subprojects enable_vm enable_fp_emulation +enable_atomics ' ac_precious_vars='build_alias host_alias @@ -1283,6 +1284,7 @@ Optional Features: Enable all optional subprojects --disable-vm Disable virtual memory --disable-fp-emulation Disable floating-point emulation + --disable-atomics Emulate atomic ops nonatomically Some influential environment variables: CC C compiler command @@ -4047,6 +4049,19 @@ $as_echo "#define PK_ENABLE_FP_EMULATION /**/" >>confdefs.h fi +# Check whether --enable-atomics was given. +if test "${enable_atomics+set}" = set; then : + enableval=$enable_atomics; +fi + +if test "x$enable_atomics" != "xno"; then : + + +$as_echo "#define PK_ENABLE_ATOMICS /**/" >>confdefs.h + + +fi + diff --git a/pk/atomic.h b/pk/atomic.h index 88bb239..abd2e05 100644 --- a/pk/atomic.h +++ b/pk/atomic.h @@ -1,44 +1,59 @@ #ifndef _RISCV_ATOMIC_H #define _RISCV_ATOMIC_H -typedef struct { long val; } atomic_t; +#include "config.h" + +typedef struct { volatile long val; } atomic_t; typedef struct { atomic_t lock; } spinlock_t; #define SPINLOCK_INIT {{0}} -static inline long atomic_add(atomic_t* a, long inc) +#define mb() __sync_synchronize() + +static inline void atomic_set(atomic_t* a, long val) { - //return __sync_fetch_and_add(&a->val, inc); - long ret = a->val; - a->val++; - return ret; + a->val = val; } -static inline long atomic_swap(atomic_t* a, long val) +static inline long atomic_read(atomic_t* a) { - //return __sync_lock_test_and_set(&a->val, val); - long reg = a->val; - a->val = val; - return reg; + return a->val; } -static inline void atomic_set(atomic_t* a, long val) +static inline long atomic_add(atomic_t* a, long inc) { - a->val = val; +#ifdef PK_ENABLE_ATOMICS + return __sync_fetch_and_add(&a->val, inc); +#else + long ret = atomic_read(a); + atomic_set(a, ret + inc); + return ret; +#endif } -static inline long atomic_read(atomic_t* a) +static inline long atomic_swap(atomic_t* a, long val) { - return a->val; +#ifdef PK_ENABLE_ATOMICS + return __sync_lock_test_and_set(&a->val, val); +#else + long ret = atomic_read(a); + atomic_set(a, val); + return ret; +#endif } static inline void spinlock_lock(spinlock_t* lock) { - while(atomic_read(&lock->lock)) - while(atomic_swap(&lock->lock,-1)); + do + { + while (atomic_read(&lock->lock)) + ; + } while (atomic_swap(&lock->lock, -1)); + mb(); } static inline void spinlock_unlock(spinlock_t* lock) { + mb(); atomic_set(&lock->lock,0); } diff --git a/pk/frontend.c b/pk/frontend.c index 4e4c138..1818b0f 100644 --- a/pk/frontend.c +++ b/pk/frontend.c @@ -17,11 +17,13 @@ sysret_t frontend_syscall(long n, long a0, long a1, long a2, long a3) magic_mem[3] = a2; magic_mem[4] = a3; - asm volatile ("cflush; fence"); + mb(); mtpcr(PCR_TOHOST, magic_mem); while (mtpcr(PCR_FROMHOST, 0) == 0); + mb(); + sysret_t ret = {magic_mem[0],magic_mem[1]}; spinlock_unlock(&lock); diff --git a/pk/pk.ac b/pk/pk.ac index 47c9207..fdcaa65 100644 --- a/pk/pk.ac +++ b/pk/pk.ac @@ -7,3 +7,8 @@ AC_ARG_ENABLE([fp-emulation], AS_HELP_STRING([--disable-fp-emulation], [Disable AS_IF([test "x$enable_fp_emulation" != "xno"], [ AC_DEFINE([PK_ENABLE_FP_EMULATION],,[Define if floating-point emulation is enabled]) ]) + +AC_ARG_ENABLE([atomics], AS_HELP_STRING([--disable-atomics], [Emulate atomic ops nonatomically])) +AS_IF([test "x$enable_atomics" != "xno"], [ + AC_DEFINE([PK_ENABLE_ATOMICS],,[Define if atomics are supported]) +]) -- cgit v1.1