LingSys
↓ 0 downloadsYour machine's memory, GPU, motherboard and network, drawn and played in the Ling design system: LingSys, a small build for USB liquid-cooler displays, LingNet for IPv4/IPv6, DNS and packets, and a LingOS edition. 64-bit and 32-bit Windows builds included.
Keywords system-monitor, visualization, network, ipv6, gpu, lcd, lingos, ling
lingfu install LingSysCode / Files (48)
src/62_board.ling
# ───────────────────────────── BOARD section ─────────────────────────────────
# Channels (rings, lanes, pulse categories): CORES, MEMBUS, PCIE, CHIPSET, STORAGE, NETWORK, THERMAL.
# Data: board.snap from sampler_hw.ps1 (Windows performance counters and SMBIOS); GPUs and memory
# traffic come from the other samplers.
fn grid_cols(n) {
bind c = floor(sqrt(n))
if c * c < n { bind c = c + 1 }
return max(c, 1)
}
# bus traces on the schematic, as flat [u, v, u, v, ...] in board units (0..1)
fn board_path(ch, variant) {
if ch == 1 {
if variant < 0.5 { return [0.435, 0.25, 0.62, 0.25] }
return [0.435, 0.35, 0.62, 0.35]
}
if ch == 2 {
if variant < 0.5 { return [0.33, 0.435, 0.33, 0.7] }
return [0.37, 0.435, 0.37, 0.8]
}
if ch == 3 { return [0.4, 0.435, 0.4, 0.6, 0.68, 0.6] }
if ch == 4 {
if variant < 0.5 { return [0.18, 0.435, 0.18, 0.5] }
return [0.84, 0.64, 0.93, 0.64]
}
if ch == 5 { return [0.76, 0.72, 0.76, 0.95, 0.035, 0.95, 0.035, 0.46] }
return [0.3, 0.3, 0.3, 0.3]
}
# the point a fraction p of the way along a path: [u, v]
fn path_pt(path, p) {
bind n = len(path) / 2 - 1
bind total = 0.0
bind i = 0
while i < n {
bind total = total + sqrt(pow(path[i * 2 + 2] - path[i * 2], 2.0) + pow(path[i * 2 + 3] - path[i * 2 + 1], 2.0))
bind i = i + 1
}
bind target = clamp(p, 0.0, 1.0) * total
bind i = 0
while i < n {
bind sl = sqrt(pow(path[i * 2 + 2] - path[i * 2], 2.0) + pow(path[i * 2 + 3] - path[i * 2 + 1], 2.0))
if target <= sl {
bind f = target / max(sl, 0.0001)
return [mix(path[i * 2], path[i * 2 + 2], f), mix(path[i * 2 + 1], path[i * 2 + 3], f)]
}
bind target = target - sl
bind i = i + 1
}
return [path[n * 2], path[n * 2 + 1]]
}
# ---- view 1: LAYOUT, a schematic of the board with live traffic on its buses
fn view_board_layout(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind en = Z[Z_ENERGY]
bind D = Z[Z_D]
bind bp = D[D_BRD]
bind gp = D[D_GPU]
bind info = bp[BP_INFO]
bind bv = bp[BP_BV]
bind cu = bp[BP_CU]
bind S = min(H - 24.0, W * 0.6)
bind x0 = 22.0
bind y0 = (H - S) / 2.0 + 6.0
# board outline, mounting holes
ink(34.0)
brect(x0, y0, S, 0.0, 0.0, 1.0, 1.0)
ink(20.0)
brect(x0, y0, S, 0.012, 0.012, 0.988, 0.988)
bind hk = 0
while hk < 6 {
bind hu = 0.04
if hk % 2 == 1 { bind hu = 0.96 }
bind hv = 0.04 + floor(hk / 2) * 0.46
ink(44.0)
draw_circle(x0 + hu * S, y0 + hv * S, S * 0.014)
draw_circle(x0 + hu * S, y0 + hv * S, S * 0.006)
bind hk = hk + 1
}
# traces
bind ch = 1
while ch < 6 {
bind vr = 0
while vr < 2 {
bind pth = board_path(ch, vr * 0.7)
col(ch, sat * 0.6, 17.0 + 22.0 * en[ch], hs)
bind q = 0
while q < len(pth) / 2 - 1 {
bline(x0, y0, S, pth[q * 2], pth[q * 2 + 1], pth[q * 2 + 2], pth[q * 2 + 3])
bind q = q + 1
}
bind vr = vr + 1
}
bind ch = ch + 1
}
# rear I/O and VRM
col(5, sat * 0.8, 38.0 + 24.0 * en[5], hs)
brect(x0, y0, S, 0.0, 0.06, 0.075, 0.46)
bind pq = 0
while pq < 6 {
bline(x0, y0, S, 0.012, 0.09 + pq * 0.058, 0.063, 0.09 + pq * 0.058)
bind pq = pq + 1
}
col(0, sat * 0.8, 26.0 + 30.0 * en[0], hs)
brect(x0, y0, S, 0.09, 0.06, 0.33, 0.115)
brect(x0, y0, S, 0.09, 0.125, 0.135, 0.44)
bhatch(x0, y0, S, 0.09, 0.06, 0.33, 0.115, 5.0 - 3.0 * en[0])
bhatch(x0, y0, S, 0.09, 0.125, 0.135, 0.44, 5.0 - 3.0 * en[0])
# CPU socket and the logical processors inside it
bind ncores = max(len(cu), 1)
bind cols = grid_cols(ncores)
bind su = 0.3
bind sv = 0.3
bind sh_ = 0.135
bind heat = en[6]
col(0, sat, 40.0 + 30.0 * heat, hs)
brect(x0, y0, S, su - sh_, sv - sh_, su + sh_, sv + sh_)
bind bk = 0.02
bind cx_ = x0 + su * S
bind cy_ = y0 + sv * S
col(0, sat * 0.8, 30.0 + 20.0 * heat, hs)
brect(x0, y0, S, su - sh_ + 0.012, sv - sh_ + 0.012, su + sh_ - 0.012, sv + sh_ - 0.012)
bind inner = (sh_ - 0.03) * 2.0
bind cell = inner / cols
bind i = 0
while i < ncores {
bind gx = i % cols
bind gy = floor(i / cols)
bind ccx = x0 + (su - sh_ + 0.03 + (gx + 0.5) * cell) * S
bind ccy = y0 + (sv - sh_ + 0.03 + (gy + 0.5) * cell) * S
bind u = cu[i] / 100.0
bind hh = cell * S * 0.4
col(0, sat, 22.0 + 66.0 * u, hs + 28.0 * u)
square(ccx, ccy, hh, 0.0)
if u > 0.2 { square(ccx, ccy, hh * u * 0.8, t * 0.5 + i) }
bind i = i + 1
}
bind nm = str_slice(info[BI_CPU], 0, 28)
ink(60.0)
daemon_text(nm, cx_ - text_w(nm, 10.0) / 2.0, y0 + (sv + sh_ + 0.025) * S, 10.0)
# memory slots
bind slots = clamp(info[BI_SLOTS], 1.0, 8.0)
bind dimms = bp[BP_DIMM]
bind order = [1, 3, 0, 2, 5, 7, 4, 6]
bind slot = 0
while slot < slots {
bind occ = 0 - 1
bind oi = 0
while oi < len(dimms) {
if oi < 8 {
if order[oi] == slot { bind occ = oi }
}
bind oi = oi + 1
}
bind u0 = 0.62 + slot * (0.34 / slots)
bind u1 = u0 + 0.026
col(1, sat * 0.8, 36.0 + 20.0 * en[1], hs)
if occ < 0 { ink(24.0) }
brect(x0, y0, S, u0, 0.06, u1, 0.46)
if occ >= 0 {
bind dm = dimms[occ]
col(1, sat, 28.0 + 30.0 * en[1], hs)
bhatch(x0, y0, S, u0, 0.06, u1, 0.46, 6.0 - 3.0 * en[1])
bind ctext = fmt_mb(dm[1] * 1024.0)
col(1, sat, 70.0, hs)
daemon_text(ctext, x0 + u0 * S + (u1 - u0) * S / 2.0 - text_w(ctext, 9.0) / 2.0, y0 + 0.485 * S, 9.0)
bind sp = num_str(round(dm[2]))
ink(52.0)
daemon_text(sp, x0 + u0 * S + (u1 - u0) * S / 2.0 - text_w(sp, 8.0) / 2.0, y0 + 0.515 * S, 8.0)
}
bind slot = slot + 1
}
# storage, chipset
col(4, sat, 40.0 + 30.0 * en[4], hs)
brect(x0, y0, S, 0.1, 0.5, 0.3, 0.54)
bhatch(x0, y0, S, 0.1, 0.5, 0.3, 0.54, 5.0 - 3.0 * en[4])
draw_circle(x0 + 0.315 * S, y0 + 0.52 * S, S * 0.007)
bind sa = 0
while sa < 5 {
brect(x0, y0, S, 0.93, 0.5 + sa * 0.07, 0.985, 0.54 + sa * 0.07)
bind sa = sa + 1
}
col(3, sat, 40.0 + 30.0 * en[3], hs)
brect(x0, y0, S, 0.68, 0.56, 0.84, 0.72)
bhatch(x0, y0, S, 0.68, 0.56, 0.84, 0.72, 6.0 - 3.0 * en[3])
col(3, sat, 80.0, hs)
daemon_text("PCH", x0 + 0.76 * S - text_w("PCH", 16.0) / 2.0, y0 + 0.64 * S, 16.0)
# PCIe slots and the cards in them
bind ngpu = gp[GP_N]
bind sl = 0
while sl < 3 {
bind sv2 = 0.68 + sl * 0.1
bind hit = 0
if sl < ngpu { bind hit = 1 }
col(2, sat * 0.8, 30.0 + 26.0 * en[2], hs)
if hit == 0 { ink(22.0) }
brect(x0, y0, S, 0.07, sv2 - 0.007, 0.5, sv2 + 0.007)
bline(x0, y0, S, 0.4, sv2 - 0.007, 0.4, sv2 + 0.007)
if hit == 1 {
bind gv = gp[GP_VEC][sl]
bind gu = gv[GV_UTIL] / 100.0
col(sl % 7 + 2, sat, 40.0 + 40.0 * gu, hs)
brect(x0, y0, S, 0.065, sv2 - 0.052, 0.53, sv2 - 0.012)
bhatch(x0, y0, S, 0.065, sv2 - 0.052, 0.53, sv2 - 0.012, 7.0 - 5.0 * gu)
bind gl = "GPU" + num_str(sl) + " " + short_gpu(gp[GP_NAME][sl]) + " " + pct(gv[GV_UTIL]) + "%"
col(sl % 7 + 2, sat, 86.0, hs)
daemon_text(gl, x0 + 0.08 * S, y0 + (sv2 - 0.032) * S, 11.0)
ink(55.0)
daemon_text("GEN" + pct(gv[GV_PGEN]) + " X" + pct(gv[GV_PW]), x0 + 0.54 * S, y0 + sv2 * S, 10.0)
} else {
ink(32.0)
daemon_text("PCIE X16", x0 + 0.54 * S, y0 + sv2 * S, 10.0)
}
bind sl = sl + 1
}
# pulses: circles come in towards the CPU, squares go out from it
bind ev = Z[Z_EV]
bind j = 0
while j < len(ev) {
bind p = (t - ev[j + 2]) / 1.8
bind c = ev[j + 1]
bind a = 1.0 - p
if c == 0 {
bind pi_ = ev[j + 5]
if pi_ < ncores {
bind gx = pi_ % cols
bind gy = floor(pi_ / cols)
bind ccx = x0 + (su - sh_ + 0.03 + (gx + 0.5) * cell) * S
bind ccy = y0 + (sv - sh_ + 0.03 + (gy + 0.5) * cell) * S
col(0, sat, a * (60.0 + 38.0 * ev[j + 4]), hs)
if ev[j] == 0 { draw_circle(ccx, ccy, cell * S * (0.4 + 0.9 * p)) } else { square(ccx, ccy, cell * S * (0.8 - 0.3 * p), p * 3.0) }
}
}
if c == 6 {
col(6, sat, a * (50.0 + 40.0 * ev[j + 4]), hs)
draw_circle(cx_, cy_, S * (0.1 + 0.15 * p))
}
if c > 0 {
if c < 6 {
bind pth = board_path(c, ev[j + 3])
bind q = p
if ev[j] == 0 { bind q = 1.0 - p }
bind pt = path_pt(pth, q)
bind x = x0 + pt[0] * S
bind y = y0 + pt[1] * S
col(c, sat, 55.0 + 40.0 * ev[j + 4], hs)
if ev[j] == 0 {
draw_circle(x, y, S * 0.012)
draw_circle(x, y, S * 0.006)
} else {
square(x, y, S * 0.012, p * 3.0)
}
}
}
bind j = j + 6
}
# facts, right of the board
bind px0 = x0 + S + 36.0
bind pw = W - px0 - 18.0
bind lh = 24.0
bind ly = 40.0
bind hl = min(14.0, pw / 46.0)
tile("B", px0, ly - 18.0, 46.0, 66.0, 1, sat, hs, 0.6)
col(1, sat, 80.0, hs)
daemon_text(str_slice(info[BI_PROD], 0, 28), px0 + 62.0, ly + 6.0, min(18.0, pw / 32.0))
ink(56.0)
daemon_text(str_slice(info[BI_MAKER], 0, 30), px0 + 62.0, ly + 28.0, 11.0)
bind ly = ly + 66.0
bind facts = ["BIOS " + str_slice(info[BI_BIOSV], 0, 20) + " " + info[BI_BIOSVER] + " " + info[BI_BIOSDATE],
"CPU " + pct(info[BI_CORES]) + " CORES " + pct(info[BI_THR]) + " THREADS " + num_str(round(bv[BV_MHZ] / 100.0) / 10.0) + " GHZ",
"MEMORY " + pct(len(dimms)) + " OF " + pct(info[BI_SLOTS]) + " SLOTS MAX " + pct(info[BI_MAXGB]) + "G",
"ACPI " + num_str(round(bv[BV_TEMP] * 10.0) / 10.0) + "C UP " + fmt_up(bv[BV_UP]),
"LOAD " + pct(bv[BV_UTIL]) + "% PROCS " + pct(bv[BV_PROCS]) + " THREADS " + fmt_rate(bv[BV_THR]),
"IRQ " + fmt_rate(bv[BV_INTR]) + "/S DPC " + fmt_rate(bv[BV_DPC]) + "/S CTX " + fmt_rate(bv[BV_CTX]) + "/S"]
bind i = 0
while i < len(facts) {
ink(64.0 - 3.0 * i)
daemon_text(facts[i], px0, ly + i * lh, hl)
bind i = i + 1
}
bind ly = ly + len(facts) * lh + 14.0
col(4, sat, 70.0, hs)
daemon_text("DISKS", px0, ly, 13.0)
bind dio = bp[BP_DIO]
bind d = 0
while d < min(len(dio), 6) {
bind dd = dio[d]
bind dy = ly + 24.0 + d * 36.0
ink(62.0)
daemon_text(str_slice(dd[0], 0, 10) + " R " + fmt_bytes(dd[1]) + " W " + fmt_bytes(dd[2]), px0, dy, 12.0)
hbar(px0, dy + 16.0, pw * 0.8, dd[3] / 100.0, 4, sat, 58.0 + 20.0 * dd[3] / 100.0, hs)
ink(50.0)
daemon_text(pct(dd[3]) + "%", px0 + pw * 0.8 + 8.0, dy + 12.0, 11.0)
bind d = d + 1
}
# real sensors, only when a monitor that exposes WMI is running
bind sens = bp[BP_SENS]
if len(sens) > 0 {
bind ly = ly + 24.0 + min(len(dio), 6) * 36.0 + 10.0
col(6, sat, 70.0, hs)
daemon_text("SENSORS", px0, ly, 13.0)
bind s = 0
while s < min(len(sens), 5) {
bind sn = sens[s]
ink(60.0)
daemon_text(str_slice(sn[1], 0, 24) + " " + num_str(round(sn[2] * 10.0) / 10.0), px0, ly + 22.0 + s * 20.0, 12.0)
bind s = s + 1
}
}
}
# ---- view 2: CORES, every logical processor as a body: circle = clock, square = load
fn view_board_cores(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind cx = W / 2.0
bind cy = H / 2.0
bind R = min(W, H) * 0.5 - 20.0
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind bp = Z[Z_D][D_BRD]
bind info = bp[BP_INFO]
bind bv = bp[BP_BV]
bind cu = bp[BP_CU]
bind cf = bp[BP_CF]
bind n = max(len(cu), 1)
bind maxf = max(info[BI_MHZ] * 1.8, 1.0)
bind i = 0
while i < n {
bind maxf = max(maxf, cf[i])
bind i = i + 1
}
# Chesilin rim: the CPU, turning
bind rim = str_slice(info[BI_CPU], 0, 30) + " " + pct(info[BI_CORES]) + " CORES " + pct(info[BI_THR]) + " THREADS "
col(0, sat, 60.0, hs)
draw_circle(cx, cy, R)
draw_circle(cx, cy, R * 0.915)
ring_text(rim, cx, cy, R * 0.925, R * 0.99, Z[Z_ROT] * 0.4, 66.0, 0, sat, hs)
# hub
bind hr = R * 0.2
ink(34.0)
draw_circle(cx, cy, hr)
bind k = 0
while k < 48 {
bind a = k * TAU / 48.0 + Z[Z_ROT] * 0.5
bind tl = 5.0
if k % 4 == 0 { bind tl = 10.0 }
pline(cx, cy, hr - tl, a, hr, a)
bind k = k + 1
}
bind big = pct(bv[BV_UTIL]) + "%"
col(0, sat, 78.0, hs)
bind bh = fit_h(big, hr * 1.4, hr * 0.5)
daemon_text(big, cx - text_w(big, bh) / 2.0, cy - hr * 0.1, bh)
bind sm = num_str(round(bv[BV_MHZ] / 100.0) / 10.0) + " GHZ"
ink(58.0)
bind sh2 = fit_h(sm, hr * 1.4, hr * 0.2)
daemon_text(sm, cx - text_w(sm, sh2) / 2.0, cy + hr * 0.38, sh2)
# bodies
bind two = 0
if n > 36 { bind two = 1 }
bind pos = []
bind i = 0
while i < n {
bind rr = R * 0.74
bind m = n
bind idx = i
if two == 1 {
bind m = ceil(n / 2.0)
if i < m {
bind rr = R * 0.8
} else {
bind rr = R * 0.56
bind m = n - m
bind idx = i - ceil(n / 2.0)
}
}
bind dir = 1.0
if two == 1 {
if i >= ceil(n / 2.0) { bind dir = 0.0 - 1.0 }
}
bind a = idx * TAU / m + Z[Z_ROT] * 0.12 * dir
bind x = px(cx, rr, a)
bind y = py(cy, rr, a)
bind pos = list_push(pos, x)
bind pos = list_push(pos, y)
bind u = cu[i] / 100.0
bind fq = clamp(cf[i] / maxf, 0.0, 1.0)
bind k = floor(i * 7.0 / n)
bind r = min(R * 0.052, TAU * rr / m * 0.4) * (0.55 + 0.45 * fq)
ink(12.0 + 22.0 * u)
pline(cx, cy, hr, a, rr - r, a)
col(k, sat, 46.0 + 28.0 * u, hs)
draw_circle(x, y, r)
draw_circle(x, y, r * 0.86)
col(k, sat, 28.0 + 26.0 * u, hs)
hatch_disc(x, y, r * 0.84, ANG1[k] + Z[Z_ROT] * 0.5, max(2.2, r * 0.5 * (1.15 - u)))
col(k, sat, 78.0, hs)
square(x, y, r * 0.72 * sqrt(clamp(u, 0.04, 1.0)), t * 0.6 * dir + i)
if r > 10.0 {
col(k, sat, 90.0, hs)
daemon_text(num_str(i), x - text_w(num_str(i), r * 0.55) / 2.0, y + r * 1.5, r * 0.55)
}
bind i = i + 1
}
bind ev = Z[Z_EV]
bind j = 0
while j < len(ev) {
bind pidx = ev[j + 5]
if pidx < n {
bind p = (t - ev[j + 2]) / 1.8
bind x = pos[pidx * 2]
bind y = pos[pidx * 2 + 1]
bind k = floor(pidx * 7.0 / n)
bind r = R * 0.04
col(k, sat, (1.0 - p) * (60.0 + 38.0 * ev[j + 4]), hs)
if ev[j] == 0 {
draw_circle(x, y, r * (1.0 + 1.1 * p))
draw_circle(x, y, r * (1.0 + 0.5 * p))
} else {
square(x, y, r * (1.9 - 0.8 * p), p * 2.5)
square(x, y, r * (1.4 - 0.6 * p), 0.0 - p * 2.5)
}
}
bind j = j + 6
}
}
# ---- view 3: SIGNALS, the last minute of seven vital signs
fn view_board_signals(Z) {
bind bv = Z[Z_D][D_BRD][BP_BV]
bind titles = ["CPU LOAD", "ACPI TEMP", "INTERRUPTS", "DPCS", "CONTEXT SW", "DISK READ", "DISK WRITE"]
bind vals = [pct(bv[BV_UTIL]) + "%", num_str(round(bv[BV_TEMP] * 10.0) / 10.0) + "C", fmt_rate(bv[BV_INTR]) + "/S", fmt_rate(bv[BV_DPC]) + "/S",
fmt_rate(bv[BV_CTX]) + "/S", fmt_bytes(bv[BV_DRD]) + "/S", fmt_bytes(bv[BV_DWR]) + "/S"]
bind ids = [HS_BRD, HS_BRD + 1, HS_BRD + 2, HS_BRD + 3, HS_BRD + 4, HS_BRD + 5, HS_BRD + 6]
scope(Z, titles, "CTIDXRW", ids, vals)
}