Control Surface stm32
MIDI Control Surface library for Arduino
AtomicPosition.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <Settings/NamespaceSettings.hpp>
5
6#ifdef __AVR__
7#include <util/atomic.h>
8#else
9#include <atomic>
10#endif
11#ifdef ARDUINO_ARCH_MBED
12#include <CriticalSectionLock.h>
13#endif
14
16
17#if defined(ATOMIC_INT_LOCK_FREE) && ATOMIC_INT_LOCK_FREE == 2
18template <class T>
19struct AtomicPosition {
20 using type = T;
21 std::atomic<type> value {};
22
23 AtomicPosition(T t) : value {t} {}
27 this->set(o.get());
28 return *this;
29 }
31 this->set(o.get());
32 return *this;
33 }
34
35 constexpr static std::memory_order mo_rlx = std::memory_order_relaxed;
36 void add(type other) { value.fetch_add(other, mo_rlx); }
37 type get() const { return value.load(mo_rlx); }
38 void set(type other) { value.store(other, mo_rlx); }
39 type xchg(type other) { return value.exchange(other, mo_rlx); }
40 void add_isr(type other) { add(other); }
41};
42#elif defined(__AVR__)
43template <class T>
44struct AtomicPosition {
45 using type = T;
46 volatile type value;
47
48 AtomicPosition(T t) : value {t} {}
52 this->set(o.get());
53 return *this;
54 }
56 this->set(o.get());
57 return *this;
58 }
59
60 void add(type other) {
61 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { value += other; }
62 }
63 type get() const {
64 type copy;
65 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { copy = value; }
66 return copy;
67 }
68 void set(type other) {
69 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { value = other; }
70 }
71 type xchg(type other) {
72 type copy;
73 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
74 copy = value;
75 value = other;
76 }
77 return copy;
78 }
79 void add_isr(type other) { value += other; }
80};
81#elif defined(ARDUINO_ARCH_MBED)
82template <class T>
83struct AtomicPosition {
84 using type = T;
85 volatile type value;
86
87 AtomicPosition(T t) : value {t} {}
91 this->set(o.get());
92 return *this;
93 }
95 this->set(o.get());
96 return *this;
97 }
98
99 void add(type other) {
100 mbed::CriticalSectionLock lck;
101 value += other;
102 }
103 type get() const {
104 mbed::CriticalSectionLock lck;
105 return value;
106 }
107 void set(type other) {
108 mbed::CriticalSectionLock lck;
109 value = other;
110 }
111 type xchg(type other) {
112 mbed::CriticalSectionLock lck;
113 type copy = value;
114 value = other;
115 return copy;
116 }
117 void add_isr(type other) { value += other; }
118};
119#else
120template <class T>
122 using type = T;
123 volatile type value;
124
125 AtomicPosition(T t) : value {t} {}
129 this->set(o.get());
130 return *this;
131 }
133 this->set(o.get());
134 return *this;
135 }
136
137 void add(type other) {
138 noInterrupts();
139 value += other;
140 interrupts();
141 }
142 type get() const {
143 type copy;
144 noInterrupts();
145 copy = value;
146 interrupts();
147 return copy;
148 }
149 void set(type other) {
150 noInterrupts();
151 value = other;
152 interrupts();
153 }
154 type xchg(type other) {
155 type copy;
156 noInterrupts();
157 copy = value;
158 value = other;
159 interrupts();
160 return copy;
161 }
162 void add_isr(type other) { value += other; }
163};
164#endif
165
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
static constexpr auto mo_rlx
AtomicPosition & operator=(const AtomicPosition &o)
volatile type value
type xchg(type other)
void set(type other)
void add_isr(type other)
void add(type other)
AtomicPosition(AtomicPosition &&o)
AtomicPosition(const AtomicPosition &o)
AtomicPosition & operator=(AtomicPosition &&o)
type get() const