mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 17:55:06 +00:00
Kernel: Port process thread lists to SpinLockProtectedValue
I had to move the thread list out of the protected base area of Process so that it could live with its lock (which needs to be mutable). Ideally it would live in the protected area, so maybe we can figure out a way to do that later.
This commit is contained in:
parent
d6667e4cb8
commit
b197fc40a7
3 changed files with 38 additions and 27 deletions
|
@ -856,8 +856,9 @@ bool Process::remove_thread(Thread& thread)
|
||||||
ProtectedDataMutationScope scope { *this };
|
ProtectedDataMutationScope scope { *this };
|
||||||
auto thread_cnt_before = m_thread_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel);
|
auto thread_cnt_before = m_thread_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel);
|
||||||
VERIFY(thread_cnt_before != 0);
|
VERIFY(thread_cnt_before != 0);
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
thread_list().with([&](auto& thread_list) {
|
||||||
m_thread_list.remove(thread);
|
thread_list.remove(thread);
|
||||||
|
});
|
||||||
return thread_cnt_before == 1;
|
return thread_cnt_before == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,8 +866,9 @@ bool Process::add_thread(Thread& thread)
|
||||||
{
|
{
|
||||||
ProtectedDataMutationScope scope { *this };
|
ProtectedDataMutationScope scope { *this };
|
||||||
bool is_first = m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) == 0;
|
bool is_first = m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) == 0;
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
thread_list().with([&](auto& thread_list) {
|
||||||
m_thread_list.append(thread);
|
thread_list.append(thread);
|
||||||
|
});
|
||||||
return is_first;
|
return is_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@ protected:
|
||||||
mode_t m_umask { 022 };
|
mode_t m_umask { 022 };
|
||||||
VirtualAddress m_signal_trampoline;
|
VirtualAddress m_signal_trampoline;
|
||||||
Atomic<u32> m_thread_count { 0 };
|
Atomic<u32> m_thread_count { 0 };
|
||||||
IntrusiveList<Thread, RawPtr<Thread>, &Thread::m_process_thread_list_node> m_thread_list;
|
|
||||||
u8 m_termination_status { 0 };
|
u8 m_termination_status { 0 };
|
||||||
u8 m_termination_signal { 0 };
|
u8 m_termination_signal { 0 };
|
||||||
};
|
};
|
||||||
|
@ -724,9 +723,12 @@ public:
|
||||||
const FileDescriptions& fds() const { return m_fds; }
|
const FileDescriptions& fds() const { return m_fds; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileDescriptions m_fds;
|
SpinLockProtectedValue<Thread::ListInProcess>& thread_list() { return m_thread_list; }
|
||||||
|
SpinLockProtectedValue<Thread::ListInProcess> const& thread_list() const { return m_thread_list; }
|
||||||
|
|
||||||
mutable RecursiveSpinLock m_thread_list_lock;
|
SpinLockProtectedValue<Thread::ListInProcess> m_thread_list;
|
||||||
|
|
||||||
|
FileDescriptions m_fds;
|
||||||
|
|
||||||
const bool m_is_kernel_process;
|
const bool m_is_kernel_process;
|
||||||
Atomic<State> m_state { State::Running };
|
Atomic<State> m_state { State::Running };
|
||||||
|
@ -818,25 +820,27 @@ inline void Process::for_each_child(Callback callback)
|
||||||
template<IteratorFunction<Thread&> Callback>
|
template<IteratorFunction<Thread&> Callback>
|
||||||
inline IterationDecision Process::for_each_thread(Callback callback) const
|
inline IterationDecision Process::for_each_thread(Callback callback) const
|
||||||
{
|
{
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
return thread_list().with([&](auto& thread_list) -> IterationDecision {
|
||||||
for (auto& thread : m_thread_list) {
|
for (auto& thread : thread_list) {
|
||||||
IterationDecision decision = callback(thread);
|
IterationDecision decision = callback(thread);
|
||||||
if (decision != IterationDecision::Continue)
|
if (decision != IterationDecision::Continue)
|
||||||
return decision;
|
return decision;
|
||||||
}
|
}
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<IteratorFunction<Thread&> Callback>
|
template<IteratorFunction<Thread&> Callback>
|
||||||
inline IterationDecision Process::for_each_thread(Callback callback)
|
inline IterationDecision Process::for_each_thread(Callback callback)
|
||||||
{
|
{
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
return thread_list().with([&](auto& thread_list) -> IterationDecision {
|
||||||
for (auto& thread : m_thread_list) {
|
for (auto& thread : thread_list) {
|
||||||
IterationDecision decision = callback(thread);
|
IterationDecision decision = callback(thread);
|
||||||
if (decision != IterationDecision::Continue)
|
if (decision != IterationDecision::Continue)
|
||||||
return decision;
|
return decision;
|
||||||
}
|
}
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<IteratorFunction<Process&> Callback>
|
template<IteratorFunction<Process&> Callback>
|
||||||
|
@ -875,18 +879,20 @@ inline void Process::for_each_child(Callback callback)
|
||||||
template<VoidFunction<Thread&> Callback>
|
template<VoidFunction<Thread&> Callback>
|
||||||
inline IterationDecision Process::for_each_thread(Callback callback) const
|
inline IterationDecision Process::for_each_thread(Callback callback) const
|
||||||
{
|
{
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
thread_list().with([&](auto& thread_list) {
|
||||||
for (auto& thread : m_thread_list)
|
for (auto& thread : thread_list)
|
||||||
callback(thread);
|
callback(thread);
|
||||||
|
});
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<VoidFunction<Thread&> Callback>
|
template<VoidFunction<Thread&> Callback>
|
||||||
inline IterationDecision Process::for_each_thread(Callback callback)
|
inline IterationDecision Process::for_each_thread(Callback callback)
|
||||||
{
|
{
|
||||||
ScopedSpinLock thread_list_lock(m_thread_list_lock);
|
thread_list().with([&](auto& thread_list) {
|
||||||
for (auto& thread : m_thread_list)
|
for (auto& thread : thread_list)
|
||||||
callback(thread);
|
callback(thread);
|
||||||
|
});
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1372,6 +1372,9 @@ private:
|
||||||
void yield_and_release_relock_big_lock();
|
void yield_and_release_relock_big_lock();
|
||||||
void yield_assuming_not_holding_big_lock();
|
void yield_assuming_not_holding_big_lock();
|
||||||
void drop_thread_count(bool);
|
void drop_thread_count(bool);
|
||||||
|
|
||||||
|
public:
|
||||||
|
using ListInProcess = IntrusiveList<Thread, RawPtr<Thread>, &Thread::m_process_thread_list_node>;
|
||||||
};
|
};
|
||||||
|
|
||||||
AK_ENUM_BITWISE_OPERATORS(Thread::FileBlocker::BlockFlags);
|
AK_ENUM_BITWISE_OPERATORS(Thread::FileBlocker::BlockFlags);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue