[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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user