#import "utils.typ": * #let RR(tasks, quantum: 2, ctx-switch: 1) = { let (processes, tasks) = _prepare-tasks(tasks) let n-tasks = tasks.len() let cur-time = 0 let current = none let finished = 0 let running = 0 let last-running = none let logs = () let failsafe = 0 while (failsafe < 160 and finished < n-tasks) { failsafe += 1 for (i, p) in tasks.enumerate() { if p.state == TERMINATED { continue } logs.push("Current time: " + str(cur-time) + ", pid: " + str(p.pid)) if p.state == UNBORN { if p.arrival <= cur-time { p.state = READY if running == 0 { processes.at(p.id).events.push((RUNNING, p.arrival)) } else { processes.at(p.id).events.push((READY, p.arrival)) } running += 1 if last-running != none { logs.push("Preempting last running process (current time: " + str(cur-time) + ", pid: " + str(last-running.pid) + ")") processes.at(last-running.id).events.push((READY, cur-time)) cur-time += ctx-switch } logs.push("Process " + str(p.pid) + " is now ready") logs.push("Running processes: " + str(running)) } } if p.state == READY { //if running > 1 { if last-running == none or last-running.pid != p.pid { processes.at(p.id).events.push((RUNNING, cur-time)) } p.remaining -= quantum cur-time += quantum last-running = p logs.push("Executing quantum for process " + str(p.pid) + ", remaining time " + str(p.remaining)) if p.remaining <= 0 { logs.push(" Process has finished") processes.at(p.id).events.push((TERMINATED, cur-time + p.remaining)) p.remaining = 0 p.state = TERMINATED last-running = none finished += 1 running -= 1 } else if running > 1 { logs.push(" Preempting process (current time: " + str(cur-time) + ", pid: " + str(p.pid) + ")") last-running = none processes.at(p.id).events.push((READY, cur-time)) cur-time += ctx-switch } } tasks.at(i) = p } if finished < n-tasks and running == 0 { cur-time += 1 } } let f = failsafe //let logs2 = logs.slice(-60) return _prepare-output(processes) }