[kernel] Remove process & thread self-handles

For the coming switch to cap/handle ref-counting being the main lifetime
determiner of objects, get rid of self handles for threads and processes
to avoid circular references. Instead, passing 0 to syscalls expecting a
thread or process handle signifies "this process/thread".
This commit is contained in:
Justin C. Miller
2023-02-19 11:23:23 -08:00
parent d2a6113fb7
commit 94b2a79f79
13 changed files with 45 additions and 63 deletions

View File

@@ -7,7 +7,7 @@ object thread : object {
]
method create [constructor] {
param process ref process [cap:create_thread]
param process ref process [optional cap:create_thread]
param stack_top address
param entrypoint address
param arg0 uint64

View File

@@ -22,12 +22,12 @@ object vma : object {
}
method map [cap:map] {
param process ref process
param process ref process [optional]
param address address
}
method unmap [cap:unmap] {
param process ref process
param process ref process [optional]
}
method resize [cap:resize] {

View File

@@ -24,8 +24,6 @@ process::process() :
kobject {kobject::type::process},
m_state {state::running}
{
m_self_handle = g_cap_table.create(this, process::self_caps);
add_handle(m_self_handle);
}
// The "kernel process"-only constructor
@@ -71,28 +69,6 @@ process::exit(int32_t code)
current.exit();
}
void
process::update()
{
util::scoped_lock lock {m_threads_lock};
kassert(false, "process::update used!");
kassert(m_threads.count() > 0, "process::update with zero threads!");
size_t i = 0;
while (i < m_threads.count()) {
thread *th = m_threads[i];
if (th->has_state(thread::state::exited)) {
m_threads.remove_swap_at(i);
continue;
}
i++;
}
if (m_threads.count() == 0)
exit(-1);
}
thread *
process::create_thread(uintptr_t rsp3, uint8_t priority)
{

View File

@@ -20,9 +20,6 @@ public:
/// Capabilities on a newly constructed process handle
static constexpr j6_cap_t creation_caps = j6_cap_process_all;
/// Capabilities on a process to itself
static constexpr j6_cap_t self_caps = j6_cap_process_all;
/// Top of memory area where thread stacks are allocated
static constexpr uintptr_t stacks_top = 0x0000800000000000;
@@ -47,9 +44,6 @@ public:
/// \arg code The return code to exit with.
void exit(int32_t code);
/// Update internal bookkeeping about threads.
void update();
/// Get the process' virtual memory space
vm_space & space() { return m_space; }
@@ -105,7 +99,6 @@ private:
// This constructor is called by create_kernel_process
process(page_table *kpml4);
j6_handle_t m_self_handle;
int32_t m_return_code;
vm_space m_space;

View File

@@ -32,8 +32,6 @@ thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) :
m_tcb.rsp0 = rsp0;
m_creator = current_cpu().thread;
m_self_handle = g_cap_table.create(this, thread::parent_caps);
parent.add_handle(m_self_handle);
}
thread::~thread()

View File

@@ -57,9 +57,6 @@ public:
/// Capabilities on a newly constructed thread handle
static constexpr j6_cap_t creation_caps = j6_cap_thread_all;
/// Capabilities the parent process gets on new thread handles
static constexpr j6_cap_t parent_caps = j6_cap_thread_all;
static constexpr kobject::type type = kobject::type::thread;
enum class state : uint8_t {
@@ -168,9 +165,6 @@ public:
uintptr_t rip0 = 0,
uint64_t flags = 0);
/// 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 rsp The existing stack for the idle thread
@@ -208,7 +202,6 @@ private:
message_data m_message_data;
wait_queue m_join_queue;
j6_handle_t m_self_handle;
};
} // namespace obj

View File

@@ -133,7 +133,7 @@ for id, scope, method in syscalls.methods:
param.type.object.cname,
arg,
get_caps(param.options, param.type.object),
param.optional))
param.optional != "required"))
if needs_obj:
objparams.append((type, arg))
@@ -149,7 +149,7 @@ for id, scope, method in syscalls.methods:
f"obj::{param.type.object.cname}",
arg,
get_caps(param.options, param.type.object,
param.optional)))
param.optional != "required")))
if param.refparam:
subs = param.type.c_names(param.options)

View File

@@ -17,9 +17,14 @@ thread_create(j6_handle_t *self, process *proc, uintptr_t stack_top, uintptr_t e
thread &parent_th = thread::current();
process &parent_pr = parent_th.parent();
if (!proc)
proc = &parent_pr;
thread *child = proc->create_thread(stack_top);
child->add_thunk_user(entrypoint, arg0, arg1);
*self = child->self_handle();
*self = g_cap_table.create(child, thread::creation_caps);
child->set_state(thread::state::ready);
log::verbose(logs::task, "Thread <%02lx:%02lx> spawned new thread <%02lx:%02lx>",

View File

@@ -31,14 +31,16 @@ vma_create_map(j6_handle_t *self, size_t size, uintptr_t base, uint32_t flags)
j6_status_t
vma_map(vm_area *self, process *proc, uintptr_t base)
{
proc->space().add(base, self);
vm_space &space = proc ? proc->space() : process::current().space();
space.add(base, self);
return j6_status_ok;
}
j6_status_t
vma_unmap(vm_area *self, process *proc)
{
proc->space().remove(self);
vm_space &space = proc ? proc->space() : process::current().space();
space.remove(self);
return j6_status_ok;
}

View File

@@ -9,11 +9,10 @@
#include <j6/syscalls.h>
#include <j6/types.h>
j6_handle_t __handle_self;
namespace {
constexpr size_t static_arr_count = 8;
j6_handle_descriptor handle_array[static_arr_count];
j6_init_args init_args;
} // namespace
j6_handle_t
@@ -37,10 +36,12 @@ j6_find_first_handle(j6_object_type obj_type)
return j6_handle_invalid;
}
extern "C" void
__init_libj6(uint64_t *rsp)
extern "C" j6_init_args *
__init_libj6(uint64_t arg0, uint64_t arg1)
{
__handle_self = j6_find_first_handle(j6_object_type_process);
init_args.args[0] = arg0;
init_args.args[1] = arg1;
return &init_args;
}
#endif // __j6kernel

View File

@@ -8,6 +8,11 @@
extern "C" {
#endif
struct j6_init_args
{
uint64_t args[2];
};
/// Find the first handle of the given type held by this process
j6_handle_t j6_find_first_handle(j6_object_type obj_type);

View File

@@ -5,15 +5,21 @@ extern __init_libc
global _start:function (_start.end - _start)
_start:
mov rbp, rsp
mov rdi, rsp
call __init_libj6
call __init_libc
push 0 ; Add null frame
push 0
mov rbp, rsp
pop rdi
mov rsi, rsp
call main
call __init_libj6
mov rbx, rax
mov rdi, rax
call exit
call __init_libc
pop rdi
mov rsi, rsp
mov rdx, 0 ; TODO: actually parse stack for argc, argv, envp
mov rcx, rbx
call main
mov rdi, rax
call exit
.end:

View File

@@ -11,11 +11,14 @@ namespace {
void
run_ctor_list(cb *array, cb *end)
{
if (!array || !end)
return;
size_t i = 0;
while (true) {
const cb &ctor = array[i++];
if (&ctor == end) return;
ctor();
if (ctor) ctor();
}
}