diff options
Diffstat (limited to 'leveldata/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 |