|
From: | Peter Bex |
Subject: | [Chicken-hackers] [PATCH] Change setjmp/longjmp to _setjmp/_longjmp to avoid overhead and fix signal masking bug |
Date: | Wed, 13 Jun 2012 23:22:02 +0200 |
User-agent: | Mutt/1.4.2.3i |
Hi hackers, While looking over a system call trace while debugging another issue, I noticed a LOT of system calls to __sigprocmask14 (on NetBSD). It turns out these are generated by setjmp() and longjmp(), so upon each minor GC it make do two superfluous system calls. According to POSIX, it is actually /unspecified/ if those affect the signal mask: http://pubs.opengroup.org/onlinepubs/9699919799/functions/longjmp.html This setting of the signal mask is probably even unintended and may be the cause of bugs when the mask is set since the GC might reset any masked signals. The following program prints "signaling" and "GOT SIGINT" with Chicken master on NetBSD (using csi): (use posix) (set-signal-handler! signal/int (lambda (sig) (print "GOT SIGINT"))) (signal-mask! signal/int) (let lp ((i 0)) (if (= i 1000) (begin (print "signaling") (process-signal (current-process-id) signal/int) (lp 0)) (lp (add1 i)))) With the attached patch it only prints "signaling", which is the same behavior this program shows on Linux with both versions. I also made a small test but I wasn't sure whether the GC is guaranteed to be triggered so it might not be a very valid test (it doesn't when you compile it, but for me it does in csi). This test is attached. If it's okay, feel free to add it to the testsuite. So, to solve this, it's more correct to use sigsetjmp/siglongjmp to explicitly set the mask or not. However, according to this GNULib manual http://www.gnu.org/software/gnulib/manual/gnulib.html#sigsetjmp this function isn't supported by MingW, MSVC and Minix. That's why the attached patch uses _sigsetjmp and _siglongjmp. Those are in POSIX, and pretty widely supported (but they're slated to be *possibly* removed in future POSIX versions). According to the aforementioned GNULib manual, _sigsetjmp/_siglongjmp are the fastest way to set and restore the registers without signal mask. I've also attached two outputs from the resurrected Chicken benchmarks by Mario: https://github.com/mario-goulart/chicken-benchmarks These clearly show about a 5% speed improvement across the board. (you can see a clear comparison by using the "compare.scm" program from that repo). I compiled Chicken with itself before running this benchmark. This may have an effect because according to Mario the compilation time is included in the measurements. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth
0001-Use-_setjmp-_longjmp-instead-of-setjmp-longjmp-to-pr.patch
Description: Text document
with-patch.log
Description: Text document
without-patch.log
Description: Text document
test.scm
Description: Text document
[Prev in Thread] | Current Thread | [Next in Thread] |