From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 299 invoked by alias); 21 Oct 2013 15:30:35 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 31869 Received: (qmail 26623 invoked from network); 21 Oct 2013 15:30:29 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <131021083018.ZM23575@torch.brasslantern.com> Date: Mon, 21 Oct 2013 08:30:18 -0700 In-reply-to: <1382351360.2595.0@numa-i.igpm.rwth-aachen.de> Comments: In reply to Helmut Jarausch "100,000 calls to rt_sigprocmask for a single ?" (Oct 21, 12:29pm) References: <1382351360.2595.0@numa-i.igpm.rwth-aachen.de> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: Helmut Jarausch , zsh-workers@zsh.org Subject: Re: 100,000 calls to rt_sigprocmask for a single ? MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Oct 21, 12:29pm, Helmut Jarausch wrote: } } ./hg } } takes more than 20 seconds. An strace shows that zsh executes nearly } 100,000 calls to rt_sigprocmask Zsh started fiddling with the WINCH signal pretty recently, May 2013. System calls were getting interrupted by things like window managers that move and resize windows automatically (probably for "zoom" visual effects when popping open the terminal app) combined with terminal emulators that start the shell before the window is fully opened. It's a fairly nasty problem; you want the shell to respond relatively quickly to the window size changing for visual feedback, but most of the code has to keep the signal blocked so system calls aren't borked. We adopted the strategy of unblocking the signal whenever the shell may be blocked for some other reason (usually, input) and then blocking it again immediately. Given your description of the strace, the most likely bit of code to be executing is input.c:shingetline() -- it's the only place where you'd see unblock/block pairs without another system call (select or poll or read) in between [because it's wrapped around fgetc() which buffers the input so there needn't be a system call every time], and in that close proximity to a memory allocation, and in a tight loop. BUT ... that implies that a lot of input (50k or so, if it's 2600-some unblock/block pairs repeated 20 times) is being consumed (e.g., by the "source" or "." command). Is it always 2602 unblock/block repeats or does it vary? Still, as a first check, you could try the patch below, which should cut down the number of block/unblock pairs or at least reverse the order you see them (i.e., the SIG_BLOCK should preceed SIG_UNBLOCK in most of the repetitions). If this does fix it, your next task would be to figure out why the shingetline() call is happening during that particular completion. diff --git a/Src/input.c b/Src/input.c index 9bd9663..4ac7e6e 100644 --- a/Src/input.c +++ b/Src/input.c @@ -142,14 +142,14 @@ shingetline(void) char *p; p = buf; + winch_unblock(); for (;;) { - winch_unblock(); do { errno = 0; c = fgetc(bshin); } while (c < 0 && errno == EINTR); - winch_block(); if (c < 0 || c == '\n') { + winch_block(); if (c == '\n') *p++ = '\n'; if (p > buf) { @@ -165,11 +165,13 @@ shingetline(void) } else *p++ = c; if (p >= buf + BUFSIZ - 1) { + winch_block(); line = zrealloc(line, ll + (p - buf) + 1); memcpy(line + ll, buf, p - buf); ll += p - buf; line[ll] = '\0'; p = buf; + winch_unblock(); } } }