diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index b8f294a..d65acd3 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -45,49 +45,50 @@ 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); + util::scoped_lock lock {m_wait_lock}; + + m_wait_type = wait_type::signal; + m_wait_data = signals; + + 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); + util::scoped_lock lock {m_wait_lock}; + + m_wait_type = wait_type::time; + m_wait_time = t; + + 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}; + util::scoped_lock lock {m_wait_lock}; - m_wait_type = wait_type::object; - m_wait_data = reinterpret_cast(o); + m_wait_type = wait_type::object; + m_wait_data = reinterpret_cast(o); - if (t) { - m_wait_type |= wait_type::time; - m_wait_time = t; - } - - clear_state(state::ready); + if (t) { + m_wait_type |= wait_type::time; + m_wait_time = t; } - 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 diff --git a/src/kernel/objects/thread.h b/src/kernel/objects/thread.h index 9d5e671..c0c3578 100644 --- a/src/kernel/objects/thread.h +++ b/src/kernel/objects/thread.h @@ -98,17 +98,20 @@ public: inline void set_priority(uint8_t p) { if (!constant()) m_tcb.priority = p; } /// Block the thread, waiting an object's signals. - /// \arg signals Mask of signals to wait for - void wait_on_signals(j6_signal_t signals); + /// \arg signals Mask of signals to wait for + /// \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); + /// \arg t Clock value to wait for + /// \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); + /// \arg o The object that should wake this thread + /// \arg t The timeout clock value to wait for + /// \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 @@ -122,9 +125,10 @@ public: bool wake_on_time(uint64_t now); /// Wake the thread if it is waiting on the given object. - /// \arg o Object trying to wake the thread + /// \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(m_state) & static_cast(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;