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);
|
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) {
|
pub const E = switch (native_arch) {
|
||||||
.mips, .mipsel, .mips64, .mips64el => enum(u16) {
|
.mips, .mipsel, .mips64, .mips64el => enum(u16) {
|
||||||
/// No error occurred.
|
/// No error occurred.
|
||||||
|
|||||||
@ -165,6 +165,15 @@ test "sigset_t" {
|
|||||||
try expectEqual(sigset[2], 0);
|
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 {
|
test {
|
||||||
_ = linux.IoUring;
|
_ = linux.IoUring;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1748,7 +1748,12 @@ pub const TotalSystemMemoryError = error{
|
|||||||
pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
||||||
switch (native_os) {
|
switch (native_os) {
|
||||||
.linux => {
|
.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 => {
|
.freebsd => {
|
||||||
var physmem: c_ulong = undefined;
|
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.
|
/// 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
|
/// In debug builds, this is a no-op, so that the calling code's
|
||||||
/// cleanup mechanisms are tested and so that external tools that
|
/// cleanup mechanisms are tested and so that external tools that
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user