summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorReimer Behrends <behrends@gmail.com>2014-09-25 23:29:02 +0200
committerReimer Behrends <behrends@gmail.com>2014-09-25 23:29:02 +0200
commitf99c40f61bc47f98390aab42f686fcb697dc9ce8 (patch)
tree6aa9856aa5e9ca35e3fbfa7735505837e35dc6fd /lib
parent9f047f4351b100c929153d0070f3cd34752a08e1 (diff)
downloadNim-f99c40f61bc47f98390aab42f686fcb697dc9ce8.tar.gz
Improve setjmp()/longjmp() performance.
Exception handling for the C backend used setjmp()/longjmp()
unconditionally. However, on POSIX systems, these functions save and
restore the signal mask, adding considerable overhead to exception
handling, even where no exceptions are involved. The compiler and
library now try to use either _setjmp()/_longjmp() or
sigsetjmp()/siglongjmp() where possible, marked by the defines
"nimRawSetjmp" and "nimSigSetjmp", respectively. The define
"nimStdSetjmp" can be used to revert to setjmp()/longjmp() instead.
Diffstat (limited to 'lib')
-rw-r--r--lib/system/ansi_c.nim21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index e012697ae..673d55582 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -78,10 +78,23 @@ when defined(macosx):
 else:
   template SIGBUS: expr = SIGSEGV
 
-proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
-  header: "<setjmp.h>", importc: "longjmp".}
-proc c_setjmp(jmpb: C_JmpBuf): cint {.
-  header: "<setjmp.h>", importc: "setjmp".}
+when defined(nimSigSetjmp) and not defined(nimStdSetjmp):
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "siglongjmp".}
+  template c_setjmp(jmpb: C_JmpBuf): cint =
+    proc c_sigsetjmp(jmpb: C_JmpBuf, savemask: cint): cint {.
+      header: "<setjmp.h>", importc: "sigsetjmp".}
+    c_sigsetjmp(jmpb, 0)
+elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "_longjmp".}
+  proc c_setjmp(jmpb: C_JmpBuf): cint {.
+    header: "<setjmp.h>", importc: "_setjmp".}
+else:
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "longjmp".}
+  proc c_setjmp(jmpb: C_JmpBuf): cint {.
+    header: "<setjmp.h>", importc: "setjmp".}
 
 proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
   importc: "signal", header: "<signal.h>".}