Skip to content

Commit

Permalink
Merge branch 'system-info' into api-redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
bens committed Mar 17, 2024
2 parents a992d41 + 59f8d7a commit 59e0ebe
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 71 deletions.
1 change: 0 additions & 1 deletion examples/basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ test "bench test basic" {
});

const sysinfo = try bench.getSystemInfo();
defer sysinfo.deinit();
try std.fmt.format(stdout, "\n{}\n", .{sysinfo});

const results = try bench.run();
Expand Down
41 changes: 24 additions & 17 deletions util/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,56 @@ const fs = std.fs;
const mem = std.mem;
const log = std.log.scoped(.zbench_platform_linux);

pub fn getCpuName(allocator: mem.Allocator) ![]const u8 {
pub fn getCpuName(allocator: std.mem.Allocator) ![]const u8 {
const file = try fs.cwd().openFile("/proc/cpuinfo", .{});
defer file.close();

var buf: [128]u8 = undefined;
_ = try file.read(&buf);
const buf = try allocator.alloc(u8, 1024);
_ = try file.read(buf);

const start = if (mem.indexOf(u8, &buf, "model name")) |pos| pos + 13 else 0;
const end = if (mem.indexOfScalar(u8, buf[start..], '\n')) |pos| start + pos else 0;
const needle = "model name";
const start = if (mem.indexOf(u8, buf, needle)) |pos|
pos + needle.len + 3
else
return error.CouldNotFindCpuName;

if ((start == 0 and end == 0) or (start > end)) {
const len = if (mem.indexOfScalar(u8, buf[start..], '\n')) |pos|
pos
else
return error.CouldNotFindCpuName;
}

return allocator.dupe(u8, buf[start..end]);
return buf[start..][0..len];
}

pub fn getCpuCores() !u32 {
pub fn getCpuCores(allocator: std.mem.Allocator) !u32 {
const file = try fs.cwd().openFile("/proc/cpuinfo", .{});
defer file.close();

var buf: [1024]u8 = undefined;
_ = try file.read(&buf);
const buf = try allocator.alloc(u8, 1024);
_ = try file.read(buf);

var token_iterator = std.mem.tokenizeSequence(u8, &buf, "\n");
var token_iterator = std.mem.tokenizeSequence(u8, buf, "\n");
while (token_iterator.next()) |line| {
if (std.mem.startsWith(u8, line, "cpu cores")) {
const start = if (mem.indexOf(u8, line, ":")) |pos| pos + 2 else 0;
return try std.fmt.parseInt(u32, line[start..], 10);
return std.fmt.parseInt(u32, line[start..], 10) catch |err| {
log.err("Error parsing total memory size: {}\n", .{err});
return err;
};
}
}

return error.CouldNotFindNumCores;
}

pub fn getTotalMemory() !u64 {
pub fn getTotalMemory(allocator: std.mem.Allocator) !u64 {
const file = try std.fs.cwd().openFile("/proc/meminfo", .{});
defer file.close();

var buf: [128]u8 = undefined;
_ = try file.read(&buf);
const buf: []u8 = try allocator.alloc(u8, 1024);
_ = try file.read(buf);

var token_iterator = std.mem.tokenizeSequence(u8, &buf, "\n");
var token_iterator = std.mem.tokenizeSequence(u8, buf, "\n");
while (token_iterator.next()) |line| {
if (std.mem.startsWith(u8, line, "MemTotal:")) {
// Extract the numeric value from the line
Expand Down
13 changes: 4 additions & 9 deletions util/os/osx.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,16 @@ pub fn getCpuName(allocator: std.mem.Allocator) ![]const u8 {
}

pub fn getCpuCores(allocator: std.mem.Allocator) !u32 {
const coresString = try exec(allocator, &.{ "sysctl", "-n", "hw.physicalcpu" });
defer allocator.free(coresString);

return std.fmt.parseInt(u32, coresString, 10) catch |err| {
const str = try exec(allocator, &.{ "sysctl", "-n", "hw.physicalcpu" });
return std.fmt.parseInt(u32, str, 10) catch |err| {
log.err("Error parsing CPU cores count: {}\n", .{err});
return err;
};
}

pub fn getTotalMemory(allocator: std.mem.Allocator) !u64 {
const memSizeString = try exec(allocator, &.{ "sysctl", "-n", "hw.memsize" });
defer allocator.free(memSizeString);

// Parse the string to a 64-bit unsigned integer
return std.fmt.parseInt(u64, memSizeString, 10) catch |err| {
const str = try exec(allocator, &.{ "sysctl", "-n", "hw.memsize" });
return std.fmt.parseInt(u64, str, 10) catch |err| {
log.err("Error parsing total memory size: {}\n", .{err});
return err;
};
Expand Down
92 changes: 50 additions & 42 deletions util/platform.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@ const lnx = @import("os/linux.zig");
const mac = @import("os/osx.zig");
const win = @import("os/windows.zig");

var cpu_name_buffer: [128]u8 = undefined;
var osinfo: ?OsInfo = null;

pub const OsInfo = struct {
allocator: std.mem.Allocator,
platform: []const u8,
cpu: []const u8,
cpu_cores: u32,
memory_total: []const u8,
memory_total: u64,
// ... other system information

pub fn deinit(self: OsInfo) void {
self.allocator.free(self.cpu);
self.allocator.free(self.memory_total);
}

pub fn format(
info: OsInfo,
comptime _: []const u8,
Expand All @@ -30,60 +27,71 @@ pub const OsInfo = struct {
\\ Operating System: {s}
\\ CPU: {s}
\\ CPU Cores: {d}
\\ Total Memory: {s}
\\ Total Memory: {d:.3}
\\
, .{
info.platform,
info.cpu,
info.cpu_cores,
info.memory_total,
std.fmt.fmtIntSizeBin(info.memory_total),
});
}
};

const platform = @tagName(builtin.os.tag) ++ " " ++ @tagName(builtin.cpu.arch);

pub fn getSystemInfo(allocator: std.mem.Allocator) !OsInfo {
return switch (builtin.os.tag) {
.linux => try linux(allocator),
.macos => try macos(allocator),
.windows => try windows(allocator),
else => error.UnsupportedOs,
pub fn getSystemInfo() !OsInfo {
if (osinfo) |x| return x;
osinfo = OsInfo{
.platform = platform,
.cpu = try getCpuName(),
.cpu_cores = try getCpuCores(),
.memory_total = try getTotalMemory(),
};
return osinfo.?;
}

pub fn linux(allocator: std.mem.Allocator) !OsInfo {
const memory = try lnx.getTotalMemory();

return OsInfo{
.allocator = allocator,
.platform = platform,
.cpu = try lnx.getCpuName(allocator),
.cpu_cores = try lnx.getCpuCores(),
.memory_total = try format.memorySize(memory, allocator),
fn getCpuName() ![]const u8 {
var scratch: [4096]u8 = undefined;
var fbs = std.heap.FixedBufferAllocator.init(&scratch);
const cpu = switch (builtin.os.tag) {
.linux => try lnx.getCpuName(fbs.allocator()),
.macos => try mac.getCpuName(fbs.allocator()),
.windows => try win.getCpuName(fbs.allocator()),
else => error.UnsupportedOs,
};
const len: usize = @min(cpu_name_buffer.len, cpu.len);
std.mem.copyForwards(u8, cpu_name_buffer[0..len], cpu[0..len]);
return cpu_name_buffer[0..len];
}

pub fn macos(allocator: std.mem.Allocator) !OsInfo {
const memory = try mac.getTotalMemory(allocator);

return OsInfo{
.allocator = allocator,
.platform = platform,
.cpu = try mac.getCpuName(allocator),
.cpu_cores = try mac.getCpuCores(allocator),
.memory_total = try format.memorySize(memory, allocator),
fn getCpuCores() !u32 {
var scratch: [4096]u8 = undefined;
var fbs = std.heap.FixedBufferAllocator.init(&scratch);
return switch (builtin.os.tag) {
.linux => try lnx.getCpuCores(fbs.allocator()),
.macos => try mac.getCpuCores(fbs.allocator()),
.windows => try win.getCpuCores(fbs.allocator()),
else => error.UnsupportedOs,
};
}

pub fn windows(allocator: std.mem.Allocator) !OsInfo {
const memory = try win.getTotalMemory(allocator);

return OsInfo{
.allocator = allocator,
.platform = platform,
.cpu = try win.getCpuName(allocator),
.cpu_cores = try win.getCpuCores(allocator),
.memory_total = try format.memorySize(memory, allocator),
fn getTotalMemory() !u64 {
var scratch: [4096]u8 = undefined;
var fbs = std.heap.FixedBufferAllocator.init(&scratch);
return switch (builtin.os.tag) {
.linux => try lnx.getTotalMemory(fbs.allocator()),
.macos => try mac.getTotalMemory(fbs.allocator()),
.windows => try win.getTotalMemory(fbs.allocator()),
else => error.UnsupportedOs,
};
}

test "OsInfo" {
// No allocator and no free needed, it's stored statically.
const sysinfo = try getSystemInfo();
try std.testing.expect(sysinfo.platform.len != 0);
try std.testing.expect(sysinfo.cpu.len != 0);
try std.testing.expect(0 < sysinfo.cpu_cores);
try std.testing.expect(0 < sysinfo.memory_total);
}
4 changes: 2 additions & 2 deletions zbench.zig
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ pub const Benchmark = struct {
}

/// Get a copy of the system information, cpu type, cores, memory, etc.
pub fn getSystemInfo(self: Benchmark) !platform.OsInfo {
return try platform.getSystemInfo(self.allocator);
pub fn getSystemInfo(_: Benchmark) !platform.OsInfo {
return try platform.getSystemInfo();
}
};

Expand Down

0 comments on commit 59e0ebe

Please sign in to comment.