diff options
author | Andrew Waterman <waterman@eecs.berkeley.edu> | 2012-11-17 03:43:57 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@eecs.berkeley.edu> | 2012-11-17 03:43:57 -0800 |
commit | 8c4a41f9835d56437c44631d97ef592e948385d9 (patch) | |
tree | a9f957f4123aa99e4ceee1957e84df40cd9c299b /pk | |
parent | 93f6f1ff134333a61580677a685ad61718ad0726 (diff) | |
download | riscv-pk-8c4a41f9835d56437c44631d97ef592e948385d9.zip riscv-pk-8c4a41f9835d56437c44631d97ef592e948385d9.tar.gz riscv-pk-8c4a41f9835d56437c44631d97ef592e948385d9.tar.bz2 |
fix spinlocks; add --disable-atomics cfg opt
Diffstat (limited to 'pk')
-rw-r--r-- | pk/atomic.h | 49 | ||||
-rw-r--r-- | pk/frontend.c | 4 | ||||
-rw-r--r-- | pk/pk.ac | 5 |
3 files changed, 40 insertions, 18 deletions
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); @@ -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]) +]) |