kernel: Allow returning early from Scheduler::for_each_child

This commit is contained in:
apio 2023-04-28 15:13:53 +02:00
parent f3ffdd32d4
commit bcdec62f51
Signed by: apio
GPG Key ID: B8A7D06E42258954
3 changed files with 30 additions and 14 deletions

View File

@ -7,7 +7,10 @@ Result<u64> sys_exit(Registers*, SyscallArgs args)
Thread* current = Scheduler::current(); Thread* current = Scheduler::current();
Scheduler::for_each_child((pid_t)current->id, [](Thread* child) { child->parent_id = 1; }); Scheduler::for_each_child((pid_t)current->id, [](Thread* child) {
child->parent_id = 1;
return true;
});
current->status = status; current->status = status;
current->state = ThreadState::Exited; current->state = ThreadState::Exited;

View File

@ -249,12 +249,13 @@ namespace Scheduler
g_current->ticks_left--; g_current->ticks_left--;
g_threads.for_each([](Thread* thread) { for (auto* const thread : g_threads)
{
if (thread->state == ThreadState::Sleeping) if (thread->state == ThreadState::Sleeping)
{ {
if (--thread->sleep_ticks_left == 0) thread->state = ThreadState::Runnable; if (--thread->sleep_ticks_left == 0) thread->state = ThreadState::Runnable;
} }
}); }
if (!g_current->ticks_left) switch_task(regs); if (!g_current->ticks_left) switch_task(regs);
} }
@ -276,20 +277,22 @@ namespace Scheduler
Option<Thread*> find_by_pid(pid_t pid) Option<Thread*> find_by_pid(pid_t pid)
{ {
Option<Thread*> result; for (auto* const thread : g_threads)
{
if (thread->id == (u64)pid && thread->state != ThreadState::Dying) return thread;
}
g_threads.for_each([&](Thread* thread) { return {};
if (thread->id == (u64)pid && thread->state != ThreadState::Dying) result = thread;
});
return result;
} }
bool has_children(pid_t pid) bool has_children(pid_t pid)
{ {
bool result { false }; bool result { false };
for_each_child(pid, [&](Thread*) { result = true; }); for_each_child(pid, [&](Thread*) {
result = true;
return false;
});
return result; return result;
} }
@ -299,7 +302,12 @@ namespace Scheduler
Option<Thread*> result; Option<Thread*> result;
for_each_child(pid, [&](Thread* child) { for_each_child(pid, [&](Thread* child) {
if (!result.has_value() && child->state == ThreadState::Exited) result = child; if (!result.has_value() && child->state == ThreadState::Exited)
{
result = child;
return false;
}
return true;
}); });
return result; return result;

View File

@ -31,9 +31,14 @@ namespace Scheduler
template <typename Callback> void for_each_child(pid_t pid, Callback callback) template <typename Callback> void for_each_child(pid_t pid, Callback callback)
{ {
g_threads.for_each([&](Thread* thread) { for (auto* const thread : g_threads)
if (thread->parent_id == (u64)pid) callback(thread); {
}); if (thread->parent_id == (u64)pid)
{
bool should_continue = callback(thread);
if (!should_continue) return;
}
}
} }
bool has_children(pid_t pid); bool has_children(pid_t pid);