155 lines
4.8 KiB
Typst
155 lines
4.8 KiB
Typst
|
#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)
|
||
|
}
|