Merge pull request #4714 from roc-lang/expect-dbg-atomics

use atomics for expect/dbg
This commit is contained in:
Folkert de Vries 2022-12-09 09:21:13 +01:00 committed by GitHub
commit 234f9f54cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 169 additions and 169 deletions

View File

@ -1042,12 +1042,9 @@ fn roc_dev_native(
envp: bumpalo::collections::Vec<*const c_char>,
expect_metadata: ExpectMetadata,
) -> ! {
use roc_repl_expect::run::ExpectMemory;
use signal_hook::{
consts::signal::SIGCHLD,
consts::signal::{SIGUSR1, SIGUSR2},
iterator::Signals,
};
use std::sync::{atomic::AtomicBool, Arc};
use roc_repl_expect::run::{ChildProcessMsg, ExpectMemory};
let ExpectMetadata {
mut expectations,
@ -1055,11 +1052,9 @@ fn roc_dev_native(
layout_interner,
} = expect_metadata;
let mut signals = Signals::new(&[SIGCHLD, SIGUSR1, SIGUSR2]).unwrap();
// let shm_name =
let shm_name = format!("/roc_expect_buffer_{}", std::process::id());
let memory = ExpectMemory::create_or_reuse_mmap(&shm_name);
let mut memory = ExpectMemory::create_or_reuse_mmap(&shm_name);
let layout_interner = layout_interner.into_global();
@ -1085,12 +1080,14 @@ fn roc_dev_native(
std::process::exit(1)
}
1.. => {
for sig in &mut signals {
match sig {
SIGCHLD => break,
SIGUSR1 => {
// this is the signal we use for an expect failure. Let's see what the child told us
let sigchld = Arc::new(AtomicBool::new(false));
signal_hook::flag::register(signal_hook::consts::SIGCHLD, Arc::clone(&sigchld))
.unwrap();
loop {
match memory.wait_for_child(sigchld.clone()) {
ChildProcessMsg::Terminate => break,
ChildProcessMsg::Expect => {
roc_repl_expect::run::render_expects_in_memory(
&mut writer,
arena,
@ -1100,10 +1097,10 @@ fn roc_dev_native(
&memory,
)
.unwrap();
}
SIGUSR2 => {
// this is the signal we use for a dbg
memory.reset();
}
ChildProcessMsg::Dbg => {
roc_repl_expect::run::render_dbgs_in_memory(
&mut writer,
arena,
@ -1113,8 +1110,9 @@ fn roc_dev_native(
&memory,
)
.unwrap();
memory.reset();
}
_ => println!("received signal {}", sig),
}
}

View File

@ -78,9 +78,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -92,7 +89,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -77,9 +77,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -91,7 +88,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -94,9 +94,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -108,7 +105,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -93,9 +93,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -107,7 +104,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -98,9 +98,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -112,7 +109,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -1,8 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const SIGUSR1: c_int = if (builtin.os.tag.isDarwin()) 30 else 10;
const SIGUSR2: c_int = if (builtin.os.tag.isDarwin()) 31 else 12;
const Atomic = std.atomic.Atomic;
const O_RDWR: c_int = 2;
const O_CREAT: c_int = 64;
@ -51,7 +50,6 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
}
}
extern fn roc_send_signal(pid: c_int, sig: c_int) c_int;
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;
@ -81,18 +79,24 @@ pub fn readSharedBufferEnv() callconv(.C) void {
}
}
pub fn expectFailedFinalize() callconv(.C) void {
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const parent_pid = roc_getppid();
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
atomic_ptr.storeUnchecked(tag);
_ = roc_send_signal(parent_pid, SIGUSR1);
// 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 sendDbg() callconv(.C) void {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const parent_pid = roc_getppid();
_ = roc_send_signal(parent_pid, SIGUSR2);
}
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);
}

View File

@ -172,8 +172,8 @@ comptime {
if (builtin.target.cpu.arch != .wasm32) {
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
exportUtilsFn(expect.expectFailedFinalize, "expect_failed_finalize");
exportUtilsFn(expect.sendDbg, "send_dbg");
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
// sets the buffer used for expect failures
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });

View File

@ -32,9 +32,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn testing_roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn testing_roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -55,7 +52,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(testing_roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(testing_roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(testing_roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(testing_roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}

View File

@ -424,9 +424,9 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str =
"roc_builtins.utils.expect_failed_start_shared_buffer";
pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
"roc_builtins.utils.expect_failed_start_shared_file";
pub const UTILS_EXPECT_FAILED_FINALIZE: &str = "roc_builtins.utils.expect_failed_finalize";
pub const UTILS_EXPECT_READ_ENV_SHARED_BUFFER: &str = "roc_builtins.utils.read_env_shared_buffer";
pub const UTILS_SEND_DBG: &str = "roc_builtins.utils.send_dbg";
pub const NOTIFY_PARENT_EXPECT: &str = "roc_builtins.utils.notify_parent_expect";
pub const NOTIFY_PARENT_DBG: &str = "roc_builtins.utils.notify_parent_dbg";
pub const UTILS_LONGJMP: &str = "longjmp";
pub const UTILS_SETJMP: &str = "setjmp";

View File

@ -3,7 +3,7 @@ use crate::llvm::build_list::{self, allocate_list, empty_polymorphic_list};
use crate::llvm::convert::{
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
};
use crate::llvm::expect::clone_to_shared_memory;
use crate::llvm::expect::{clone_to_shared_memory, SharedMemoryPointer};
use crate::llvm::refcounting::{
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
};
@ -2611,17 +2611,20 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
match env.target_info.ptr_width() {
roc_target::PtrWidth::Bytes8 => {
let shared_memory = SharedMemoryPointer::get(env);
clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
*cond_symbol,
*region,
lookups,
);
if let LlvmBackendMode::BinaryDev = env.mode {
crate::llvm::expect::finalize(env);
crate::llvm::expect::notify_parent_expect(env, &shared_memory);
}
bd.build_unconditional_branch(then_block);
@ -2677,10 +2680,13 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
match env.target_info.ptr_width() {
roc_target::PtrWidth::Bytes8 => {
let shared_memory = SharedMemoryPointer::get(env);
clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
*cond_symbol,
*region,
lookups,

View File

@ -18,6 +18,32 @@ use super::build::{
Scope,
};
pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
impl<'ctx> SharedMemoryPointer<'ctx> {
pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self {
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
} else {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
};
let func = env.module.get_function(start_function).unwrap();
let call_result = env
.builder
.build_call(func, &[], "call_expect_start_failed");
let ptr = call_result
.try_as_basic_value()
.left()
.unwrap()
.into_pointer_value();
Self(ptr)
}
}
#[derive(Debug, Clone, Copy)]
struct Cursors<'ctx> {
offset: IntValue<'ctx>,
@ -94,48 +120,39 @@ fn write_state<'a, 'ctx, 'env>(
env.builder.build_store(offset_ptr, offset);
}
pub(crate) fn finalize(env: &Env) {
pub(crate) fn notify_parent_expect(env: &Env, shared_memory: &SharedMemoryPointer) {
let func = env
.module
.get_function(bitcode::UTILS_EXPECT_FAILED_FINALIZE)
.get_function(bitcode::NOTIFY_PARENT_EXPECT)
.unwrap();
env.builder
.build_call(func, &[], "call_expect_failed_finalize");
env.builder.build_call(
func,
&[shared_memory.0.into()],
"call_expect_failed_finalize",
);
}
pub(crate) fn send_dbg(env: &Env) {
let func = env.module.get_function(bitcode::UTILS_SEND_DBG).unwrap();
pub(crate) fn notify_parent_dbg(env: &Env, shared_memory: &SharedMemoryPointer) {
let func = env.module.get_function(bitcode::NOTIFY_PARENT_DBG).unwrap();
env.builder
.build_call(func, &[], "call_expect_failed_finalize");
env.builder.build_call(
func,
&[shared_memory.0.into()],
"call_expect_failed_finalize",
);
}
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
layout_ids: &mut LayoutIds<'a>,
shared_memory: &SharedMemoryPointer<'ctx>,
condition: Symbol,
region: Region,
lookups: &[Symbol],
) {
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
} else {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
};
let func = env.module.get_function(start_function).unwrap();
let call_result = env
.builder
.build_call(func, &[], "call_expect_start_failed");
let original_ptr = call_result
.try_as_basic_value()
.left()
.unwrap()
.into_pointer_value();
let original_ptr = shared_memory.0;
let (count, mut offset) = read_state(env, original_ptr);

View File

@ -158,7 +158,6 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
unreachable_function(env, "roc_getppid");
unreachable_function(env, "roc_mmap");
unreachable_function(env, "roc_send_signal");
unreachable_function(env, "roc_shm_open");
add_sjlj_roc_panic(env)
@ -168,7 +167,10 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
fn unreachable_function(env: &Env, name: &str) {
// The type of this function (but not the implementation) should have
// already been defined by the builtins, which rely on it.
let fn_val = env.module.get_function(name).unwrap();
let fn_val = match env.module.get_function(name) {
Some(f) => f,
None => panic!("extern function {name} is not defined by the builtins"),
};
// Add a basic block for the entry point
let entry = env.context.append_basic_block(fn_val, "entry");

View File

@ -1126,16 +1126,19 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
if env.mode.runs_expects() {
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
crate::llvm::expect::clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
args[0],
region,
&[args[0]],
);
crate::llvm::expect::send_dbg(env);
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
}
condition

View File

@ -85,7 +85,6 @@ fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap<St
// for expects
"roc_mmap" => Some("mmap"),
"roc_getppid" => Some("getppid"),
"roc_send_signal" => Some("kill"),
"roc_shm_open" => Some("shm_open"),
_ => None,

View File

@ -1,4 +1,10 @@
use std::{os::unix::process::parent_id, sync::Arc};
use std::{
os::unix::process::parent_id,
sync::{
atomic::{AtomicBool, AtomicU32},
Arc,
},
};
use bumpalo::collections::Vec as BumpVec;
use bumpalo::Bump;
@ -105,6 +111,16 @@ impl<'a> ExpectMemory<'a> {
let mut result = RocCallResult::default();
unsafe { set_shared_buffer((self.ptr, self.length), &mut result) };
}
pub fn wait_for_child(&self, sigchld: Arc<AtomicBool>) -> ChildProcessMsg {
let sequence = ExpectSequence { ptr: self.ptr };
sequence.wait_for_child(sigchld)
}
pub fn reset(&mut self) {
let mut sequence = ExpectSequence { ptr: self.ptr };
sequence.reset();
}
}
#[allow(clippy::too_many_arguments)]
@ -591,16 +607,18 @@ struct ExpectSequence {
}
impl ExpectSequence {
const START_OFFSET: usize = 16;
const START_OFFSET: usize = 8 + 8 + 8;
const COUNT_INDEX: usize = 0;
const OFFSET_INDEX: usize = 1;
const LOCK_INDEX: usize = 2;
fn new(ptr: *mut u8) -> Self {
unsafe {
let ptr = ptr as *mut usize;
std::ptr::write_unaligned(ptr.add(Self::COUNT_INDEX), 0);
std::ptr::write_unaligned(ptr.add(Self::OFFSET_INDEX), Self::START_OFFSET);
std::ptr::write_unaligned(ptr.add(Self::LOCK_INDEX), 0);
}
Self {
@ -611,11 +629,47 @@ impl ExpectSequence {
fn count_failures(&self) -> usize {
unsafe { *(self.ptr as *const usize).add(Self::COUNT_INDEX) }
}
fn wait_for_child(&self, sigchld: Arc<AtomicBool>) -> ChildProcessMsg {
use std::sync::atomic::Ordering;
let ptr = self.ptr as *const u32;
let atomic_ptr: *const AtomicU32 = unsafe { ptr.add(5).cast() };
let atomic = unsafe { &*atomic_ptr };
loop {
if sigchld.load(Ordering::Relaxed) {
break ChildProcessMsg::Terminate;
}
match atomic.load(Ordering::Acquire) {
0 => std::hint::spin_loop(),
1 => break ChildProcessMsg::Expect,
2 => break ChildProcessMsg::Dbg,
n => panic!("invalid atomic value set by the child: {:#x}", n),
}
}
}
fn reset(&mut self) {
unsafe {
let ptr = self.ptr as *mut usize;
std::ptr::write_unaligned(ptr.add(Self::COUNT_INDEX), 0);
std::ptr::write_unaligned(ptr.add(Self::OFFSET_INDEX), Self::START_OFFSET);
std::ptr::write_unaligned(ptr.add(Self::LOCK_INDEX), 0);
}
}
}
pub enum ChildProcessMsg {
Expect = 1,
Dbg = 2,
Terminate = 3,
}
struct ExpectFrame {
region: Region,
module_id: ModuleId,
start_offset: usize,
}
@ -627,8 +681,8 @@ impl ExpectFrame {
let module_id_bytes: [u8; 4] = unsafe { *(start.add(offset + 8).cast()) };
let module_id: ModuleId = unsafe { std::mem::transmute(module_id_bytes) };
// skip to frame, 8 bytes for region, 4 for module id
let start_offset = offset + 12;
// skip to frame
let start_offset = offset + 8 + 4;
Self {
region,

View File

@ -105,12 +105,6 @@ pub unsafe extern "C" fn roc_shm_open(
libc::shm_open(name, oflag, mode as libc::c_uint)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
fn print_backtrace() {
eprintln!("Here is the call stack that led to the crash:\n");

View File

@ -97,9 +97,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -111,7 +108,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -101,12 +101,6 @@ pub unsafe extern "C" fn roc_shm_open(
libc::shm_open(name, oflag, mode as libc::c_uint)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let arg = env::args()

View File

@ -157,9 +157,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -171,7 +168,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -105,9 +105,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -119,7 +116,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -36,27 +36,18 @@ void* roc_memcpy(void* dest, const void* src, size_t n) {
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
int roc_send_signal(int pid, int sig) {
int roc_shm_open(char* name, int oflag, int mode) {
#ifdef _WIN32
return 0;
#else
return kill(pid, sig);
return shm_open(name, oflag, mode);
#endif
}
int roc_shm_open(char* name, int oflag, int mode) {
#ifdef _WIN32
return 0;
#else
return shm_open(name, oflag, mode);
#endif
}
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) {
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) {
#ifdef _WIN32
return addr;
#else
return mmap(addr, length, prot, flags, fd, offset);
return mmap(addr, length, prot, flags, fd, offset);
#endif
}

View File

@ -83,12 +83,6 @@ pub unsafe extern "C" fn roc_shm_open(
libc::shm_open(name, oflag, mode as libc::c_uint)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let mut roc_str = RocStr::default();

View File

@ -88,9 +88,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
@ -102,7 +99,6 @@ comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}

View File

@ -30,26 +30,18 @@ void* roc_memcpy(void* dest, const void* src, size_t n) {
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
int roc_send_signal(int pid, int sig) {
int roc_shm_open(char* name, int oflag, int mode) {
#ifdef _WIN32
return 0;
#else
return kill(pid, sig);
return shm_open(name, oflag, mode);
#endif
}
int roc_shm_open(char* name, int oflag, int mode) {
#ifdef _WIN32
return 0;
#else
return shm_open(name, oflag, mode);
#endif
}
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) {
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) {
#ifdef _WIN32
return addr;
#else
return mmap(addr, length, prot, flags, fd, offset);
return mmap(addr, length, prot, flags, fd, offset);
#endif
}

View File

@ -62,12 +62,6 @@ pub unsafe extern "C" fn roc_shm_open(
libc::shm_open(name, oflag, mode as libc::c_uint)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let args: Vec<String> = env::args().collect();
@ -113,14 +107,11 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut
}
fn run(input_dirname: &str, output_dirname: &str) -> Result<(), String> {
let input_dir =
strip_windows_prefix(
PathBuf::from(input_dirname)
let input_dir = strip_windows_prefix(
PathBuf::from(input_dirname)
.canonicalize()
.map_err(|e| format!("{}: {}", input_dirname, e))?
);
.map_err(|e| format!("{}: {}", input_dirname, e))?,
);
let output_dir = {
let dir = PathBuf::from(output_dirname);
@ -129,7 +120,7 @@ fn run(input_dirname: &str, output_dirname: &str) -> Result<(), String> {
}
strip_windows_prefix(
dir.canonicalize()
.map_err(|e| format!("{}: {}", output_dirname, e))?
.map_err(|e| format!("{}: {}", output_dirname, e))?,
)
};
@ -157,7 +148,10 @@ fn run(input_dirname: &str, output_dirname: &str) -> Result<(), String> {
num_successes += 1;
}
Err(e) => {
eprintln!("Failed to process file:\n\n ({:?})with error:\n\n {}", &input_file, e);
eprintln!(
"Failed to process file:\n\n ({:?})with error:\n\n {}",
&input_file, e
);
num_errors += 1;
}
}
@ -176,7 +170,6 @@ fn run(input_dirname: &str, output_dirname: &str) -> Result<(), String> {
}
fn process_file(input_dir: &Path, output_dir: &Path, input_file: &Path) -> Result<(), String> {
match input_file.extension() {
Some(s) if s.eq("md".into()) => {}
_ => return Err("Only .md files are supported".into()),

View File

@ -301,7 +301,6 @@ on the same line, although the convention is to use the original version's style
</p>
</section>
<section><h2 id="debugging"><a href="#debugging">Debugging</a></h2>
<p><code>dbg doesn't work yet on MacOS x86_64</code></p>
<p><a href="https://en.wikipedia.org/wiki/Debugging#Techniques">Print debugging</a> is the most
common debugging technique in the history of programming, and Roc has a <code>dbg</code>
keyword to facilitate it. Here's an example of how to use <code>dbg</code>:</p>