From d871fc30b0ed1518fd33206e312f64004c80cf31 Mon Sep 17 00:00:00 2001
From: Takamichi Horikawa <takamichiho@gmail.com>
Date: Thu, 17 Aug 2017 00:25:47 +0900
Subject: add leveldata.h

---
 leveldata/leveldata.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 leveldata/leveldata.h

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
-- 
cgit v1.2.3