[libj6] Add thread wrapper class

This new class makes it easier for user programs to spawn threads. This
change also includes support for .hh files in modules, to differentiate
headers that are C++-only in system libraries.
This commit is contained in:
Justin C. Miller
2022-10-20 22:12:02 -07:00
parent 2703080df2
commit 6583744532
5 changed files with 103 additions and 13 deletions

View File

@@ -8,6 +8,7 @@ j6 = module("j6",
"protocol_ids.cpp",
"syscalls.s.cog",
"sysconf.cpp.cog",
"thread.cpp",
],
public_headers = [
"j6/cap_flags.h.cog",
@@ -18,6 +19,7 @@ j6 = module("j6",
"j6/protocols/service_locator.h",
"j6/syscalls.h.cog",
"j6/sysconf.h.cog",
"j6/thread.hh",
"j6/types.h",
"j6/tables/log_areas.inc",

View File

@@ -0,0 +1,46 @@
#pragma once
/// \file thread.h
/// High level threading interface
// The kernel depends on libj6 for some shared code,
// but should not include the user-specific code.
#ifndef __j6kernel
#include <stddef.h>
#include <stdint.h>
#include <j6/types.h>
namespace j6 {
class thread
{
public:
using proc = void (*)();
/// Constructor. Create a thread and its stack space, but
/// do not start executing the thread.
/// \arg p The function where the thread will begin execution
/// \arg stack_top The address where the top of this thread's stack should be mapped
thread(proc p, uintptr_t stack_top);
/// Start executing the thread.
/// \returns j6_status_ok if the thread was successfully started.
j6_status_t start();
/// Wait for the thread to stop executing.
void join();
thread() = delete;
thread(const thread&) = delete;
private:
j6_status_t m_status;
j6_handle_t m_stack;
j6_handle_t m_thread;
uintptr_t m_stack_top;
proc m_proc;
};
} // namespace j6
#endif // __j6kernel

View File

@@ -0,0 +1,50 @@
// The kernel depends on libj6 for some shared code,
// but should not include the user-specific code.
#ifndef __j6kernel
#include <string.h>
#include <j6/errors.h>
#include <j6/flags.h>
#include <j6/syscalls.h>
#include <j6/thread.hh>
extern j6_handle_t __handle_self;
namespace j6 {
static constexpr size_t stack_size = 0x10000;
static constexpr size_t zeros_size = 0x10;
thread::thread(thread::proc p, uintptr_t stack_top) :
m_stack {j6_handle_invalid},
m_thread {j6_handle_invalid},
m_stack_top {stack_top},
m_proc {p}
{
uintptr_t stack_base = stack_top - stack_size;
m_status = j6_vma_create_map(&m_stack, stack_size, stack_base, j6_vm_flag_write);
if (m_status != j6_status_ok)
return;
m_stack_top -= zeros_size;
memset(reinterpret_cast<void*>(m_stack_top), 0, zeros_size);
}
j6_status_t
thread::start()
{
if (m_status != j6_status_ok)
return m_status;
if (m_thread != j6_handle_invalid)
return j6_err_invalid_arg;
m_status = j6_thread_create(&m_thread, __handle_self,
m_stack_top, reinterpret_cast<uintptr_t>(m_proc));
return m_status;
}
}
#endif // __j6kernel