Skip to content
This repository was archived by the owner on Sep 27, 2024. It is now read-only.

Commit 7cc94e8

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

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-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) c_int;
350+
pub extern "c" fn shmat(shmid: i32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) c_int;
351+
pub extern "c" fn shmctl(shmid: i32, cmd: i32, buf: ?[*]u8) c_int;
352+
pub extern "c" fn shmdt(shmaddr: [*]u8) c_int;

lib/std/os/linux.zig

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,93 @@ 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 = struct {
804+
pub const PRIVATE = 0;
805+
806+
/// create key if key does not exist
807+
pub const CREAT = 0x200;
808+
809+
/// fail if key exists
810+
pub const EXCL = 0x400;
811+
812+
/// return error on wait
813+
pub const NOWAIT = 0x800;
814+
815+
/// remove identifier
816+
pub const RMID = 0;
817+
818+
/// set 'ipc_perm' options
819+
pub const SET = 1;
820+
821+
/// get 'ipc_perm' options
822+
pub const STAT = 2;
823+
824+
/// get info about shared memory limits and parameters
825+
pub const INFO = 3;
826+
};
827+
828+
pub const SHM = struct {
829+
/// segment will be destroyed on last detach
830+
pub const DEST = 0x200;
831+
832+
/// segment will not be swapped
833+
pub const LOCKED = 0x400;
834+
835+
/// segment will use huge TLB pages
836+
pub const HUGETLB = 0x800;
837+
838+
pub const HUGE_SHIFT = 26;
839+
pub const HUGE_2MB = 21 << HUGE_SHIFT;
840+
pub const HUGE_1GB = 30 << HUGE_SHIFT;
841+
842+
/// don't check for reservations
843+
pub const NORESERVE = 0x1000;
844+
845+
/// attach read-only else read-write
846+
pub const RDONLY = 0x1000;
847+
848+
/// round attach address to SHMLBA
849+
pub const RND = 0x2000;
850+
851+
/// take-over region on attach
852+
pub const REMAP = 0x4000;
853+
854+
/// execution access
855+
pub const EXEC = 0x8000;
856+
857+
/// lock segment
858+
pub const LOCK = 11;
859+
860+
/// unlock segment
861+
pub const UNLOCK = 12;
862+
863+
/// get 'ipc_perm' options from kernel index
864+
pub const STAT = 13;
865+
866+
/// get info about about system resources consumed by shared memory
867+
pub const INFO = 14;
868+
869+
/// get 'ipc_perm' options from kernel index without checking read access
870+
pub const STAT_ANY = 15;
871+
};
872+
873+
pub fn shmget(key: key_t, size: usize, shmflg: u32) usize {
874+
return syscall3(.shmget, key, size, shmflg);
875+
}
876+
877+
pub fn shmat(shmid: u32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) usize {
878+
return syscall3(.shmat, shmid, @intFromPtr(shmaddr), shmflg);
879+
}
880+
881+
pub fn shmctl(shmid: u32, cmd: i32, buf: ?[*]u8) usize {
882+
return syscall3(.shmctl, shmid, cmd, @intFromPtr(buf));
883+
}
884+
885+
pub fn shmdt(shmaddr: *const anyopaque) usize {
886+
return syscall1(.shmdt, @intFromPtr(shmaddr));
887+
}
888+
802889
pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
803890
if (@hasField(SYS, "poll")) {
804891
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)));

lib/std/os/linux/test.zig

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,36 @@ 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+
switch (linux.getErrno(segment)) {
127+
.SUCCESS => {},
128+
else => unreachable,
129+
}
130+
131+
defer {
132+
const r = linux.shmctl(@intCast(segment), linux.IPC.RMID, null);
133+
switch (linux.getErrno(r)) {
134+
.SUCCESS => {},
135+
else => unreachable,
136+
}
137+
}
138+
139+
const addr = std.os.linux.shmat(@intCast(segment), null, 0);
140+
switch (linux.getErrno(addr)) {
141+
.SUCCESS => {},
142+
else => unreachable,
143+
}
144+
145+
defer {
146+
const r = std.os.linux.shmdt(@ptrFromInt(addr));
147+
switch (linux.getErrno(r)) {
148+
.SUCCESS => {},
149+
else => unreachable,
150+
}
151+
}
152+
}
153+
124154
test {
125155
_ = linux.IoUring;
126156
}

0 commit comments

Comments
 (0)