Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions kernel/arch/x86_64/src/hal/impl/spinlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,33 @@ class alignas(kCacheLineSizeBytes) Spinlock : public SpinlockAPI

FORCE_INLINE_F void Lock()
{
if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
LockDebug_();
return;
}

while (__builtin_expect(__sync_lock_test_and_set(&lock_, 1), 0)) {
Pause_();
}
// if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
// LockDebug_();
// return;
// }
//
// while (__builtin_expect(__sync_lock_test_and_set(&lock_, 1), 0)) {
// Pause_();
// }
}

FORCE_INLINE_F void Unlock()
{
if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
UnlockDebug_();
return;
}

__sync_lock_release(&lock_);
// if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
// UnlockDebug_();
// return;
// }
//
// __sync_lock_release(&lock_);
}

FORCE_INLINE_F NODISCARD bool TryLock()
{
if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
return TryLockDebug_();
}

return !__sync_lock_test_and_set(&lock_, 1);
// if constexpr (FeatureEnabled<FeatureFlag::kDebugSpinlock>) {
// return TryLockDebug_();
// }
//
// return !__sync_lock_test_and_set(&lock_, 1);
}

FORCE_INLINE_F NODISCARD bool IsLocked() const { return lock_ != 0; }
Expand Down
3 changes: 2 additions & 1 deletion kernel/arch/x86_64/src/include/thread.nasm
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
; ------------------------------------------------------------

struc Thread
.intrusive_data resb 88
.intrusive_data resb 144

.tid: resq 1
.owner: resq 1
.flags resq 1
.state resq 1
.retval resq 1
.wait_queue resq 1

.kernel_stack: resq 1
.kernel_stack_bottom: resq 1
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/mem/virt/addr_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ expected<void, MemError> AS::AddArea(VMemArea *vma)
pos->prev ? area_list_.InsertAfter(pos->prev, vma) : area_list_.PushFront(vma);

RET_UNEXPECTED_IF(!new_node, MemError::OutOfMemory);
vma_guard.dismiss();
vma_guard.Dismiss();
return {};
}
}

RET_UNEXPECTED_IF(!area_list_.PushBack(vma), MemError::OutOfMemory);
vma_guard.dismiss();
vma_guard.Dismiss();

return {};
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/mem/virt/page_fault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void HandleUnresolvableFault(const PageFaultData &pfd, const hal::ExceptionData
if (hal::IsInterruptFromUserSpace(data)) {
auto pid = hardware::GetRunningPid();
TRACE_FATAL_GENERAL(
"Process %llu Segmentation Fault at %p (RIP=%p)", pid.id, pfd.faulting_ptr,
"Process %llu Segmentation Fault at %p (RIP=%p)", pid, pfd.faulting_ptr,
data.isr_stack_frame.rip
);

Expand Down
4 changes: 2 additions & 2 deletions kernel/src/mem/virt/vmm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ expected<VPtr<AddressSpace>, MemError> Vmm::CreateUserAddrSpace()
auto res = as->AddArea(*kernel_sync_vma);
RET_UNEXPECTED_IF_ERR(res);

as_guard.dismiss();
as_guard.Dismiss();
return as;
}

Expand Down Expand Up @@ -197,7 +197,7 @@ expected<VPtr<void>, MemError> Vmm::MapUserBackbuffer(
auto add_res = as->AddArea(vma);
RET_UNEXPECTED_IF_ERR(add_res);

vma_guard.dismiss();
vma_guard.Dismiss();

return gap_res->start;
}
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/scheduling/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum class Error {
JoiningDetachedThread,
SelfJoin,
AlreadyJoined,
NoPermission,
};

} // namespace Sched
Expand All @@ -41,6 +42,8 @@ static constexpr const char *to_string(const Sched::Error &error)
return "SelfJoin";
case Sched::Error::AlreadyJoined:
return "AlreadyJoined";
case Sched::Error::NoPermission:
return "NoPermission";
}

return "unknown error";
Expand Down
21 changes: 20 additions & 1 deletion kernel/src/scheduling/kworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ void Sched::KWorkerMain()
hal::Noop();
hal::Noop();
}

SchedulingModule::Get().GetScheduler().Yield();
}
}
Expand All @@ -39,6 +38,26 @@ void Sched::TraceDumperMain()
}
}

void Sched::ThreadRipperMain()
{
TRACE_INFO_SCHEDULING("Created new ThreadRipper!");

while (true) {
SchedulingModule::Get().GetTaskMgr().ThreadRipperWork();
SchedulingModule::Get().GetScheduler().Yield();
}
}

