summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Thread.cpp13
-rw-r--r--Kernel/Thread.h2
2 files changed, 11 insertions, 4 deletions
diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp
index 3eca547e4b..7794a2afdd 100644
--- a/Kernel/Thread.cpp
+++ b/Kernel/Thread.cpp
@@ -39,6 +39,12 @@ UNMAP_AFTER_INIT void Thread::initialize()
KResultOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> process)
{
+ // FIXME: Once we have aligned + nothrow operator new, we can avoid the manual kfree.
+ FPUState* fpu_state = (FPUState*)kmalloc_aligned<16>(sizeof(FPUState));
+ if (!fpu_state)
+ return ENOMEM;
+ ArmedScopeGuard fpu_guard([fpu_state]() { kfree_aligned(fpu_state); });
+
auto kernel_stack_region = MM.allocate_kernel_region(default_kernel_stack_size, {}, Region::Access::Read | Region::Access::Write, AllocationStrategy::AllocateNow);
if (!kernel_stack_region)
return ENOMEM;
@@ -48,16 +54,18 @@ KResultOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> proce
if (!block_timer)
return ENOMEM;
- auto thread = adopt_ref_if_nonnull(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull()));
+ auto thread = adopt_ref_if_nonnull(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull(), fpu_state));
if (!thread)
return ENOMEM;
+ fpu_guard.disarm();
return thread.release_nonnull();
}
-Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer)
+Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer, FPUState* fpu_state)
: m_process(move(process))
, m_kernel_stack_region(move(kernel_stack_region))
+ , m_fpu_state(fpu_state)
, m_name(m_process->name())
, m_block_timer(block_timer)
, m_global_procfs_inode_index(ProcFSComponentsRegistrar::the().allocate_inode_index())
@@ -84,7 +92,6 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Region> kernel_stac
if constexpr (THREAD_DEBUG)
dbgln("Created new thread {}({}:{})", m_process->name(), m_process->pid().value(), m_tid.value());
- m_fpu_state = (FPUState*)kmalloc_aligned<16>(sizeof(FPUState));
reset_fpu_state();
#if ARCH(I386)
diff --git a/Kernel/Thread.h b/Kernel/Thread.h
index ad758aa5e7..c90bec766f 100644
--- a/Kernel/Thread.h
+++ b/Kernel/Thread.h
@@ -1188,7 +1188,7 @@ public:
InodeIndex global_procfs_inode_index() const { return m_global_procfs_inode_index; }
private:
- Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
+ Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>, FPUState*);
IntrusiveListNode<Thread> m_process_thread_list_node;
int m_runnable_priority { -1 };