[kernel] Have threads return status from wait_on_*

If the thread waiting is the current thread, it should have the result
when it wakes. Might as well return it, so that syscalls that know
they're putting the current thread to sleep can get the result easily.
This commit is contained in:
Justin C. Miller
2022-02-03 00:06:58 -08:00
parent ad5ebae304
commit 401e662f0b
2 changed files with 69 additions and 46 deletions

View File

@@ -45,36 +45,37 @@ thread::~thread()
thread & thread::current() { return *current_cpu().thread; }
inline void schedule_if_current(thread *t) { if (t == current_cpu().thread) scheduler::get().schedule(); }
void
j6_status_t
thread::wait_on_signals(j6_signal_t signals)
{
{
util::scoped_lock lock {m_wait_lock};
m_wait_type = wait_type::signal;
m_wait_data = signals;
clear_state(state::ready);
}
schedule_if_current(this);
lock.release();
block();
return m_wait_result;
}
void
j6_status_t
thread::wait_on_time(uint64_t t)
{
{
util::scoped_lock lock {m_wait_lock};
m_wait_type = wait_type::time;
m_wait_time = t;
clear_state(state::ready);
}
schedule_if_current(this);
lock.release();
block();
return m_wait_result;
}
void
thread::wait_on_object(kobject *o, uint64_t t)
j6_status_t
thread::wait_on_object(void *o, uint64_t t)
{
{
util::scoped_lock lock {m_wait_lock};
m_wait_type = wait_type::object;
@@ -85,9 +86,9 @@ thread::wait_on_object(kobject *o, uint64_t t)
m_wait_time = t;
}
clear_state(state::ready);
}
schedule_if_current(this);
lock.release();
block();
return m_wait_result;
}
bool
@@ -129,7 +130,7 @@ thread::wake_on_time(uint64_t now)
}
bool
thread::wake_on_object(kobject *o)
thread::wake_on_object(void *o, uint64_t id)
{
util::scoped_lock lock {m_wait_lock};
@@ -139,7 +140,7 @@ thread::wake_on_object(kobject *o)
m_wait_type = wait_type::none;
m_wait_result = j6_status_ok;
m_wait_obj = o->koid();
m_wait_obj = id;
set_state(state::ready);
return true;
}
@@ -156,15 +157,27 @@ thread::wake_on_result(kobject *obj, j6_status_t result)
set_state(state::ready);
}
void
thread::block()
{
clear_state(state::ready);
if (current_cpu().thread == this)
scheduler::get().schedule();
}
void
thread::wake()
{
set_state(state::ready);
}
void
thread::exit(int32_t code)
{
m_return_code = code;
set_state(state::exited);
clear_state(state::ready);
close();
schedule_if_current(this);
block();
}
void

View File

@@ -99,16 +99,19 @@ public:
/// Block the thread, waiting an object's signals.
/// \arg signals Mask of signals to wait for
void wait_on_signals(j6_signal_t signals);
/// \returns j6_status_ok on success
j6_status_t wait_on_signals(j6_signal_t signals);
/// Block the thread, waiting for a given clock value
/// \arg t Clock value to wait for
void wait_on_time(uint64_t t);
/// \returns j6_status_ok on success
j6_status_t wait_on_time(uint64_t t);
/// Block the thread, waiting on the given object
/// \arg o The object that should wake this thread
/// \arg t The timeout clock value to wait for
void wait_on_object(kobject *o, uint64_t t = 0);
/// \returns j6_status_ok on success
j6_status_t wait_on_object(void *o, uint64_t t = 0);
/// Wake the thread if it is waiting on signals.
/// \arg obj Object that changed signals
@@ -123,8 +126,9 @@ public:
/// Wake the thread if it is waiting on the given object.
/// \arg o Object trying to wake the thread
/// \arg id Id of the object trying to wake the thread
/// \returns True if this action unblocked the thread
bool wake_on_object(kobject *o);
bool wake_on_object(void *o, uint64_t id = 0);
/// Wake the thread with a given result code.
/// \arg obj Object that changed signals
@@ -140,6 +144,12 @@ public:
/// Get the current blocking operation's wait ojbect (as a handle)
j6_koid_t get_wait_object() const { return m_wait_obj; }
/// Primitive thread blocking, instead of using wait framework
void block();
/// Primitive thread unblocking, instead of using wait framework
void wake();
inline bool has_state(state s) const {
return static_cast<uint8_t>(m_state) & static_cast<uint8_t>(s);
}
@@ -208,7 +218,7 @@ private:
uint64_t m_wait_data;
uint64_t m_wait_time;
j6_status_t m_wait_result;
j6_koid_t m_wait_obj;
uint64_t m_wait_obj;
util::spinlock m_wait_lock;
j6_handle_t m_self_handle;