From 0db7eef398f7db03d95c28642c23db174f207b9b Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Sat, 27 Feb 2021 23:30:28 +0100 Subject: [PATCH 1/2] os/bits/linux: add the fadvise advice values --- lib/std/os/bits/linux.zig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 72ea62c32c53..e5e92241c897 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -2409,6 +2409,27 @@ pub const MADV_PAGEOUT = 21; pub const MADV_HWPOISON = 100; pub const MADV_SOFT_OFFLINE = 101; +pub const POSIX_FADV_NORMAL = 0; +pub const POSIX_FADV_RANDOM = 1; +pub const POSIX_FADV_SEQUENTIAL = 2; +pub const POSIX_FADV_WILLNEED = 3; +pub usingnamespace switch (arch) { + .s390x => if (@typeInfo(usize).Int.bits == 64) + struct { + pub const POSIX_FADV_DONTNEED = 6; + pub const POSIX_FADV_NOREUSE = 7; + } + else + struct { + pub const POSIX_FADV_DONTNEED = 4; + pub const POSIX_FADV_NOREUSE = 5; + }, + else => struct { + pub const POSIX_FADV_DONTNEED = 4; + pub const POSIX_FADV_NOREUSE = 5; + }, +}; + pub const __kernel_timespec = extern struct { tv_sec: i64, tv_nsec: i64, From fcc72659130e5885ad68c4c1503eb0c62ceb22c1 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Sat, 27 Feb 2021 23:30:43 +0100 Subject: [PATCH 2/2] os/linux: add fadvise --- lib/std/os/linux.zig | 59 +++++++++++++++++++++++++++++++++++++++ lib/std/os/linux/test.zig | 20 +++++++++++++ 2 files changed, 79 insertions(+) diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 0d6b87c15ffa..319e341ae78f 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1454,6 +1454,65 @@ pub fn process_vm_writev(pid: pid_t, local: [*]const iovec, local_count: usize, ); } +pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { + if (comptime std.Target.current.cpu.arch.isMIPS()) { + // MIPS requires a 7 argument syscall + + const offset_halves = splitValue64(offset); + const length_halves = splitValue64(len); + + return syscall7( + .fadvise64, + @bitCast(usize, @as(isize, fd)), + 0, + offset_halves[0], + offset_halves[1], + length_halves[0], + length_halves[1], + advice, + ); + } else if (comptime std.Target.current.cpu.arch.isARM()) { + // ARM reorders the arguments + + const offset_halves = splitValue64(offset); + const length_halves = splitValue64(len); + + return syscall6( + .fadvise64_64, + @bitCast(usize, @as(isize, fd)), + advice, + offset_halves[0], + offset_halves[1], + length_halves[0], + length_halves[1], + ); + } else if (@hasField(SYS, "fadvise64_64") and usize_bits != 64) { + // The extra usize check is needed to avoid SPARC64 because it provides both + // fadvise64 and fadvise64_64 but the latter behaves differently than other platforms. + + const offset_halves = splitValue64(offset); + const length_halves = splitValue64(len); + + return syscall6( + .fadvise64_64, + @bitCast(usize, @as(isize, fd)), + offset_halves[0], + offset_halves[1], + length_halves[0], + length_halves[1], + advice, + ); + } else { + return syscall4( + .fadvise64, + @bitCast(usize, @as(isize, fd)), + @bitCast(usize, offset), + @bitCast(usize, len), + advice, + ); + } +} + test { if (std.Target.current.os.tag == .linux) { _ = @import("linux/test.zig"); diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index c4a00c48ec9d..2e98fe359d7b 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -108,3 +108,23 @@ test "user and group ids" { try expectEqual(linux.getauxval(elf.AT_EUID), linux.geteuid()); try expectEqual(linux.getauxval(elf.AT_EGID), linux.getegid()); } + +test "fadvise" { + const tmp_file_name = "temp_posix_fadvise.txt"; + var file = try fs.cwd().createFile(tmp_file_name, .{}); + defer { + file.close(); + fs.cwd().deleteFile(tmp_file_name) catch {}; + } + + var buf: [2048]u8 = undefined; + try file.writeAll(&buf); + + const ret = linux.fadvise( + file.handle, + 0, + 0, + linux.POSIX_FADV_SEQUENTIAL, + ); + try expectEqual(@as(usize, 0), ret); +}