aboutsummaryrefslogtreecommitdiff
path: root/pk/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'pk/atomic.h')
-rw-r--r--pk/atomic.h49
1 files changed, 32 insertions, 17 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);
}