mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std: add os.linux.sysinfo(), use it for process.totalSystemMemory()
Co-authored-by: Alex Rønne Petersen <alex@alexrp.com>
This commit is contained in:
parent
933beb4cbd
commit
6c598e8341
@ -2610,6 +2610,71 @@ pub fn map_shadow_stack(addr: u64, size: u64, flags: u32) usize {
|
||||
return syscall3(.map_shadow_stack, addr, size, flags);
|
||||
}
|
||||
|
||||
pub const Sysinfo = switch (native_abi) {
|
||||
.gnux32, .muslx32 => extern struct {
|
||||
/// Seconds since boot
|
||||
uptime: i64,
|
||||
/// 1, 5, and 15 minute load averages
|
||||
loads: [3]u64,
|
||||
/// Total usable main memory size
|
||||
totalram: u64,
|
||||
/// Available memory size
|
||||
freeram: u64,
|
||||
/// Amount of shared memory
|
||||
sharedram: u64,
|
||||
/// Memory used by buffers
|
||||
bufferram: u64,
|
||||
/// Total swap space size
|
||||
totalswap: u64,
|
||||
/// swap space still available
|
||||
freeswap: u64,
|
||||
/// Number of current processes
|
||||
procs: u16,
|
||||
/// Explicit padding for m68k
|
||||
pad: u16,
|
||||
/// Total high memory size
|
||||
totalhigh: u64,
|
||||
/// Available high memory size
|
||||
freehigh: u64,
|
||||
/// Memory unit size in bytes
|
||||
mem_unit: u32,
|
||||
},
|
||||
else => extern struct {
|
||||
/// Seconds since boot
|
||||
uptime: isize,
|
||||
/// 1, 5, and 15 minute load averages
|
||||
loads: [3]usize,
|
||||
/// Total usable main memory size
|
||||
totalram: usize,
|
||||
/// Available memory size
|
||||
freeram: usize,
|
||||
/// Amount of shared memory
|
||||
sharedram: usize,
|
||||
/// Memory used by buffers
|
||||
bufferram: usize,
|
||||
/// Total swap space size
|
||||
totalswap: usize,
|
||||
/// swap space still available
|
||||
freeswap: usize,
|
||||
/// Number of current processes
|
||||
procs: u16,
|
||||
/// Explicit padding for m68k
|
||||
pad: u16,
|
||||
/// Total high memory size
|
||||
totalhigh: usize,
|
||||
/// Available high memory size
|
||||
freehigh: usize,
|
||||
/// Memory unit size in bytes
|
||||
mem_unit: u32,
|
||||
/// Pad
|
||||
_f: [20 - 2 * @sizeOf(usize) - @sizeOf(u32)]u8,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn sysinfo(info: *Sysinfo) usize {
|
||||
return syscall1(.sysinfo, @intFromPtr(info));
|
||||
}
|
||||
|
||||
pub const E = switch (native_arch) {
|
||||
.mips, .mipsel, .mips64, .mips64el => enum(u16) {
|
||||
/// No error occurred.
|
||||
|
||||
@ -165,6 +165,15 @@ test "sigset_t" {
|
||||
try expectEqual(sigset[2], 0);
|
||||
}
|
||||
|
||||
test "sysinfo" {
|
||||
var info: linux.Sysinfo = undefined;
|
||||
const result: usize = linux.sysinfo(&info);
|
||||
try expect(std.os.linux.E.init(result) == .SUCCESS);
|
||||
|
||||
try expect(info.mem_unit > 0);
|
||||
try expect(info.mem_unit <= std.heap.page_size_max);
|
||||
}
|
||||
|
||||
test {
|
||||
_ = linux.IoUring;
|
||||
}
|
||||
|
||||
@ -1748,7 +1748,12 @@ pub const TotalSystemMemoryError = error{
|
||||
pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
||||
switch (native_os) {
|
||||
.linux => {
|
||||
return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
|
||||
var info: std.os.linux.Sysinfo = undefined;
|
||||
const result: usize = std.os.linux.sysinfo(&info);
|
||||
if (std.os.linux.E.init(result) != .SUCCESS) {
|
||||
return error.UnknownTotalSystemMemory;
|
||||
}
|
||||
return info.totalram * info.mem_unit;
|
||||
},
|
||||
.freebsd => {
|
||||
var physmem: c_ulong = undefined;
|
||||
@ -1793,22 +1798,6 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn totalSystemMemoryLinux() !u64 {
|
||||
var file = try std.fs.openFileAbsoluteZ("/proc/meminfo", .{});
|
||||
defer file.close();
|
||||
var buf: [50]u8 = undefined;
|
||||
const amt = try file.read(&buf);
|
||||
if (amt != 50) return error.Unexpected;
|
||||
var it = std.mem.tokenizeAny(u8, buf[0..amt], " \n");
|
||||
const label = it.next().?;
|
||||
if (!std.mem.eql(u8, label, "MemTotal:")) return error.Unexpected;
|
||||
const int_text = it.next() orelse return error.Unexpected;
|
||||
const units = it.next() orelse return error.Unexpected;
|
||||
if (!std.mem.eql(u8, units, "kB")) return error.Unexpected;
|
||||
const kilobytes = try std.fmt.parseInt(u64, int_text, 10);
|
||||
return kilobytes * 1024;
|
||||
}
|
||||
|
||||
/// Indicate that we are now terminating with a successful exit code.
|
||||
/// In debug builds, this is a no-op, so that the calling code's
|
||||
/// cleanup mechanisms are tested and so that external tools that
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user