Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheduler: implement fair scheduling between user threads #1759

Merged
merged 2 commits into from
Aug 19, 2022

Conversation

francescolavra
Copy link
Member

This change introduces a new scheduling algorithm that assigns CPU resources to a task based on how much CPU time the task used in the past. It uses a priority queue where tasks are ordered based on their CPU time: when a task is enqueued, it is positioned according to the time it has been running since it was last scheduled; when a task is dequeued, its CPU time is subtracted from the CPU time of any other tasks in the queue, so that their priority in the queue is increased; this is implemented by storing a reference CPU time in the queue (min_runtime struct member), which prevents long-running tasks from being starved by newly created tasks.
This algorithm is applied for scheduling user threads, so that CPU time is distributed fairly between all runnable threads.

The first commit is a fix to a pre-existing bug that has been exposed by modifying the execution order of runnable user threads.

Copy link
Contributor

@wjhun wjhun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -240,7 +247,8 @@ static void thread_resume(context ctx)
static void thread_schedule_return(context ctx)
{
thread t = (thread)ctx;
assert(enqueue_irqsafe(t->scheduling_queue, &t->thread_return));
thread_cputime_update(t); /* so that it is scheduled based on how much CPU time it used */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't the thread be paused at this point, with t->start_time == 0, thus making the call to thread_cputime_update() a no-op here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a user thread is interrupted by a hardware interrupt, the interrupt handler calls context_schedule_return() without the thread being paused. Also, when the Unix fault handler raises a signal or resolves a page fault without blocking, it calls schedule_thread(), again without the thread being paused.

When an unhandled page fault occurs in a syscall context, the
syscall is abandoned and a SIGSEGV is raised. The syscall context
should not be reused by other threads until the offending thread
runs the signal handler, otherwise if another thread executes a
syscall, the assert(sc->context.refcount.c == 1) in the syscall
handler fails.
This commit fxes the above issue by adding a call to
orphan_syscall_context() in the Unix fault handler, so that the
syscall context is not reused by any threads that might run on the
same CPU before the signal handler of the offending thread. Since
orphaning a context releases its refcount, a call to
context_release_refcount() is being removed from the arch-specific
exception handlers.
This change introduces a new scheduling algorithm that assigns CPU
resources to a task based on how much CPU time the task used in
the past. It uses a priority queue where tasks are ordered based on
their CPU time: when a task is enqueued, it is positioned according
to the time it has been running since it was last scheduled; when a
task is dequeued, its CPU time is subtracted from the CPU time of
any other tasks in the queue, so that their priority in the queue
is increased; this is implemented by storing a reference CPU time
in the queue (min_runtime struct member), which prevents
long-running tasks from being starved by newly created tasks.
This algorithm is applied for scheduling user threads, so
that CPU time is distributed fairly between all runnable threads.
@francescolavra francescolavra merged commit 20ef40d into master Aug 19, 2022
@francescolavra francescolavra deleted the feature/fair-scheduler branch August 19, 2022 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants