Skip to content

Add basic support for System V shm #7214

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

Closed
wants to merge 4 commits into from
Closed
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
67 changes: 67 additions & 0 deletions lib/std/os/bits/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,73 @@ pub const MAP_FIXED_NOREPLACE = 0x100000;
/// For anonymous mmap, memory could be uninitialized
pub const MAP_UNINITIALIZED = 0x4000000;

pub const key_t = i32;
pub const IPC_PRIVATE = 0;

/// create key if key does not exist
pub const IPC_CREAT = 0x200;

/// fail if key exists
pub const IPC_EXCL = 0x400;

/// return error on wait
pub const IPC_NOWAIT = 0x800;

/// segment will be destroyed on last detach
pub const SHM_DEST = 0x200;

/// segment will not be swapped
pub const SHM_LOCKED = 0x400;

/// segment will use huge TLB pages
pub const SHM_HUGETLB = 0x800;

pub const SHM_HUGE_SHIFT = 26;
pub const SHM_HUGE_2MB = 21 << SHM_HUGE_SHIFT;
pub const SHM_HUGE_1GB = 30 << SHM_HUGE_SHIFT;

/// don't check for reservations
pub const SHM_NORESERVE = 0x1000;

/// attach read-only else read-write
pub const SHM_RDONLY = 0x1000;

/// round attach address to SHMLBA
pub const SHM_RND = 0x2000;

/// take-over region on attach
pub const SHM_REMAP = 0x4000;

/// execution access
pub const SHM_EXEC = 0x8000;

/// remove identifier
pub const IPC_RMID = 0;

/// set 'ipc_perm' options
pub const IPC_SET = 1;

/// get 'ipc_perm' options
pub const IPC_STAT = 2;

/// get info about shared memory limits and parameters
pub const IPC_INFO = 3;

/// lock segment
pub const SHM_LOCK = 11;

/// unlock segment
pub const SHM_UNLOCK = 12;

/// get 'ipc_perm' options from kernel index
pub const SHM_STAT = 13;

/// get info about about system resources consumed by shared memory
pub const SHM_INFO = 14;

/// get 'ipc_perm' options from kernel index without checking read access
pub const SHM_STAT_ANY = 15;

pub const FD_CLOEXEC = 1;

pub const F_OK = 0;
Expand Down
16 changes: 16 additions & 0 deletions lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,22 @@ pub fn munmap(address: [*]const u8, length: usize) usize {
return syscall2(.munmap, @ptrToInt(address), length);
}

pub fn shmget(key: key_t, size: usize, shmflg: u32) usize {
return syscall3(.shmget, @bitCast(u32, key), size, shmflg);
}

pub fn shmat(shmid: i32, shmaddr: ?[*]align(std.mem.page_size) u8, shmflg: u32) usize {
return syscall3(.shmat, @bitCast(u32, shmid), @ptrToInt(shmaddr), shmflg);
}

pub fn shmctl(shmid: i32, cmd: i32, buf: ?[*]u8) usize {
return syscall3(.shmctl, @bitCast(u32, shmid), @bitCast(u32, cmd), @ptrToInt(buf));
}

pub fn shmdt(shmaddr: [*]u8) usize {
return syscall1(.shmdt, @ptrToInt(shmaddr));
}

pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
if (@hasField(SYS, "poll")) {
return syscall3(.poll, @ptrToInt(fds), n, @bitCast(u32, timeout));
Expand Down
18 changes: 17 additions & 1 deletion lib/std/os/linux/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test "fallocate" {
0 => {},
linux.ENOSYS => return error.SkipZigTest,
linux.EOPNOTSUPP => return error.SkipZigTest,
else => |errno| std.debug.panic("unhandled errno: {}", .{ errno }),
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
}

expect((try file.stat()).size == len);
Expand Down Expand Up @@ -99,3 +99,19 @@ test "statx" {
expect(@bitCast(u64, @as(i64, stat_buf.blksize)) == statx_buf.blksize);
expect(@bitCast(u64, @as(i64, stat_buf.blocks)) == statx_buf.blocks);
}

test "shm" {
const segment = linux.shmget(linux.IPC_PRIVATE, mem.page_size, linux.IPC_CREAT + 0o666);
expect(linux.getErrno(segment) == 0);
defer {
const r = linux.shmctl(@intCast(i32, segment), linux.IPC_RMID, null);
expect(linux.getErrno(r) == 0);
}

const addr = std.os.linux.shmat(@intCast(i32, segment), null, 0);
expect(linux.getErrno(addr) == 0);
defer {
const r = std.os.linux.shmdt(@intToPtr([*]u8, addr));
expect(linux.getErrno(r) == 0);
}
}