void Sched::ProcessRipperMain()
{
TRACE_INFO_SCHEDULING("Created new ProcessRipper!");

while (true) {
SchedulingModule::Get().GetTaskMgr().ProcessRipperWork();
SchedulingModule::Get().GetScheduler().Yield();
}
}

void Sched::StdoutTracerMain(Pid pid)
{
TRACE_INFO_SCHEDULING("Created new StdoutTracer!");
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/scheduling/kworker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct Pid;

void KWorkerMain();
void TraceDumperMain();
void ThreadRipperMain();
void ProcessRipperMain();
void FdHierarchyDumperMain();
void StdoutTracerMain(Pid pid);
} // namespace Sched
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/scheduling/policies/mlfq_policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ class MLFQPolicy : public PolicyImpl
}
}

void RemoveTask(Thread *thread) { queues_[thread->flags.priority].Delete(thread); }

// ------------------------------
// Private methods
// ------------------------------
Expand All @@ -192,8 +194,8 @@ class MLFQPolicy : public PolicyImpl
// Class fields
// ------------------------------

data_structures::IntrusiveRBTree<Thread, u64, 1> queues_[kNumLevels];
using HookT = data_structures::IntrusiveRBTree<Thread, u64, 1>::HookT;
data_structures::IntrusiveRBTree<Thread, u64, kSchedulingIntrusiveLevel> queues_[kNumLevels];
using HookT = data_structures::IntrusiveRBTree<Thread, u64, kSchedulingIntrusiveLevel>::HookT;

u64 last_boost_time_ns_{0};
u64 min_vruntime_{0};
Expand Down
5 changes: 4 additions & 1 deletion kernel/src/scheduling/policies/priority_queue_policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class PriorityQueuePolicy : public PolicyImpl
return flags->priority >= kMaxPriority;
}

void RemoveTask(Thread *thread) { priority_queue_.Remove(thread, thread->flags.priority); }

// ------------------------------
// Private methods
// ------------------------------
Expand All @@ -73,7 +75,8 @@ class PriorityQueuePolicy : public PolicyImpl
// Class fields
// ------------------------------

data_structures::BitmapPriorityQueue<Thread, kMaxPriority> priority_queue_{};
data_structures::BitmapPriorityQueue<Thread, kMaxPriority, kSchedulingIntrusiveLevel>
priority_queue_{};
};

} // namespace Sched
Expand Down
4 changes: 3 additions & 1 deletion kernel/src/scheduling/policies/round_robin_policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class RoundRobinPolicy : public PolicyImpl

NODISCARD bool ValidateThreadFlags(const ThreadFlags *) { return false; }

void RemoveTask(Thread *thread) { threads_.Remove(thread); }

// ------------------------------
// Private methods
// ------------------------------
Expand All @@ -61,7 +63,7 @@ class RoundRobinPolicy : public PolicyImpl
// Class fields
// ------------------------------

data_structures::IntrusiveList<Thread> threads_{};
data_structures::IntrusiveDoubleList<Thread, kSchedulingIntrusiveLevel> threads_{};
};

} // namespace Sched
Expand Down
11 changes: 11 additions & 0 deletions kernel/src/scheduling/policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct Policy {
bool (*validate_flags)(void *, const ThreadFlags *);
void (*on_thread_yield)(void *, Thread *);
void (*on_periodic_update)(void *, u64 current_time_ns);
void (*remove_task)(void *, Thread *);
} cbs;
void *self;
};
Expand All @@ -51,6 +52,7 @@ struct PolicyImpl {
NODISCARD u64 GetPreemptTime(Thread *) { R_FAIL_ALWAYS("NOT_IMPLEMENTED"); }
NODISCARD bool IsFirstHigherPriority(Thread *, Thread *) { R_FAIL_ALWAYS("NOT_IMPLEMENTED"); }
NODISCARD bool ValidateThreadFlags(const ThreadFlags *) { R_FAIL_ALWAYS("NOT_IMPLEMENTED"); }
void RemoveTask(Thread *) { R_FAIL_ALWAYS("NOT_IMPLEMENTED"); }

// Event callbacks
void OnThreadYield(Thread *) {}
Expand Down Expand Up @@ -113,6 +115,14 @@ void OnPeriodicUpdateImpl(void *self, u64 current_time_ns)
policy->OnPeriodicUpdate(current_time_ns);
}

template <class T>
requires std::derived_from<T, PolicyImpl>
void RemoveTaskImpl(void *self, Thread *thread)
{
const auto policy = static_cast<T *>(self);
policy->RemoveTask(thread);
}

