Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Performance increase by limiting the call to sygprocmask



Hello,

I found that sygprocmask system call is being called lots of times during the startup of zsh. most of them were inside the function `shingetline`.

So This patch add a flag into the function, so that it only call `winch_(un)?block` witch make the system call only if needed.

I have included a benchmarking test after and before the patch, as you can see it got rid of 90% of the system calls, and zsh startup and exit times got reduced by 20%.

Kind regards,

--
Mohamed Elawadi
mohamed@xxxxxxxxxxx

➜  code git:(master) ✗ /usr/bin/time -p bash -c 'for i in $(seq 1 100); do zsh -i -c "exit"; done'
real 29.93
user 16.90
sys 7.84

➜  code git:(master) ✗ strace -cf zsh -i -c 'exit'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 68.12    0.012507           0    169032           rt_sigprocmask
 24.79    0.004552          71        64        28 wait4
  3.13    0.000574           2       271           getdents
------ ----------- ----------- --------- --------- ----------------
100.00    0.018361                180201      1465 total

After applying the patch

➜  code git:(master) ✗ /usr/bin/time -p bash -c 'for i in $(seq 1 100); do zsh -i -c "exit"; done'
real 25.08
user 14.52
sys 5.49

➜  code git:(master) ✗ strace -cf zsh -i -c 'exit'

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 69.71    0.004623          72        64        28 wait4
  8.40    0.000557           0     16364           rt_sigprocmask
  4.27    0.000283           9        33           clone
  2.86    0.000190           1       271           getdents
------ ----------- ----------- --------- --------- ----------------
100.00    0.006632                 27476      1464 total

From ab3624c2901007e991efc9624fa8d55c0b15013f Mon Sep 17 00:00:00 2001
From: Mohamed Elawadi <mohamed@xxxxxxxxxxx>
Date: Fri, 16 Sep 2016 16:24:58 +0200
Subject: [PATCH] call winch_block inside shingetline only if needed

---
 Src/input.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/Src/input.c b/Src/input.c
index eb968ea..7de4e76 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -142,17 +142,24 @@ shingetline(void)
     char buf[BUFSIZ];
     char *p;
     int q = queue_signal_level();
+    int winch_blocked = 1;
 
     p = buf;
     for (;;) {
-	winch_unblock();
+	if (winch_blocked) {
+		winch_unblock();
+		winch_blocked = 0;
+	}
 	dont_queue_signals();
 	do {
 	    errno = 0;
 	    c = fgetc(bshin);
 	} while (c < 0 && errno == EINTR);
 	if (c < 0 || c == '\n') {
-	    winch_block();
+		if (! winch_blocked) {
+			winch_block();
+			winch_blocked = 1;
+		}
 	    restore_queue_signals(q);
 	    if (c == '\n')
 		*p++ = '\n';
@@ -169,7 +176,10 @@ shingetline(void)
 	} else
 	    *p++ = c;
 	if (p >= buf + BUFSIZ - 1) {
-	    winch_block();
+		if (! winch_blocked) {
+			winch_block();
+			winch_blocked = 1;
+		}
 	    queue_signals();
 	    line = zrealloc(line, ll + (p - buf) + 1);
 	    memcpy(line + ll, buf, p - buf);
-- 
2.5.0



Messages sorted by: Reverse Date, Date, Thread, Author