www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/07/26/06:20:22

Date: Sun, 26 Jul 1998 13:20:05 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: DJ Delorie <dj AT delorie DOT com>
cc: djgpp-workers AT delorie DOT com
Subject: A call to `sync' inside `spawn'
Message-ID: <Pine.SUN.3.91.980726130802.26805A-100000@is>
MIME-Version: 1.0

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019