blob: 9e3ebfe56e95026863f94293baad82943e642ffe [file] [log] [blame]
brians2fdfc072013-02-26 05:35:15 +00001#ifdef __VXWORKS__
2#include <taskLib.h>
3#else
4#include <sched.h>
5#endif
6
7#include "aos/common/type_traits.h"
8
9// It doesn't use pthread_once, because Brian looked at the pthreads
10// implementation for vxworks and noticed that it is completely and entirely
11// broken for doing just about anything (including its pthread_once). It has the
Brian Silverman14fd0fb2014-01-14 21:42:01 -080012// same implementation under linux for simplicity.
brians2fdfc072013-02-26 05:35:15 +000013
14namespace aos {
15
16// Setting function_ multiple times would be OK because it'll get set to the
17// same value each time.
18template<typename T>
19Once<T>::Once(Function function)
20 : function_(function) {
21 static_assert(shm_ok<Once<T>>::value, "Once should work in shared memory");
22}
23
24template<typename T>
25void Once<T>::Reset() {
26 done_ = false;
27 run_ = 0;
28}
29
30template<typename T>
31T *Once<T>::Get() {
32 if (__sync_lock_test_and_set(&run_, 1) == 0) {
33 result_ = function_();
34 done_ = true;
35 } else {
36 while (!done_) {
37#ifdef __VXWORKS__
38 taskDelay(1);
39#else
40 sched_yield();
41#endif
42 }
43 }
44 return result_;
45}
46
47} // namespace aos