Skip to content

Commit 98cc499

Browse files
std.os.linux: resurrect shm
This reintroduces Linux's shared memory system calls which was in #7214. It also adds the externs necessary for C.
1 parent 4f782d1 commit 98cc499

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

lib/std/c/linux.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub const dl_phdr_info = linux.dl_phdr_info;
6565
pub const empty_sigset = linux.empty_sigset;
6666
pub const epoll_event = linux.epoll_event;
6767
pub const fd_t = linux.fd_t;
68+
pub const key_t = linux.key_t;
6869
pub const gid_t = linux.gid_t;
6970
pub const ifreq = linux.ifreq;
7071
pub const ino_t = linux.ino_t;
@@ -344,3 +345,8 @@ pub const dirent64 = struct {
344345
type: u8,
345346
name: [256]u8,
346347
};
348+
349+
pub extern "c" fn shmget(key: key_t, size: usize, shmflg: u32) usize;
350+
pub extern "c" fn shmat(shmid: i32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) usize;
351+
pub extern "c" fn shmctl(shmid: i32, cmd: i32, buf: ?[*]u8) usize;
352+
pub extern "c" fn shmdt(shmaddr: [*]u8) usize;

lib/std/os/linux.zig

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,89 @@ pub fn munmap(address: [*]const u8, length: usize) usize {
799799
return syscall2(.munmap, @intFromPtr(address), length);
800800
}
801801

802+
pub const key_t = i32;
803+
pub const IPC_PRIVATE = 0;
804+
805+
/// create key if key does not exist
806+
pub const IPC_CREAT = 0x200;
807+
808+
/// fail if key exists
809+
pub const IPC_EXCL = 0x400;
810+
811+
/// return error on wait
812+
pub const IPC_NOWAIT = 0x800;
813+
814+
/// segment will be destroyed on last detach
815+
pub const SHM_DEST = 0x200;
816+
817+
/// segment will not be swapped
818+
pub const SHM_LOCKED = 0x400;
819+
820+
/// segment will use huge TLB pages
821+
pub const SHM_HUGETLB = 0x800;
822+
823+
pub const SHM_HUGE_SHIFT = 26;
824+
pub const SHM_HUGE_2MB = 21 << SHM_HUGE_SHIFT;
825+
pub const SHM_HUGE_1GB = 30 << SHM_HUGE_SHIFT;
826+
827+
/// don't check for reservations
828+
pub const SHM_NORESERVE = 0x1000;
829+
830+
/// attach read-only else read-write
831+
pub const SHM_RDONLY = 0x1000;
832+
833+
/// round attach address to SHMLBA
834+
pub const SHM_RND = 0x2000;
835+
836+
/// take-over region on attach
837+
pub const SHM_REMAP = 0x4000;
838+
839+
/// execution access
840+
pub const SHM_EXEC = 0x8000;
841+
842+
/// remove identifier
843+
pub const IPC_RMID = 0;
844+
845+
/// set 'ipc_perm' options
846+
pub const IPC_SET = 1;
847+
848+
/// get 'ipc_perm' options
849+
pub const IPC_STAT = 2;
850+
851+
/// get info about shared memory limits and parameters
852+
pub const IPC_INFO = 3;
853+
854+
/// lock segment
855+
pub const SHM_LOCK = 11;
856+
857+
/// unlock segment
858+
pub const SHM_UNLOCK = 12;
859+
860+
/// get 'ipc_perm' options from kernel index
861+
pub const SHM_STAT = 13;
862+
863+
/// get info about about system resources consumed by shared memory
864+
pub const SHM_INFO = 14;
865+
866+
/// get 'ipc_perm' options from kernel index without checking read access
867+
pub const SHM_STAT_ANY = 15;
868+
869+
pub fn shmget(key: key_t, size: usize, shmflg: u32) usize {
870+
return syscall3(.shmget, @bitCast(key), size, shmflg);
871+
}
872+
873+
pub fn shmat(shmid: i32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) usize {
874+
return syscall3(.shmat, @bitCast(shmid), @intFromPtr(shmaddr), shmflg);
875+
}
876+
877+
pub fn shmctl(shmid: i32, cmd: i32, buf: ?[*]u8) usize {
878+
return syscall3(.shmctl, @bitCast(shmid), @bitCast(cmd), @intFromPtr(buf));
879+
}
880+
881+
pub fn shmdt(shmaddr: [*]u8) usize {
882+
return syscall1(.shmdt, @intFromPtr(shmaddr));
883+
}
884+
802885
pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
803886
if (@hasField(SYS, "poll")) {
804887
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)));

lib/std/os/linux/test.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ test "fadvise" {
121121
try expectEqual(@as(usize, 0), ret);
122122
}
123123

124+
test "shm" {
125+
const segment = linux.shmget(linux.IPC_PRIVATE, mem.page_size, linux.IPC_CREAT | 0o666);
126+
expect(linux.getErrno(segment) == 0);
127+
defer {
128+
const r = linux.shmctl(@intCast(segment), linux.IPC_RMID, null);
129+
expect(linux.getErrno(r) == 0);
130+
}
131+
132+
const addr = std.os.linux.shmat(@intCast(segment), null, 0);
133+
expect(linux.getErrno(addr) == 0);
134+
defer {
135+
const r = std.os.linux.shmdt(@intFromPtr(addr));
136+
expect(linux.getErrno(r) == 0);
137+
}
138+
}
139+
124140
test {
125141
_ = linux.IoUring;
126142
}

0 commit comments

Comments
 (0)