Subject: bin/3309: bin/install: very slow for files > 8 MB
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bruce@zuhause.mn.org>
List: netbsd-bugs
Date: 03/10/1997 07:40:23
>Number:         3309
>Category:       bin
>Synopsis:       Install very slow for large files
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 10 06:05:03 1997
>Last-Modified:
>Originator:     Bruce Albrecht
>Organization:
>Release:        3/4/97 (but xinstall.c from 3/6/97)
>Environment:
System: NetBSD zuhause 1.2C NetBSD 1.2C (ZuHause) #1: Thu Mar 6 21:43:31 CST 1997 root@zuhause:/NetBSD-current/usr/src/sys/arch/amiga/compile/ZuHause amiga


>Description:
Install is order of magnitude slower for files > 8 MB than cp, because code that
supposedly is work-around for broken gcccauses install to write large (> 8 MB)
files 4 bytes at a time.
>How-To-Repeat:
attempt to install 10 MB file.
>Fix:
These changes are against usr.bin/xinstall/xinstall.c v1.12.  I've changed the
code to match the copy file routine in bin/cp/utils.c.

diff -c xinstall.c~ xinstall.c
*** xinstall.c~	Fri Mar  7 06:24:35 1997
--- xinstall.c	Mon Mar 10 07:27:30 1997
***************
*** 298,325 ****
  {
  	register int nr, nw;
  	int serrno;
! #ifndef XXX_BROKEN_GCC
! 	char *p, buf[MAXBSIZE];
! #else
! 	char *p, *buf;
  
  	if ((buf = (char *)malloc(MAXBSIZE)) == NULL)
  		err(1, "can't allocate memory for copy");
- #endif
  
  	/*
  	 * Mmap and write if less than 8M (the limit is so we don't totally
  	 * trash memory on big files.  This is really a minor hack, but it
  	 * wins some CPU back.
  	 */
  	if (size <= 8 * 1048576) {
  		if ((p = mmap(NULL, (size_t)size, PROT_READ,
  		    0, from_fd, (off_t)0)) == (char *)-1)
  			err(1, "%s", from_name);
  		if (write(to_fd, p, size) != size)
  			err(1, "%s", to_name);
! 	} else {
! 		while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
  			if ((nw = write(to_fd, buf, nr)) != nr) {
  				serrno = errno;
  				(void)unlink(to_name);
--- 298,327 ----
  {
  	register int nr, nw;
  	int serrno;
! 	char *buf;
! #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
! 	char *p;
! #endif
  
  	if ((buf = (char *)malloc(MAXBSIZE)) == NULL)
  		err(1, "can't allocate memory for copy");
  
  	/*
  	 * Mmap and write if less than 8M (the limit is so we don't totally
  	 * trash memory on big files.  This is really a minor hack, but it
  	 * wins some CPU back.
  	 */
+ #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
  	if (size <= 8 * 1048576) {
  		if ((p = mmap(NULL, (size_t)size, PROT_READ,
  		    0, from_fd, (off_t)0)) == (char *)-1)
  			err(1, "%s", from_name);
  		if (write(to_fd, p, size) != size)
  			err(1, "%s", to_name);
! 	} else 
! #endif
!                 {
! 		while ((nr = read(from_fd, buf, MAXBSIZE)) > 0)
  			if ((nw = write(to_fd, buf, nr)) != nr) {
  				serrno = errno;
  				(void)unlink(to_name);
***************
*** 332,340 ****
  			errx(1, "%s: %s", from_name, strerror(serrno));
  		}
  	}
- #ifdef XXX_BROKEN_GCC
  	free(buf);
- #endif
  }
  
  /*
--- 334,340 ----
>Audit-Trail:
>Unformatted: