Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Sat, 8 Sep 2001 16:44:12 -0400 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: Re: cygwin slowdown in current cvs version Message-ID: <20010908164412.B13528@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com References: <130160175780 DOT 20010908204017 AT logos-m DOT ru> <127165775081 DOT 20010908221336 AT logos-m DOT ru> <186168543292 DOT 20010908225944 AT logos-m DOT ru> <20010908155203 DOT C12571 AT redhat DOT com> <20010908222326 DOT B937 AT cygbert DOT vinschen DOT de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20010908222326.B937@cygbert.vinschen.de> User-Agent: Mutt/1.3.21i On Sat, Sep 08, 2001 at 10:23:26PM +0200, Corinna Vinschen wrote: >I think we should do that. I'm thinking of a different way to >do the same by starting an additional thread which wakes up on a >file change event or something. AFAICS there's a call in Windows >which allows that on changes to a directory but not on changes to >a single file. Anyway, perhaps that's sufficient for the /etc >directory. > >What do you think? This occurred to me prior to seeing your email. I actually just hacked passwd.cc to do this. AFAICT, things got *slower*. I don't understand it. I've included my hack below. I have no intention of checking it in, of course. If you want to apply this, do a 'patch -l' since there may be arbitrary whitespace changes. If we were going to do that, though, we should set up one global "change notification" handle for /etc/group and /etc/passwd, right? >> Have you compared the numbers against 1.3.2 by any chance? >> >> It occurred to me today that by moving the large zombies buffer into the >> heap, I ended up having fork always copy the array. I don't know which >> is better -- having a large dll with a slower load time vs more to copy >> on fork. > >Hum, I would prefer the larger DLL in that case. The DLL is loaded >once, the fork is pretty often. The DLL is loaded every time someone starts a cygwin application, whether it is forked or not. The data_nocopy segment has to be copied from "disk" (or maybe backing store) every time. That's where zombies used to live. My initial change only allocated zombies when it was needed but that failed due to the thread unsafety that I noted. The new method just allocates zombies whenever it is non-null. cgf Index: passwd.cc =================================================================== RCS file: /cvs/uberbaum/winsup/cygwin/passwd.cc,v retrieving revision 1.31 diff -p -w -r1.31 passwd.cc *** passwd.cc 2001/09/07 21:32:04 1.31 --- passwd.cc 2001/09/08 20:38:01 *************** class pwd_check { *** 45,77 **** pwd_state state; FILETIME last_modified; char pwd_w32[MAX_PATH]; ! public: ! pwd_check () : state (uninitialized) { last_modified.dwLowDateTime = last_modified.dwHighDateTime = 0; pwd_w32[0] = '\0'; } operator pwd_state () { - HANDLE h; - WIN32_FIND_DATA data; - if (!pwd_w32[0]) /* First call. */ { ! path_conv p ("/etc/passwd", PC_SYM_FOLLOW | PC_FULL); ! if (!p.error) ! strcpy (pwd_w32, p.get_win32 ()); ! } ! ! if ((h = FindFirstFile (pwd_w32, &data)) != INVALID_HANDLE_VALUE) { ! if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0) { ! state = uninitialized; ! last_modified = data.ftLastWriteTime; } ! FindClose (h); } return state; } --- 45,82 ---- pwd_state state; FILETIME last_modified; char pwd_w32[MAX_PATH]; ! HANDLE hchanged; public: ! pwd_check () : state (uninitialized), hchanged (NULL) { last_modified.dwLowDateTime = last_modified.dwHighDateTime = 0; pwd_w32[0] = '\0'; } operator pwd_state () { if (!pwd_w32[0]) /* First call. */ { ! char *p; ! path_conv pwd ("/etc/passwd", PC_SYM_FOLLOW | PC_FULL); ! if (!pwd.error) ! strcpy (pwd_w32, pwd); ! if ((p = strrchr (pwd, '\\')) != NULL) { ! *p = '\0'; ! hchanged = FindFirstChangeNotification (pwd, FALSE, ! FILE_NOTIFY_CHANGE_LAST_WRITE); ! if (hchanged == INVALID_HANDLE_VALUE) { ! system_printf ("hchanged '%s', %p, %E", (char *) pwd, hchanged); ! hchanged = NULL; ! } } ! } ! else if (hchanged && WaitForSingleObject (hchanged, 0) == WAIT_OBJECT_0) ! { ! (void) FindNextChangeNotification (hchanged); ! small_printf ("/etc changed\n"); ! state = uninitialized; } return state; }