From 40beb4c5c08cbf860c3cfb347e655c2e42fed779 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 13 Oct 2019 14:36:55 +0200 Subject: [PATCH] Kernel: Don't leak an FPU state buffer for every spawned thread We were leaking 512 bytes of kmalloc memory for every new thread. This patch fixes that, and also makes sure to zero out the FPU state buffer after allocating it, and finally also makes the LogStream operator<< for Thread look a little bit nicer. :^) --- Kernel/Thread.cpp | 7 ++++++- Kernel/Thread.h | 5 +---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index f03a7030c3..8963b2b54c 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -50,6 +50,7 @@ Thread::Thread(Process& process) dbgprintf("Thread{%p}: New thread TID=%u in %s(%u)\n", this, m_tid, process.name().characters(), process.pid()); set_default_signal_dispositions(); m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16); + memset(m_fpu_state, 0, sizeof(FPUState)); memset(&m_tss, 0, sizeof(m_tss)); // Only IF is set when a process boots. @@ -564,7 +565,6 @@ Thread* Thread::clone(Process& process) auto* clone = new Thread(process); memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data)); clone->m_signal_mask = m_signal_mask; - clone->m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16); memcpy(clone->m_fpu_state, m_fpu_state, sizeof(FPUState)); clone->m_has_used_fpu = m_has_used_fpu; clone->m_thread_specific_data = m_thread_specific_data; @@ -658,3 +658,8 @@ void Thread::make_thread_specific_region(Badge) if (process().m_master_tls_size) memcpy(thread_local_storage, process().m_master_tls_region->vaddr().as_ptr(), process().m_master_tls_size); } + +const LogStream& operator<<(const LogStream& stream, const Thread& value) +{ + return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; +} diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 3f5cacec70..dc728f9d35 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -379,10 +379,7 @@ inline IterationDecision Thread::for_each_in_state(State state, Callback callbac return Scheduler::for_each_nonrunnable(new_callback); } -inline const LogStream& operator<<(const LogStream& stream, const Thread& value) -{ - return stream << "Thread{" << &value << "}(" << value.pid() << ":" << value.tid() << ")"; -} +const LogStream& operator<<(const LogStream&, const Thread&); struct SchedulerData { typedef IntrusiveList ThreadList;