mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[kernel] Add thread_join syscall
Thread joining is an important primitive that I seem to have totally forgotten to implement previously.
This commit is contained in:
@@ -3,6 +3,7 @@ object thread : object {
|
|||||||
|
|
||||||
capabilities [
|
capabilities [
|
||||||
kill
|
kill
|
||||||
|
join
|
||||||
]
|
]
|
||||||
|
|
||||||
method create [constructor] {
|
method create [constructor] {
|
||||||
@@ -13,6 +14,8 @@ object thread : object {
|
|||||||
|
|
||||||
method kill [destructor cap:kill]
|
method kill [destructor cap:kill]
|
||||||
|
|
||||||
|
method join [cap:join]
|
||||||
|
|
||||||
method exit [static]
|
method exit [static]
|
||||||
|
|
||||||
method sleep [static] {
|
method sleep [static] {
|
||||||
|
|||||||
@@ -52,6 +52,20 @@ thread::block()
|
|||||||
return m_wake_value;
|
return m_wake_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j6_status_t
|
||||||
|
thread::join()
|
||||||
|
{
|
||||||
|
if (has_state(state::exited))
|
||||||
|
return j6_status_ok;
|
||||||
|
|
||||||
|
thread &caller = current();
|
||||||
|
if (&caller == this)
|
||||||
|
return j6_err_invalid_arg;
|
||||||
|
|
||||||
|
m_join_queue.add_thread(&caller);
|
||||||
|
return caller.block();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
thread::wake(uint64_t value)
|
thread::wake(uint64_t value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <util/spinlock.h>
|
#include <util/spinlock.h>
|
||||||
|
|
||||||
#include "objects/kobject.h"
|
#include "objects/kobject.h"
|
||||||
|
#include "wait_queue.h"
|
||||||
|
|
||||||
struct cpu_data;
|
struct cpu_data;
|
||||||
struct page_table;
|
struct page_table;
|
||||||
@@ -98,6 +99,9 @@ public:
|
|||||||
/// \returns The value passed to wake()
|
/// \returns The value passed to wake()
|
||||||
uint64_t block();
|
uint64_t block();
|
||||||
|
|
||||||
|
/// Block the calling thread until this thread exits
|
||||||
|
j6_status_t join();
|
||||||
|
|
||||||
/// Wake this thread, giving it a value
|
/// Wake this thread, giving it a value
|
||||||
/// \arg value The value that block() should return
|
/// \arg value The value that block() should return
|
||||||
void wake(uint64_t value = 0);
|
void wake(uint64_t value = 0);
|
||||||
@@ -123,15 +127,16 @@ public:
|
|||||||
message_data & get_message_data() { return m_message_data; }
|
message_data & get_message_data() { return m_message_data; }
|
||||||
|
|
||||||
inline bool has_state(state s) const {
|
inline bool has_state(state s) const {
|
||||||
return static_cast<uint8_t>(m_state) & static_cast<uint8_t>(s);
|
return __atomic_load_n(reinterpret_cast<const uint8_t*>(&m_state), __ATOMIC_ACQUIRE) &
|
||||||
|
static_cast<uint8_t>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_state(state s) {
|
inline void set_state(state s) {
|
||||||
m_state = static_cast<state>(static_cast<uint8_t>(m_state) | static_cast<uint8_t>(s));
|
__atomic_or_fetch(reinterpret_cast<uint8_t*>(&m_state), static_cast<uint8_t>(s), __ATOMIC_ACQ_REL);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear_state(state s) {
|
inline void clear_state(state s) {
|
||||||
m_state = static_cast<state>(static_cast<uint8_t>(m_state) & ~static_cast<uint8_t>(s));
|
__atomic_and_fetch(reinterpret_cast<uint8_t*>(&m_state), ~static_cast<uint8_t>(s), __ATOMIC_ACQ_REL);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline tcb_node * tcb() { return &m_tcb; }
|
inline tcb_node * tcb() { return &m_tcb; }
|
||||||
@@ -191,6 +196,7 @@ private:
|
|||||||
uint64_t m_wake_timeout;
|
uint64_t m_wake_timeout;
|
||||||
message_data m_message_data;
|
message_data m_message_data;
|
||||||
|
|
||||||
|
wait_queue m_join_queue;
|
||||||
j6_handle_t m_self_handle;
|
j6_handle_t m_self_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ thread_kill(thread *self)
|
|||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j6_status_t
|
||||||
|
thread_join(thread *self)
|
||||||
|
{
|
||||||
|
return self->join();
|
||||||
|
}
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
thread_exit()
|
thread_exit()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user