Subject: Re: Slow shell script execution on Cygwin
From: Brian Dessent <[email-masked]>
To: [email-masked]
Date: Thu, 14 Apr 2005 16:21:45 -0700

Robert Ögren wrote:

> My questions for you:
> 1. Do these numbers seem reasonable?

Yes, unfortunately.  Heavy fork()-exec() based scripts just take
forever.

> 2. Is there anything (apart from cross-compiling on Linux :) ) that can
> be done to increase script execution speed?

You can try mounting your /usr/bin as cygexec.  The manpage for mount
has some information.  From my understanding, the way this works is that
when a Cygwin process goes to execute a binary, it checks the mount
table.  If that binary is mounted on a path that is marked "cygexec" it
assumes that it is a Cygwin binary and skips a bit of the normal
song-and-dance, because it knows that it can just communicate directly
with the child process via the Cygwin shared memory area after the
process has started.  I'm not entirely sure of how much of a speedup can
be expected, or whether it's significant or not, but it's worth testing.

Note that any non-Cygwin binaries in a directory mounted cygexec will
not work properly, so you have to mark them specifically as not being
cygwin programs.  In the stock Cygwin environment the only two such
programs under /usr/bin are cygcheck and strace.

I have found also that because a given binary can be called in several
different ways you have to include all of them.  E.g. strace could be
invoked as "/bin/strace" or "/usr/bin/strace.exe" and so on.  I use the
following two functions in my profile to enable and disable cygexec:

nocygexec="cygcheck strace"
cygbin="`cygpath -m /usr/bin`"

mkcygexec()
{
    for F in $nocygexec; do
        for G in /usr/bin /bin; do 
            mount -f -s -b -x "$cygbin/$F.exe" "$G/$F.exe"
            mount -f -s -b -x "$cygbin/$F" "$G/$F"
        done
    done
    mount -f -s -b -X "$cygbin" "/usr/bin"
    mount -f -s -b -X "$cygbin" "/bin"
}

rmcygexec()
{
    for F in $nocygexec; do
        for G in /usr/bin /bin; do
            umount "$G/$F.exe" 2>/dev/null
            umount "$G/$F" 2>/dev/null
        done
    done
    mount -f -s -b "$cygbin" "/usr/bin"
    umount "/bin" 2>/dev/null
}

With these you can just type "mkcygexec" and "rmcygexec" to toggle this
feature on and off.  I am not sure if the paranoia above is really
necessary.  It creates mount exceptions for each of the 4 variations of
strace and cygcheck, resulting in 8 somewhat spam-ism entries in the
mount table.  But I found that, for example, if I only mounted strace as
/usr/bin/strace that if I typed "/usr/bin/strace.exe" from the prompt it
would not recognise that it was not supposed to be treated as cygexec. 
You tend to invoke cygcheck and strace manually so I realize that the
possibility of this being an issue is quite remote, but I figured that
since I was writing functions to enable/disable cygexec that I might as
well just include all the combinations.

Brian

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/