#import "utils.typ": * #let remtime-add(list, task) = { let left-i = list.rev() .position(t => t.remaining > task.remaining) if left-i == none { left-i = list.rev() .position(t => t.arrival > task.arrival) } let i = if left-i == none { 0 } else { list.len() - left-i } if task.pid == 7 { let dbg = (list, task, i) } list.insert(i, task) return list } #let SRTF(tasks, ctx-switch: 1) = { let (processes, tasks) = _prepare-tasks(tasks) tasks = tasks.rev() let n-tasks = tasks.len() let cur-time = 0 let current = none let finished = 0 let remtime-list = () let logs = () while finished != n-tasks { let log = "Current time: " + str(cur-time) + " / " if (current != none) { log += "Current: " + str(current.pid) + " / " } else { log += "Current: none / " } if (tasks.len() != 0) { log += "Next: " + str(tasks.last().pid) } else { log += "Next: none" } logs.push(log) if current == none { current = tasks.pop() logs.push("No running process: running " + str(current.pid)) current.state = RUNNING processes.at(current.id).events.push((RUNNING, current.arrival)) } else if tasks.len() != 0 { logs.push(log-list(remtime-list)) logs.push("Processing next process (" + str(tasks.last().pid) + ")") tasks.last().state = READY let delta = tasks.last().arrival - cur-time while current != none and current.remaining <= delta { logs.push(" Process " + str(current.pid) + " finished before next") if current.state != RUNNING { processes.at(current.id).events.push((RUNNING, cur-time)) } current.state = TERMINATED cur-time += current.remaining delta = tasks.last().arrival - cur-time current.remaining = 0 processes.at(current.id).events.push((TERMINATED, cur-time)) finished += 1 if remtime-list.len() != 0 { current = remtime-list.pop() } else { current = none } } if current != none { logs.push("Removing time from current process") if current.state != RUNNING and tasks.last().arrival > cur-time { processes.at(current.id).events.push((RUNNING, cur-time)) current.state = RUNNING //processes.at(current.id).events.push((READY, tasks.last().arrival)) } current.remaining -= delta logs.push(" New remaining time " + str(current.remaining)) } if tasks.last().arrival > cur-time { cur-time = tasks.last().arrival } tasks.last().state = READY if current == none { current = tasks.pop() logs.push("Queue is empty, running next process " + str(current.pid)) current.state = RUNNING processes.at(current.id).events.push((RUNNING, cur-time)) } else if tasks.last().remaining < current.remaining { logs.push("Next process (" + str(tasks.last().pid) + ") has shorter remaining time") if current.state != READY { processes.at(current.id).events.push((READY, cur-time)) } if current.state == RUNNING { logs.push(" Preempting current process (" + str(current.pid) +")") current.remaining -= tasks.last().arrival - cur-time processes.at(tasks.last().id).events.push((READY, cur-time)) cur-time += ctx-switch } if current.state == RUNNING { current.state = READY remtime-list = remtime-add(remtime-list, current) } else { remtime-list.push(current) } current = tasks.pop() current.state = RUNNING processes.at(current.id).events.push((RUNNING, cur-time)) } else { logs.push("Adding next process (" + str(tasks.last().pid) + ") to list") processes.at(tasks.last().id).events.push((READY, cur-time)) remtime-list = remtime-add(remtime-list, tasks.pop()) } if current != none { if current.state != RUNNING { processes.at(current.id).events.push((RUNNING, cur-time)) } current.state = RUNNING } } else { logs.push("No new processes, emptying queue") logs.push(log-list(remtime-list)) while current != none { logs.push("Completing process " + str(current.pid)) current.state = TERMINATED cur-time += current.remaining current.remaining = 0 processes.at(current.id).events.push((TERMINATED, cur-time)) finished += 1 if remtime-list.len() != 0 { current = remtime-list.pop() current.state = RUNNING processes.at(current.id).events.push((RUNNING, cur-time)) } else { current = none } } } } return _prepare-output(processes) }