mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Add mlock syscalls to std.c and std.posix
Linux already gained the relevant syscalls and consts in #24473 The basic mlock() and munlock() are fairly universal across the *nix world with a consistent interface, but are missing on wasi and windows. The mlockall() and munlockall() calls are not as widely supported as the basic ones. Notable non-implementers include darwin, haiku, and serenity (and of course wasi and windows again). mlock2() is Linux-only, as are its MLOCK flags.
This commit is contained in:
parent
172e97154d
commit
8248597a27
2 changed files with 122 additions and 0 deletions
|
|
@ -1599,6 +1599,25 @@ pub const MADV = switch (native_os) {
|
|||
},
|
||||
else => void,
|
||||
};
|
||||
pub const MCL = switch (native_os) {
|
||||
.linux => linux.MCL,
|
||||
// https://github.com/freebsd/freebsd-src/blob/39fea5c8dc598021e900c4feaf0e18111fda57b2/sys/sys/mman.h#L133
|
||||
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/088552723935447397400336f5ddb7aa5f5de660/sys/sys/mman.h#L118
|
||||
// https://github.com/NetBSD/src/blob/fd2741deca927c18e3ba15acdf78b8b14b2abe36/sys/sys/mman.h#L179
|
||||
// https://github.com/openbsd/src/blob/39404228f6d36c0ca4be5f04ab5385568ebd6aa3/sys/sys/mman.h#L129
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/mman.h#L379
|
||||
// https://github.com/illumos/illumos-gate/blob/5280477614f83fea20fc938729df6adb3e44340d/usr/src/uts/common/sys/mman.h#L343
|
||||
.freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => packed struct(c_int) {
|
||||
CURRENT: bool = 0,
|
||||
FUTURE: bool = 0,
|
||||
_: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 2) = 0,
|
||||
},
|
||||
else => void,
|
||||
};
|
||||
pub const MLOCK = switch (native_os) {
|
||||
.linux => linux.MLOCK,
|
||||
else => void,
|
||||
};
|
||||
pub const MSF = switch (native_os) {
|
||||
.linux => linux.MSF,
|
||||
.emscripten => emscripten.MSF,
|
||||
|
|
@ -10425,6 +10444,31 @@ pub const gettimeofday = switch (native_os) {
|
|||
else => private.gettimeofday,
|
||||
};
|
||||
|
||||
pub const mlock = switch (native_os) {
|
||||
.windows, .wasi => {},
|
||||
else => private.mlock,
|
||||
};
|
||||
|
||||
pub const mlock2 = switch (native_os) {
|
||||
linux => private.mlock2,
|
||||
else => {},
|
||||
};
|
||||
|
||||
pub const munlock = switch (native_os) {
|
||||
.windows, .wasi => {},
|
||||
else => private.munlock,
|
||||
};
|
||||
|
||||
pub const mlockall = switch (native_os) {
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.mlockall,
|
||||
else => {},
|
||||
};
|
||||
|
||||
pub const munlockall = switch (native_os) {
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.munlockall,
|
||||
else => {},
|
||||
};
|
||||
|
||||
pub const msync = switch (native_os) {
|
||||
.netbsd => private.__msync13,
|
||||
else => private.msync,
|
||||
|
|
@ -11314,6 +11358,12 @@ const private = struct {
|
|||
extern "c" fn malloc_usable_size(?*const anyopaque) usize;
|
||||
extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
|
||||
|
||||
extern "c" fn mlock(addr: *align(page_size) const anyopaque, len: usize) c_int;
|
||||
extern "c" fn mlock2(addr: *align(page_size) const anyopaque, len: usize, flags: MLOCK) c_int;
|
||||
extern "c" fn munlock(addr: *align(page_size) const anyopaque, len: usize) c_int;
|
||||
extern "c" fn mlockall(flags: MCL) c_int;
|
||||
extern "c" fn munlockall() c_int;
|
||||
|
||||
/// macos modernized symbols.
|
||||
/// x86_64 links to $INODE64 suffix for 64-bit support.
|
||||
/// Note these are not necessary on aarch64.
|
||||
|
|
|
|||
|
|
@ -81,7 +81,9 @@ pub const Kevent = system.Kevent;
|
|||
pub const MADV = system.MADV;
|
||||
pub const MAP = system.MAP;
|
||||
pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
|
||||
pub const MCL = system.MCL;
|
||||
pub const MFD = system.MFD;
|
||||
pub const MLOCK = system.MLOCK;
|
||||
pub const MREMAP = system.MREMAP;
|
||||
pub const MSF = system.MSF;
|
||||
pub const MSG = system.MSG;
|
||||
|
|
@ -4745,6 +4747,76 @@ pub fn fanotify_markZ(
|
|||
}
|
||||
}
|
||||
|
||||
pub const MlockError = error{
|
||||
PermissionDenied,
|
||||
LockedMemoryLimitExceeded,
|
||||
SystemResources,
|
||||
} || UnexpectedError;
|
||||
|
||||
pub fn mlock(memory: []align(page_size_min) const u8) MlockError!void {
|
||||
if (@TypeOf(system.mlock) == void)
|
||||
@compileError("mlock not supported on this OS");
|
||||
return switch (errno(system.mlock(memory.ptr, memory.len))) {
|
||||
.SUCCESS => {},
|
||||
.INVAL => unreachable, // unaligned, negative, runs off end of addrspace
|
||||
.PERM => error.PermissionDenied,
|
||||
.NOMEM => error.LockedMemoryLimitExceeded,
|
||||
.AGAIN => error.SystemResources,
|
||||
else => |err| unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn mlock2(memory: []align(page_size_min) const u8, flags: MLOCK) MlockError!void {
|
||||
if (@TypeOf(system.mlock2) == void)
|
||||
@compileError("mlock2 not supported on this OS");
|
||||
return switch (errno(system.mlock2(memory.ptr, memory.len, flags))) {
|
||||
.SUCCESS => {},
|
||||
.INVAL => unreachable, // bad memory or bad flags
|
||||
.PERM => error.PermissionDenied,
|
||||
.NOMEM => error.LockedMemoryLimitExceeded,
|
||||
.AGAIN => error.SystemResources,
|
||||
else => |err| unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn munlock(memory: []align(page_size_min) const u8) MlockError!void {
|
||||
if (@TypeOf(system.munlock) == void)
|
||||
@compileError("munlock not supported on this OS");
|
||||
return switch (errno(system.munlock(memory.ptr, memory.len))) {
|
||||
.SUCCESS => {},
|
||||
.INVAL => unreachable, // unaligned or runs off end of addr space
|
||||
.PERM => return error.PermissionDenied,
|
||||
.NOMEM => return error.LockedMemoryLimitExceeded,
|
||||
.AGAIN => return error.SystemResources,
|
||||
else => |err| unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn mlockall(flags: MCL) MlockError!void {
|
||||
if (@TypeOf(system.mlockall) == void)
|
||||
@compileError("mlockall not supported on this OS");
|
||||
return switch (errno(system.mlockall(flags))) {
|
||||
.SUCCESS => {},
|
||||
.INVAL => unreachable, // bad flags
|
||||
.PERM => error.PermissionDenied,
|
||||
.NOMEM => error.LockedMemoryLimitExceeded,
|
||||
.AGAIN => error.SystemResources,
|
||||
else => |err| unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn munlockall() MlockError!void {
|
||||
if (@TypeOf(system.munlockall) == void)
|
||||
@compileError("munlockall not supported on this OS");
|
||||
return switch (errno(system.munlockall())) {
|
||||
.SUCCESS => {},
|
||||
.PERM => error.PermissionDenied,
|
||||
.NOMEM => error.LockedMemoryLimitExceeded,
|
||||
.AGAIN => error.SystemResources,
|
||||
else => |err| unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
pub const MProtectError = error{
|
||||
/// The memory cannot be given the specified access. This can happen, for example, if you
|
||||
/// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue