mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[kernel] Add lock-releasing version of thread::block()
Add a version of thread::block() that takes a lock and releases it after marking the thread as unready, but before calling the scheduler. Use this version of block() in the wait_queue.
This commit is contained in:
@@ -52,6 +52,18 @@ thread::block()
|
|||||||
return m_wake_value;
|
return m_wake_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
thread::block(util::scoped_lock &lock)
|
||||||
|
{
|
||||||
|
kassert(current_cpu().thread == this,
|
||||||
|
"unlocking block() called on non-current thread");
|
||||||
|
|
||||||
|
clear_state(state::ready);
|
||||||
|
lock.release();
|
||||||
|
scheduler::get().schedule();
|
||||||
|
return m_wake_value;
|
||||||
|
}
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
thread::join()
|
thread::join()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,9 +96,14 @@ public:
|
|||||||
inline void set_priority(uint8_t p) { if (!constant()) m_tcb.priority = p; }
|
inline void set_priority(uint8_t p) { if (!constant()) m_tcb.priority = p; }
|
||||||
|
|
||||||
/// Block this thread, waiting for a value
|
/// Block this thread, waiting for a value
|
||||||
/// \returns The value passed to wake()
|
/// \returns The value passed to wake()
|
||||||
uint64_t block();
|
uint64_t block();
|
||||||
|
|
||||||
|
/// Block this thread, waiting for a value
|
||||||
|
/// \arg held A held lock to unlock when blocking
|
||||||
|
/// \returns The value passed to wake()
|
||||||
|
uint64_t block(util::scoped_lock &held);
|
||||||
|
|
||||||
/// Block the calling thread until this thread exits
|
/// Block the calling thread until this thread exits
|
||||||
j6_status_t join();
|
j6_status_t join();
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ wait_queue::~wait_queue() { clear(); }
|
|||||||
void
|
void
|
||||||
wait_queue::add_thread(obj::thread *t)
|
wait_queue::add_thread(obj::thread *t)
|
||||||
{
|
{
|
||||||
|
kassert(t, "Adding a null thread to the wait queue");
|
||||||
util::scoped_lock lock {m_lock};
|
util::scoped_lock lock {m_lock};
|
||||||
t->handle_retain();
|
t->handle_retain();
|
||||||
m_threads.push_back(t);
|
m_threads.push_back(t);
|
||||||
@@ -15,8 +16,12 @@ void
|
|||||||
wait_queue::wait()
|
wait_queue::wait()
|
||||||
{
|
{
|
||||||
obj::thread ¤t = obj::thread::current();
|
obj::thread ¤t = obj::thread::current();
|
||||||
add_thread(¤t);
|
|
||||||
current.block();
|
util::scoped_lock lock {m_lock};
|
||||||
|
current.handle_retain();
|
||||||
|
m_threads.push_back(¤t);
|
||||||
|
|
||||||
|
current.block(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -54,9 +59,10 @@ void
|
|||||||
wait_queue::clear(uint64_t value)
|
wait_queue::clear(uint64_t value)
|
||||||
{
|
{
|
||||||
util::scoped_lock lock {m_lock};
|
util::scoped_lock lock {m_lock};
|
||||||
for (auto *t : m_threads) {
|
while (!m_threads.empty()) {
|
||||||
|
obj::thread *t = pop_next_unlocked();
|
||||||
|
kassert(t, "Null thread in the wait queue");
|
||||||
if (!t->exited()) t->wake(value);
|
if (!t->exited()) t->wake(value);
|
||||||
t->handle_release();
|
t->handle_release();
|
||||||
}
|
}
|
||||||
m_threads.clear();
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user