made it so once is actually guaranteed to work using atomic primitives
diff --git a/aos/common/once-tmpl.h b/aos/common/once-tmpl.h
index 9e3ebfe..0618395 100644
--- a/aos/common/once-tmpl.h
+++ b/aos/common/once-tmpl.h
@@ -23,22 +23,18 @@
template<typename T>
void Once<T>::Reset() {
- done_ = false;
- run_ = 0;
+ __atomic_store_n(&run_, false, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&done_, false, __ATOMIC_SEQ_CST);
}
template<typename T>
T *Once<T>::Get() {
- if (__sync_lock_test_and_set(&run_, 1) == 0) {
+ if (__atomic_exchange_n(&run_, true, __ATOMIC_RELAXED) == false) {
result_ = function_();
- done_ = true;
+ __atomic_store_n(&done_, true, __ATOMIC_RELEASE);
} else {
- while (!done_) {
-#ifdef __VXWORKS__
- taskDelay(1);
-#else
+ while (!__atomic_load_n(&done_, __ATOMIC_ACQUIRE)) {
sched_yield();
-#endif
}
}
return result_;
diff --git a/aos/common/once.h b/aos/common/once.h
index 026b1bd..b7fbcb1 100644
--- a/aos/common/once.h
+++ b/aos/common/once.h
@@ -50,12 +50,12 @@
private:
// The function to run to calculate result_.
Function function_;
- // Whether or not it is running. Gets atomically swapped from 0 to 1 by the
- // thread that actually runs function_.
- volatile int run_;
+ // Whether or not it is running. Gets atomically swapped from false to true by
+ // the thread that actually runs function_.
+ bool run_;
// Whether or not it is done. Gets set to true after the thread that is
// running function_ finishes running it and storing the result in result_.
- volatile bool done_;
+ bool done_;
// What function_ returned when it was executed.
T *result_;