diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-10-27 06:45:56 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-10-27 06:45:56 -0700 |
commit | 0faa7cf4c73cc7c95488ed3055dd3c693dd341bc (patch) | |
tree | b640255b695ead0854653f68add9a16d1506566a | |
parent | 9d02ab722536227d488a31f5d580bc41501a7f68 (diff) | |
download | txr-0faa7cf4c73cc7c95488ed3055dd3c693dd341bc.tar.gz txr-0faa7cf4c73cc7c95488ed3055dd3c693dd341bc.tar.bz2 txr-0faa7cf4c73cc7c95488ed3055dd3c693dd341bc.zip |
Reduce size of saved/restored signal masks.
On glibc, sigset_t has a ridiculous size: one kilobyte!
The kernel doesn't access most of it in the sigprocmask call.
Yet it blows up the size of our dynamic frames quite a lot.
In this commit, we define a small_sigset_t type and
use that instead. We convert to the bloated one when
calling the library.
* signal.c (sig_blocked_cache): Type changes to small_sigset_t.
(sig_reload_cache): Retrieve signal mask with sigprocmask into a local
variable, then copy a small portion from that to sig_blocked_cache.
(small_sigfillset): New static function.
(set_sig_handler): Local variables of sigset_t changed to small_sigset_t.
(sig_mask): Arguments are pointers to small_sigset_t. Conversion to
sigset_t done around the call to sigprocmask.
* signal.h (copy_sigset): Inline funtion removed.
(small_sigset_t): New struct type.
(extended_jmp_buf): Member blocked changed to small_sigset_t.
(extended_setjmp): Cast expression updated with small_sigset_t *.
(extended_longjmp): Use assignment instead of copy_sigset.
(sig_blocked_cache, sig_mask): Declarations updated.
-rw-r--r-- | signal.c | 32 | ||||
-rw-r--r-- | signal.h | 22 |
2 files changed, 31 insertions, 23 deletions
@@ -50,7 +50,7 @@ volatile sig_atomic_t async_sig_enabled = 0; static volatile sig_atomic_t interrupt_count = 0; -sigset_t sig_blocked_cache; +small_sigset_t sig_blocked_cache; static val sig_lambda[MAX_SIG]; volatile unsigned long sig_deferred; @@ -69,7 +69,9 @@ static int is_cpu_exception(int sig) static int sig_reload_cache(void) { - return sigprocmask(SIG_BLOCK, 0, &sig_blocked_cache); + sigset_t set; + return sigprocmask(SIG_BLOCK, 0, &set); + memcpy(&sig_blocked_cache, &set, sizeof sig_blocked_cache); } static void sig_handler(int sig) @@ -246,14 +248,19 @@ static void teardown_alt_stack(void) #endif +static void small_sigfillset(small_sigset_t *ss) +{ + ss->set = (uint_ptr_t) -1; +} + val set_sig_handler(val signo, val lambda) { static struct sigaction blank; cnum sig = c_num(signo); val old_lambda; - sigset_t block, saved; + small_sigset_t block, saved; - sigfillset(&block); + small_sigfillset(&block); sig_mask(SIG_BLOCK, &block, &saved); if (sig < 0 || sig >= MAX_SIG) @@ -342,10 +349,10 @@ static void mem_clr_bits(mem_t *target, const mem_t *bits, size_t size) *target++ &= ~*bits++; } -int sig_mask(int how, const sigset_t *set, sigset_t *oldset) +int sig_mask(int how, const small_sigset_t *set, small_sigset_t *oldset) { - sigset_t newset; - const sigset_t *pnew; + small_sigset_t newset; + const small_sigset_t *pnew; switch (how) { case SIG_SETMASK: @@ -367,11 +374,18 @@ int sig_mask(int how, const sigset_t *set, sigset_t *oldset) } if (memcmp(&sig_blocked_cache, pnew, sizeof *pnew) != 0) { + static sigset_t blank; + sigset_t real_newset = blank, real_oldset; sig_blocked_cache = *pnew; + int ret; #if HAVE_VALGRIND - VALGRIND_MAKE_MEM_DEFINED(oldset, sizeof *oldset); + VALGRIND_MAKE_MEM_DEFINED(real_oldset, sizeof real_oldset); #endif - return sigprocmask(SIG_SETMASK, &sig_blocked_cache, oldset); + memcpy(&real_newset, &sig_blocked_cache, sizeof sig_blocked_cache); + ret = sigprocmask(SIG_SETMASK, &real_newset, &real_oldset); + if (ret == 0 && oldset != 0) + memcpy(oldset, &real_oldset, sizeof *oldset); + return ret; } if (oldset != 0) @@ -111,14 +111,9 @@ void jmp_restore(struct jmp *, int); #if HAVE_POSIX_SIGS -INLINE void copy_sigset(volatile sigset_t *dest, const sigset_t *src) -{ -#ifdef __cplusplus - *strip_qual(sigset_t *, dest) = *src; -#else - *dest = *src; -#endif -} +typedef struct { + uint_ptr_t set; +} small_sigset_t; #define sig_save_enable \ do { \ @@ -159,7 +154,7 @@ INLINE val sig_check_fast(void) typedef struct { struct jmp jb; volatile sig_atomic_t se; - volatile sigset_t blocked; + volatile small_sigset_t blocked; volatile val de; volatile int gc; val **volatile gc_pt; @@ -174,7 +169,7 @@ typedef struct { gc_enabled = (EJB).gc, \ gc_prot_top = (EJB).gc_pt, \ sig_mask(SIG_SETMASK, \ - strip_qual(sigset_t *, \ + strip_qual(small_sigset_t *, \ &(EJB).blocked), 0), \ EJ_OPT_REST(EJB) \ (EJB).rv) \ @@ -182,15 +177,14 @@ typedef struct { (EJB).de = dyn_env, \ (EJB).gc = gc_enabled, \ (EJB).gc_pt = gc_prot_top, \ - copy_sigset(&(EJB).blocked, \ - &sig_blocked_cache), \ + (EJB).blocked.set = sig_blocked_cache.set,\ EJ_OPT_SAVE(EJB) \ 0)) #define extended_longjmp(EJB, ARG) \ ((EJB).rv = (ARG), jmp_restore(&(EJB).jb, 1)) -extern sigset_t sig_blocked_cache; +extern small_sigset_t sig_blocked_cache; extern volatile sig_atomic_t async_sig_enabled; #else @@ -238,7 +232,7 @@ void sig_init(void); val set_sig_handler(val signo, val lambda); val get_sig_handler(val signo); #if HAVE_POSIX_SIGS -int sig_mask(int how, const sigset_t *set, sigset_t *oldset); +int sig_mask(int how, const small_sigset_t *set, small_sigset_t *oldset); #endif #if HAVE_ITIMER |