#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) })