Add a threading syscall API.
This commit is contained in:
parent
e2aad55a8a
commit
ef8eb5d993
14 changed files with 235 additions and 30 deletions
|
|
@ -13,4 +13,6 @@ jump_user_space:
|
|||
pushf # Can we just push 0 for flags?
|
||||
pushq $0x1B # cs
|
||||
pushq %rdi
|
||||
mov %rdx, %rdi
|
||||
mov %rcx, %rsi
|
||||
iretq
|
||||
|
|
|
|||
|
|
@ -23,11 +23,18 @@ SharedPtr<Process> Process::RootProcess() {
|
|||
|
||||
Process::Process() : id_(gNextId++), state_(RUNNING) {}
|
||||
|
||||
SharedPtr<Thread> Process::CreateThread() {
|
||||
SharedPtr<Thread> thread{new Thread(*this, next_thread_id_++, 0)};
|
||||
threads_.PushBack(thread);
|
||||
return thread;
|
||||
}
|
||||
|
||||
void Process::CreateThread(uint64_t entry) {
|
||||
Thread* thread = new Thread(*this, next_thread_id_++, entry);
|
||||
threads_.PushBack(thread);
|
||||
caps_.PushBack(new Capability(this, Capability::PROCESS, next_cap_id_++,
|
||||
ZC_PROC_SPAWN_PROC));
|
||||
caps_.PushBack(new Capability(this, Capability::PROCESS, Z_INIT_PROC_SELF,
|
||||
ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD));
|
||||
thread->SetState(Thread::RUNNABLE);
|
||||
gScheduler->Enqueue(thread);
|
||||
}
|
||||
|
||||
|
|
@ -65,3 +72,10 @@ SharedPtr<Capability> Process::GetCapability(uint64_t cid) {
|
|||
dbgln("Bad cap access");
|
||||
return {};
|
||||
}
|
||||
|
||||
uint64_t Process::AddCapability(SharedPtr<Thread>& thread) {
|
||||
uint64_t cap_id = next_cap_id_++;
|
||||
caps_.PushBack(
|
||||
new Capability(thread.ptr(), Capability::THREAD, cap_id, ZC_WRITE));
|
||||
return cap_id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@ class Process {
|
|||
uint64_t id() const { return id_; }
|
||||
VirtualMemory& vmm() { return vmm_; }
|
||||
|
||||
SharedPtr<Thread> CreateThread();
|
||||
void CreateThread(uint64_t entry);
|
||||
SharedPtr<Thread> GetThread(uint64_t tid);
|
||||
|
||||
SharedPtr<Capability> GetCapability(uint64_t cid);
|
||||
uint64_t AddCapability(SharedPtr<Thread>& t);
|
||||
// Checks the state of all child threads and transitions to
|
||||
// finished if all have finished.
|
||||
void CheckState();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
extern "C" void jump_user_space(uint64_t rip, uint64_t rsp);
|
||||
extern "C" void jump_user_space(uint64_t rip, uint64_t rsp, uint64_t arg1,
|
||||
uint64_t arg2);
|
||||
|
||||
extern "C" void thread_init() {
|
||||
asm("sti");
|
||||
|
|
@ -40,11 +41,20 @@ Thread::Thread(Process& proc, uint64_t tid, uint64_t entry)
|
|||
|
||||
uint64_t Thread::pid() const { return process_.id(); }
|
||||
|
||||
void Thread::Start(uint64_t entry, uint64_t arg1, uint64_t arg2) {
|
||||
rip_ = entry;
|
||||
arg1_ = arg1;
|
||||
arg2_ = arg2;
|
||||
state_ = RUNNABLE;
|
||||
// Get from parent to avoid creating a new shared ptr.
|
||||
gScheduler->Enqueue(process_.GetThread(id_));
|
||||
}
|
||||
|
||||
void Thread::Init() {
|
||||
dbgln("Thread start.", pid(), id_);
|
||||
uint64_t rsp = process_.vmm().AllocateUserStack();
|
||||
SetRsp0(rsp0_start_);
|
||||
jump_user_space(rip_, rsp);
|
||||
jump_user_space(rip_, rsp, arg1_, arg2_);
|
||||
}
|
||||
|
||||
void Thread::Exit() {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class Thread {
|
|||
public:
|
||||
enum State {
|
||||
UNSPECIFIED,
|
||||
CREATED,
|
||||
RUNNING,
|
||||
RUNNABLE,
|
||||
FINISHED,
|
||||
|
|
@ -27,6 +28,9 @@ class Thread {
|
|||
uint64_t* Rsp0Ptr() { return &rsp0_; }
|
||||
uint64_t Rsp0Start() { return rsp0_start_; }
|
||||
|
||||
// Switches the thread's state to runnable and enqueues it.
|
||||
void Start(uint64_t entry, uint64_t arg1, uint64_t arg2);
|
||||
|
||||
// Called the first time the thread starts up.
|
||||
void Init();
|
||||
|
||||
|
|
@ -40,10 +44,12 @@ class Thread {
|
|||
Thread(Process& proc) : process_(proc), id_(0) {}
|
||||
Process& process_;
|
||||
uint64_t id_;
|
||||
State state_ = RUNNABLE;
|
||||
State state_ = CREATED;
|
||||
|
||||
// Startup Context for the thread.
|
||||
uint64_t rip_;
|
||||
uint64_t arg1_;
|
||||
uint64_t arg2_;
|
||||
|
||||
// Stack pointer to take on resume.
|
||||
// Stack will contain the full thread context.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue