]> granicus.if.org Git - strace/commitdiff
strace: further optimize unblocking of the delay signal handler
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 23 Mar 2018 00:20:33 +0000 (00:20 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 23 Mar 2018 00:20:33 +0000 (00:20 +0000)
Do not unblock the delay signal handler unless the delay timer is armed.

* defs.h (is_delay_timer_created): Remove.
(is_delay_timer_armed, delay_timer_expired): New prototypes.
* delay.c (delay_timer_is_armed): New static variable.
(is_delay_timer_created): Add static qualifier.
(is_delay_timer_armed, delay_timer_expired): New functions.
(arm_delay_timer): Set delay_timer_is_armed.
* strace.c (next_event): Use is_delay_timer_armed instead of
is_delay_timer_created to check whether the delay signal handler
has to be unblocked.
(timer_sighandler): Invoke delay_timer_expired.

defs.h
delay.c
strace.c

diff --git a/defs.h b/defs.h
index ef13552800981a6b71380ae211767198cb3f527a..3899dd3de0071447a7c4610dca8d4f779bfdf17c 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1026,7 +1026,8 @@ extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
 
 uint16_t alloc_delay_data(void);
 void fill_delay_data(uint16_t delay_idx, int intval, bool isenter);
-bool is_delay_timer_created(void);
+bool is_delay_timer_armed(void);
+void delay_timer_expired(void);
 void arm_delay_timer(const struct tcb *);
 void delay_tcb(struct tcb *, uint16_t delay_idx, bool isenter);
 
diff --git a/delay.c b/delay.c
index 8adf4cc5be28accdd82bf6cddbfc38a177da756f..86dd828e79de4dcd406dc1bae1528861e0cf8625 100644 (file)
--- a/delay.c
+++ b/delay.c
@@ -37,6 +37,7 @@ static size_t delay_data_vec_capacity; /* size of the arena */
 static size_t delay_data_vec_size;     /* size of the used arena */
 
 static timer_t delay_timer = (timer_t) -1;
+static bool delay_timer_is_armed;
 
 static void
 expand_delay_data_vec(void)
@@ -80,12 +81,24 @@ fill_delay_data(uint16_t delay_idx, int intval, bool isenter)
        ts->tv_nsec = intval % 1000000 * 1000;
 }
 
-bool
+static bool
 is_delay_timer_created(void)
 {
        return delay_timer != (timer_t) -1;
 }
 
+bool
+is_delay_timer_armed(void)
+{
+       return delay_timer_is_armed;
+}
+
+void
+delay_timer_expired(void)
+{
+       delay_timer_is_armed = false;
+}
+
 void
 arm_delay_timer(const struct tcb *const tcp)
 {
@@ -96,6 +109,8 @@ arm_delay_timer(const struct tcb *const tcp)
        if (timer_settime(delay_timer, TIMER_ABSTIME, &its, NULL))
                perror_msg_and_die("timer_settime");
 
+       delay_timer_is_armed = true;
+
        debug_func_msg("timer set to %lld.%09ld for pid %d",
                       (long long) tcp->delay_expiration_time.tv_sec,
                       (long) tcp->delay_expiration_time.tv_nsec,
index 16b1a8648f5df91ae711fb32b47322ff835e939f..1493e9d900e4ab1e906aba95f1ec782871652ada 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -2236,7 +2236,7 @@ next_event(int *pstatus, siginfo_t *si)
                        return TE_BREAK;
        }
 
-       const bool unblock_delay_timer = is_delay_timer_created();
+       const bool unblock_delay_timer = is_delay_timer_armed();
 
        /*
         * The window of opportunity to handle expirations
@@ -2607,6 +2607,8 @@ restart_delayed_tcbs(void)
 static void
 timer_sighandler(int sig)
 {
+       delay_timer_expired();
+
        if (restart_failed)
                return;