Add scope guards
This commit is contained in:
parent
6de7753b4c
commit
1d5d1daa57
@ -4,6 +4,7 @@
|
|||||||
#include "arch/MMU.h"
|
#include "arch/MMU.h"
|
||||||
#include "memory/KernelVM.h"
|
#include "memory/KernelVM.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
|
#include <luna/ScopeGuard.h>
|
||||||
#include <luna/Stack.h>
|
#include <luna/Stack.h>
|
||||||
|
|
||||||
static Thread g_idle;
|
static Thread g_idle;
|
||||||
@ -44,12 +45,19 @@ namespace Scheduler
|
|||||||
return &g_idle;
|
return &g_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> kernel_thread_alloc_stack_and_append_impl(Thread* thread)
|
Result<void> new_kernel_thread_impl(Thread* thread)
|
||||||
{
|
{
|
||||||
// FIXME: We will leak the thread if VM allocation or alloc_at fail.
|
// If anything fails, make sure to clean up.
|
||||||
|
auto thread_guard = make_scope_guard([&] { delete thread; });
|
||||||
|
|
||||||
u64 thread_stack_vm = TRY(KernelVM::alloc_several_pages(4));
|
u64 thread_stack_vm = TRY(KernelVM::alloc_several_pages(4));
|
||||||
|
auto vm_guard = make_scope_guard([&] { KernelVM::free_several_pages(thread_stack_vm, 4); });
|
||||||
|
|
||||||
TRY(MemoryManager::alloc_at(thread_stack_vm, 4, MMU::NoExecute | MMU::ReadWrite));
|
TRY(MemoryManager::alloc_at(thread_stack_vm, 4, MMU::NoExecute | MMU::ReadWrite));
|
||||||
|
|
||||||
|
thread_guard.deactivate();
|
||||||
|
vm_guard.deactivate();
|
||||||
|
|
||||||
Stack thread_stack{thread_stack_vm, ARCH_PAGE_SIZE * 4};
|
Stack thread_stack{thread_stack_vm, ARCH_PAGE_SIZE * 4};
|
||||||
thread->set_sp(thread_stack.top());
|
thread->set_sp(thread_stack.top());
|
||||||
|
|
||||||
@ -66,7 +74,7 @@ namespace Scheduler
|
|||||||
thread->init_regs_kernel();
|
thread->init_regs_kernel();
|
||||||
thread->set_ip(address);
|
thread->set_ip(address);
|
||||||
|
|
||||||
return kernel_thread_alloc_stack_and_append_impl(thread);
|
return new_kernel_thread_impl(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> new_kernel_thread(void (*func)(void))
|
Result<void> new_kernel_thread(void (*func)(void))
|
||||||
@ -75,7 +83,7 @@ namespace Scheduler
|
|||||||
thread->init_regs_kernel();
|
thread->init_regs_kernel();
|
||||||
thread->set_ip((u64)func);
|
thread->set_ip((u64)func);
|
||||||
|
|
||||||
return kernel_thread_alloc_stack_and_append_impl(thread);
|
return new_kernel_thread_impl(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> new_kernel_thread(void (*func)(void*), void* arg)
|
Result<void> new_kernel_thread(void (*func)(void*), void* arg)
|
||||||
@ -85,7 +93,7 @@ namespace Scheduler
|
|||||||
thread->set_ip((u64)func);
|
thread->set_ip((u64)func);
|
||||||
thread->set_arguments((u64)arg, 0, 0, 0);
|
thread->set_arguments((u64)arg, 0, 0, 0);
|
||||||
|
|
||||||
return kernel_thread_alloc_stack_and_append_impl(thread);
|
return new_kernel_thread_impl(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* pick_task()
|
Thread* pick_task()
|
||||||
|
28
luna/include/luna/ScopeGuard.h
Normal file
28
luna/include/luna/ScopeGuard.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
template <typename Callback> class ScopeGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopeGuard(const Callback& callback) : m_callback(callback)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void deactivate()
|
||||||
|
{
|
||||||
|
m_activated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopeGuard()
|
||||||
|
{
|
||||||
|
if (m_activated) m_callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_activated{true};
|
||||||
|
Callback m_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Callback> [[nodiscard]] ScopeGuard<Callback> make_scope_guard(const Callback& callback)
|
||||||
|
{
|
||||||
|
return {callback};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user