diff --git a/src/kernel/objects/process.cpp b/src/kernel/objects/process.cpp index dcb40d7..5ef62fe 100644 --- a/src/kernel/objects/process.cpp +++ b/src/kernel/objects/process.cpp @@ -1,5 +1,6 @@ #include "j6/signals.h" #include "kutil/assert.h" +#include "cpu.h" #include "objects/process.h" #include "objects/thread.h" #include "page_manager.h" @@ -9,6 +10,7 @@ kutil::vector process::s_processes; process::process(page_table *pml4) : kobject(kobject::type::process), m_pml4(pml4), + m_next_handle(0), m_state(state::running) { s_processes.append(this); @@ -19,6 +21,12 @@ process::~process() s_processes.remove_swap(this); } +process & +process::current() +{ + return *bsp_cpu_data.p; +} + void process::exit(unsigned code) { @@ -104,28 +112,21 @@ process::add_handle(kobject *obj) return j6_handle_invalid; obj->handle_retain(); - size_t len = m_handles.count(); - m_handles.append(obj); - return static_cast(len); + j6_handle_t handle = m_next_handle++; + m_handles.insert(handle, obj); + return handle; } bool process::remove_handle(j6_handle_t handle) { - if (handle < m_handles.count()) { - kobject *obj = m_handles[handle]; - m_handles[handle] = nullptr; - if (obj) - obj->handle_release(); - return true; - } - return false; + kobject *obj = m_handles.find(handle); + if (obj) obj->handle_release(); + return m_handles.erase(handle); } kobject * process::lookup_handle(j6_handle_t handle) { - if (handle < m_handles.count()) - return m_handles[handle]; - return nullptr; + return m_handles.find(handle); } diff --git a/src/kernel/objects/process.h b/src/kernel/objects/process.h index f429930..84eb6cd 100644 --- a/src/kernel/objects/process.h +++ b/src/kernel/objects/process.h @@ -2,6 +2,8 @@ /// \file process.h /// Definition of process kobject types +#include "kutil/map.h" +#include "kutil/vector.h" #include "objects/kobject.h" #include "page_table.h" @@ -22,6 +24,9 @@ public: /// Destructor. virtual ~process(); + /// Get the currently executing process. + static process & current(); + /// Terminate this process. /// \arg code The return code to exit with. void exit(unsigned code); @@ -68,7 +73,8 @@ private: page_table *m_pml4; kutil::vector m_threads; - kutil::vector m_handles; + kutil::map m_handles; + j6_handle_t m_next_handle; enum class state : uint8_t { running, exited }; state m_state; diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index 96d3cf9..f23dc8c 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -1,4 +1,5 @@ #include "j6/signals.h" +#include "cpu.h" #include "log.h" #include "objects/thread.h" #include "objects/process.h" @@ -40,6 +41,12 @@ thread::from_tcb(TCB *tcb) return reinterpret_cast(kutil::offset_pointer(tcb, offset)); } +thread & +thread::current() +{ + return *bsp_cpu_data.t; +} + void thread::wait_on_signals(kobject *obj, j6_signal_t signals) { diff --git a/src/kernel/objects/thread.h b/src/kernel/objects/thread.h index 547b157..542521b 100644 --- a/src/kernel/objects/thread.h +++ b/src/kernel/objects/thread.h @@ -50,6 +50,9 @@ public: /// Destructor virtual ~thread(); + /// Get the currently executing thread. + static thread & current(); + /// Get the `ready` state of the thread. /// \returns True if the thread is ready to execute. inline bool ready() const { return has_state(state::ready); } diff --git a/src/kernel/syscalls/channel.cpp b/src/kernel/syscalls/channel.cpp index 90881f0..df34e28 100644 --- a/src/kernel/syscalls/channel.cpp +++ b/src/kernel/syscalls/channel.cpp @@ -2,19 +2,14 @@ #include "j6/types.h" #include "objects/channel.h" -#include "objects/thread.h" #include "objects/process.h" -#include "scheduler.h" namespace syscalls { j6_status_t channel_create(j6_handle_t *handle) { - scheduler &s = scheduler::get(); - TCB *tcb = s.current(); - thread *parent = thread::from_tcb(tcb); - process &p = parent->parent(); + process &p = process::current(); channel *c = new channel; *handle = p.add_handle(c); @@ -25,10 +20,7 @@ channel_create(j6_handle_t *handle) j6_status_t channel_close(j6_handle_t handle) { - scheduler &s = scheduler::get(); - TCB *tcb = s.current(); - thread *parent = thread::from_tcb(tcb); - process &p = parent->parent(); + process &p = process::current(); kobject *o = p.lookup_handle(handle); if (!o || o->get_type() != kobject::type::channel) @@ -44,10 +36,7 @@ channel_close(j6_handle_t handle) j6_status_t channel_send(j6_handle_t handle, size_t *len, void *data) { - scheduler &s = scheduler::get(); - TCB *tcb = s.current(); - thread *parent = thread::from_tcb(tcb); - process &p = parent->parent(); + process &p = process::current(); kobject *o = p.lookup_handle(handle); if (!o || o->get_type() != kobject::type::channel) @@ -60,10 +49,7 @@ channel_send(j6_handle_t handle, size_t *len, void *data) j6_status_t channel_receive(j6_handle_t handle, size_t *len, void *data) { - scheduler &s = scheduler::get(); - TCB *tcb = s.current(); - thread *parent = thread::from_tcb(tcb); - process &p = parent->parent(); + process &p = process::current(); kobject *o = p.lookup_handle(handle); if (!o || o->get_type() != kobject::type::channel) diff --git a/src/kernel/syscalls/object.cpp b/src/kernel/syscalls/object.cpp index ba3ef13..a7ee587 100644 --- a/src/kernel/syscalls/object.cpp +++ b/src/kernel/syscalls/object.cpp @@ -13,8 +13,8 @@ j6_status_t object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs) { scheduler &s = scheduler::get(); - thread *th = thread::from_tcb(s.current()); - process &p = th->parent(); + thread &th = thread::current(); + process &p = process::current(); kobject *obj = p.lookup_handle(handle); if (!obj) @@ -26,13 +26,13 @@ object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs) return j6_status_ok; } - obj->add_blocked_thread(th); - th->wait_on_signals(obj, mask); + obj->add_blocked_thread(&th); + th.wait_on_signals(obj, mask); s.schedule(); - j6_status_t result = th->get_wait_result(); + j6_status_t result = th.get_wait_result(); if (result == j6_status_ok) { - *sigs = th->get_wait_data(); + *sigs = th.get_wait_data(); } return result; } @@ -43,10 +43,7 @@ object_signal(j6_handle_t handle, j6_signal_t signals) if ((signals & j6_signal_user_mask) != signals) return j6_err_invalid_arg; - scheduler &s = scheduler::get(); - thread *th = thread::from_tcb(s.current()); - process &p = th->parent(); - + process &p = process::current(); kobject *obj = p.lookup_handle(handle); if (!obj) return j6_err_invalid_arg;