Mail Archives: djgpp-workers/1998/07/26/06:20:22
A change to the code of `sync' made it call `_flush_disk_cache' in
v2.02. This is probably a good thing, since that's what it does on Unix.
However, since DJGPP calls `sync' just before it runs subsidiary programs,
this has a side effect of making subsidiary programs, especially if they
access files, significantly slower. To see this effetct, try something
like "redir -t sed -n $p a_long_file", with redir.exe from v2.01 and from
v2.02. I get 4-fold slow-down when Sed reads a 1MB file.
The reason for this is that, at least with SmartDrv and VCACHE from
Windows 95, the disk cache usually invalidates all its buffers when it is
forced to flush itself. So the net effect is that the cache is much less
effective.
A patch is attached which solves this problem. To recap, the call to
`sync' inside dosexec.c is meant to prevent out-of-order output when both
the parent and the child write to the same handle. But for this to work,
you don't need the data actually delivered to the disk. So I think
flushing the DOS buffers only (which is what `fsync' does) is okay here.
Btw, this was the first time I actively used wc202.txi to find the
offending change, and it was extremely efficient: took me no more than a
single minute until the "Aha!".
*** src/libc/dos/process/dosexec.c~0 Thu Jan 1 23:09:58 1998
--- src/libc/dos/process/dosexec.c Sat Jul 25 12:30:32 1998
*************** direct_exec_tail(const char *program, co
*** 163,169 ****
int i;
unsigned long fcb1_la, fcb2_la, fname_la;
! sync();
if (lfn == 2) /* don't know yet */
lfn = _USE_LFN;
--- 163,174 ----
int i;
unsigned long fcb1_la, fcb2_la, fname_la;
! /* This used to just call sync(). But `sync' flushes the disk
! cache nowadays, and that can slow down the child tremendously,
! since some caches (e.g. SmartDrv) invalidate all of their
! buffers when `_flush_disk_cache' is called. */
! for (i = 0; i < 255; i++)
! fsync(i);
if (lfn == 2) /* don't know yet */
lfn = _USE_LFN;
- Raw text -