Cygwin Filesystem Performance degradation 1.7.5 vs 1.7.7, and methods for improving performance

Derry Shribman derry@hola.org
Wed Sep 29 09:44:00 GMT 2010


Hi,

Another way to go about handling Cygwin's performance is to add cygwin1.sys as a 
dynamically loaded kernel driver to the NTOS kernel.

This is not as scary as it might sound at start.

1) It does not mean the whole cygwin1.dll code needs to be ported to kernel 
mode. It only means that working around the 1% of corners of Win32 user-mode API 
limitations.

2) It does not mean that from now running cygwin exe's require installing 
cygwin1.sys. The cygwin1.dll opens a handle to Cygwin's kernel at the beginning 
(h_kernel = CreateFile("\\Devices\Cygwin")), and uses the acceleration only if 
it succeeds.

3) It does not mean that a reboot is required. In Windoes NT kernel SYS files 
can be loaded/unloaded dynamically.

So the kernel module will be a kind of tiny helper, to solve places where a 
single POSIX API (such as stat...) requires multiple Win32 APIs (CreateFile(), 
Query(), CloseFile() x 3 times...), and only in 'hotspots' (places that are 
critical for performance).

A good example for this is the Process Hacker:
http://processhacker.sourceforge.net/

Win32 supplies most of the APIs needed to implement it, but they dont always 
work correctly... and sometimes even get stuck. So they implemented a small 
kernel helper, and gets loaded automatically by the user-mode GUI application on 
start. The gui application also knows how to revert back to using only Win32 if 
the SYS file does not exist or did not load.

For Cygin this means that Cygwin would run in today's speed if the CYGWIN1.SYS 
does not exist or was not loaded, but if it is: it will be able to improve 
filesystem performance x10...

Back to the stat() API:
In the kernel it can be implemented without opening a real handle by (from 
ddk/inc/wdm.h):

typedef struct _FILE_BASIC_INFORMATION {
     LARGE_INTEGER CreationTime;
     LARGE_INTEGER LastAccessTime;
     LARGE_INTEGER LastWriteTime;
     LARGE_INTEGER ChangeTime;
     ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

BOOLEAN FastIoQueryBasicInfo (
     __in struct _FILE_OBJECT *FileObject,
     __in BOOLEAN Wait,
     __out PFILE_BASIC_INFORMATION Buffer,
     __out PIO_STATUS_BLOCK IoStatus,
     __in struct _DEVICE_OBJECT *DeviceObject
     );

typedef struct _FILE_STANDARD_INFORMATION {
     LARGE_INTEGER AllocationSize;
     LARGE_INTEGER EndOfFile;
     ULONG NumberOfLinks;
     BOOLEAN DeletePending;
     BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;

BOOLEAN FastIoQueryStandardInformation (
     __in struct _FILE_OBJECT *FileObject,
     __in BOOLEAN Wait,
     __out PFILE_STANDARD_INFORMATION Buffer,
     __out PIO_STATUS_BLOCK IoStatus,
     __in struct _DEVICE_OBJECT *DeviceObject
     );

The FastIo APIs in the kernel dont require a real FileObject: they also work 
with dummy file objects so you dont really "open" then file.

A tiny Cygwin helper kernel driver can assist in making stat().
And in the future can assist solving POSIX compliance issues where the existing 
W32 user API is just not enough...

Derry Shribman



More information about the Cygwin-developers mailing list