mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
102 lines
3.1 KiB
Zig
102 lines
3.1 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
|
|
const Atomic = std.atomic.Atomic;
|
|
|
|
const O_RDWR: c_int = 2;
|
|
const O_CREAT: c_int = 64;
|
|
|
|
pub const PROT_WRITE: c_int = 2;
|
|
pub const MAP_SHARED: c_int = 0x0001;
|
|
|
|
// IMPORTANT: shared memory object names must begin with / and contain no other slashes!
|
|
var SHARED_BUFFER: []u8 = undefined;
|
|
|
|
pub fn setSharedBuffer(ptr: [*]u8, length: usize) callconv(.C) usize {
|
|
SHARED_BUFFER = ptr[0..length];
|
|
|
|
// the rust side expects that a pointer is returned
|
|
return 0;
|
|
}
|
|
|
|
pub fn expectFailedStartSharedBuffer() callconv(.C) [*]u8 {
|
|
return SHARED_BUFFER.ptr;
|
|
}
|
|
|
|
pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
|
|
// IMPORTANT: shared memory object names must begin with / and contain no other slashes!
|
|
var name: [100]u8 = undefined;
|
|
_ = std.fmt.bufPrint(name[0..100], "/roc_expect_buffer_{}\x00", .{roc_getppid()}) catch unreachable;
|
|
|
|
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
|
const shared_fd = roc_shm_open(@ptrCast(*const i8, &name), O_RDWR | O_CREAT, 0o666);
|
|
|
|
const length = 4096;
|
|
|
|
const shared_ptr = roc_mmap(
|
|
null,
|
|
length,
|
|
PROT_WRITE,
|
|
MAP_SHARED,
|
|
shared_fd,
|
|
0,
|
|
);
|
|
|
|
const ptr = @ptrCast([*]u8, shared_ptr);
|
|
|
|
return ptr;
|
|
} else {
|
|
unreachable;
|
|
}
|
|
}
|
|
|
|
extern fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
|
|
extern fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
|
|
extern fn roc_getppid() c_int;
|
|
|
|
pub fn readSharedBufferEnv() callconv(.C) void {
|
|
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
|
|
|
// IMPORTANT: shared memory object names must begin with / and contain no other slashes!
|
|
var name: [100]u8 = undefined;
|
|
_ = std.fmt.bufPrint(name[0..100], "/roc_expect_buffer_{}\x00", .{roc_getppid()}) catch unreachable;
|
|
|
|
const shared_fd = roc_shm_open(@ptrCast(*const i8, &name), O_RDWR | O_CREAT, 0o666);
|
|
const length = 4096;
|
|
|
|
const shared_ptr = roc_mmap(
|
|
null,
|
|
length,
|
|
PROT_WRITE,
|
|
MAP_SHARED,
|
|
shared_fd,
|
|
0,
|
|
);
|
|
|
|
const ptr = @ptrCast([*]u8, shared_ptr);
|
|
|
|
SHARED_BUFFER = ptr[0..length];
|
|
}
|
|
}
|
|
|
|
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
|
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
|
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
|
|
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
|
|
atomic_ptr.storeUnchecked(tag);
|
|
|
|
// wait till the parent is done before proceeding
|
|
const Ordering = std.atomic.Ordering;
|
|
while (atomic_ptr.load(Ordering.Acquire) != 0) {
|
|
std.atomic.spinLoopHint();
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
|
|
notifyParent(shared_buffer, 1);
|
|
}
|
|
|
|
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
|
|
notifyParent(shared_buffer, 2);
|
|
}
|