Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement fadvise for linux #8301

Merged
merged 2 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/std/os/bits/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is going on with indentation here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well that's what zig fmt produces.

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,
Expand Down
59 changes: 59 additions & 0 deletions lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
20 changes: 20 additions & 0 deletions lib/std/os/linux/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}