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
>From c21fd1ae69cdae80c563753d56c66480eb5fe2a3 Mon Sep 17 00:00:00 2001
From: Peter Bex <peter....@xs4all.nl>
Date: Wed, 13 Jun 2012 22:54:26 +0200
Subject: [PATCH] Use _setjmp/_longjmp instead of setjmp/longjmp to prevent
 unneccessary system call overhead for saving/restoring the
 signal mask on systems where this is done

---
 chicken.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/chicken.h b/chicken.h
index 837a51c..31960b0 100644
--- a/chicken.h
+++ b/chicken.h
@@ -874,8 +874,8 @@ DECL_C_PROC_p0 (128,  1,0,0,0,0,0,0,0)
 # define C_gettimeofday             gettimeofday
 # define C_gmtime                   gmtime
 # define C_localtime                localtime
-# define C_setjmp                   setjmp
-# define C_longjmp                  longjmp
+# define C_setjmp                   _setjmp
+# define C_longjmp                  _longjmp
 # define C_alloca                   alloca
 # define C_strerror                 strerror
 # define C_isalpha                  isalpha
-- 
1.7.9.1

((repetitions . 10)
 (installation-prefix . "/home/sjamaan/chicken-test")
 (csc-options . "")
 (results
   ("triangl" . 10.951)
   ("travinit" . 0.907)
   ("traverse" . 3.569)
   ("takr" . 7.649)
   ("takl" . 2.825)
   ("tak" . 4.519)
   ("sort1" . 41.279)
   ("slatex" . 10.483)
   ("scheme" . 0.724)
   ("sboyer" . 410.743)
   ("puzzle" . 0.682)
   ("psyntax" . 22.867)
   ("nucleic2" . 50.316)
   ("nqueens" . 0.77)
   ("nfa" . 33.036)
   ("nestedloop" . 45.192)
   ("nboyer" . 177.593)
   ("nbody" . 49.134)
   ("mazefun" . 42.822)
   ("maze" . 2.124)
   ("lattice" . 118.835)
   ("kanren" . 62.096)
   ("hanoi" . 6.023)
   ("graphs" . 15.114)
   ("fread" . 17.907)
   ("fprint" . 2.769)
   ("fibc" . 18.013)
   ("fib" . 2.034)
   ("fft" . 0.501)
   ("earley" . 0.62)
   ("dynamic" . 2.404)
   ("div-rec" . 1.031)
   ("div-iter" . 0.339)
   ("destructive" . 1.219)
   ("deriv" . 10.01)
   ("dderiv" . 9.12)
   ("ctak" . 2.708)
   ("cpstak" . 6.139)
   ("conform" . 1.853)
   ("browse" . 1.85)
   ("boyer" . 1.446)
   ("binarytrees" . 1.224)
   ("0" . 0)))
((repetitions . 10)
 (installation-prefix . "/home/sjamaan/chicken-master")
 (csc-options . "")
 (results
   ("triangl" . 10.715)
   ("travinit" . 0.911)
   ("traverse" . 3.59)
   ("takr" . 7.663)
   ("takl" . 2.733)
   ("tak" . 4.562)
   ("sort1" . 42.108)
   ("slatex" . 10.574)
   ("scheme" . 0.724)
   ("sboyer" . 403.714)
   ("puzzle" . 0.679)
   ("psyntax" . 22.871)
   ("nucleic2" . 50.934)
   ("nqueens" . 0.78)
   ("nfa" . 32.666)
   ("nestedloop" . 45.033)
   ("nboyer" . 182.13)
   ("nbody" . 49.638)
   ("mazefun" . 43.324)
   ("maze" . 2.133)
   ("lattice" . 115.285)
   ("kanren" . 62.23)
   ("hanoi" . 10.827)
   ("graphs" . 25.053)
   ("fread" . 26.729)
   ("fprint" . 4.951)
   ("fibc" . 30.96)
   ("fib" . 3.472)
   ("fft" . 0.643)
   ("earley" . 0.873)
   ("dynamic" . 3.436)
   ("div-rec" . 1.673)
   ("div-iter" . 0.381)
   ("destructive" . 1.55)
   ("deriv" . 13.002)
   ("dderiv" . 11.782)
   ("ctak" . 4.97)
   ("cpstak" . 9.325)
   ("conform" . 3.017)
   ("browse" . 3.255)
   ("boyer" . 2.073)
   ("binarytrees" . 1.673)
   ("0" . 0)))
(use posix)

(define got-signal #f)

(set-signal-handler! signal/int (lambda (sig) (set! got-signal #t)))

(signal-mask! signal/int)

(process-signal (current-process-id) signal/int)

(assert (not got-signal))
_______________________________________________
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers

Reply via email to