Use sigsetjmp instead of setjmp (#2645)
Apparently on macOS `setjmp` manipulates the process-wide signal mask which adds a good deal of overhead. We don't actually need this functionality so this commit switches to using the `sig` version of setjmp/longjmp where we can explicitly ask the signal mask to not get preserved. This came out of poking around on #2644 and on macOS locally thi sdropped the overhead from 721ns to 55ns.
This commit is contained in:
@@ -1,7 +1,13 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=src/helpers.c");
|
println!("cargo:rerun-if-changed=src/helpers.c");
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.warnings(true)
|
.warnings(true)
|
||||||
|
.define(
|
||||||
|
&format!("CFG_TARGET_OS_{}", env::var("CARGO_CFG_TARGET_OS").unwrap()),
|
||||||
|
None,
|
||||||
|
)
|
||||||
.file("src/helpers.c")
|
.file("src/helpers.c")
|
||||||
.compile("helpers");
|
.compile("helpers");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
// Note that `sigsetjmp` and `siglongjmp` are used here where possible to
|
||||||
|
// explicitly pass a 0 argument to `sigsetjmp` that we don't need to preserve
|
||||||
|
// the process signal mask. This should make this call a bit faster b/c it
|
||||||
|
// doesn't need to touch the kernel signal handling routines.
|
||||||
|
#ifdef CFG_TARGET_OS_windows
|
||||||
|
#define platform_setjmp(buf) setjmp(buf)
|
||||||
|
#define platform_longjmp(buf, arg) longjmp(buf, arg)
|
||||||
|
#define platform_jmp_buf jmp_buf
|
||||||
|
#else
|
||||||
|
#define platform_setjmp(buf) sigsetjmp(buf, 0)
|
||||||
|
#define platform_longjmp(buf, arg) siglongjmp(buf, arg)
|
||||||
|
#define platform_jmp_buf sigjmp_buf
|
||||||
|
#endif
|
||||||
|
|
||||||
int RegisterSetjmp(
|
int RegisterSetjmp(
|
||||||
void **buf_storage,
|
void **buf_storage,
|
||||||
void (*body)(void*),
|
void (*body)(void*),
|
||||||
void *payload) {
|
void *payload) {
|
||||||
jmp_buf buf;
|
platform_jmp_buf buf;
|
||||||
if (setjmp(buf) != 0) {
|
if (platform_setjmp(buf) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*buf_storage = &buf;
|
*buf_storage = &buf;
|
||||||
@@ -14,6 +28,6 @@ int RegisterSetjmp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Unwind(void *JmpBuf) {
|
void Unwind(void *JmpBuf) {
|
||||||
jmp_buf *buf = (jmp_buf*) JmpBuf;
|
platform_jmp_buf *buf = (platform_jmp_buf*) JmpBuf;
|
||||||
longjmp(*buf, 1);
|
platform_longjmp(*buf, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user