Add READ_ONCE and WRITE_ONCE (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 24 Aug 2017 15:28:31 +0000 (11:28 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 25 Aug 2017 18:41:49 +0000 (14:41 -0400)
These aren't quite the same as Linux's, in that they don't handle
structs.  Currently we don't need that, especially in a kernel header.
The thing we do need is the atomicity of writes of size up to uintptr_t.

There are places on both the user and kernel sides where we expect
writes to be done atomically, and not torn or otherwise mucked with by
the compiler.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/rbtree.h
kern/include/ros/common.h

index 04b9ddc..1e1a512 100644 (file)
@@ -30,9 +30,6 @@
 
 /* TODO: eventually we'll support some form of RCU and concurrent rb-tree
  * usage.  When we do that, we'll need to grab these functions from Linux. */
-#ifndef WRITE_ONCE
-#define WRITE_ONCE(d, s) (d) = (s)
-#endif
 #ifndef rcu_assign_pointer
 #define rcu_assign_pointer(d, s) (d) = (s)
 #endif
index 78ec9e2..bb23ca2 100644 (file)
@@ -120,9 +120,11 @@ static inline bool mult_will_overflow_u64(uint64_t a, uint64_t b)
        (type*)((char*)ptr - offsetof(type, member));                             \
 })
 
-/* Force the reading exactly once of x.  You may still need mbs().  See
+/* Force the reading/writing exactly once of x.  You may still need mbs().  See
  * http://lwn.net/Articles/508991/ for more info. */
 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+#define READ_ONCE(x) ACCESS_ONCE(x)
+#define WRITE_ONCE(x, val) ((*(volatile typeof(x) *)&(x)) = val)
 
 /* Makes sure func is run exactly once.  Can handle concurrent callers, and
  * other callers spin til the func is complete. */