mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 06:15:07 +00:00
Kernel: Restore thread count if thread cannot be fully created
This commit is contained in:
parent
bf9be3ec01
commit
a0c91719d8
2 changed files with 13 additions and 2 deletions
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Demangle.h>
|
#include <AK/Demangle.h>
|
||||||
|
#include <AK/ScopeGuard.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Time.h>
|
#include <AK/Time.h>
|
||||||
#include <Kernel/Arch/i386/CPU.h>
|
#include <Kernel/Arch/i386/CPU.h>
|
||||||
|
@ -50,7 +51,11 @@ Thread::Thread(NonnullRefPtr<Process> process)
|
||||||
: m_process(move(process))
|
: m_process(move(process))
|
||||||
, m_name(m_process->name())
|
, m_name(m_process->name())
|
||||||
{
|
{
|
||||||
if (m_process->m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) == 0) {
|
bool is_first_thread = m_process->m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) == 0;
|
||||||
|
ArmedScopeGuard guard([&]() {
|
||||||
|
drop_thread_count(is_first_thread);
|
||||||
|
});
|
||||||
|
if (is_first_thread) {
|
||||||
// First thread gets TID == PID
|
// First thread gets TID == PID
|
||||||
m_tid = m_process->pid().value();
|
m_tid = m_process->pid().value();
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,6 +117,7 @@ Thread::Thread(NonnullRefPtr<Process> process)
|
||||||
// The finalizer is responsible for dropping this reference once this
|
// The finalizer is responsible for dropping this reference once this
|
||||||
// thread is ready to be cleaned up.
|
// thread is ready to be cleaned up.
|
||||||
ref();
|
ref();
|
||||||
|
guard.disarm();
|
||||||
|
|
||||||
if (m_process->pid() != 0)
|
if (m_process->pid() != 0)
|
||||||
Scheduler::init_thread(*this);
|
Scheduler::init_thread(*this);
|
||||||
|
@ -374,11 +380,15 @@ void Thread::finalize()
|
||||||
dbg() << backtrace_impl();
|
dbg() << backtrace_impl();
|
||||||
|
|
||||||
kfree_aligned(m_fpu_state);
|
kfree_aligned(m_fpu_state);
|
||||||
|
drop_thread_count(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::drop_thread_count(bool initializing_first_thread)
|
||||||
|
{
|
||||||
auto thread_cnt_before = m_process->m_thread_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel);
|
auto thread_cnt_before = m_process->m_thread_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel);
|
||||||
|
|
||||||
ASSERT(thread_cnt_before != 0);
|
ASSERT(thread_cnt_before != 0);
|
||||||
if (thread_cnt_before == 1)
|
if (!initializing_first_thread && thread_cnt_before == 1)
|
||||||
process().finalize();
|
process().finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1216,6 +1216,7 @@ private:
|
||||||
void donate_without_holding_big_lock(RefPtr<Thread>&, const char*);
|
void donate_without_holding_big_lock(RefPtr<Thread>&, const char*);
|
||||||
void yield_while_not_holding_big_lock();
|
void yield_while_not_holding_big_lock();
|
||||||
void update_state_for_thread(Thread::State previous_state);
|
void update_state_for_thread(Thread::State previous_state);
|
||||||
|
void drop_thread_count(bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue