mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 15:48:21 +00:00
fix(ke): fix various scheduler bugs
This commit is contained in:
+8
-7
@@ -188,7 +188,7 @@ pub fn clock(_: ?*anyopaque) void {
|
|||||||
// Advance the insert index every tick, while keeping a separation of 1 with runidx.
|
// Advance the insert index every tick, while keeping a separation of 1 with runidx.
|
||||||
// This ensures fairness.
|
// This ensures fairness.
|
||||||
if (sched_cpu.runidx == sched_cpu.insidx) {
|
if (sched_cpu.runidx == sched_cpu.insidx) {
|
||||||
sched_cpu.insidx = (sched_cpu.insidx) % runqueues_n;
|
sched_cpu.insidx = (sched_cpu.insidx + 1) % runqueues_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curtd.priority_class == .Batch) {
|
if (curtd.priority_class == .Batch) {
|
||||||
@@ -243,7 +243,7 @@ pub fn unblock(td: *ke.Thread) void {
|
|||||||
|
|
||||||
td.sleep_time = (ke.timecounter.read_time_nano() - td.sleep_start) / std.time.ns_per_ms;
|
td.sleep_time = (ke.timecounter.read_time_nano() - td.sleep_start) / std.time.ns_per_ms;
|
||||||
|
|
||||||
if (td.sleep_time >= config.CONFIG_SCHED_TIMESLICE and .priority_class == .Batch) {
|
if (td.sleep_time >= config.CONFIG_SCHED_TIMESLICE and td.priority_class == .Batch) {
|
||||||
// If we have slept for more than a tick, update interactivity.
|
// If we have slept for more than a tick, update interactivity.
|
||||||
clamp_time(td);
|
clamp_time(td);
|
||||||
recompute_priority(td);
|
recompute_priority(td);
|
||||||
@@ -311,7 +311,7 @@ fn pick_realtime_thread(cpu: *PerCpu, minprio: u8, migrate: bool) ?*ke.Thread {
|
|||||||
// Search higher priority queues first.
|
// Search higher priority queues first.
|
||||||
var i: usize = ke.Thread.Priority.max;
|
var i: usize = ke.Thread.Priority.max;
|
||||||
|
|
||||||
qloop: while (i >= minprio) : (i -= 1) {
|
qloop: while (i >= minprio and i > 0) : (i -= 1) {
|
||||||
const bit = (@as(u64, 1) << @intCast(i));
|
const bit = (@as(u64, 1) << @intCast(i));
|
||||||
|
|
||||||
if (runq.status & bit == 0) {
|
if (runq.status & bit == 0) {
|
||||||
@@ -345,6 +345,8 @@ fn pick_realtime_thread(cpu: *PerCpu, minprio: u8, migrate: bool) ?*ke.Thread {
|
|||||||
// Queue is now empty, clear its bit.
|
// Queue is now empty, clear its bit.
|
||||||
runq.status &= ~bit;
|
runq.status &= ~bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -415,7 +417,7 @@ fn pick_idle_thread(cpu: *PerCpu, migrate: bool) ?*ke.Thread {
|
|||||||
// Just get the first thread from the queue.
|
// Just get the first thread from the queue.
|
||||||
const td: *ke.Thread = @fieldParentPtr("runq_link", cpu.idle_queue.first());
|
const td: *ke.Thread = @fieldParentPtr("runq_link", cpu.idle_queue.first());
|
||||||
|
|
||||||
if (!migrate and td.pinned) {
|
if (!(migrate and td.pinned)) {
|
||||||
// We can safely remove it.
|
// We can safely remove it.
|
||||||
td.runq_link.remove();
|
td.runq_link.remove();
|
||||||
}
|
}
|
||||||
@@ -429,7 +431,6 @@ fn insert_in_list(list: *rtl.List, link: *rtl.List.Entry, head: bool) void {
|
|||||||
|
|
||||||
// Insert a thread into its respective queue.
|
// Insert a thread into its respective queue.
|
||||||
fn insert_in_queue(cpu: *PerCpu, td: *ke.Thread, head: bool) void {
|
fn insert_in_queue(cpu: *PerCpu, td: *ke.Thread, head: bool) void {
|
||||||
std.debug.assert(td.lock.is_locked());
|
|
||||||
std.debug.assert(cpu.queues_lock.is_locked());
|
std.debug.assert(cpu.queues_lock.is_locked());
|
||||||
|
|
||||||
if (td.priority_class == .Realtime or td.interactive) {
|
if (td.priority_class == .Realtime or td.interactive) {
|
||||||
@@ -629,7 +630,7 @@ fn should_preempt_cpu(td: *ke.Thread, cpu: *ke.Cpu) bool {
|
|||||||
|
|
||||||
// Enqueue a thread on a CPU.
|
// Enqueue a thread on a CPU.
|
||||||
fn enqueue_on_cpu(cpu: *ke.Cpu, td: *ke.Thread) void {
|
fn enqueue_on_cpu(cpu: *ke.Cpu, td: *ke.Thread) void {
|
||||||
var c = percpu_data.local();
|
var c = percpu_data.remote(cpu);
|
||||||
|
|
||||||
c.queues_lock.acquire_no_ipl();
|
c.queues_lock.acquire_no_ipl();
|
||||||
|
|
||||||
@@ -810,7 +811,7 @@ fn find_most_loaded(exclude: ?*ke.CpuMask) ?*ke.Cpu {
|
|||||||
const cpu = ke.cpus[i];
|
const cpu = ke.cpus[i];
|
||||||
const load = percpu_data.remote(cpu).load.load(.monotonic);
|
const load = percpu_data.remote(cpu).load.load(.monotonic);
|
||||||
|
|
||||||
if (most == null or load > most_load) {
|
if (most == null) {
|
||||||
most = cpu;
|
most = cpu;
|
||||||
most_load = load;
|
most_load = load;
|
||||||
} else if (load > most_load) {
|
} else if (load > most_load) {
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ pub const Thread = struct {
|
|||||||
pub fn init(thread: *Thread, stack: b.VAddr, stack_size: usize, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) void {
|
pub fn init(thread: *Thread, stack: b.VAddr, stack_size: usize, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) void {
|
||||||
thread.* = .{
|
thread.* = .{
|
||||||
.context = .init(stack, stack_size, entry, arg),
|
.context = .init(stack, stack_size, entry, arg),
|
||||||
.lock = ke.SpinLock.init(),
|
.lock = .init(),
|
||||||
.nice = 0,
|
.nice = 0,
|
||||||
.priority = Thread.Priority.default,
|
.priority = Thread.Priority.default,
|
||||||
.priority_class = Thread.Priority.Class.Batch,
|
.priority_class = Thread.Priority.Class.Batch,
|
||||||
|
|||||||
Reference in New Issue
Block a user