aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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