diff options
author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-08-17 00:25:47 +0900 |
---|---|---|
committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-08-17 00:25:47 +0900 |
commit | d871fc30b0ed1518fd33206e312f64004c80cf31 (patch) | |
tree | 7105ecce1467f33478dfcef07dd21de04b28f326 | |
parent | bbd61540874219bdf0590ca8a14d7f1e8d8fff47 (diff) |
add leveldata.h
-rw-r--r-- | leveldata/leveldata.h | 32 |
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 |