Date: Sun, 26 Jul 1998 13:20:05 +0300 (IDT) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: A call to `sync' inside `spawn' Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk 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;