-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hannu Kotipalo kirjoitti Sunnuntai 10. Marraskuuta 2002 14:49:
> are speeded up a lot. For example, wzebra opening database readout :
>
>  Before : over 700 seconds
>  After : 12-13 seconds
>
A new version, replacing the earlier.
I tested this with a few applications, looks like for most of applications 
this has not much effect. However, wzebra proves that the effect can be 
enourmous on some. (And Simcity tellls that it can be negative on some 
applications :-(

Changelog:
- - This patch speeds up applications reading files by small packets
- - 4 static 512 byte buffers (can be defined for n * n buffers, see file.c)
- - Buffer invalidation mechanism changed. With several buffers this *should* 
fix the reported (thans to Tony Lambregts) slowdown on SIMCITY2000. I haven't 
got it, cannot test. Please test and see -debugmsg +file, it can give a hint 
about needed buffers and their sizes. 

diff is made by 
'diff -urN wine-20021031/ wine-20021031-patched/ > patch.diff'

Hannu
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE90XAUuA3ghgc3fUsRAuk7AKDwLK/E4WzkCHMf0j615aktFuiWEgCgt0xq
FLujbIUEEASUu9K51siPOwA=
=RxKU
-----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	Tue Nov 12 21:44:01 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,15 @@
 
 mode_t FILE_umask;
 
+/* Buffers and pointers for buffered ReadFile */
+#define RFbufsize 0x200
+#define RFBuffers 4
+static HANDLE hRFBufferedFile[RFBuffers+1]={0,0,0,0,0};
+static char RFBuf[RFBuffers][RFbufsize];
+static WORD RFBufPtr[RFBuffers];
+static WORD RFBufEnd[RFBuffers];
+
+
 extern HANDLE WINAPI FILE_SmbOpen(LPCSTR name);
 
 /***********************************************************************
@@ -421,7 +432,7 @@
                         DWORD attributes, HANDLE template, BOOL fail_read_only,
                         UINT drive_type )
 {
-    unsigned int err;
+    unsigned int err,i;
     HANDLE ret;
 
     for (;;)
@@ -468,6 +479,12 @@
         }
 
         if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError());
+	for (i=0; i<RFBuffers; i++)
+	if (ret==hRFBufferedFile[i])
+	{
+	    //RFBufPtr[i]=RFBufEnd[i]=0;
+	    hRFBufferedFile[i]=0;
+	}
         return ret;
     }
 }
@@ -1514,6 +1531,7 @@
  */
 HFILE16 WINAPI _lclose16( HFILE16 hFile )
 {
+int i;
     if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile])
     {
         SetLastError( ERROR_INVALID_HANDLE );
@@ -1521,6 +1539,13 @@
     }
     TRACE("%d (handle32=%d)\n", hFile, dos_handles[hFile] );
     CloseHandle( dos_handles[hFile] );
+    for (i=0; i<RFBuffers; i++)
+    if (dos_handles[hFile]==hRFBufferedFile[i])
+    {
+    //RFBufPtr[i]=RFBufEnd[i]=0;
+        hRFBufferedFile[i]=0;
+    }
+
     dos_handles[hFile] = 0;
     return 0;
 }
@@ -1531,7 +1556,14 @@
  */
 HFILE WINAPI _lclose( HFILE hFile )
 {
+int i;
     TRACE("handle %d\n", hFile );
+    for (i=0; i<RFBuffers; i++)
+    if ((HANDLE)hFile==hRFBufferedFile[i])
+    {
+    //RFBufPtr[i]=RFBufEnd[i]=0;
+        hRFBufferedFile[i]=0;
+    }
     return CloseHandle( (HANDLE)hFile ) ? 0 : HFILE_ERROR;
 }
 
@@ -1774,9 +1806,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 +1908,104 @@
     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;
+int iBufferID;
+	//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 */
+	for (iBufferID=0; iBufferID<RFBuffers; iBufferID++)
+	{
+	    	if (hFile==hRFBufferedFile[iBufferID])
+		break;
+	}
+	while (bytesToRead)
+	{
+	    	if (hFile==hRFBufferedFile[iBufferID])
+		{
+			if (RFBufPtr[iBufferID] == RFBufEnd[iBufferID])
+			{
+			        TRACE("RF Fill buffer %p\n",&RFBuf);
+				RFBufPtr[iBufferID]=0;
+				if (!ubReadFile(hFile, &RFBuf[iBufferID], RFbufsize, &BufRead, NULL)) return FALSE;
+				RFBufEnd[iBufferID]=(WORD)BufRead;
+				if (RFBufEnd[iBufferID]==0) return TRUE;
+			}
+			if ((RFBufEnd[iBufferID]-RFBufPtr[iBufferID])>=bytesToRead)
+			{
+			        TRACE("RF Use buffer %p <- %p %ld bytes\n",buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],bytesToRead);
+				memcpy(buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],bytesToRead);
+				RFBufPtr[iBufferID] += bytesToRead;
+				if (bytesRead) *bytesRead += bytesToRead;
+				//bytesToRead=0;
+				return TRUE;
+			}
+			else
+			{
+			        TRACE("RF Use buffer to the end\n");
+				memcpy(buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				if (bytesRead) *bytesRead += (RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				bytesToRead-=(RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				buffer+=(RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				RFBufPtr[iBufferID] = RFBufEnd[iBufferID];
+				hRFBufferedFile[iBufferID]=0;
+				if (bytesToRead)
+				{
+					if (ubReadFile(hFile, buffer, bytesToRead, &BufRead, NULL))
+					{
+						if (bytesRead) *bytesRead += BufRead;
+						return TRUE;
+					}
+					else
+						return FALSE;
+				}
+				else
+					return TRUE;
+			}
+		}
+		else
+		{
+			if ((bytesToRead>=RFbufsize)||overlapped)
+			{
+			        TRACE("RF NON_BUFFERED\n");
+				return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped);
+			}
+			else
+			{
+				for (iBufferID=0; iBufferID<RFBuffers; iBufferID++)
+				{
+	    				if (hRFBufferedFile[iBufferID]==0)
+					break;
+				}
+				if (iBufferID>=RFBuffers)
+				{
+				        TRACE("RF NO FREE BUFFERS\n");
+					return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped);
+				}
+				//if (hRFBufferedFile)
+				//{ // invalidate buffer
+				//    ubSetFilePointer(hRFBufferedFile, (long int)RFBufPtr-RFBufEnd, NULL,FILE_CURRENT);
+				//}
+				hRFBufferedFile[iBufferID]=hFile;
+			        TRACE("RF Assign buffer to %d\n",hRFBufferedFile[iBufferID]);
+				RFBufPtr[iBufferID]=RFBufEnd[iBufferID]=0;
+			}
+		}
+	}
+	return TRUE;
+}
 
 /***********************************************************************
  *             FILE_AsyncWriteService      (INTERNAL)
@@ -2177,7 +2308,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 +2334,23 @@
     return ret;
 }
 
+DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
+                             DWORD method )
+{
+int i;
+	for (i=0; i<RFBuffers; i++)
+	if (hRFBufferedFile[i]==hFile)
+	{ // invalidate buffer
+	    TRACE("RF Invalidate buffer\n");
+	    if (method==FILE_CURRENT)
+	    {
+	    	distance-=RFBufEnd[i]-RFBufPtr[i];
+            }
+	    hRFBufferedFile[i]=0;
+	    break;
+	}
+	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
 {

Reply via email to