[MSVCRT #3]Lower fragmentation of Readfile calls for TEXT mode
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Sun Oct 5 09:54:18 CDT 2003
Changelog
dlls/msvcrt/file.c: _read()
In _O_TEXT mode make Readfile Calls in Chunks as big as possible
This increases the the speed of XILINX ISE.
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
--- wine/dlls/msvcrt/file.c_fread 2003-10-05 13:45:24.000000000 +0200
+++ wine/dlls/msvcrt/file.c 2003-10-05 13:52:30.000000000 +0200
@@ -1164,11 +1164,47 @@
}
/*********************************************************************
+ * (internal) remove_cr
+ *
+ * Remove all \r inplace.
+ * return the number of \r removed
+ */
+
+static DWORD remove_cr(void *buf, unsigned int count)
+{
+ DWORD i=0;
+ char *bufstart=(char*)buf;
+ char *from;
+ char *to;
+
+ if (!count) return 0;
+ if (count == 1)
+ return (*bufstart == '\r')?1:0;
+ from= (char *)memchr((const void *) buf, '\r', count);
+ if (from)
+ to = (char *)memchr((const void *) (from+1),'\r',bufstart + count - from - 1);
+ while (from && to)
+ {
+ i++;
+ memmove((void*)from,(void*)(from+i), to - from -i);
+ from += to - from -i;
+ to = memchr((const void *) (to+1),'\r',bufstart + count - to +1);
+ }
+ if (from)
+ {
+ i++;
+ memmove((void*)from,(void*)(from+i), bufstart + count - from -i);
+ }
+ return i;
+}
+
+/*********************************************************************
* _read (MSVCRT.@)
*/
int _read(int fd, void *buf, unsigned int count)
{
- DWORD num_read;
+ DWORD num_read, all_read =0;
+ char *bufstart = (char*) buf;
HANDLE hand = msvcrt_fdtoh(fd);
/* Dont trace small reads, it gets *very* annoying */
@@ -1177,56 +1213,49 @@
if (hand == INVALID_HANDLE_VALUE)
return -1;
- if (MSVCRT_flags[fd]& _O_BINARY)
+ /* Reading single bytes in O_TEXT mode makes things slow
+ * So read big chunks, then remove the \r in memory and try reading
+ * the rest until the request is satisfied or EOF is met
+ */
+ while ( all_read < count)
{
- if (ReadFile(hand, buf, count, &num_read, NULL))
+ if (ReadFile(hand, bufstart+all_read, count - all_read, &num_read, NULL))
{
- if (num_read != count && MSVCRT_files[fd])
+ if (num_read != (count- all_read))
{
TRACE(":EOF\n");
+ if ( MSVCRT_files[fd])
+ {
MSVCRT_flags[fd] |= MSVCRT__IOEOF;
/*
MSVCRT_files[fd]->_flag |= MSVCRT__IOEOF;
*/
}
- TRACE("%s\n",debugstr_an(buf,num_read));
- return num_read;
- }
- TRACE(":failed-last error (%ld)\n",GetLastError());
- if (MSVCRT_files[fd])
- MSVCRT_files[fd]->_flag |= MSVCRT__IOERR;
- return -1;
+ if ((MSVCRT_flags[fd]& _O_BINARY ) != _O_BINARY )
+ num_read -= remove_cr(bufstart+all_read,num_read);
+ all_read += num_read;
+ if (count > 4)
+ TRACE("%s\n",debugstr_an(buf,all_read));
+ return all_read;
}
- else
- {
- char cc, *s=(char*)buf,* buf_start=(char*)buf;
- unsigned int i;
-
- for (i = 0 , num_read = 1; i < count && (num_read == 1);)
+ if ((MSVCRT_flags[fd]& _O_BINARY ) != _O_BINARY )
{
- if (ReadFile(hand, &cc, 1, &num_read, NULL))
- if (num_read == 1)
- if ((cc != '\r') || MSVCRT_flags[fd] & _O_BINARY)
- {
- *s++ = (char)cc;
- i++;
+ num_read -= remove_cr(bufstart+all_read,num_read);
}
+ all_read += num_read;
}
- if (num_read != 1)
+ else
{
- TRACE(":EOF\n");
+ TRACE(":failed-last error (%ld)\n",GetLastError());
if (MSVCRT_files[fd])
- MSVCRT_flags[fd] |= MSVCRT__IOEOF;
- /*
- MSVCRT_files[fd]->_flag |= MSVCRT__IOEOF;
- */
+ MSVCRT_files[fd]->_flag |= MSVCRT__IOERR;
+ return -1;
+ }
}
if (count > 4)
- TRACE("%s\n",debugstr_an(buf_start, s-buf_start));
- return s-buf_start;
- }
- return 0;
+ TRACE("%s\n",debugstr_an(buf, all_read));
+ return all_read;
}
/*********************************************************************
More information about the wine-patches
mailing list