Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1410049
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH -v3 2/8] locking: Introduce cmpwait() |
| Date | 2016-05-31 12:00 +0200 |
| Message-ID | <rEOCR-11o-7@gated-at.bofh.it> (permalink) |
| References | <rEOCR-11o-9@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Provide the cmpwait() primitive, which will 'spin' wait for a variable
to change and use it to implement smp_cond_load_acquire().
This primitive can be implemented with hardware assist on some
platforms (ARM64, x86).
Suggested-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/linux/compiler.h | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -305,6 +305,23 @@ static __always_inline void __write_once
})
/**
+ * cmpwait - compare and wait for a variable to change
+ * @ptr: pointer to the variable to wait on
+ * @val: the value it should change from
+ *
+ * A simple constuct that waits for a variable to change from a known
+ * value; some architectures can do this in hardware.
+ */
+#ifndef cmpwait
+#define cmpwait(ptr, val) do { \
+ typeof (ptr) __ptr = (ptr); \
+ typeof (val) __val = (val); \
+ while (READ_ONCE(*__ptr) == __val) \
+ cpu_relax(); \
+} while (0)
+#endif
+
+/**
* smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering
* @ptr: pointer to the variable to wait on
* @cond: boolean expression to wait for
@@ -327,7 +344,7 @@ static __always_inline void __write_once
VAL = READ_ONCE(*__PTR); \
if (cond_expr) \
break; \
- cpu_relax(); \
+ cmpwait(__PTR, VAL); \
} \
smp_rmb(); /* ctrl + rmb := acquire */ \
VAL; \
Back to linux.kernel | Previous | Next | Find similar | Unroll thread
[PATCH -v3 2/8] locking: Introduce cmpwait() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:00 +0200
csiph-web