aboutsummaryrefslogtreecommitdiff
path: root/leveldata/leveldata.h
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-08-17 00:25:47 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-08-17 00:25:47 +0900
commitd871fc30b0ed1518fd33206e312f64004c80cf31 (patch)
tree7105ecce1467f33478dfcef07dd21de04b28f326 /leveldata/leveldata.h
parentbbd61540874219bdf0590ca8a14d7f1e8d8fff47 (diff)
add leveldata.h
Diffstat (limited to 'leveldata/leveldata.h')
-rw-r--r--leveldata/leveldata.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/leveldata/leveldata.h b/leveldata/leveldata.h
new file mode 100644
index 0000000..e24f3e4
--- /dev/null
+++ b/leveldata/leveldata.h
@@ -0,0 +1,32 @@
+#ifndef MYON_LEVELDATA_H_INCLUDED
+#define MYON_LEVELDATA_H_INCLUDED
+
+#include <stdatomic.h>
+
+struct leveldata {
+ atomic_flag flag;
+ unsigned level;
+ bool read;
+};
+
+static inline unsigned leveldata_read(struct leveldata *data) {
+ while (atomic_flag_test_and_set_explicit(&data->flag, memory_order_acquire));
+ unsigned level = data->level;
+ data->read = true;
+ atomic_flag_clear_explicit(&data->flag, memory_order_release);
+ return level;
+}
+
+static inline void leveldata_update(struct leveldata *data, unsigned level) {
+ while (atomic_flag_test_and_set_explicit(&data->flag, memory_order_acquire));
+ if (data->read || (level > data->level)) data->level = level;
+ data->read = false;
+ atomic_flag_clear_explicit(&data->flag, memory_order_release);
+}
+
+static inline void leveldata_init(struct leveldata *data) {
+ *data = (struct leveldata) {0};
+ atomic_flag_clear_explicit(&data->flag, memory_order_relaxed);
+}
+
+#endif // MYON_LEVELDATA_H_INCLUDED