schedule tasks across all cores
Per-core GDT/TSS and AP scheduler entry; fix AP SSE + single_threaded.
This commit is contained in:
@@ -68,6 +68,8 @@ pub fn run(case: []const u8, boot_info: *const BootInfo) void {
|
||||
eventTest();
|
||||
} else if (eql(case, "ipc")) {
|
||||
ipcTest();
|
||||
} else if (eql(case, "smp")) {
|
||||
smpTest();
|
||||
} else if (eql(case, "fault-ud")) {
|
||||
faultInvalidOpcode();
|
||||
} else if (eql(case, "fault-pf")) {
|
||||
@@ -437,6 +439,49 @@ fn sleepTest() void {
|
||||
result();
|
||||
}
|
||||
|
||||
// --- SMP parallelism ------------------------------------------------------
|
||||
|
||||
var seen_core = [_]bool{false} ** 8;
|
||||
var smp_running: bool = true;
|
||||
|
||||
/// A worker that, while running, records which core it's executing on. Spread across
|
||||
/// spawned workers and idle APs, these should land on more than one core.
|
||||
fn smpWorker() void {
|
||||
const p: *volatile bool = &smp_running;
|
||||
while (p.*) {
|
||||
const c = sched.currentCpuIndex();
|
||||
if (c < seen_core.len) seen_core[c] = true;
|
||||
}
|
||||
sched.exit();
|
||||
}
|
||||
|
||||
/// Prove tasks run **in parallel** on multiple cores (not just interleaved on one).
|
||||
/// Spawn several CPU-bound workers; each stamps the core it runs on into `seen_core`.
|
||||
/// With the application processors online, more than one core should show up — which
|
||||
/// can only happen if work is genuinely running at the same time on different cores.
|
||||
/// (Run with QEMU `-smp N`; on a single core this would see just one and fail.)
|
||||
fn smpTest() void {
|
||||
log("DANOS-TEST-BEGIN: smp\n", .{});
|
||||
seen_core = .{false} ** 8;
|
||||
smp_running = true;
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < 4) : (i += 1) sched.spawn(smpWorker, 4);
|
||||
|
||||
// Let the workers run across cores for a stretch of real time.
|
||||
var spins: u64 = 0;
|
||||
while (spins < 2_000_000_000) spins +%= 1;
|
||||
smp_running = false;
|
||||
|
||||
var cores_seen: u32 = 0;
|
||||
for (seen_core) |s| {
|
||||
if (s) cores_seen += 1;
|
||||
}
|
||||
log("DANOS-SMP: workers ran on {d} distinct core(s)\n", .{cores_seen});
|
||||
check("tasks ran on multiple cores in parallel", cores_seen >= 2);
|
||||
result();
|
||||
}
|
||||
|
||||
fn faultInvalidOpcode() void {
|
||||
log("DANOS-TEST-BEGIN: fault-ud\n", .{});
|
||||
asm volatile ("ud2");
|
||||
|
||||
Reference in New Issue
Block a user