summaryrefslogtreecommitdiffstats
path: root/signal.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-12-20 06:57:13 -0800
committerKaz Kylheku <kaz@kylheku.com>2013-12-20 06:57:13 -0800
commit6e8aaedc1f3be2c9c7c3031499ad2b4bce05dfbc (patch)
treea972a7ce0467da3e666c4f841b9970971c5c211e /signal.h
parent0231fc1659ea0a75e058b38c3085d7631162f1b1 (diff)
downloadtxr-6e8aaedc1f3be2c9c7c3031499ad2b4bce05dfbc.tar.gz
txr-6e8aaedc1f3be2c9c7c3031499ad2b4bce05dfbc.tar.bz2
txr-6e8aaedc1f3be2c9c7c3031499ad2b4bce05dfbc.zip
Fixing a bug and performance issue.
Problem: we are using sigsetjmp but with a jmp_buf structure; it requires sigjmp_buf! Performance issue: sigsetjmp is a dog which makes system calls. Solution: let's roll our own cached version of sigprocmask which only calls the real sigprocmask when the mask changes. Then our extended_setjmp will just use regular setjmp, plus our own custom signal saving and restoring based on the cached version. * signal.c (sig_blocked_cache): New variable. (set_sig_handler): Use our sig_mask instead of sigprocmask. (mem_set_bits, mem_clr_bits): New static functions. (sig_mask): New function. * signal.h (extended_jmp_buf): New member, blocked. (extended_setjmp): save blocked signals by peeking into sig_blocked_cache, and restore using sig_mask. (sig_blocked_cache, sig_mask): Declared.
Diffstat (limited to 'signal.h')
-rw-r--r--signal.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/signal.h b/signal.h
index e2b794c1..8882c259 100644
--- a/signal.h
+++ b/signal.h
@@ -60,17 +60,23 @@
typedef struct {
jmp_buf jb;
sig_atomic_t se;
+ sigset_t blocked;
int rv;
} extended_jmp_buf;
#define extended_setjmp(EJB) \
- (sigsetjmp((EJB).jb, 1) \
- ? (async_sig_enabled = (EJB).se, (EJB).rv) \
- : ((EJB).se = async_sig_enabled, 0))
+ (setjmp((EJB).jb) \
+ ? (async_sig_enabled = (EJB).se, \
+ sig_mask(SIG_SETMASK, &(EJB).blocked, 0), \
+ (EJB).rv) \
+ : ((EJB).se = async_sig_enabled, \
+ (EJB).blocked = sig_blocked_cache, 0))
#define extended_longjmp(EJB, ARG) \
((EJB).rv = (ARG), longjmp((EJB).jb, 1))
+extern sigset_t sig_blocked_cache;
+
#else
#define sig_save_enable do {
@@ -98,3 +104,4 @@ void sig_init(void);
val set_sig_handler(val signo, val lambda);
val get_sig_handler(val signo);
val sig_check(void);
+int sig_mask(int how, const sigset_t *set, sigset_t *oldset);