155 lines
3.1 KiB
Typst
155 lines
3.1 KiB
Typst
#import "@preview/cetz:0.3.1": canvas, draw
|
|
|
|
|
|
#let UNBORN = 0
|
|
#let READY = 1
|
|
#let RUNNING = 2
|
|
#let TERMINATED = 3
|
|
|
|
#let colors = (
|
|
none,
|
|
gray,
|
|
green,
|
|
blue.lighten(50%)
|
|
)
|
|
|
|
#let task(pid, arrival, duration, priority) = {
|
|
return ((
|
|
pid: pid,
|
|
arrival: arrival,
|
|
duration: duration,
|
|
remaining: duration,
|
|
priority: priority
|
|
),)
|
|
}
|
|
|
|
#let display-processes(width: auto, display-durations: none, display-priorities: false, ..args) = layout(size => {
|
|
let processes = args.pos()
|
|
processes = processes.map(p => if type(p) == dictionary {p} else {(
|
|
pid: p.first(),
|
|
priority: if display-priorities {p.at(1)} else {0},
|
|
events: p.slice(if display-priorities {2} else {1})
|
|
)})
|
|
let max-t = calc.max(
|
|
..processes.map(
|
|
p => calc.max(
|
|
..p.events.map(
|
|
e => e.last()
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
let display-durations = if display-durations == none {
|
|
()
|
|
} else if type(display-durations) == array {
|
|
display-durations
|
|
} else {
|
|
(display-durations,)
|
|
}
|
|
|
|
let shapes = ()
|
|
let width = width
|
|
if (width == auto) {
|
|
width = size.width
|
|
}
|
|
let y = 0
|
|
for proc in processes {
|
|
proc.events.push((TERMINATED, max-t))
|
|
shapes += draw.content(
|
|
(0, y - .25),
|
|
str(proc.pid),
|
|
anchor: "east",
|
|
padding: 5pt
|
|
)
|
|
|
|
for i in range(proc.events.len() - 1) {
|
|
let (state1, t1) = proc.events.at(i)
|
|
let (state2, t2) = proc.events.at(i+1)
|
|
let x1 = t1 / max-t * width
|
|
let x2 = t2 / max-t * width
|
|
let y1 = y
|
|
let y2 = y - .5
|
|
if (state1 == TERMINATED) {
|
|
y1 = y - .2
|
|
y2 = y - .3
|
|
}
|
|
|
|
shapes += draw.rect(
|
|
(x1, y1),
|
|
(x2, y2),
|
|
fill: colors.at(state1)
|
|
)
|
|
|
|
if i == 0 and display-priorities {
|
|
shapes += draw.content(
|
|
((x1 + x2) / 2, (y1 + y2) / 2),
|
|
strong(str(proc.priority)),
|
|
anchor: "center"
|
|
)
|
|
}
|
|
if state1 in display-durations {
|
|
shapes += draw.content(
|
|
((x1 + x2) / 2, (y1 + y2) / 2),
|
|
strong(str(t2 - t1)),
|
|
anchor: "center"
|
|
)
|
|
}
|
|
|
|
if state1 == RUNNING and state2 == READY {
|
|
shapes += draw.on-layer(1, draw.circle(
|
|
(x2, (y1 + y2)/2),
|
|
radius: .1,
|
|
fill: red
|
|
))
|
|
}
|
|
}
|
|
y -= 0.5
|
|
}
|
|
|
|
let step = calc.pow(
|
|
10,
|
|
calc.max(
|
|
0,
|
|
calc.floor(
|
|
calc.log(
|
|
base: 10,
|
|
max-t
|
|
) - 1
|
|
)
|
|
)
|
|
)
|
|
let n-steps = calc.floor(max-t / step) + 1
|
|
for i in range(n-steps) {
|
|
let t = i * step
|
|
let x = t / max-t * width
|
|
shapes += draw.line(
|
|
(x, 0),
|
|
(x, if calc.rem(i, 2) == 0 {.5} else {.3}),
|
|
stroke: black
|
|
)
|
|
shapes += draw.on-layer(-1, draw.line(
|
|
(x, 0),
|
|
(x, -processes.len() * .5),
|
|
stroke: (
|
|
dash: (6pt, 4pt),
|
|
thickness: 1pt,
|
|
paint: gray
|
|
)
|
|
))
|
|
if calc.rem(i, 2) == 0 {
|
|
shapes += draw.content(
|
|
(x, .5),
|
|
str(t),
|
|
anchor: "south",
|
|
padding: 5pt
|
|
)
|
|
}
|
|
}
|
|
shapes += draw.rect(
|
|
(0, 0),
|
|
(width, -processes.len() * .5)
|
|
)
|
|
|
|
canvas(shapes)
|
|
}) |