From 12aa014a3dcb18ea6ef2d36816e9fbccbfb7d659 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 7 Dec 2022 15:02:46 +0100 Subject: [PATCH] Add a Thread class which can be part of a DoublyLinkedList --- kernel/src/arch/x86_64/Thread.cpp | 49 +++++++++++++++++++++++++++++++ kernel/src/thread/Thread.cpp | 15 ++++++++++ kernel/src/thread/Thread.h | 46 +++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 kernel/src/arch/x86_64/Thread.cpp create mode 100644 kernel/src/thread/Thread.cpp create mode 100644 kernel/src/thread/Thread.h diff --git a/kernel/src/arch/x86_64/Thread.cpp b/kernel/src/arch/x86_64/Thread.cpp new file mode 100644 index 00000000..1abd34a0 --- /dev/null +++ b/kernel/src/arch/x86_64/Thread.cpp @@ -0,0 +1,49 @@ +#include "thread/Thread.h" +#include + +bool is_in_kernel(Registers* regs) +{ + return regs->cs == 8; +} + +void Thread::set_ip(u64 ip) +{ + regs.rip = ip; +} + +u64 Thread::ip() +{ + return regs.rip; +} + +void Thread::set_sp(u64 sp) +{ + regs.rsp = sp; +} + +u64 Thread::sp() +{ + return regs.rsp; +} + +void Thread::init_regs_kernel() +{ + memset(®s, 0, sizeof(Registers)); + regs.cs = 0x08; + regs.ss = 0x10; +} + +void Thread::set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4) +{ + regs.rdi = arg1; + regs.rsi = arg2; + regs.rdx = arg3; + regs.rcx = arg4; +} + +void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs) +{ + if (!old_thread->is_idle) memcpy(&old_thread->regs, regs, sizeof(Registers)); + + memcpy(regs, &new_thread->regs, sizeof(Registers)); +} \ No newline at end of file diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp new file mode 100644 index 00000000..5f834d6e --- /dev/null +++ b/kernel/src/thread/Thread.cpp @@ -0,0 +1,15 @@ +#include "thread/Thread.h" +#include + +static u64 g_next_id = 1; + +DoublyLinkedList g_threads; + +Result new_thread() +{ + Thread* thread = TRY(make()); + + thread->id = g_next_id++; + + return thread; +} \ No newline at end of file diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h new file mode 100644 index 00000000..3b3b7a39 --- /dev/null +++ b/kernel/src/thread/Thread.h @@ -0,0 +1,46 @@ +#pragma once + +#include "arch/CPU.h" +#include +#include + +#ifdef ARCH_X86_64 +#include "arch/x86_64/CPU.h" +#else +#error "Unknown architecture." +#endif + +struct Thread : public DoublyLinkedListNode +{ + Registers regs; + + u64 id; + + u64 ticks = 0; + u64 ticks_in_user = 0; + u64 ticks_in_kernel = 0; + + u64 ticks_left; + + bool is_idle = false; + + void init_regs_kernel(); + void init_regs_user(); + + void set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4); + + void set_ip(u64 ip); + u64 ip(); + + void set_sp(u64 sp); + u64 sp(); +}; + +void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs); + +bool is_in_kernel(Registers* regs); + +Result new_thread(); +Result create_idle_thread(); + +extern DoublyLinkedList g_threads; \ No newline at end of file