C2: migrate consumers off the runtime shim to direct concern-module imports
Every user binary and the two device-logic library modules (pci, usb) now
`@import` the concern modules directly instead of aliasing through `runtime`:
runtime.ipc/process/time/service/input/block/display -> @import("<module>")
runtime.device / runtime.device_manager -> @import("driver")
runtime.fs -> @import("file-system")
runtime.Thread -> @import("thread").Thread
runtime.system.{write,writeRecord,klog*} -> logging.*
runtime.system.{sleep,timerOnce,wallClock,clock} -> time.*
runtime.system.{spawn*,kill,exit,yield,processes,...}-> process.*
runtime.system.{mmap,munmap,PROT_*} -> memory.*
runtime.dma.* / runtime.shared_memory.* / runtime.allocator -> memory.*
Each consumer keeps its own alias name (e.g. `const device = @import("driver")`),
so call sites are unchanged and there are no collisions with local `driver`
variables. build.zig now injects the concern modules into every user binary via
`default_imports`; pci/usb module import lists were updated to match.
The `runtime` and `system` shims remain for one more step (root.zig still uses
runtime); they are deleted in C5. Nothing but root.zig imports `runtime` now.
Verified: zig build, zig build test, and 17 QEMU cases (smoke, device-manager,
logger, fat-mount, fat-mutations, usb-storage, usb-hid, display-native,
virtio-gpu, input, thread-spawn, thread-mutex, process-kill, shared-memory,
driver-restart, acpi-ps2, pci-scan).
This commit is contained in:
@@ -16,15 +16,18 @@
|
||||
//! (docs/display-v2.md).
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const ipc = @import("ipc");
|
||||
const input = @import("input");
|
||||
const Thread = @import("thread").Thread;
|
||||
const service = @import("service");
|
||||
const time = @import("time");
|
||||
const display = @import("display");
|
||||
const memory = @import("memory");
|
||||
const logging = @import("logging");
|
||||
const compositor = @import("compositor.zig");
|
||||
const backend_mod = @import("backend.zig");
|
||||
|
||||
const display_protocol = @import("display-protocol");
|
||||
const ipc = runtime.ipc;
|
||||
const system = runtime.system;
|
||||
const input = runtime.input;
|
||||
const Thread = runtime.Thread;
|
||||
const Rect = compositor.Rect;
|
||||
const Surface = compositor.Surface;
|
||||
|
||||
@@ -105,7 +108,7 @@ fn updateFrameClock() void {
|
||||
const rate: u64 = if (reported == 0) 60 else @min(@max(reported, 30), 120);
|
||||
frame_interval_milliseconds = @max(1000 / rate, 1);
|
||||
var line: [96]u8 = undefined;
|
||||
_ = system.write(std.fmt.bufPrint(&line, "display: frame clock {d} Hz ({s})\n", .{
|
||||
_ = logging.write(std.fmt.bufPrint(&line, "display: frame clock {d} Hz ({s})\n", .{
|
||||
1000 / frame_interval_milliseconds,
|
||||
if (reported == 0) "default" else "panel EDID",
|
||||
}) catch return);
|
||||
@@ -116,7 +119,7 @@ fn updateFrameClock() void {
|
||||
fn schedulePresent() void {
|
||||
if (frame_timer_armed) return;
|
||||
frame_timer_armed = true;
|
||||
_ = system.timerOnce(service_endpoint, frame_interval_milliseconds);
|
||||
_ = time.timerOnce(service_endpoint, frame_interval_milliseconds);
|
||||
}
|
||||
|
||||
/// A timer landing — the frame clock, or the deferred first native present armed by
|
||||
@@ -177,8 +180,8 @@ fn createLayer(x: i32, y: i32, w: u32, h: u32, z: u32, visible: bool) ?u32 {
|
||||
if (w == 0 or h == 0) return null;
|
||||
const slot = freeLayer() orelse return null;
|
||||
const len = @as(usize, w) * h * 4;
|
||||
const base = system.mmap(len, system.PROT_READ | system.PROT_WRITE);
|
||||
if (system.mmapFailed(base)) return null;
|
||||
const base = memory.mmap(len, memory.PROT_READ | memory.PROT_WRITE);
|
||||
if (memory.mmapFailed(base)) return null;
|
||||
layers[slot] = .{
|
||||
.used = true,
|
||||
.x = x,
|
||||
@@ -222,7 +225,7 @@ fn configureLayer(id: u32, x: i32, y: i32, z: u32, visible: bool) bool {
|
||||
fn destroyLayer(id: u32) bool {
|
||||
const l = layerAt(id) orelse return false;
|
||||
addDamage(layerScreenRect(l));
|
||||
_ = system.munmap(@intFromPtr(l.surface.pixels), l.surface_len);
|
||||
_ = memory.munmap(@intFromPtr(l.surface.pixels), l.surface_len);
|
||||
l.* = .{};
|
||||
return true;
|
||||
}
|
||||
@@ -294,9 +297,9 @@ fn verifyNativePresent() void {
|
||||
const s = backend.surface();
|
||||
const sample = s.pixels[@as(usize, s.height / 2) * s.stride + s.width / 2];
|
||||
if (sample != 0) {
|
||||
_ = system.write("display: native present verified\n");
|
||||
_ = logging.write("display: native present verified\n");
|
||||
} else {
|
||||
_ = system.write("display: native present FAILED (blank surface)\n");
|
||||
_ = logging.write("display: native present FAILED (blank surface)\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +310,7 @@ fn verifyNativePresent() void {
|
||||
fn attachScanout(stride: u32, width: u32, height: u32, format: u32, refresh_hz: u32, capability: ?ipc.Handle, reply: []u8) usize {
|
||||
const cap = capability orelse return fail(reply);
|
||||
if (width == 0 or height == 0 or stride < width) return fail(reply);
|
||||
const mapped = runtime.shared_memory.map(cap) orelse return fail(reply);
|
||||
const mapped = memory.sharedMap(cap) orelse return fail(reply);
|
||||
const scanout = ipc.lookup(.scanout) orelse return fail(reply);
|
||||
// A second announce means the driver died and was restarted (V6): re-attach to its fresh
|
||||
// scanout. (The previous shared mapping leaks — there is no shared_memory_unmap syscall yet — but the
|
||||
@@ -331,8 +334,8 @@ fn attachScanout(stride: u32, width: u32, height: u32, format: u32, refresh_hz:
|
||||
addDamage(screenRect()); // the whole new surface must be painted
|
||||
pending_native_verify = true;
|
||||
if (!reattach) pending_modeset_check = true; // the mode-set self-check runs once, on first upgrade
|
||||
_ = system.timerOnce(service_endpoint, 50); // present once the driver is serving .scanout
|
||||
_ = system.write(if (reattach)
|
||||
_ = time.timerOnce(service_endpoint, 50); // present once the driver is serving .scanout
|
||||
_ = logging.write(if (reattach)
|
||||
"display: scanout re-attached\n"
|
||||
else
|
||||
"display: scanout upgraded to virtio-gpu\n");
|
||||
@@ -349,7 +352,7 @@ fn modesetSelfCheck() void {
|
||||
var mode_list: [4]backend_mod.Mode = undefined;
|
||||
const count = backend.modes(&mode_list);
|
||||
if (count == 0) {
|
||||
_ = system.write("display: mode-set self-check: no modes reported\n");
|
||||
_ = logging.write("display: mode-set self-check: no modes reported\n");
|
||||
return;
|
||||
}
|
||||
const current = backend.info();
|
||||
@@ -361,11 +364,11 @@ fn modesetSelfCheck() void {
|
||||
}
|
||||
}
|
||||
const wanted = target orelse {
|
||||
_ = system.write("display: mode-set self-check: no alternate mode offered\n");
|
||||
_ = logging.write("display: mode-set self-check: no alternate mode offered\n");
|
||||
return;
|
||||
};
|
||||
if (!backend.setMode(wanted.width, wanted.height)) {
|
||||
_ = system.write("display: mode set FAILED\n");
|
||||
_ = logging.write("display: mode set FAILED\n");
|
||||
return;
|
||||
}
|
||||
addDamage(screenRect()); // repaint the whole screen at the new resolution, then present it
|
||||
@@ -374,10 +377,10 @@ fn modesetSelfCheck() void {
|
||||
const now = backend.info();
|
||||
if (now.width == wanted.width and now.height == wanted.height) {
|
||||
var line: [80]u8 = undefined;
|
||||
_ = system.write(std.fmt.bufPrint(&line, "display: mode set to {d}x{d}, verified\n", .{ now.width, now.height }) catch "display: mode set, verified\n");
|
||||
if (backend.hasFencedPresent()) _ = system.write("display: fenced present ok\n");
|
||||
_ = logging.write(std.fmt.bufPrint(&line, "display: mode set to {d}x{d}, verified\n", .{ now.width, now.height }) catch "display: mode set, verified\n");
|
||||
if (backend.hasFencedPresent()) _ = logging.write("display: fenced present ok\n");
|
||||
} else {
|
||||
_ = system.write("display: mode set FAILED (geometry unchanged)\n");
|
||||
_ = logging.write("display: mode set FAILED (geometry unchanged)\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,14 +409,14 @@ fn selfCheck() void {
|
||||
present(); // repaint the self-check region back to the background
|
||||
|
||||
if (overlap == green and bottom_only == red) {
|
||||
_ = system.write("display: compositor self-check ok\n");
|
||||
_ = logging.write("display: compositor self-check ok\n");
|
||||
} else {
|
||||
_ = system.write("display: compositor self-check FAILED\n");
|
||||
_ = logging.write("display: compositor self-check FAILED\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_check(_: []const u8) void {
|
||||
_ = system.write("display: compositor self-check FAILED (setup)\n");
|
||||
_ = logging.write("display: compositor self-check FAILED (setup)\n");
|
||||
}
|
||||
|
||||
// --- cursor + mouse-input thread --------------------------------------------
|
||||
@@ -499,7 +502,7 @@ fn clampAxis(value: i32, max: i32) i32 {
|
||||
/// compositor — so no lock guards the framebuffer.
|
||||
fn mouseListener(width: u32, height: u32) void {
|
||||
var mouse = input.subscribeMouse() orelse {
|
||||
_ = system.write("display: mouse subscribe failed\n");
|
||||
_ = logging.write("display: mouse subscribe failed\n");
|
||||
return;
|
||||
};
|
||||
// Our own handle to the compositor's endpoint. IPC handles are per-thread, so we
|
||||
@@ -507,7 +510,7 @@ fn mouseListener(width: u32, height: u32) void {
|
||||
// handle in this thread's table. A poke posted here wakes the compositor loop parked
|
||||
// in replyWait (docs/threading.md: handles do not cross threads).
|
||||
cursor_channel.poke_endpoint = ipc.lookup(.display) orelse {
|
||||
_ = system.write("display: mouse listener could not reach the compositor endpoint\n");
|
||||
_ = logging.write("display: mouse listener could not reach the compositor endpoint\n");
|
||||
return;
|
||||
};
|
||||
const max_x: i32 = @as(i32, @intCast(width)) - 1;
|
||||
@@ -543,7 +546,7 @@ fn renderCursor() void {
|
||||
@abs(snapshot.y - cursor_origin_y) >= cursor_report_threshold)
|
||||
{
|
||||
cursor_tracking_reported = true;
|
||||
_ = system.write("display: cursor tracking mouse ok\n");
|
||||
_ = logging.write("display: cursor tracking mouse ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,7 +558,7 @@ fn startCursorTracking() void {
|
||||
cursor_origin_x = @divTrunc(@as(i32, @intCast(mode.width)), 2);
|
||||
cursor_origin_y = @divTrunc(@as(i32, @intCast(mode.height)), 2);
|
||||
const id = createLayer(cursor_origin_x, cursor_origin_y, cursor_size, cursor_size, cursor_z, true) orelse {
|
||||
_ = system.write("display: could not create cursor layer\n");
|
||||
_ = logging.write("display: could not create cursor layer\n");
|
||||
return;
|
||||
};
|
||||
cursor_layer = id;
|
||||
@@ -563,7 +566,7 @@ fn startCursorTracking() void {
|
||||
present(); // show the cursor at its start position
|
||||
|
||||
_ = Thread.spawn(.{}, mouseListener, .{ mode.width, mode.height }) catch {
|
||||
_ = system.write("display: could not spawn mouse listener\n");
|
||||
_ = logging.write("display: could not spawn mouse listener\n");
|
||||
};
|
||||
}
|
||||
|
||||
@@ -583,11 +586,11 @@ fn initialise(endpoint: ipc.Handle) bool {
|
||||
present();
|
||||
|
||||
var line: [96]u8 = undefined;
|
||||
_ = system.write(std.fmt.bufPrint(&line, "display: online {d}x{d} pitch {d} format {d}\n", .{
|
||||
_ = logging.write(std.fmt.bufPrint(&line, "display: online {d}x{d} pitch {d} format {d}\n", .{
|
||||
mode.width, mode.height, mode.pitch, mode.format,
|
||||
}) catch "display: online\n");
|
||||
updateFrameClock();
|
||||
_ = system.write("display: presented frame 0\n");
|
||||
_ = logging.write("display: presented frame 0\n");
|
||||
|
||||
selfCheck();
|
||||
|
||||
@@ -692,7 +695,7 @@ fn onNotification(badge: u64) void {
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
runtime.service.run(display_protocol.message_maximum, .{
|
||||
service.run(display_protocol.message_maximum, .{
|
||||
.service = .display,
|
||||
.init = initialise,
|
||||
.on_message = onMessage,
|
||||
|
||||
Reference in New Issue
Block a user