This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: cygwin slowdown in current cvs version


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;
    }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]