tinykernel
Toggle main menu visibility
読み取り中…
検索中…
一致する文字列を見つけられません
sync.hpp
[詳解]
1
#pragma once
2
3
#include "
kernel.hpp
"
4
#include <cstdint>
5
6
namespace
tk
{
7
24
class
Semaphore
{
25
public
:
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);
44
detail::block_current_task_locked
();
45
detail::sched_unlock
(save);
46
// 他タスクから release() されて再開したら再チェック
47
save =
detail::sched_lock
();
48
}
49
count_--;
50
detail::sched_unlock
(save);
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
}
66
detail::sched_unlock
(save);
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);
82
detail::wake_task_locked
(
TaskHandle
{slot});
83
}
84
}
85
detail::sched_unlock
(save);
86
}
87
89
int32_t
count
()
const
{
90
uint32_t save =
detail::sched_lock
();
91
int32_t c = count_;
92
detail::sched_unlock
(save);
93
return
c;
94
}
95
96
private
:
97
int32_t count_;
98
int32_t max_count_;
99
task_mask_t
wait_mask_{0};
100
};
101
105
using
BinarySemaphore
=
Semaphore
;
106
123
class
Mutex
{
124
public
:
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);
137
detail::block_current_task_locked
();
138
detail::sched_unlock
(save);
139
save =
detail::sched_lock
();
140
}
141
locked_ =
true
;
142
owner_slot_ = my_slot;
143
detail::sched_unlock
(save);
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
}
161
detail::sched_unlock
(save);
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);
181
detail::wake_task_locked
(
TaskHandle
{slot});
182
}
183
}
184
}
185
detail::sched_unlock
(save);
186
}
187
189
bool
is_locked
()
const
{
190
uint32_t save =
detail::sched_lock
();
191
bool
lk = locked_;
192
detail::sched_unlock
(save);
193
return
lk;
194
}
195
196
private
:
197
bool
locked_{
false
};
198
uint8_t owner_slot_{0xFF};
199
task_mask_t
wait_mask_{0};
200
};
201
210
template
<
typename
Lockable>
211
class
LockGuard
{
212
public
:
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
225
private
:
226
Lockable& m_;
227
};
228
229
}
// namespace tk
tk::LockGuard::LockGuard
LockGuard(Lockable &m)
ロック対象を受け取り、即座に lock() します
定義
sync.hpp:217
tk::LockGuard::operator=
LockGuard & operator=(const LockGuard &)=delete
tk::LockGuard::~LockGuard
~LockGuard()
定義
sync.hpp:220
tk::LockGuard::LockGuard
LockGuard(const LockGuard &)=delete
tk::Mutex::try_lock
bool try_lock()
ミューテックスのロックを試みます (ノンブロッキング)
定義
sync.hpp:152
tk::Mutex::lock
void lock()
ミューテックスをロックします (空くまでブロック待機)
定義
sync.hpp:132
tk::Mutex::Mutex
Mutex()=default
tk::Mutex::is_locked
bool is_locked() const
定義
sync.hpp:189
tk::Mutex::unlock
void unlock()
ミューテックスのロックを解除します
定義
sync.hpp:171
tk::Semaphore
計数セマフォ (Counting Semaphore) / バイナリセマフォ
定義
sync.hpp:24
tk::Semaphore::try_acquire
bool try_acquire()
資源の獲得を試みます (ノンブロッキング)
定義
sync.hpp:59
tk::Semaphore::Semaphore
Semaphore(int32_t initial_count=1, int32_t max_count=1)
セマフォを初期化します
定義
sync.hpp:31
tk::Semaphore::release
void release()
資源を返却し、待機中タスクがあれば最優先度のタスクを 1 つ起床させます
定義
sync.hpp:73
tk::Semaphore::acquire
void acquire()
資源を獲得するまで現在のタスクをブロックします
定義
sync.hpp:39
tk::Semaphore::count
int32_t count() const
定義
sync.hpp:89
kernel.hpp
tk::detail::block_current_task_locked
void block_current_task_locked()
定義
scheduler.cpp:333
tk::detail::sched_lock
uint32_t sched_lock()
定義
scheduler.cpp:325
tk::detail::find_highest_prio_waiter
uint8_t find_highest_prio_waiter(task_mask_t wait_mask)
定義
scheduler.cpp:355
tk::detail::current_task_slot
uint8_t current_task_slot()
定義
scheduler.cpp:349
tk::detail::sched_unlock
void sched_unlock(uint32_t save)
定義
scheduler.cpp:329
tk::detail::wake_task_locked
void wake_task_locked(TaskHandle handle)
定義
scheduler.cpp:340
tk
定義
actor.hpp:9
tk::BinarySemaphore
Semaphore BinarySemaphore
バイナリセマフォ (初期値1, 最大1) の型エイリアス
定義
sync.hpp:105
tk::task_mask_t
uint32_t task_mask_t
定義
kernel.hpp:165
tk::TaskHandle
タスクの識別ハンドル
定義
kernel.hpp:49
tinykernel
include
tinykernel
sync.hpp
構築:
1.18.0