From e08e00790ffb08b8e121e8321ab2c6a7d86c6a08 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Wed, 6 Jan 2021 23:14:39 -0800 Subject: [PATCH] [kernel] Give processes and threads self handles It was not consistent how processes got handles to themselves or their threads, ending up with double entries. Now make such handles automatic and expose them with new self_handle() methods. --- src/kernel/objects/process.cpp | 6 +++++- src/kernel/objects/process.h | 3 +++ src/kernel/objects/thread.cpp | 2 ++ src/kernel/objects/thread.h | 5 +++++ src/kernel/scheduler.cpp | 4 ++-- src/kernel/syscalls/thread.cpp | 2 +- 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/kernel/objects/process.cpp b/src/kernel/objects/process.cpp index 7cdf6a3..3232fcc 100644 --- a/src/kernel/objects/process.cpp +++ b/src/kernel/objects/process.cpp @@ -21,13 +21,16 @@ process::process() : m_state {state::running} { s_processes.append(this); + + j6_handle_t self = add_handle(this); + kassert(self == self_handle(), "Process self-handle is not 0"); } // The "kernel process"-only constructor process::process(page_table *kpml4) : kobject {kobject::type::process}, m_space {kpml4}, - m_next_handle {0}, + m_next_handle {self_handle()+1}, m_state {state::running} { } @@ -120,6 +123,7 @@ process::thread_exited(thread *th) kassert(&th->m_parent == this, "Process got thread_exited for non-child!"); uint32_t status = th->m_return_code; m_threads.remove_swap(th); + remove_handle(th->self_handle()); delete th; if (m_threads.count() == 0) { diff --git a/src/kernel/objects/process.h b/src/kernel/objects/process.h index fb7d2eb..14c8a8f 100644 --- a/src/kernel/objects/process.h +++ b/src/kernel/objects/process.h @@ -68,6 +68,9 @@ public: /// \returns True if this thread ending has ended the process bool thread_exited(thread *th); + /// Get the handle for this process to refer to itself + inline j6_handle_t self_handle() const { return 0; } + /// Get the process object that owns kernel threads and the /// kernel address space static process & kernel_process(); diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index 6a5b1ca..3eb6a9f 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -26,6 +26,8 @@ thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) : setup_kernel_stack(); else m_tcb.rsp0 = rsp0; + + m_self_handle = parent.add_handle(this); } thread::~thread() diff --git a/src/kernel/objects/thread.h b/src/kernel/objects/thread.h index 68e6257..41c0e7f 100644 --- a/src/kernel/objects/thread.h +++ b/src/kernel/objects/thread.h @@ -141,6 +141,9 @@ public: /// \arg rip The address to return to, must be user space void add_thunk_user(uintptr_t rip); + /// Get the handle representing this thread to its process + j6_handle_t self_handle() const { return m_self_handle; } + /// Create the kernel idle thread /// \arg kernel The process object that owns kernel tasks /// \arg pri The idle thread priority value @@ -175,4 +178,6 @@ private: uint64_t m_wait_data; j6_status_t m_wait_result; j6_koid_t m_wait_obj; + + j6_handle_t m_self_handle; }; diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index 5f89f25..b8e203f 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -116,11 +116,11 @@ load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) initv = push(tcb->rsp3); initv->type = j6_init_handle_process; - initv->value = static_cast(proc.add_handle(&proc)); + initv->value = static_cast(proc.self_handle()); initv = push(tcb->rsp3); initv->type = j6_init_handle_thread; - initv->value = static_cast(proc.add_handle(&th)); + initv->value = static_cast(th.self_handle()); initv = push(tcb->rsp3); initv->type = j6_init_handle_space; diff --git a/src/kernel/syscalls/thread.cpp b/src/kernel/syscalls/thread.cpp index f1a0cad..49091b2 100644 --- a/src/kernel/syscalls/thread.cpp +++ b/src/kernel/syscalls/thread.cpp @@ -15,7 +15,7 @@ thread_create(void *rip, j6_handle_t *handle) thread *child = p.create_thread(); child->add_thunk_user(reinterpret_cast(rip)); - *handle = p.add_handle(child); + *handle = p.self_handle(); child->clear_state(thread::state::loading); child->set_state(thread::state::ready);