Commit 6c598e8341
Changed files (3)
lib
std
lib/std/os/linux/test.zig
@@ -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;
}
lib/std/os/linux.zig
@@ -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.
lib/std/process.zig
@@ -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