mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 20:33:10 +00:00
Kernel: Scheduler donations need to verify that the beneficiary is valid.
Add a Thread::is_thread(void*) helper that we can use to check that the incoming donation beneficiary is a valid thread. The O(n) here is a bit sad and we should eventually rethink the process/thread table data structures.
This commit is contained in:
parent
6bb0dbe8bf
commit
c59f8cd663
|
@ -243,11 +243,14 @@ bool Scheduler::pick_next()
|
|||
|
||||
bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
if (!Thread::is_thread(beneficiary))
|
||||
return false;
|
||||
|
||||
(void)reason;
|
||||
unsigned ticks_left = current->ticks_left();
|
||||
if (!beneficiary || beneficiary->state() != Thread::Runnable || ticks_left <= 1) {
|
||||
if (!beneficiary || beneficiary->state() != Thread::Runnable || ticks_left <= 1)
|
||||
return yield();
|
||||
}
|
||||
|
||||
unsigned ticks_to_donate = min(ticks_left - 1, time_slice_for(beneficiary->process().priority()));
|
||||
#ifdef SCHEDULER_DEBUG
|
||||
|
@ -256,7 +259,7 @@ bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
|
|||
context_switch(*beneficiary);
|
||||
beneficiary->set_ticks_left(ticks_to_donate);
|
||||
switch_now();
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Scheduler::yield()
|
||||
|
@ -266,11 +269,11 @@ bool Scheduler::yield()
|
|||
// dbgprintf("%s(%u:%u) yield()\n", current->process().name().characters(), current->pid(), current->tid());
|
||||
|
||||
if (!pick_next())
|
||||
return 1;
|
||||
return false;
|
||||
|
||||
// dbgprintf("yield() jumping to new process: sel=%x, %s(%u:%u)\n", current->far_ptr().selector, current->process().name().characters(), current->pid(), current->tid());
|
||||
switch_now();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scheduler::pick_next_and_switch_now()
|
||||
|
|
|
@ -526,3 +526,13 @@ Vector<Thread*> Thread::all_threads()
|
|||
threads.append(thread);
|
||||
return threads;
|
||||
}
|
||||
|
||||
bool Thread::is_thread(void* ptr)
|
||||
{
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
for (auto* thread = g_threads->head(); thread; thread = thread->next()) {
|
||||
if (thread == ptr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
static void finalize_dying_threads();
|
||||
|
||||
static Vector<Thread*> all_threads();
|
||||
static bool is_thread(void*);
|
||||
|
||||
int tid() const { return m_tid; }
|
||||
int pid() const;
|
||||
|
|
Loading…
Reference in a new issue