Skip to content

Commit cd501f5

Browse files
committed
Add mlock syscalls to std.c and std.posix
Linux already gained the relevant syscalls and consts in ziglang#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.
1 parent 51a2c0f commit cd501f5

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

lib/std/c.zig

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,19 @@ pub const MADV = switch (native_os) {
15991599
},
16001600
else => void,
16011601
};
1602+
pub const MCL = switch (native_os) {
1603+
.linux => linux.MCL,
1604+
.freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => packed struct(c_int) {
1605+
CURRENT: bool = 0,
1606+
FUTURE: bool = 0,
1607+
_: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 2) = 0,
1608+
},
1609+
else => void,
1610+
};
1611+
pub const MLOCK = switch (native_os) {
1612+
.linux => linux.MLOCK,
1613+
else => void,
1614+
};
16021615
pub const MSF = switch (native_os) {
16031616
.linux => linux.MSF,
16041617
.emscripten => emscripten.MSF,
@@ -10425,6 +10438,31 @@ pub const gettimeofday = switch (native_os) {
1042510438
else => private.gettimeofday,
1042610439
};
1042710440

10441+
pub const mlock = switch (native_os) {
10442+
.windows, .wasi => {},
10443+
else => private.mlock,
10444+
};
10445+
10446+
pub const mlock2 = switch (native_os) {
10447+
linux => private.mlock2,
10448+
else => {},
10449+
};
10450+
10451+
pub const munlock = switch (native_os) {
10452+
.windows, .wasi => {},
10453+
else => private.mlock,
10454+
};
10455+
10456+
pub const mlockall = switch (native_os) {
10457+
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.mlockall,
10458+
else => {},
10459+
};
10460+
10461+
pub const munlockall = switch (native_os) {
10462+
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.munlockall,
10463+
else => {},
10464+
};
10465+
1042810466
pub const msync = switch (native_os) {
1042910467
.netbsd => private.__msync13,
1043010468
else => private.msync,
@@ -11313,6 +11351,12 @@ const private = struct {
1131311351
extern "c" fn malloc_usable_size(?*const anyopaque) usize;
1131411352
extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
1131511353

11354+
extern "c" fn mlock(addr: *align(page_size) const anyopaque, len: usize) c_int;
11355+
extern "c" fn mlock2(addr: *align(page_size) const anyopaque, len: usize, flags: MLOCK) c_int;
11356+
extern "c" fn munlock(addr: *align(page_size) const anyopaque, len: usize) c_int;
11357+
extern "c" fn mlockall(flags: MCL) c_int;
11358+
extern "c" fn munlockall() c_int;
11359+
1131611360
/// macos modernized symbols.
1131711361
/// x86_64 links to $INODE64 suffix for 64-bit support.
1131811362
/// Note these are not necessary on aarch64.

lib/std/posix.zig

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ pub const Kevent = system.Kevent;
8181
pub const MADV = system.MADV;
8282
pub const MAP = system.MAP;
8383
pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
84+
pub const MCL = system.MCL;
8485
pub const MFD = system.MFD;
86+
pub const MLOCK = system.MLOCK;
8587
pub const MREMAP = system.MREMAP;
8688
pub const MSF = system.MSF;
8789
pub const MSG = system.MSG;
@@ -4745,6 +4747,76 @@ pub fn fanotify_markZ(
47454747
}
47464748
}
47474749

4750+
pub const MlockError = error{
4751+
PermissionDenied,
4752+
LockedMemoryLimitExceeded,
4753+
SystemResources,
4754+
} || UnexpectedError;
4755+
4756+
pub fn mlock(memory: []align(page_size_min) const u8) MlockError!void {
4757+
if (@TypeOf(system.mlock) == void)
4758+
@compileError("mlock not supported on this OS");
4759+
return switch (errno(system.mlock(memory.ptr, memory.len))) {
4760+
.SUCCESS => {},
4761+
.INVAL => unreachable, // unaligned, negative, runs off end of addrspace
4762+
.PERM => error.PermissionDenied,
4763+
.NOMEM => error.LockedMemoryLimitExceeded,
4764+
.AGAIN => error.SystemResources,
4765+
else => |err| unexpectedErrno(err),
4766+
};
4767+
}
4768+
4769+
pub fn mlock2(memory: []align(page_size_min) const u8, flags: MLOCK) MlockError!void {
4770+
if (@TypeOf(system.mlock2) == void)
4771+
@compileError("mlock2 not supported on this OS");
4772+
return switch (errno(system.mlock2(memory.ptr, memory.len, flags))) {
4773+
.SUCCESS => {},
4774+
.INVAL => unreachable, // bad memory or bad flags
4775+
.PERM => error.PermissionDenied,
4776+
.NOMEM => error.LockedMemoryLimitExceeded,
4777+
.AGAIN => error.SystemResources,
4778+
else => |err| unexpectedErrno(err),
4779+
};
4780+
}
4781+
4782+
pub fn munlock(memory: []align(page_size_min) const u8) MlockError!void {
4783+
if (@TypeOf(system.munlock) == void)
4784+
@compileError("munlock not supported on this OS");
4785+
return switch (errno(system.munlock(memory.ptr, memory.len))) {
4786+
.SUCCESS => {},
4787+
.INVAL => unreachable, // unaligned or runs off end of addr space
4788+
.PERM => return error.PermissionDenied,
4789+
.NOMEM => return error.LockedMemoryLimitExceeded,
4790+
.AGAIN => return error.SystemResources,
4791+
else => |err| unexpectedErrno(err),
4792+
};
4793+
}
4794+
4795+
pub fn mlockall(flags: MCL) MlockError!void {
4796+
if (@TypeOf(system.mlockall) == void)
4797+
@compileError("mlockall not supported on this OS");
4798+
return switch (errno(system.mlockall(flags))) {
4799+
.SUCCESS => {},
4800+
.INVAL => unreachable, // bad flags
4801+
.PERM => error.PermissionDenied,
4802+
.NOMEM => error.LockedMemoryLimitExceeded,
4803+
.AGAIN => error.SystemResources,
4804+
else => |err| unexpectedErrno(err),
4805+
};
4806+
}
4807+
4808+
pub fn munlockall() MlockError!void {
4809+
if (@TypeOf(system.munlockall) == void)
4810+
@compileError("munlockall not supported on this OS");
4811+
return switch (errno(system.munlockall())) {
4812+
.SUCCESS => {},
4813+
.PERM => error.PermissionDenied,
4814+
.NOMEM => error.LockedMemoryLimitExceeded,
4815+
.AGAIN => error.SystemResources,
4816+
else => |err| unexpectedErrno(err),
4817+
};
4818+
}
4819+
47484820
pub const MProtectError = error{
47494821
/// The memory cannot be given the specified access. This can happen, for example, if you
47504822
/// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it

0 commit comments

Comments
 (0)