| author | |
| committer | |
| log | 6c598e8341c202a61dc24678f4450fd5af961b4e |
| tree | cba11463a469fb9185b504056d13b6e2fb5984b5 |
| parent | 933beb4cbd82ce8026a7bd4e887d8096dd3784a9 |
Co-authored-by: Alex Rønne Petersen <alex@alexrp.com>3 files changed, 80 insertions(+), 17 deletions(-)
lib/std/os/linux.zig+65| ... | ... | @@ -2610,6 +2610,71 @@ pub fn map_shadow_stack(addr: u64, size: u64, flags: u32) usize { |
| 2610 | 2610 | return syscall3(.map_shadow_stack, addr, size, flags); |
| 2611 | 2611 | } |
| 2612 | 2612 | |
| 2613 | pub const Sysinfo = switch (native_abi) { | |
| 2614 | .gnux32, .muslx32 => extern struct { | |
| 2615 | /// Seconds since boot | |
| 2616 | uptime: i64, | |
| 2617 | /// 1, 5, and 15 minute load averages | |
| 2618 | loads: [3]u64, | |
| 2619 | /// Total usable main memory size | |
| 2620 | totalram: u64, | |
| 2621 | /// Available memory size | |
| 2622 | freeram: u64, | |
| 2623 | /// Amount of shared memory | |
| 2624 | sharedram: u64, | |
| 2625 | /// Memory used by buffers | |
| 2626 | bufferram: u64, | |
| 2627 | /// Total swap space size | |
| 2628 | totalswap: u64, | |
| 2629 | /// swap space still available | |
| 2630 | freeswap: u64, | |
| 2631 | /// Number of current processes | |
| 2632 | procs: u16, | |
| 2633 | /// Explicit padding for m68k | |
| 2634 | pad: u16, | |
| 2635 | /// Total high memory size | |
| 2636 | totalhigh: u64, | |
| 2637 | /// Available high memory size | |
| 2638 | freehigh: u64, | |
| 2639 | /// Memory unit size in bytes | |
| 2640 | mem_unit: u32, | |
| 2641 | }, | |
| 2642 | else => extern struct { | |
| 2643 | /// Seconds since boot | |
| 2644 | uptime: isize, | |
| 2645 | /// 1, 5, and 15 minute load averages | |
| 2646 | loads: [3]usize, | |
| 2647 | /// Total usable main memory size | |
| 2648 | totalram: usize, | |
| 2649 | /// Available memory size | |
| 2650 | freeram: usize, | |
| 2651 | /// Amount of shared memory | |
| 2652 | sharedram: usize, | |
| 2653 | /// Memory used by buffers | |
| 2654 | bufferram: usize, | |
| 2655 | /// Total swap space size | |
| 2656 | totalswap: usize, | |
| 2657 | /// swap space still available | |
| 2658 | freeswap: usize, | |
| 2659 | /// Number of current processes | |
| 2660 | procs: u16, | |
| 2661 | /// Explicit padding for m68k | |
| 2662 | pad: u16, | |
| 2663 | /// Total high memory size | |
| 2664 | totalhigh: usize, | |
| 2665 | /// Available high memory size | |
| 2666 | freehigh: usize, | |
| 2667 | /// Memory unit size in bytes | |
| 2668 | mem_unit: u32, | |
| 2669 | /// Pad | |
| 2670 | _f: [20 - 2 * @sizeOf(usize) - @sizeOf(u32)]u8, | |
| 2671 | }, | |
| 2672 | }; | |
| 2673 | ||
| 2674 | pub fn sysinfo(info: *Sysinfo) usize { | |
| 2675 | return syscall1(.sysinfo, @intFromPtr(info)); | |
| 2676 | } | |
| 2677 | ||
| 2613 | 2678 | pub const E = switch (native_arch) { |
| 2614 | 2679 | .mips, .mipsel, .mips64, .mips64el => enum(u16) { |
| 2615 | 2680 | /// No error occurred. |
lib/std/os/linux/test.zig+9| ... | ... | @@ -165,6 +165,15 @@ test "sigset_t" { |
| 165 | 165 | try expectEqual(sigset[2], 0); |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | test "sysinfo" { | |
| 169 | var info: linux.Sysinfo = undefined; | |
| 170 | const result: usize = linux.sysinfo(&info); | |
| 171 | try expect(std.os.linux.E.init(result) == .SUCCESS); | |
| 172 | ||
| 173 | try expect(info.mem_unit > 0); | |
| 174 | try expect(info.mem_unit <= std.heap.page_size_max); | |
| 175 | } | |
| 176 | ||
| 168 | 177 | test { |
| 169 | 178 | _ = linux.IoUring; |
| 170 | 179 | } |
lib/std/process.zig+6-17| ... | ... | @@ -1748,7 +1748,12 @@ pub const TotalSystemMemoryError = error{ |
| 1748 | 1748 | pub fn totalSystemMemory() TotalSystemMemoryError!u64 { |
| 1749 | 1749 | switch (native_os) { |
| 1750 | 1750 | .linux => { |
| 1751 | return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory; | |
| 1751 | var info: std.os.linux.Sysinfo = undefined; | |
| 1752 | const result: usize = std.os.linux.sysinfo(&info); | |
| 1753 | if (std.os.linux.E.init(result) != .SUCCESS) { | |
| 1754 | return error.UnknownTotalSystemMemory; | |
| 1755 | } | |
| 1756 | return info.totalram * info.mem_unit; | |
| 1752 | 1757 | }, |
| 1753 | 1758 | .freebsd => { |
| 1754 | 1759 | var physmem: c_ulong = undefined; |
| ... | ... | @@ -1793,22 +1798,6 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { |
| 1793 | 1798 | } |
| 1794 | 1799 | } |
| 1795 | 1800 | |
| 1796 | fn totalSystemMemoryLinux() !u64 { | |
| 1797 | var file = try std.fs.openFileAbsoluteZ("/proc/meminfo", .{}); | |
| 1798 | defer file.close(); | |
| 1799 | var buf: [50]u8 = undefined; | |
| 1800 | const amt = try file.read(&buf); | |
| 1801 | if (amt != 50) return error.Unexpected; | |
| 1802 | var it = std.mem.tokenizeAny(u8, buf[0..amt], " \n"); | |
| 1803 | const label = it.next().?; | |
| 1804 | if (!std.mem.eql(u8, label, "MemTotal:")) return error.Unexpected; | |
| 1805 | const int_text = it.next() orelse return error.Unexpected; | |
| 1806 | const units = it.next() orelse return error.Unexpected; | |
| 1807 | if (!std.mem.eql(u8, units, "kB")) return error.Unexpected; | |
| 1808 | const kilobytes = try std.fmt.parseInt(u64, int_text, 10); | |
| 1809 | return kilobytes * 1024; | |
| 1810 | } | |
| 1811 | ||
| 1812 | 1801 | /// Indicate that we are now terminating with a successful exit code. |
| 1813 | 1802 | /// In debug builds, this is a no-op, so that the calling code's |
| 1814 | 1803 | /// cleanup mechanisms are tested and so that external tools that |