template <class T>
requires std::derived_from<T, PolicyImpl>
NODISCARD FAST_CALL Policy PreparePolicy(T *self)
Expand All @@ -127,6 +137,7 @@ NODISCARD FAST_CALL Policy PreparePolicy(T *self)
policy.cbs.validate_flags = ValidateThreadFlagsImpl<T>;
policy.cbs.on_thread_yield = OnThreadYieldImpl<T>;
policy.cbs.on_periodic_update = OnPeriodicUpdateImpl<T>;
policy.cbs.remove_task = RemoveTaskImpl<T>;

return policy;
}
Expand Down
17 changes: 17 additions & 0 deletions kernel/src/scheduling/process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "hal/tasks.hpp"
#include "io/pipe.hpp"
#include "mem/types.hpp"
#include "wait_queue.hpp"

namespace Mem
{
Expand All @@ -23,6 +24,8 @@ class FdTable;

namespace Sched
{
struct Thread;

struct PACK Pid {
u16 id;
u64 count : 48;
Expand All @@ -36,13 +39,27 @@ struct PACK ProcessFlags {
};
static_assert(sizeof(ProcessFlags) == 1);

enum class ProcessState : u64 {
kReady = 0,
kWaitingForJoin,
kTerminated,
kLast,
};
static_assert(sizeof(ProcessState) == sizeof(u64));

struct Process : hal::Process {
static constexpr size_t kMaxNameLength = vfs::kMaxComponentSize;

/* Management */
char name[kMaxNameLength];
Pid pid;
ProcessFlags flags;
Thread *threads;
u64 live_threads;
u64 threads_to_clean;
ProcessState state;
WaitQueue<Thread, 3> *wait_queue;
int status;

/* Process resources */
Mem::VPtr<Mem::AddressSpace> address_space;
Expand Down
18 changes: 15 additions & 3 deletions kernel/src/scheduling/processes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@ std::expected<Sched::Process *, Sched::Error> Sched::Processes::PrepareProcess()
// Initialize standard I/O pipes
// ----------------------------------------------------------

// Allocate wait queue
const auto wait_queue = Mem::KNew<WaitQueue<Thread, kWaitQueueIntrusiveLevel>>();
if (!wait_queue) {
return std::unexpected(Error::OutOfMemory);
}
template_lib::BatchedScopeGuard wait_queue_guard(dismiss, [&]() {
Mem::KDelete(wait_queue.value());
});
process->wait_queue = wait_queue.value();

// Create the process's file descriptor table
auto fd_table_ptr = Mem::KNew<Fs::FdTable>();
const auto fd_table_ptr = Mem::KNew<Fs::FdTable>();
RET_UNEXPECTED_IF(!fd_table_ptr, Error::OutOfMemory);

auto *fd_table = process->fd_table = *fd_table_ptr;
Expand Down Expand Up @@ -80,10 +90,12 @@ void Sched::Processes::CleanupProcess(Process *process)
{
ASSERT_NOT_NULL(process);

VideoModule::Get().GetWindowManager().ReleaseFocus(process->pid);

auto fd_table = process->fd_table;
ASSERT_NOT_NULL(fd_table);

Mem::KDelete(fd_table);

ASSERT_NOT_NULL(process->wait_queue);
ASSERT_TRUE(process->wait_queue->IsEmpty());
Mem::KDelete(process->wait_queue);
}
12 changes: 9 additions & 3 deletions kernel/src/scheduling/processes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ class Processes

void CleanupProcess(Process *process);

NODISCARD FORCE_INLINE_F std::expected<Process *, Error> GetProcess(const Pid pid)
NODISCARD FORCE_INLINE_F std::expected<Process *, Error> GetProcess(const u32 id)
{
const u16 id = pid.id;
auto ptr = processes_.Get(id);
auto ptr = processes_.Get(id);

if (ptr == nullptr) {
return std::unexpected(Error::ProcessNotFound);
Expand All @@ -45,6 +44,11 @@ class Processes
return ptr;
}

NODISCARD FORCE_INLINE_F std::expected<Process *, Error> GetProcess(const Pid pid)
{
return GetProcess(pid.id);
}

NODISCARD FORCE_INLINE_F std::expected<Process *, Error> GetCurrentProcess()
{
const Pid pid = hardware::GetRunningPid();
Expand All @@ -61,6 +65,8 @@ class Processes

CleanupProcess(processes_.Get(id));
processes_.Free(id);

TRACE_INFO_SCHEDULING("Fully freed process with PID: %llu", pid);
return {};
}

Expand Down
Loading
Loading