Unknown state [2025-08-04]
This commit is contained in:
1
statusline/.tool-versions
Normal file
1
statusline/.tool-versions
Normal file
@@ -0,0 +1 @@
|
||||
zig 0.15.0-dev.905+edf785db0
|
79
statusline/Cpu.zig
Normal file
79
statusline/Cpu.zig
Normal file
@@ -0,0 +1,79 @@
|
||||
const std = @import("std");
|
||||
const Self = @This();
|
||||
|
||||
fh: std.fs.File,
|
||||
buf: []u8,
|
||||
stats: Stats,
|
||||
perc: u8 = 0,
|
||||
|
||||
pub fn init(self: *Self, alloc: std.mem.Allocator) !void {
|
||||
self.fh = try std.fs.openFileAbsolute("/proc/stat", .{ .mode = .read_only });
|
||||
errdefer self.fh.close();
|
||||
|
||||
self.buf = try alloc.alloc(u8, 256);
|
||||
errdefer alloc.free(self.buf);
|
||||
|
||||
self.stats = try self.get();
|
||||
}
|
||||
|
||||
pub const Stats = struct {
|
||||
all: u32,
|
||||
all_idle: u32,
|
||||
all_active: u32,
|
||||
};
|
||||
|
||||
pub fn update(self: *Self) ![]const u8 {
|
||||
const delta = try self.get_delta();
|
||||
if (delta.all != 0) {
|
||||
self.perc = @intCast(@divFloor(1 + 2 * 100 * delta.all_active, 2 * delta.all));
|
||||
}
|
||||
return try std.fmt.bufPrint(self.buf, "cpu: {d:0>2}%", .{self.perc});
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self, alloc: std.mem.Allocator) void {
|
||||
self.fh.close();
|
||||
alloc.free(self.buf);
|
||||
}
|
||||
|
||||
fn get(self: Self) !Stats {
|
||||
try self.fh.seekTo(0);
|
||||
const line = try self.fh.reader().readUntilDelimiter(self.buf, '\n');
|
||||
|
||||
var tokens = std.mem.tokenizeScalar(u8, line, ' ');
|
||||
_ = tokens.next(); // skip "cpu"
|
||||
|
||||
var raw: struct {
|
||||
user: u32,
|
||||
nice: u32,
|
||||
system: u32,
|
||||
idle: u32,
|
||||
iowait: u32,
|
||||
irq: u32,
|
||||
softirq: u32,
|
||||
steal: u32,
|
||||
guest: u32,
|
||||
guest_nice: u32,
|
||||
} = undefined;
|
||||
|
||||
inline for (std.meta.fields(@TypeOf(raw))) |f| {
|
||||
const token = tokens.next() orelse return error.MissingStat;
|
||||
@field(raw, f.name) = try std.fmt.parseInt(f.type, token, 10);
|
||||
}
|
||||
|
||||
const idle = raw.idle + raw.iowait;
|
||||
const active = raw.user + raw.nice + raw.system + raw.irq + raw.softirq + raw.steal;
|
||||
|
||||
return .{ .all = idle + active, .all_idle = idle, .all_active = active };
|
||||
}
|
||||
|
||||
fn get_delta(self: *Self) !Stats {
|
||||
const prev = self.stats;
|
||||
const next = try self.get();
|
||||
self.stats = next;
|
||||
|
||||
return .{
|
||||
.all = next.all - prev.all,
|
||||
.all_idle = next.all_idle - prev.all_idle,
|
||||
.all_active = next.all_active - prev.all_active,
|
||||
};
|
||||
}
|
58
statusline/Mem.zig
Normal file
58
statusline/Mem.zig
Normal file
@@ -0,0 +1,58 @@
|
||||
const std = @import("std");
|
||||
const Self = @This();
|
||||
|
||||
fh: std.fs.File,
|
||||
dat: []u8,
|
||||
buf: []u8,
|
||||
perc: u8 = 0,
|
||||
|
||||
pub fn init(self: *Self, alloc: std.mem.Allocator) !void {
|
||||
self.fh = try std.fs.openFileAbsolute("/proc/meminfo", .{ .mode = .read_only });
|
||||
errdefer self.fh.close();
|
||||
|
||||
self.dat = try alloc.alloc(u8, 256);
|
||||
errdefer alloc.free(self.dat);
|
||||
|
||||
self.buf = try alloc.alloc(u8, 256);
|
||||
errdefer alloc.free(self.buf);
|
||||
}
|
||||
|
||||
pub fn update(self: *Self) ![]const u8 {
|
||||
try self.fh.seekTo(0);
|
||||
var br = std.io.bufferedReader(self.fh.reader());
|
||||
const reader = br.reader();
|
||||
|
||||
var total: u32 = undefined;
|
||||
var free: u32 = undefined;
|
||||
var avail: u32 = undefined;
|
||||
|
||||
for (0..3) |_| {
|
||||
const line = try reader.readUntilDelimiterOrEof(self.dat, '\n');
|
||||
var tokens = std.mem.tokenizeAny(u8, line.?, ": ");
|
||||
|
||||
const label = tokens.next().?;
|
||||
const value = try std.fmt.parseInt(u32, tokens.next().?, 10);
|
||||
|
||||
if (std.mem.eql(u8, label, "MemTotal")) {
|
||||
total = value;
|
||||
} else if (std.mem.eql(u8, label, "MemFree")) {
|
||||
free = value;
|
||||
} else if (std.mem.eql(u8, label, "MemAvailable")) {
|
||||
avail = value;
|
||||
}
|
||||
}
|
||||
|
||||
const perc_used: u8 = @intCast(@divFloor(1 + 2 * 100 * (total - avail), 2 * total));
|
||||
|
||||
return try std.fmt.bufPrint(
|
||||
self.buf,
|
||||
"mem: {d: >2}%",
|
||||
.{perc_used},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self, alloc: std.mem.Allocator) void {
|
||||
self.fh.close();
|
||||
alloc.free(self.dat);
|
||||
alloc.free(self.buf);
|
||||
}
|
29
statusline/Time.zig
Normal file
29
statusline/Time.zig
Normal file
@@ -0,0 +1,29 @@
|
||||
const std = @import("std");
|
||||
const Self = @This();
|
||||
|
||||
const time = @cImport({
|
||||
@cInclude("time.h");
|
||||
});
|
||||
|
||||
buf: []u8,
|
||||
|
||||
pub fn init(self: *Self, alloc: std.mem.Allocator) !void {
|
||||
self.buf = try alloc.alloc(u8, 64);
|
||||
errdefer alloc.free(self.buf);
|
||||
}
|
||||
|
||||
pub fn update(self: *Self) ![]const u8 {
|
||||
const tt: time.time_t = time.time(null);
|
||||
const tp = time.localtime(&tt);
|
||||
const n = time.strftime(
|
||||
self.buf.ptr,
|
||||
self.buf.len,
|
||||
"%c",
|
||||
tp,
|
||||
);
|
||||
return self.buf[0..n];
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, alloc: std.mem.Allocator) void {
|
||||
alloc.free(self.buf);
|
||||
}
|
95
statusline/cpu.bak.zig
Normal file
95
statusline/cpu.bak.zig
Normal file
@@ -0,0 +1,95 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
const RawStats = struct {
|
||||
user: u32,
|
||||
nice: u32,
|
||||
system: u32,
|
||||
idle: u32,
|
||||
iowait: u32,
|
||||
irq: u32,
|
||||
softirq: u32,
|
||||
steal: u32,
|
||||
guest: u32,
|
||||
guest_nice: u32,
|
||||
};
|
||||
|
||||
pub const Stats = struct {
|
||||
all: u32,
|
||||
all_idle: u32,
|
||||
all_active: u32,
|
||||
|
||||
pub fn active_ratio(self: Stats) f32 {
|
||||
return @as(f32, @floatFromInt(self.all_active)) / @as(f32, @floatFromInt(self.all));
|
||||
}
|
||||
|
||||
pub fn active_perc(self: Stats) u8 {
|
||||
return @intCast(100 * self.all_active / self.all);
|
||||
}
|
||||
};
|
||||
|
||||
fh: std.fs.File,
|
||||
buf: []u8,
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator) !Self {
|
||||
const fh = try std.fs.openFileAbsolute("/proc/stat", .{ .mode = .read_only });
|
||||
errdefer fh.close();
|
||||
|
||||
const buf = try alloc.alloc(u8, 512);
|
||||
errdefer alloc.free(buf);
|
||||
|
||||
return .{ .fh = fh, .buf = buf };
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self, alloc: std.mem.Allocator) void {
|
||||
self.fh.close();
|
||||
alloc.free(self.buf);
|
||||
}
|
||||
|
||||
pub fn get(self: Self) !Stats {
|
||||
try self.fh.seekTo(0);
|
||||
const line = try self.fh.reader().readUntilDelimiter(self.buf, '\n');
|
||||
|
||||
var tokens = std.mem.tokenizeScalar(u8, line, ' ');
|
||||
_ = tokens.next(); // skip "cpu"
|
||||
|
||||
var raw: RawStats = undefined;
|
||||
|
||||
inline for (std.meta.fields(RawStats)) |f| {
|
||||
const token = tokens.next() orelse return error.MissingStat;
|
||||
@field(raw, f.name) = try std.fmt.parseInt(f.type, token, 10);
|
||||
}
|
||||
|
||||
const idle = raw.idle + raw.iowait;
|
||||
const active = raw.user + raw.nice + raw.system + raw.irq + raw.softirq + raw.steal;
|
||||
|
||||
return .{ .all = idle + active, .all_idle = idle, .all_active = active };
|
||||
}
|
||||
|
||||
pub fn get_delta(self: Self, prev: *Stats) !Stats {
|
||||
const next = try self.get();
|
||||
const delta: Stats = .{
|
||||
.all = next.all - prev.all,
|
||||
.all_idle = next.all_idle - prev.all_idle,
|
||||
.all_active = next.all_active - prev.all_active,
|
||||
};
|
||||
prev.* = next;
|
||||
return delta;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
const monitor = try Self.init(alloc);
|
||||
defer monitor.deinit(alloc);
|
||||
|
||||
var stats = try monitor.get();
|
||||
std.time.sleep(std.time.ns_per_s);
|
||||
const delta = try monitor.get_delta(&stats);
|
||||
|
||||
std.debug.print("{any}\n", .{delta});
|
||||
std.debug.print("{d:.6} {d}\n", .{ delta.active_ratio(), delta.active_perc() });
|
||||
}
|
41
statusline/main.zig
Normal file
41
statusline/main.zig
Normal file
@@ -0,0 +1,41 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Frequency = 500;
|
||||
const Mods = .{
|
||||
@import("Mem.zig"),
|
||||
@import("Cpu.zig"),
|
||||
@import("Time.zig"),
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
var mods: std.meta.Tuple(&Mods) = undefined;
|
||||
inline for (&mods) |*mod| {
|
||||
try mod.init(alloc);
|
||||
}
|
||||
defer {
|
||||
inline for (&mods) |*mod| {
|
||||
mod.deinit(alloc);
|
||||
}
|
||||
}
|
||||
|
||||
const stdout = std.io.getStdOut();
|
||||
const buffer = try alloc.alloc(u8, 512);
|
||||
defer alloc.free(buffer);
|
||||
|
||||
var outputs: [Mods.len][]const u8 = undefined;
|
||||
|
||||
while (true) {
|
||||
std.time.sleep(Frequency * std.time.ns_per_ms);
|
||||
|
||||
inline for (&mods, &outputs) |*mod, *out| {
|
||||
out.* = try mod.update();
|
||||
}
|
||||
|
||||
const output = try std.fmt.bufPrint(buffer, "{s}\n", .{outputs});
|
||||
try stdout.writeAll(output);
|
||||
}
|
||||
}
|
80
statusline/modules-wip.zig
Normal file
80
statusline/modules-wip.zig
Normal file
@@ -0,0 +1,80 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Module = struct {
|
||||
init: *const fn (std.mem.Allocator) *anyopaque,
|
||||
deinit: *const fn (*anyopaque, std.mem.Allocator) void,
|
||||
update: *const fn (*anyopaque, std.mem.Allocator) void,
|
||||
};
|
||||
|
||||
const Foo = struct {
|
||||
fn init(alloc: std.mem.Allocator) *@This() {
|
||||
return alloc.create(@This()) catch @panic("OOM");
|
||||
}
|
||||
|
||||
fn deinit(self: *@This(), alloc: std.mem.Allocator) void {
|
||||
alloc.destroy(self);
|
||||
}
|
||||
|
||||
fn update(self: *@This(), alloc: std.mem.Allocator) void {
|
||||
_ = self;
|
||||
_ = alloc;
|
||||
|
||||
std.log.debug("Hello, {s}", .{@typeName(@This())});
|
||||
}
|
||||
};
|
||||
|
||||
const Bar = struct {
|
||||
fn init(alloc: std.mem.Allocator) *@This() {
|
||||
return alloc.create(@This()) catch @panic("OOM");
|
||||
}
|
||||
|
||||
fn deinit(self: *@This(), alloc: std.mem.Allocator) void {
|
||||
alloc.destroy(self);
|
||||
}
|
||||
|
||||
fn update(self: *@This(), alloc: std.mem.Allocator) void {
|
||||
_ = self;
|
||||
_ = alloc;
|
||||
|
||||
std.log.debug("Hello, {s}", .{@typeName(@This())});
|
||||
}
|
||||
};
|
||||
|
||||
const Modules = .{
|
||||
Foo,
|
||||
Bar,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
// comptime var modules: [Modules.len]Module = undefined;
|
||||
comptime var modules: [Modules.len]type = undefined;
|
||||
|
||||
inline for (Modules, &modules) |Mod, *mod| {
|
||||
mod.* = struct {
|
||||
pub fn init(alloc: std.mem.Allocator) void {
|
||||
}
|
||||
};
|
||||
// mod.* = .{
|
||||
// .init = @ptrCast(&Mod.init),
|
||||
// .deinit = @ptrCast(&Mod.deinit),
|
||||
// .update = @ptrCast(&Mod.update),
|
||||
// };
|
||||
}
|
||||
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
var states: [Modules.len]*anyopaque = undefined;
|
||||
for (modules, &states) |mod, *state| {
|
||||
state.* = mod.init(alloc);
|
||||
}
|
||||
defer for (modules, states) |mod, state| {
|
||||
mod.deinit(state, alloc);
|
||||
};
|
||||
|
||||
std.log.debug("Performing update...", .{});
|
||||
for (modules, states) |mod, state| {
|
||||
mod.update(state, alloc);
|
||||
}
|
||||
}
|
73
statusline/status.zig
Normal file
73
statusline/status.zig
Normal file
@@ -0,0 +1,73 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Blocks = .{
|
||||
@import("Cpu.zig").block(.{}),
|
||||
@import("Cpu.zig").block(.{}), // just testing a second block
|
||||
};
|
||||
|
||||
const freq_ms = 500;
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
var blocks: std.meta.Tuple(&Blocks) = undefined;
|
||||
var arenas: [Blocks.len]std.heap.ArenaAllocator = undefined;
|
||||
var outputs: [Blocks.len][]const u8 = undefined;
|
||||
|
||||
var combined_arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer combined_arena.deinit();
|
||||
|
||||
inline for (Blocks, &blocks, &arenas) |Block, *block, *arena| {
|
||||
block.* = try Block.init(alloc);
|
||||
arena.* = std.heap.ArenaAllocator.init(alloc);
|
||||
}
|
||||
|
||||
defer inline for (blocks, arenas) |block, arena| {
|
||||
block.deinit(alloc);
|
||||
arena.deinit();
|
||||
};
|
||||
|
||||
std.time.sleep(std.time.ns_per_s);
|
||||
|
||||
inline for (&blocks, &arenas, &outputs) |*block, *arena, *output| {
|
||||
output.* = try block.update(arena.allocator());
|
||||
}
|
||||
|
||||
_ = combined_arena.reset(.retain_capacity);
|
||||
const combined = try std.mem.join(combined_arena.allocator(), " * ", &outputs);
|
||||
try std.io.getStdOut().writeAll(combined);
|
||||
try std.io.getStdOut().writeAll("\n");
|
||||
}
|
||||
|
||||
// pub fn main() !void {
|
||||
// var arenas: [Blocks.len]std.heap.ArenaAllocator = undefined;
|
||||
// inline for (&arenas) |*arena| {
|
||||
// arena.* = std.heap.ArenaAllocator.init(alloc);
|
||||
// }
|
||||
//
|
||||
// var outs: [Blocks.len][]u8 = undefined;
|
||||
//
|
||||
// var buf = std.ArrayList(u8).init(alloc);
|
||||
// defer buf.deinit();
|
||||
// try buf.ensureTotalCapacity(512);
|
||||
//
|
||||
// while (true) {
|
||||
// inline for (&blocks, &arenas, &outs) |*block, *arena, *out| {
|
||||
// arena.reset(.{ .retain_with_limit = 100 });
|
||||
// out.* = try block.update(arena.allocator());
|
||||
// }
|
||||
//
|
||||
// std.mem.join(allocator: Allocator, separator: []const u8, slices: []const []const u8)
|
||||
//
|
||||
// // try buf.resize(0);
|
||||
// // inline for (&blocks) |*block| {
|
||||
// // try block.update();
|
||||
// // try block.print(buf.fixedWriter().any());
|
||||
// // }
|
||||
// // std.debug.print("buf: {s}\n", .{buf.items});
|
||||
// //
|
||||
// // std.time.sleep(freq_ms * std.time.ns_per_ms);
|
||||
// }
|
||||
// }
|
Reference in New Issue
Block a user