-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Here is an EXPERIMENTAL patch supplementing a read-ahead buffer for ReadFile. With this patch applications reading a file with small packets are speeded up a lot. For example, wzebra opening database readout : Before : over 700 seconds After : 12-13 seconds I made this to point out that there is something to fix on file reads. This is a quick fix for this particular program (wzebra). I encounter everybody interested to keep working on this and fixing this on some better way! I do not suggest that this should be added to distributed version of wine. It should be developed (and TESTED!) further before including. What this does: 1. ReadFile is renamed to ubReadFile (unbuffered) 2. New ReadFile has one static 1k read-ahead buffer for last used file What this shgould do: 1. Dynamic buffer for every opened file. I did not found code for 'CloseFile' :-( ps. Could you PLEASE add following line to the mailing list archive configuration file: - ------------------ spamprotect = 1 - --------------- I quess it is too late :-( -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQE9zlX3uA3ghgc3fUsRArTXAJ0fiv5D/TFBi+ONyyM+fpwglRg59QCgxbLk e5kXOt/PmX/eEb3FM/qiK7I= =wQGe -----END PGP SIGNATURE-----
diff -urN wine-20021031/files/file.c wine-20021031-patched/files/file.c --- wine-20021031/files/file.c Fri Oct 25 06:32:11 2002 +++ wine-20021031-patched/files/file.c Sun Nov 10 11:12:02 2002 @@ -18,6 +18,8 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * 10.11.2002 HKo + * - Read-ahead buffered ReadFile * TODO: * Fix the CopyFileEx methods to implement the "extended" functionality. * Right now, they simply call the CopyFile method. @@ -89,6 +91,13 @@ mode_t FILE_umask; +/* Buffers and pointers for buffered ReadFile */ +static HANDLE hRFBufferedFile=0; +static char RFBuf[0x400]; +static WORD RFBufPtr=0; +static WORD RFBufEnd=0; + + extern HANDLE WINAPI FILE_SmbOpen(LPCSTR name); /*********************************************************************** @@ -1774,9 +1783,10 @@ } /*********************************************************************** - * ReadFile (KERNEL32.@) + * ubReadFile (KERNEL32.@) + * unbuffered ReadFile */ -BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, +BOOL ubReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped ) { int unix_handle, result, flags; @@ -1875,6 +1885,75 @@ return TRUE; } +//Prototype for ubSetFilePointer needed for buffered ReadFile +DWORD ubSetFilePointer( HANDLE hFile, LONG distance, LONG *highword, + DWORD method ); + +/*********************************************************************** + * ReadFile (KERNEL32.@) + */ + +BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, + LPDWORD bytesRead, LPOVERLAPPED overlapped ) +{ + +DWORD BufRead; + //return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped); + TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead, + bytesRead, overlapped ); + if (bytesRead) *bytesRead = 0; /* Do this before anything else */ + while (bytesToRead) + { + if (hFile==hRFBufferedFile) + { + if (RFBufPtr == RFBufEnd) + { + TRACE("RF Fill buffer %p\n",&RFBuf); + RFBufPtr=0; + if (!ubReadFile(hFile, &RFBuf, 0x400, &BufRead, NULL)) return FALSE; + RFBufEnd=(WORD)BufRead; + if (RFBufEnd==0) return TRUE; + } + if ((RFBufEnd-RFBufPtr)>=bytesToRead) + { + TRACE("RF Use buffer %p <- %p %ld bytes\n",buffer,&RFBuf[RFBufPtr],bytesToRead); + memcpy(buffer,&RFBuf[RFBufPtr],bytesToRead); + RFBufPtr += bytesToRead; + if (bytesRead) *bytesRead += bytesToRead; + //bytesToRead=0; + return TRUE; + } + else + { + TRACE("RF Use buffer to the end\n"); + memcpy(buffer,&RFBuf[RFBufPtr],RFBufEnd-RFBufPtr); + if (bytesRead) *bytesRead += (RFBufEnd-RFBufPtr); + bytesToRead-=(RFBufEnd-RFBufPtr); + buffer+=(RFBufEnd-RFBufPtr); + RFBufPtr = RFBufEnd; + } + } + else + { + if ((bytesToRead>=0x400)||overlapped) + { + TRACE("RF NON_BUFFERED\n"); + return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped); + } + else + { + if (hRFBufferedFile) + { // invalidate buffer + ubSetFilePointer(hRFBufferedFile, (long int)RFBufPtr-RFBufEnd, NULL,FILE_CURRENT); + } + hRFBufferedFile=hFile; + TRACE("RF Assign buffer to %d\n",hRFBufferedFile); + RFBufPtr=RFBufEnd=0; + } + } + } + return TRUE; +} /*********************************************************************** * FILE_AsyncWriteService (INTERNAL) @@ -2177,7 +2256,7 @@ /*********************************************************************** * SetFilePointer (KERNEL32.@) */ -DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, +DWORD ubSetFilePointer( HANDLE hFile, LONG distance, LONG *highword, DWORD method ) { DWORD ret = INVALID_SET_FILE_POINTER; @@ -2203,6 +2282,17 @@ return ret; } +DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, + DWORD method ) +{ + if (hRFBufferedFile==hFile) + { // invalidate buffer + TRACE("RF Invalidate buffer\n"); + ubSetFilePointer(hRFBufferedFile, (long int)RFBufPtr-RFBufEnd, NULL,FILE_CURRENT); + RFBufPtr=RFBufEnd=0; + } + return ubSetFilePointer(hFile, distance, highword,method); +} /*********************************************************************** * _llseek (KERNEL.84) diff -urN wine-20021031/files/smb.h wine-20021031-patched/files/smb.h --- wine-20021031/files/smb.h Tue Aug 27 04:13:59 2002 +++ wine-20021031-patched/files/smb.h Thu Nov 7 01:13:54 2002 @@ -99,6 +99,8 @@ extern HANDLE WINAPI SMB_CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing, LPSECURITY_ATTRIBUTES sa, DWORD creation, DWORD attributes, HANDLE template ); +extern BOOL SMB_GetSmbInfo(HANDLE hFile, USHORT *tree_id, USHORT *user_id, USHORT *dialect, USHORT *file_id, LPDWORD offset); +extern BOOL SMB_SetOffset(HANDLE hFile, DWORD offset); typedef struct tagSMB_DIR {