tinykernel
読み取り中…
検索中…
一致する文字列を見つけられません
sync.hpp
[詳解]
1#pragma once
2
3#include "kernel.hpp"
4#include <cstdint>
5
6namespace tk {
7
24class Semaphore {
25public:
31 explicit Semaphore(int32_t initial_count = 1, int32_t max_count = 1)
32 : count_(initial_count), max_count_(max_count) {}
33
39 void acquire() {
40 uint32_t save = detail::sched_lock();
41 while (count_ <= 0) {
42 uint8_t slot = detail::current_task_slot();
43 wait_mask_ |= (task_mask_t{1} << slot);
46 // 他タスクから release() されて再開したら再チェック
47 save = detail::sched_lock();
48 }
49 count_--;
51 }
52
59 bool try_acquire() {
60 uint32_t save = detail::sched_lock();
61 bool success = false;
62 if (count_ > 0) {
63 count_--;
64 success = true;
65 }
67 return success;
68 }
69
73 void release() {
74 uint32_t save = detail::sched_lock();
75 if (count_ < max_count_) {
76 count_++;
77 }
78 if (wait_mask_ != 0) {
79 uint8_t slot = detail::find_highest_prio_waiter(wait_mask_);
80 if (slot != 0xFF) {
81 wait_mask_ &= ~(task_mask_t{1} << slot);
83 }
84 }
86 }
87
89 int32_t count() const {
90 uint32_t save = detail::sched_lock();
91 int32_t c = count_;
93 return c;
94 }
95
96private:
97 int32_t count_;
98 int32_t max_count_;
99 task_mask_t wait_mask_{0};
100};
101
106
123class Mutex {
124public:
125 Mutex() = default;
126
132 void lock() {
133 uint32_t save = detail::sched_lock();
134 uint8_t my_slot = detail::current_task_slot();
135 while (locked_) {
136 wait_mask_ |= (task_mask_t{1} << my_slot);
139 save = detail::sched_lock();
140 }
141 locked_ = true;
142 owner_slot_ = my_slot;
144 }
145
152 bool try_lock() {
153 uint32_t save = detail::sched_lock();
154 uint8_t my_slot = detail::current_task_slot();
155 bool success = false;
156 if (!locked_) {
157 locked_ = true;
158 owner_slot_ = my_slot;
159 success = true;
160 }
162 return success;
163 }
164
171 void unlock() {
172 uint32_t save = detail::sched_lock();
173 uint8_t my_slot = detail::current_task_slot();
174 if (locked_ && owner_slot_ == my_slot) {
175 locked_ = false;
176 owner_slot_ = 0xFF;
177 if (wait_mask_ != 0) {
178 uint8_t slot = detail::find_highest_prio_waiter(wait_mask_);
179 if (slot != 0xFF) {
180 wait_mask_ &= ~(task_mask_t{1} << slot);
182 }
183 }
184 }
186 }
187
189 bool is_locked() const {
190 uint32_t save = detail::sched_lock();
191 bool lk = locked_;
193 return lk;
194 }
195
196private:
197 bool locked_{false};
198 uint8_t owner_slot_{0xFF};
199 task_mask_t wait_mask_{0};
200};
201
210template <typename Lockable>
212public:
217 explicit LockGuard(Lockable& m) : m_(m) { m_.lock(); }
218
220 ~LockGuard() { m_.unlock(); }
221
222 LockGuard(const LockGuard&) = delete;
223 LockGuard& operator=(const LockGuard&) = delete;
224
225private:
226 Lockable& m_;
227};
228
229} // namespace tk
LockGuard(Lockable &m)
ロック対象を受け取り、即座に lock() します
定義 sync.hpp:217
LockGuard & operator=(const LockGuard &)=delete
~LockGuard()
定義 sync.hpp:220
LockGuard(const LockGuard &)=delete
bool try_lock()
ミューテックスのロックを試みます (ノンブロッキング)
定義 sync.hpp:152
void lock()
ミューテックスをロックします (空くまでブロック待機)
定義 sync.hpp:132
Mutex()=default
bool is_locked() const
定義 sync.hpp:189
void unlock()
ミューテックスのロックを解除します
定義 sync.hpp:171
計数セマフォ (Counting Semaphore) / バイナリセマフォ
定義 sync.hpp:24
bool try_acquire()
資源の獲得を試みます (ノンブロッキング)
定義 sync.hpp:59
Semaphore(int32_t initial_count=1, int32_t max_count=1)
セマフォを初期化します
定義 sync.hpp:31
void release()
資源を返却し、待機中タスクがあれば最優先度のタスクを 1 つ起床させます
定義 sync.hpp:73
void acquire()
資源を獲得するまで現在のタスクをブロックします
定義 sync.hpp:39
int32_t count() const
定義 sync.hpp:89
void block_current_task_locked()
定義 scheduler.cpp:333
uint32_t sched_lock()
定義 scheduler.cpp:325
uint8_t find_highest_prio_waiter(task_mask_t wait_mask)
定義 scheduler.cpp:355
uint8_t current_task_slot()
定義 scheduler.cpp:349
void sched_unlock(uint32_t save)
定義 scheduler.cpp:329
void wake_task_locked(TaskHandle handle)
定義 scheduler.cpp:340
定義 actor.hpp:9
Semaphore BinarySemaphore
バイナリセマフォ (初期値1, 最大1) の型エイリアス
定義 sync.hpp:105
uint32_t task_mask_t
定義 kernel.hpp:165
タスクの識別ハンドル
定義 kernel.hpp:49