灵符lingfu

LingSys

↓ 0 downloads

Your 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 LingSys
LicenseMIT
AuthorsLing Lin <taellinglin@gmail.com>
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / 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)
}

← Back to index