ref: 254640059611d64a97b82cc8b20bf759eccc6806
dir: /mbld/build.myr/
use std use "config" use "opts" use "types" use "util" pkg bld = const buildtarg : (b : build#, targ : byte[:] -> bool) const clean : (b : build# -> bool) ;; const buildtarg = {b, targ var g g = b.deps var outs = std.htgetv(g.targs, targ, [][:]) for o : outs mark(b, o) ;; build(b, g) -> true } const clean = {b for n : b.deps.nodes if n.durable continue ;; for g : n.gen if std.remove(g) mbldput("\tclean {}\n", g) ;; ;; ;; -> true } const mark = {b, o if o.want -> void ;; o.want = true for n : o.ndep mark(b, n) ;; } const build = {b, g for n : g.leaves if n.want stale(b, n) unblock(b, n) ;; ;; while std.htcount(b.proc) != 0 || b.queue.len != 0 while std.htcount(b.proc) < opt_maxproc && b.queue.len > 0 launch(b, std.slpop(&b.queue)) ;; wait(b) ;; } const launch = {b, n var pid if stale(b, n) pid = run(n.cmd, "") std.htput(b.proc, pid, n) else unblock(b, n) ;; } const wait = {b var pp : std.pid if std.htcount(b.proc) == 0 -> void ;; match std.waitany() | (p, `std.Wfailure): std.fatal("FAIL: {j= }\n", proclbl(b, p)) | (p, `std.Wsignalled): std.fatal("CRASH: {j= }\n", proclbl(b, p)) | (p, `std.Waiterror): std.fatal("WAT: {j= }\n", proclbl(b, p)) | (p, `std.Wsuccess): pp = p match std.htget(b.proc, p) | `std.None: std.fatal("followed home by stray pid {}\n", p) | `std.Some n: n.mtime = std.now() std.htdel(b.proc, p) unblock(b, n) ;; ;; } const proclbl = {b, pid match std.htget(b.proc, pid) | `std.Some n: -> n.cmd | `std.None: -> std.sldup(["?unknown?"][:]) ;; } const unblock = {b, n for g : n.ngen std.assert(g.nblock != 0, "bogus unblock {} from {}\n", g.lbl, n.lbl) g.nblock-- if g.nblock == 0 && g.want std.slpush(&b.queue, g) ;; ;; } const stale = {b, n var staletime staletime = 0 for d : n.ndep staletime = std.max(staletime, d.mtime) ;; n.mtime = std.now() for g : n.gen match std.fmtime(g) | `std.Ok tm: n.mtime = std.min(n.mtime, tm) | `std.Err e: n.mtime = 0 ;; ;; -> staletime > n.mtime }