aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2012-11-17 03:43:57 -0800
committerAndrew Waterman <waterman@eecs.berkeley.edu>2012-11-17 03:43:57 -0800
commit8c4a41f9835d56437c44631d97ef592e948385d9 (patch)
treea9f957f4123aa99e4ceee1957e84df40cd9c299b /pk
parent93f6f1ff134333a61580677a685ad61718ad0726 (diff)
downloadriscv-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.h49
-rw-r--r--pk/frontend.c4
-rw-r--r--pk/pk.ac5
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);
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])
+])