mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 23:58:21 +00:00
refactor(ke): remove console abstraction
This commit is contained in:
+19
-60
@@ -5,48 +5,25 @@ const pl = b.pl;
|
|||||||
const ke = b.ke;
|
const ke = b.ke;
|
||||||
const ki = ke.private;
|
const ki = ke.private;
|
||||||
|
|
||||||
var console_lock = ke.SpinLock.init();
|
const DebugWriter = struct {
|
||||||
var console_list: rtl.List = .{ .head = .{ .next = &console_list.head, .prev = &console_list.head } };
|
|
||||||
|
|
||||||
/// Represents a console device.
|
|
||||||
/// This is used as an output device.
|
|
||||||
pub const Console = struct {
|
|
||||||
last_seq: u64,
|
|
||||||
write: WriteFn,
|
|
||||||
link: rtl.List.Entry,
|
|
||||||
pub const WriteFn = *const fn (self: *Console, data: []const u8) void;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Register a console.
|
|
||||||
pub fn register_console(console: *Console) void {
|
|
||||||
const ipl = console_lock.acquire();
|
|
||||||
console_list.insert_tail(&console.link);
|
|
||||||
console_lock.release(ipl);
|
|
||||||
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConsoleWriter = struct {
|
|
||||||
interface: std.Io.Writer,
|
interface: std.Io.Writer,
|
||||||
console: *Console,
|
|
||||||
|
|
||||||
pub fn init(console: *Console) ConsoleWriter {
|
pub fn init() DebugWriter {
|
||||||
return .{
|
return .{
|
||||||
.interface = .{
|
.interface = .{
|
||||||
.vtable = &.{ .drain = drain },
|
.vtable = &.{ .drain = drain },
|
||||||
.buffer = &.{},
|
.buffer = &.{},
|
||||||
.end = 0,
|
.end = 0,
|
||||||
},
|
},
|
||||||
.console = console,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain(w: *std.Io.Writer, data: []const []const u8, _: usize) std.Io.Writer.Error!usize {
|
fn drain(_: *std.Io.Writer, data: []const []const u8, _: usize) std.Io.Writer.Error!usize {
|
||||||
const self: *ConsoleWriter = @fieldParentPtr("interface", w);
|
|
||||||
|
|
||||||
var total_written: usize = 0;
|
var total_written: usize = 0;
|
||||||
for (data) |slice| {
|
for (data) |slice| {
|
||||||
self.console.write(self.console, slice);
|
for (slice) |byte| {
|
||||||
|
pl.impl.debug_write(byte);
|
||||||
|
}
|
||||||
total_written += slice.len;
|
total_written += slice.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,32 +33,6 @@ const ConsoleWriter = struct {
|
|||||||
|
|
||||||
var ringbuffer = ki.log_ring.RingBuffer(14, 5).init();
|
var ringbuffer = ki.log_ring.RingBuffer(14, 5).init();
|
||||||
|
|
||||||
fn flush() void {
|
|
||||||
var buf: [512]u8 = undefined;
|
|
||||||
|
|
||||||
// Note: we trylock here because if the lock is already held, that means
|
|
||||||
// someone else is already flushing the logs.
|
|
||||||
if (console_lock.try_acquire()) |ipl| {
|
|
||||||
var it = console_list.iterator();
|
|
||||||
|
|
||||||
while (it.next()) : (it.advance()) {
|
|
||||||
const console: *Console = @fieldParentPtr("link", it.get());
|
|
||||||
var writer = ConsoleWriter.init(console);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const info = ringbuffer.read(console.last_seq, &buf) catch break;
|
|
||||||
|
|
||||||
writer.interface.print("[{:>5}.{:06}] ", .{ info.timestamp / std.time.ns_per_s, info.timestamp / std.time.ns_per_us }) catch break;
|
|
||||||
console.write(console, buf[0..info.length]);
|
|
||||||
|
|
||||||
console.last_seq = info.sequence + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console_lock.release(ipl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log(
|
pub fn log(
|
||||||
comptime level: std.log.Level,
|
comptime level: std.log.Level,
|
||||||
comptime scope: @EnumLiteral(),
|
comptime scope: @EnumLiteral(),
|
||||||
@@ -91,17 +42,25 @@ pub fn log(
|
|||||||
_ = level;
|
_ = level;
|
||||||
_ = scope;
|
_ = scope;
|
||||||
|
|
||||||
var discarder: std.Io.Writer.Discarding = .init(&.{});
|
// Calculate the length required.
|
||||||
discarder.writer.print(fmt ++ "\n", args) catch return;
|
const required_len = std.fmt.count(fmt ++ "\n", args);
|
||||||
|
|
||||||
var res = ringbuffer.reserve(discarder.fullCount()) catch return;
|
// Reserve space in the ring buffer.
|
||||||
|
var res = ringbuffer.reserve(required_len) catch return;
|
||||||
|
|
||||||
res.info.timestamp = ke.time.read_time_nano();
|
res.info.timestamp = ke.time.read_time_nano();
|
||||||
res.info.length = @truncate(discarder.fullCount());
|
res.info.length = @truncate(required_len);
|
||||||
|
|
||||||
|
// Format the log message into the reserved buffer.
|
||||||
res.buf = std.fmt.bufPrint(res.buf, fmt ++ "\n", args) catch return;
|
res.buf = std.fmt.bufPrint(res.buf, fmt ++ "\n", args) catch return;
|
||||||
|
|
||||||
ringbuffer.publish(res);
|
ringbuffer.publish(res);
|
||||||
|
|
||||||
flush();
|
// TODO: for now, we print to the platform's debug output immediately.
|
||||||
|
// In the future, we should instead set an event that would get triggered in Ex,
|
||||||
|
// which would consume the ringbuffer from multiple consoles in a separate thread.
|
||||||
|
var writer = DebugWriter.init();
|
||||||
|
|
||||||
|
writer.interface.print("[{:>5}.{:06}] ", .{ res.info.timestamp / std.time.ns_per_s, res.info.timestamp / std.time.ns_per_us }) catch return;
|
||||||
|
_ = writer.interface.writeAll(res.buf[0..res.info.length]) catch return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ pub threadlocal var my_cpu: *ke.Cpu = undefined;
|
|||||||
|
|
||||||
pub fn devices_init() void {}
|
pub fn devices_init() void {}
|
||||||
|
|
||||||
fn debug_write(_: *ke.Console, buf: []const u8) void {
|
pub fn debug_write(char: u8) void {
|
||||||
_ = linux.write(1, buf.ptr, @intCast(buf.len));
|
_ = linux.write(linux.STDERR_FILENO, @ptrCast(&char), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const arm_timer = timer.arm_timer;
|
pub const arm_timer = timer.arm_timer;
|
||||||
@@ -60,12 +60,6 @@ const bootstrap_offsets = [1]usize{0};
|
|||||||
|
|
||||||
pub var cpu_offsets: []usize = undefined;
|
pub var cpu_offsets: []usize = undefined;
|
||||||
|
|
||||||
var early_console: ke.Console = .{
|
|
||||||
.write = debug_write,
|
|
||||||
.last_seq = 0,
|
|
||||||
.link = undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn early_init() linksection(b.init) void {
|
pub fn early_init() linksection(b.init) void {
|
||||||
// Ensure we can use per-cpu data.
|
// Ensure we can use per-cpu data.
|
||||||
cpu_offsets = @constCast(&bootstrap_offsets);
|
cpu_offsets = @constCast(&bootstrap_offsets);
|
||||||
@@ -106,8 +100,6 @@ pub fn early_init() linksection(b.init) void {
|
|||||||
b.kernel_heap_base = heap_base;
|
b.kernel_heap_base = heap_base;
|
||||||
|
|
||||||
std.log.info("um: kernel heap lives at {X}", .{heap_base});
|
std.log.info("um: kernel heap lives at {X}", .{heap_base});
|
||||||
|
|
||||||
ke.log.register_console(&early_console);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sigusr1_handler(_: posix.SIG, _: *const posix.siginfo_t, _: ?*anyopaque) callconv(.c) void {
|
fn sigusr1_handler(_: posix.SIG, _: *const posix.siginfo_t, _: ?*anyopaque) callconv(.c) void {
|
||||||
|
|||||||
Reference in New Issue
Block a user