This is the mail archive of the cygwin 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]
Other format: [Raw text]

Re: Cygwin Performance and stat()


So here is an example of a performance gain by not using cygwin stat().  I
did this patch in about an hour (with the help of some git code), so I
wouldn't recommend it for any production use.

On a dry run rsync from my local drive to my NAS (105GB, 34k files, 4k
directories).  The current release cygwin rsync did it in [36m:43s], with
the patch (below) applied, it dropped to [04m:48s].


$ diff rsync-3.0.7-1/src/rsync-3.0.7/syscall.c
fast-rsync-3.0.7-1/src/rsync-3.0.7/syscall.c
31a32,37
> // Get rid of a define for WINBOOL
> #define __OBJC__
> #define WIN32_LEAN_AND_MEAN
> #include <windows.h>
> #include <sys/cygwin.h>
>
242a249
>    printf( "doing [stat]\n" );
249a257,277
> static inline time_t filetime_to_time_t(const FILETIME *ft)
> {
>   long long winTime = ((long long)ft->dwHighDateTime << 32) +
ft->dwLowDateTime;
>   winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
>   winTime /= 10000000;     /* Nano to seconds resolution */
>   return (time_t)winTime;
> }
>
> static inline void filetime_to_timespec(const FILETIME *ft, struct
timespec *ts)
> {
>    long long winTime = ((long long)ft->dwHighDateTime << 32) +
ft->dwLowDateTime;
>    winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
>    ts->tv_sec = (time_t)(winTime/10000000); /* 100-nanosecond interval
to seconds */
>    ts->tv_nsec = (long)(winTime - ts->tv_sec*10000000LL) * 100; /*
nanoseconds */
> }
>
>
>
> #define size_to_blocks(s) (((s)+511)/512)
>
>
251a280,344
> #if 1
>    char path[ 1024 ];
>    WIN32_FILE_ATTRIBUTE_DATA fdata;
>    int fMode;
>
>    cygwin_conv_path( CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, fname, path,
1024 );
>
>    if ( GetFileAttributesEx( path, GetFileExInfoStandard, &fdata ) )
>    {
>       // if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
>       //    !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
>       //    return -1;
>       // printf( "GetFileAttributesEx() OK\n" );
>
>       if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
>          fMode |= S_IFDIR;
>       else
>          fMode |= S_IFREG;
>       if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
>          fMode |= S_IWRITE;
>
>       st->st_ino = 0;
>       st->st_gid = st->st_uid = 0;
>       st->st_nlink = 1;
>       st->st_mode = fMode;
>       st->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
>          fdata.nFileSizeLow;
>       st->st_blocks = size_to_blocks(st->st_size);
>       st->st_dev = st->st_rdev = 0;
>       filetime_to_timespec(&fdata.ftLastAccessTime, &st->st_atim);
>       filetime_to_timespec(&fdata.ftLastWriteTime, &st->st_mtim);
>       filetime_to_timespec(&fdata.ftCreationTime, &st->st_ctim);
>       errno = 0;
>       return 0;
>    }
>    else
>    {
>       // rsyserr(FERROR, errno, "GetFileAttributesEx() failed %s", path );
>       // printf( "GetFileAttributesEx() FAILED\n" );
>       errno = ENOENT;
>       return( -1 );
>    }
>
>
>    switch (GetLastError())
>    {
>       case ERROR_ACCESS_DENIED:
>       case ERROR_SHARING_VIOLATION:
>       case ERROR_LOCK_VIOLATION:
>       case ERROR_SHARING_BUFFER_EXCEEDED:
>          errno = EACCES;
>          break;
>       case ERROR_BUFFER_OVERFLOW:
>          errno = ENAMETOOLONG;
>          break;
>       case ERROR_NOT_ENOUGH_MEMORY:
>          errno = ENOMEM;
>          break;
>       default:
>          break;
>    }
>
>    return( -1 );
> #endif
>
264a358
>    // printf( "doing [fstat]\n" );



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


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