Subject: wait4 arrives in 2.11BSD (#125 - 2 of 4)
Index: sys/<many> 2.11BSD

Description:
	The wait4 syscall is not present in 2.11BSD.  This means that
	'waitpid' is also not present.

	The CGL_RTP kernel configuration option has not been known to work
	for years.  Not too long ago i was informed that even if the 'rtp'
	capability were made operable it interacted very badly with the
	networking code.  The 'rtp' option has moved from the deprecated
	to removed catagory.

	The quota system was needlessly complicated by emulation the p_quota
	member of the 4.3BSD proc structure.  It is not necessary to have
	_both_ the p_quota (in 2.11 this was emulated with the parallel
	pxquota array) and u_quota entities.  The p_quota emulation was 
	removed with no ill effect.

Repeat-By:
	Either by examination or by attempting to compile/link a program
	which uses 'wait4' or 'waitpid'.  Another method would be to attempt
	using the 'rtp' feature.

Fix:
	Apply the 4 parts (this is part 2) of the update kit, remake the
	kernel, reboot, and then remake the modified parts of libc.a

	This part (#2) consists of the kernel patches.

	If the 'kern_acct.c' patch does not apply correctly it is probably
	because i forgot to post the update of that module.  The patch is
	just adding a register variable in an effort to shrink the code.

	The files changed by this part (#2) are:

/usr/src/sys/h/kernel.h

	CGL_RTP removed.

/usr/src/sys/h/param.h

	CGL_RTP removed.

/usr/src/sys/h/proc.h

	the process id hashing method was changed to use the same
	method as 4.3+BSD/Net2 - rather than the proc structure using
	an index into the hash table (short p_idhash) a linked list is used
	(struct proc *p_hash).  this simplified the code considerably in
	a couple of places.

	CGL_RTP removed.

/usr/src/sys/h/quota.h

	The emulation of 4.3's p_quota was removed - the px_quota and pxquota
	pointer and array are no longer needed.

/usr/src/sys/h/vmsystm.h

	the 'multprog' counter was removed.  other versions of the system
	didn't attempt to count the number of resident processes in this way 
	so it was time for this to go away from 2.11BSD.  'multprog' was never
	used for anything and no utilities in the system (such as vmstat)
	ever looked at it.

/usr/src/sys/h/wait.h

	New macros (W_STOPCODE, etc) and defines (WAIT_ANY, etc) added in 
	support of 'wait4'.

/usr/src/sys/pdp/machdep2.c

	'maxmem' is no longer decremented after each memory allocation. 
	Instead the _coremap structure is examined in 'init_main.c' to see
	how much memory is left in the first map entry. 

	The print statements detailing how much memory is present and how
	much is available have been moved to init_main.c after the network
	has been loaded and started.  The memory available figure now includes
	the size of the networking code and memory that the network allocates
	at initialization time.

/usr/src/sys/pdp/mch_click.s

	CGL_RTP removed.

	A missing '$' in the "fmove" function was added.  The check for
	using a byte by byte copy or a multi-word copy was incorrect, comparing
	the transfer size to the contents of location 10. rather than against
	$10.  A couple more bytes of text were save by replacing 'asr r0;
	bic $100000,r0' with 'clc;ror r0' and similar changes elsewhere.

/usr/src/sys/pdp/net_mbuf.s

	'bcopy'like logic was added to 'mbcopyin' (and 'mbcopyout').  This
	greatly speeds up movement of data between DMA buffers and the
	mbuf pool.

/usr/src/sys/sys/init_main.c

	The 'p_quota' emulation (px_quota) was removed.

	Memory size announcements were moved here from pdp/machdep2.c.  
	The side effect of this is that network attach and MSCP online
	messages will appear before the memory sizes are printed.  Memory
	sizes now include the networking code and buffers allocated by the
	network.

/usr/src/sys/sys/init_sysent.c

	The system call 'wait' was changed to be 'owait'.  Executables
	which use the old 'wait(2)' and 'wait3(2)' syscalls will used
	the 'owait' compatibility function (in kern_exit.c).

	'wait4' was added.  the system call number for wait4(2) is 7
	which used to be "old wait".

	rtp() was removed.


/usr/src/sys/sys/kern_acct.c

	register variable added to save a few more bytes of text space.  In
	my system one of the overlays (which contained several of the kern_
	modules) slightly exceeded the 8kb limit.  rather than reshuffle
	the overlay structure and/or modify the compiler+optimizer i looked
	for places where a few bytes could be saved.  it worked.  by adding
	register variables and using 'p_hash' rather than 'p_idhash' enough
	space was saved to avoid changing the overlay structure.

/usr/src/sys/sys/kern_exit.c

	This is the module with the _major_ changes.  Essentially the Net2
	kern_exit.c was taken and modified (which for the most part meant
	dropping out VM references and the kernel malloc stuff).

	the function 'wait' is now 'owait' - this implements a compatibility
	feature for executables using the old 'wait(2)' and 'wait3(2)' syscalls.

	both 'owait()' and 'wait4' were imported (almost unchanged) from
	the Net2 kern_exit.c module.

	CGL_RTP removed.

	an extra argument to 'closef' was removed.

	the detection of 'init' (process 1) exiting was simplified and moved
	to a point earlier in the exit handling.

	'multprog' removed.

	PID hashing (p_idhash -> p_hash) adopted from Net2 - the simplification
	resulted in noticeable text space savings.

	The u_signal array is not set to 'SIG_IGN' now because all of the
	signals are ignored by 1) setting p_sigignore to all one bits and
	2) clearing the mask of signals pending (p_sigmask)

	It is interesting to note that with all the extra code needed to
	implement 'wait4' the kernel size actually shrank (in my case by
	320 bytes).

/usr/src/sys/sys/kern_fork.c

	px_quota references (p_quota emulation) removed.  p_hash PID hashing
	rather than p_idhash hashing used.  

	CGL_RTP removed.

	'multprog' removed.

/usr/src/sys/sys/kern_proc.c

	the function pfind() greatly simplified by use of 'p_hash' rather
	than p_idhash for PID hashing.

/usr/src/sys/sys/kern_resource.c

	register variables added - saved another couple dozen bytes of
	text space.

/usr/src/sys/sys/kern_synch.c

	CGL_RTP removed.

/usr/src/sys/sys/quota_subr.c

	px_quota removed.  This greatly simplified the 'qclean' routine.

/usr/src/sys/sys/vm_sched.c

	CGL_RTP removed.

/usr/src/sys/sys/vm_swap.c

	'multprog' removed.

	Save the following to a file (/tmp/foo) and then do a 
	"patch -p0 < /tmp/foo".

	With parts 1 and 2 installed you can now rebuild the kernel.  The
	kernel will handle (via the compatibility 'owait' function) old
	executable which use 'wait' and 'wait3' syscalls.  Eventually (in
	parts 3 and 4) new functions will be added to libc.a which implement
	'wait(3)', 'wait3(3)' and 'waitpid(3)' using 'wait4(2)'.

===================================cut here==================================
*** /usr/src/sys/h/kernel.h.old	Thu Dec 24 15:56:05 1992
--- /usr/src/sys/h/kernel.h	Fri Mar 12 18:47:41 1993
***************
*** 30,37 ****
  int	realitexpire();
  
  short	avenrun[3];
- 
- #ifdef CGL_RTP
- int	wantrtp;	/* set when the real-time process is runnable */
- #endif
  #endif
--- 30,33 ----
*** /usr/src/sys/h/param.h.old	Sat Dec 26 16:32:37 1992
--- /usr/src/sys/h/param.h	Fri Mar 12 18:47:57 1993
***************
*** 40,51 ****
  /*
   * Priorities
   */
- #ifdef CGL_RTP
- #define	PRTP	0
- #define	PSWP	5
- #else
  #define	PSWP	0
- #endif
  #define	PINOD	10
  #define	PRIBIO	20
  #define	PRIUBA	24
--- 40,46 ----
*** /usr/src/sys/h/proc.h.old	Thu May 24 23:53:04 1990
--- /usr/src/sys/h/proc.h	Fri Mar 12 19:44:42 1993
***************
*** 41,47 ****
  		char	P_nice;		/* nice for cpu usage */
  		char	P_slptime;	/* secs sleeping */
  		char	P_cursig;
! 		short	P_idhash;	/* hash based on p_pid */
  		long	P_sigmask;	/* current signal mask */
  		long	P_sigignore;	/* signals being ignored */
  		long	P_sigcatch;	/* signals being caught by user */
--- 41,47 ----
  		char	P_nice;		/* nice for cpu usage */
  		char	P_slptime;	/* secs sleeping */
  		char	P_cursig;
! 		struct proc *P_hash;	/* hashed based on p_pid */
  		long	P_sigmask;	/* current signal mask */
  		long	P_sigignore;	/* signals being ignored */
  		long	P_sigcatch;	/* signals being caught by user */
***************
*** 67,73 ****
  #define	p_time		p_un.p_alive.P_time
  #define	p_nice		p_un.p_alive.P_nice
  #define	p_slptime	p_un.p_alive.P_slptime
! #define	p_idhash	p_un.p_alive.P_idhash
  #define	p_cursig	p_un.p_alive.P_cursig
  #define	p_sigmask	p_un.p_alive.P_sigmask
  #define	p_sigignore	p_un.p_alive.P_sigignore
--- 67,73 ----
  #define	p_time		p_un.p_alive.P_time
  #define	p_nice		p_un.p_alive.P_nice
  #define	p_slptime	p_un.p_alive.P_slptime
! #define	p_hash		p_un.p_alive.P_hash
  #define	p_cursig	p_un.p_alive.P_cursig
  #define	p_sigmask	p_un.p_alive.P_sigmask
  #define	p_sigignore	p_un.p_alive.P_sigignore
***************
*** 91,107 ****
  #define	PIDHASH(pid)	((pid) & (PIDHSZ - 1))
  
  #if defined(KERNEL) && !defined(SUPERVISOR)
! short	pidhash[PIDHSZ];
  struct	proc *pfind();
  struct	proc proc[], *procNPROC;	/* the proc table itself */
  struct	proc *freeproc, *zombproc, *allproc, *qs;
  			/* lists of procs in various states */
  int	nproc;
- 
- #ifdef CGL_RTP
- struct	proc *rtpp;		/* pointer to real time process entry */
- int	wantrtp;		/* real-time proc is ready to run */
- #endif
  #endif
  
  /* stat codes */
--- 91,102 ----
  #define	PIDHASH(pid)	((pid) & (PIDHSZ - 1))
  
  #if defined(KERNEL) && !defined(SUPERVISOR)
! struct	proc *pidhash[PIDHSZ];
  struct	proc *pfind();
  struct	proc proc[], *procNPROC;	/* the proc table itself */
  struct	proc *freeproc, *zombproc, *allproc, *qs;
  			/* lists of procs in various states */
  int	nproc;
  #endif
  
  /* stat codes */
*** /usr/src/sys/h/quota.h.old	Thu Dec 24 16:44:47 1992
--- /usr/src/sys/h/quota.h	Thu Mar 11 20:04:27 1993
***************
*** 161,167 ****
  
  memaddr	quotreg;
  u_short	quotdesc;
- struct	quota **px_quota;
  struct	dquot **ix_dquot;
  
  #define	NQHASH		16	/* small power of 2 */
--- 161,166 ----
*** /usr/src/sys/h/vmsystm.h.old	Thu Jan 28 09:15:48 1988
--- /usr/src/sys/h/vmsystm.h	Wed Mar 10 20:26:20 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)vmsystm.h	7.1 (Berkeley) 6/4/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)vmsystm.h	7.2 (2.11BSD GTE) 3/10/93
   */
  
  /*
***************
*** 14,20 ****
  size_t	freemem;		/* remaining clicks of free memory */
  u_short	avefree;		/* moving average of remaining free clicks */
  u_short	avefree30;		/* 30 sec (avefree is 5 sec) moving average */
- int	multprog;		/* current multiprogramming degree */
  
  /* writable copies of tunables */
  int	maxslp;			/* max sleep time before very swappable */
--- 14,19 ----
*** /usr/src/sys/h/wait.h.old	Sat May 16 11:29:26 1987
--- /usr/src/sys/h/wait.h	Wed Mar 10 20:08:42 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)wait.h	7.1 (Berkeley) 6/4/86
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)wait.h	7.2 (2.11BSD GTE) 3/10/93
   */
  
  /*
***************
*** 64,66 ****
--- 64,72 ----
  #define WIFSTOPPED(x)	((x).w_stopval == WSTOPPED)
  #define WIFSIGNALED(x)	((x).w_stopval != WSTOPPED && (x).w_termsig != 0)
  #define WIFEXITED(x)	((x).w_stopval != WSTOPPED && (x).w_termsig == 0)
+ 
+ #define	W_STOPCODE(sig)	((sig << 8) | WSTOPPED)
+ #define	W_EXITCODE(ret,sig)	((ret << 8) | (sig))
+ 
+ #define	WAIT_ANY	(-1)
+ #define	WAIT_MYPGRP	0
*** /usr/src/sys/pdp/machdep2.c.old	Wed Mar 17 08:01:52 1993
--- /usr/src/sys/pdp/machdep2.c	Wed Mar 17 08:02:39 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)machdep2.c	2.1 (2.11BSD) 1/1/93
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)machdep2.c	2.2 (2.11BSD GTE) 3/13/93
   */
  
  #include "param.h"
***************
*** 127,133 ****
  #define C	(nclist * sizeof(struct cblock))
  	if ((clststrt = malloc(coremap, btoc(C))) == 0)
  		panic("clists");
- 	maxmem -= btoc(C);
  	clstaddr = ((ubadr_t)clststrt) << 6;
  #undef C
  #else
--- 127,132 ----
***************
*** 138,144 ****
  #define C (ninode * sizeof (struct icommon2))
  	if ((xitimes = malloc(coremap, btoc(C))) == 0)
  		panic("xitimes");
- 	maxmem -= btoc(C);
  	xitdesc = ((btoc(C) << 8) | RW);
  #undef C
  #endif
--- 137,142 ----
***************
*** 147,153 ****
  #define	C	(btoc(8192))
  	if ((quotreg = malloc(coremap, C)) == 0)
  		panic("quotamem");
- 	maxmem -= C;
  	quotdesc = ((C - 1) << 8) | RW;
  	QUOini();
  #undef C
--- 145,150 ----
***************
*** 164,170 ****
  		panic("nameimalloc");
  	nmidesc.se_desc = ((B - 1) << 8) | RW;
  	namecache = (struct namecache *)SEG5;
- 	maxmem -= B;
  	}
  
  #if	NRAC > 0 || NTMSCP > 0
--- 161,166 ----
***************
*** 171,177 ****
  {
  	if ((_iobase = malloc(coremap, btoc(_iosize))) == 0)
  		panic("_iobase");
- 	maxmem -= btoc(_iosize);
  }
  #endif	NRAC
  
--- 167,172 ----
***************
*** 178,221 ****
  #define B	(size_t)(((long)nbuf * (MAXBSIZE)) / ctob(1))
  	if ((bpaddr = malloc(coremap, B)) == 0)
  		panic("buffers");
- 	maxmem -= B;
  #undef B
  
  #define	C	(btoc(MSG_BSIZE))
  	if ((msgbuf.msg_click = malloc(coremap, C)) == 0)
  		panic("msgbufmem");
- 	maxmem -= C;
  	msgbuf.msg_magic = MSG_MAGIC;
  	msgbuf.msg_bufc = SEG5;
  	msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
  #undef	C
  
- #if defined(PROFILE) && !defined(ENABLE34)
- 	maxmem -= msprof();
- #endif
- 
  #if NRAM > 0
  	ramsize = raminit();
- 	maxmem -= ramsize;
  #endif
- 
- 	printf("phys mem  = %D\n", ctob((long)physmem));
- 	printf("avail mem = %D\n", ctob((long)maxmem));
- 	if (MAXMEM < maxmem)
- 		maxmem = MAXMEM;
- 	printf("user mem  = %D\n", ctob((long)maxmem));
- #if NRAM > 0
- 	printf("ram disk  = %D\n", ctob((long)ramsize));
- #endif
- #ifdef DIAGNOSTIC
- 	printf("%d procs (%d bytes)\n",nproc,nproc * sizeof(struct proc));
- 	printf("%d texts (%d bytes)\n",ntext,ntext * sizeof(struct text));
- 	printf("%d inodes (%d bytes)\n",ninode,ninode * sizeof(struct inode));
- 	printf("%d files (%d bytes)\n",nfile,nfile * sizeof(struct file));
- 	printf("%d buffers (%D bytes)\n",nbuf,(long)nbuf * MAXBSIZE);
- 	printf("%d clists (%d bytes)\n",nclist,nclist * sizeof(struct cblock));
- #endif
- 	printf("\n");
  
  	/*
  	 * Initialize callouts
--- 173,191 ----
*** /usr/src/sys/pdp/mch_click.s.old	Fri Jan  1 16:17:57 1993
--- /usr/src/sys/pdp/mch_click.s	Tue Mar 16 18:42:53 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mch_click.s	1.2 (2.11BSD GTE) 1/1/93
   */
  
  #include "DEFS.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mch_click.s	1.3 (2.11BSD GTE) 3/16/93
   */
  
  #include "DEFS.h"
***************
*** 17,25 ****
   *
   * Copy count clicks from src to dst.  Uses KDSA5 and 6 to copy with mov
   * instructions.  Interrupt routines must restore segmentation registers
!  * if needed; see seg.h.  Note that if CGL_RTP is defined, it checks whether
!  * the real-time process is runnable once each loop, and preempts the
!  * current process if necessary (which must not swap before this finishes!).
   */
  ENTRY(copy)
  	jsr	r5, csv
--- 17,23 ----
   *
   * Copy count clicks from src to dst.  Uses KDSA5 and 6 to copy with mov
   * instructions.  Interrupt routines must restore segmentation registers
!  * if needed; see seg.h.
   */
  ENTRY(copy)
  	jsr	r5, csv
***************
*** 42,54 ****
  	mov	6(r5),KDSA6		/   out and seg6 = (dst, 1 click read/
  	mov	$RW,KDSD6		/   write)
  1:
- 
- #ifdef CGL_RTP
- 	tst	_wantrtp		/ is there a real time process
- 	bne	preempt			/   process which wants the cpu?
- restart:
- #endif
- 
  	mov	$5*8192.,r0		/ r0 = SEG5 { src }
  	mov	$6*8192.,r1		/ r1 = SEG6 { dst }
  	mov	$8.,r2			/ copy one click (8*8)
--- 40,45 ----
***************
*** 75,135 ****
  #endif
  	jmp	cret
  
- #ifdef CGL_RTP
  /*
-  * Save our state and restore enough context for a process switch.
-  */
- preempt:
- 	mov	KDSA6, r0
- 	mov	_kdsa6,KDSA6		/ back to our u.
- 	mov	$USIZE-1\<8|RW, KDSD6
- 	clr	_kdsa6
- 	mov	r4, sp			/ back to normal stack
- 	mov	KDSA5, -(sp)		/ save seg5 and seg6 so we can come
- 	mov	r0, -(sp)		/   back and finish later
- 	mov	_seg5+SE_DESC, KDSD5	/ normalseg5();
- 	mov	_seg5+SE_ADDR, KDSA5	/ (restore all mapping)
- 	jsr	pc, _runrtp		/ switch context and run rtpp
- 					/ Now continue where we left off.
- 	mov	(sp)+, r0		/ KDSA6
- 	mov	(sp)+, KDSA5
- 	mov	$RO,KDSD5		/ 64 bytes, read-only
- 	mov	KDSA6,_kdsa6
- 	mov	$eintstk,sp
- 	mov	r0, KDSA6
- 	mov	$RW,KDSD6		/ 64 bytes, read-write
- 	br	restart
- 
- 
- /*
-  * copyu(dst)
-  *	memaddr	dst;
-  *
-  * Copy the u. to dst; not preemptable.  Uses KDSA5 to copy with mov
-  * instructions.  Interrupt routines must restore segmentation registers
-  * if needed; see seg.h.
-  */
- ENTRY(copyu)
- 	jsr	r5, csv
- 	mov	4(r5),KDSA5		/ point KDSA5 at dst.
- 	mov	$USIZE-1\<8.|RW,KDSD5
- 	mov	$6*8192.,r0
- 	mov	$5*8192.,r1
- 	mov	$8.*USIZE,r2		/ copy 8*8 bytes per click
- 2:
- 	mov	(r0)+,(r1)+
- 	mov	(r0)+,(r1)+
- 	mov	(r0)+,(r1)+
- 	mov	(r0)+,(r1)+
- 	sob	r2,2b
- 
- 	mov	_seg5+SE_DESC, KDSD5	/ normalseg5();
- 	mov	_seg5+SE_ADDR, KDSA5	/ (restore all mapping)
- 	jmp	cret
- #endif CGL_RTP
- 
- 
- /*
   * Clear count clicks at dst.  Uses KDSA5.  Interrupt routines must restore
   * segmentation registers if needed; see seg.h.
   *
--- 66,72 ----
***************
*** 146,156 ****
  	mov	6(r5),r3		/ count
  	beq	3f
  1:
- #ifdef CGL_RTP
- 	tst	_wantrtp
- 	bne	clrpreempt
- 4:
- #endif CGL_RTP
  	mov	$5*8192.,r0		/ point r0 at KDSA5 map
  	mov	$8.,r2			/ clear one click (8*8)
  2:
--- 83,88 ----
***************
*** 167,187 ****
  	mov	(sp)+,KDSA5		/ restore seg5
  	jmp	cret
  
- #ifdef CGL_RTP
- clrpreempt:
- 	mov	KDSA5, -(sp)
- 	mov	_seg5+SE_DESC, KDSD5	/ normalseg5();
- 	mov	_seg5+SE_ADDR, KDSA5	/ (restore all mapping)
- 	jsr	pc, _runrtp		/ switch context and run rtpp
- 	/*
- 	 * Now continue where we left off.
- 	 */
- 	mov	(sp)+, KDSA5
- 	mov	$RW,KDSD5		/ 64 bytes, read-write
- 	br	4b
- #endif CGL_RTP
- 
- 
  #ifdef INET
  /*
   * copyv(fromaddr, toaddr, count)
--- 99,104 ----
***************
*** 299,305 ****
  	 */
  	tst	r0		/ if (length == 0)
  	beq	7f		/	return
! 	cmp	r0,10.		/ if (length > 10)
  	bhi	2f		/	try words
  1:
  	movb	(r1)+,(r2)+	/ do  *dst++ = *src++
--- 216,222 ----
  	 */
  	tst	r0		/ if (length == 0)
  	beq	7f		/	return
! 	cmp	r0,$10.		/ if (length > 10)
  	bhi	2f		/	try words
  1:
  	movb	(r1)+,(r2)+	/ do  *dst++ = *src++
***************
*** 318,325 ****
  	bne	1b		/ (src even, dst odd - do bytes)
  4:
  	mov	r0,r3		/ save trailing byte indicator
! 	asr	r0		/ length >>= 1 (unsigned)
! 	bic	$0100000,r0	/ (length is now in remaining words to copy)
  	asr	r0		/ if (length >>= 1, wasodd(length))
  	bcc	5f		/	handle leading non multiple of four
  	mov	(r1)+,(r2)+
--- 235,242 ----
  	bne	1b		/ (src even, dst odd - do bytes)
  4:
  	mov	r0,r3		/ save trailing byte indicator
! 	clc
! 	ror	r0		/ length >>= 1 (unsigned)
  	asr	r0		/ if (length >>= 1, wasodd(length))
  	bcc	5f		/	handle leading non multiple of four
  	mov	(r1)+,(r2)+
***************
*** 334,341 ****
  	mov	(r1)+,(r2)+
  	mov	(r1)+,(r2)+
  	sob	r0,6b		/ while (--length)
! 	bit	$1,r3		/ if (odd trailing byte)
! 	beq	7f
  	movb	(r1)+,(r2)+	/	copy it
  	/*
  	 * End of stolen bcopy code.
--- 251,258 ----
  	mov	(r1)+,(r2)+
  	mov	(r1)+,(r2)+
  	sob	r0,6b		/ while (--length)
! 	asr	r3		/ if (odd trailing byte)
! 	bcc	7f
  	movb	(r1)+,(r2)+	/	copy it
  	/*
  	 * End of stolen bcopy code.
*** /usr/src/sys/pdp/net_mbuf.s.old	Tue Mar 16 13:08:20 1993
--- /usr/src/sys/pdp/net_mbuf.s	Tue Mar 16 14:15:42 1993
***************
*** 3,15 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)net_mbuf.s	1.1 (2.10BSD Berkeley) 4/10/88
   */
  
  #include "DEFS.h"
  #include "../machine/mch_iopage.h"
  
- 
  /*
   * mbcopyin(click, off, ptr, len)
   *	u_short click;		/ address of external DMA buffer
--- 3,14 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)net_mbuf.s	2.0 (2.11BSD GTE) 3/13/93
   */
  
  #include "DEFS.h"
  #include "../machine/mch_iopage.h"
  
  /*
   * mbcopyin(click, off, ptr, len)
   *	u_short click;		/ address of external DMA buffer
***************
*** 18,26 ****
   *	short len;		/ bytes to copy from click/off to ptr
   *
   * mbcopyout(ptr, click, off, len)
   *	u_short click;		/ address of external DMA buffer
   *	u_short off;		/ offset into click of start of buffer
-  *	caddr_t ptr;		/ address of internal buffer
   *	short len;		/ bytes to copy from ptr to click/off
   *
   * Used for copying data from/to the UNIBUS DMA pages to/from the
--- 17,25 ----
   *	short len;		/ bytes to copy from click/off to ptr
   *
   * mbcopyout(ptr, click, off, len)
+  *	caddr_t ptr;		/ address of internal buffer
   *	u_short click;		/ address of external DMA buffer
   *	u_short off;		/ offset into click of start of buffer
   *	short len;		/ bytes to copy from ptr to click/off
   *
   * Used for copying data from/to the UNIBUS DMA pages to/from the
***************
*** 32,80 ****
  
  ENTRY(mbcopyin)
  	jsr	r5,csv
! 	mov	012(r5),r2		/ grab byte count
! 	ble	mbdone			/ nothing to do if len <= 0 ...
! 	cmp	r2,$8192.		/ too big?
! 	bge	mbbad			/   yes, panic
! 
! 	mov	06(r5),r0		/ grab offset and computer pointer
! 	add	$140000,r0		/   to mapped in source data
! 	mov	010(r5),r1		/ grab ptr (destination address)
  	mov	PS,-(sp)		/ save PS since we lock out interrupts
  	SPL7
  	mov	SDSA6,r3		/ save mapping for stack / u. area
  	mov	04(r5),SDSA6		/ map in source data
! 	br	mbloop
  
  ENTRY(mbcopyout)
  	jsr	r5,csv
! 	mov	012(r5),r2		/ grab byte count
! 	ble	mbdone			/ nothing to do if len <= 0 ...
! 	cmp	r2,$8192.		/ too big?
! 	bge	mbbad			/   yes, panic
! 
! 	mov	04(r5),r0		/ grab ptr (source address)
! 	mov	010(r5),r1		/ grab offset and compute pointer
! 	add	$140000,r1		/   to mapped destination address
  	mov	PS,-(sp)		/ save PS since we lock out interrupts
  	SPL7
  	mov	SDSA6,r3		/ save mapping for stack / u. area
  	mov	06(r5),SDSA6		/ map in destination address data
  
- 
  /*
!  * Common loop and return for mbcopyin and mbcopyout.  Copy from (r0) to
!  * (r1) for r2 bytes.  R3 contains old seg6 address descriptor.  The copy
!  * loop should probably be rewritten to do something like bcopy ...
   */
! mbloop:
! 	movb	(r0)+,(r1)+		/ copy one byte at a time to avoid
! 	sob	r2,mbloop		/   allignment problems.
! 
! 	mov	r3,SDSA6		/ map back in stack / u. area
! 	mov	(sp)+,PS		/ restore original priority
! mbdone:
  	jmp	cret
! mbbad:
! 	halt				/ causes a panic trap from supervisor
! 					/   mode
--- 31,111 ----
  
  ENTRY(mbcopyin)
  	jsr	r5,csv
! 	mov	012(r5),r0		/ grab byte count
! 	ble	3f			/ nothing to do if len <= 0 ...
! 	mov	06(r5),r1		/ grab offset and computer pointer
! 	add	$140000,r1		/   to mapped in source data
! 	mov	010(r5),r2		/ grab ptr (destination address)
  	mov	PS,-(sp)		/ save PS since we lock out interrupts
  	SPL7
  	mov	SDSA6,r3		/ save mapping for stack / u. area
  	mov	04(r5),SDSA6		/ map in source data
! 	br	0f
  
  ENTRY(mbcopyout)
  	jsr	r5,csv
! 	mov	012(r5),r0		/ grab byte count
! 	ble	3f			/ nothing to do if len <= 0 ...
! 	mov	04(r5),r1		/ grab ptr (source address)
! 	mov	010(r5),r2		/ grab offset and compute pointer
! 	add	$140000,r2		/   to mapped destination address
  	mov	PS,-(sp)		/ save PS since we lock out interrupts
  	SPL7
  	mov	SDSA6,r3		/ save mapping for stack / u. area
  	mov	06(r5),SDSA6		/ map in destination address data
  
  /*
!  * Common loop and return for mbcopyin and mbcopyout.  Copy from (r1) to
!  * (r2) for r0 bytes.  r3 contains old seg6 address descriptor.
   */
! 0:
! 	cmp	r0,$8192.	/ too big?
! 	bge	2f		/   yes, ignore it
! 	cmp	r0,$10.		/ if (length >= 10)
! 	bhi	4f		/	try words
! 1:
! 	movb	(r1)+,(r2)+	/ do  *dst++ = *src++
! 	sob	r0,1b		/ while (--length)
! 2:
! 	mov	r3,SDSA6	/ map back in stack / u. area
! 	mov	(sp)+,PS	/ restore original priority
! 3:
  	jmp	cret
! /*
!  * The length of the copy justifies trying a word by word copy.  If src and
!  * dst are of the same parity, we can do a word copy by handling any leading
!  * and trailing odd bytes separately.  NOTE:  r4 is used to hold the odd byte
!  * indicator because the stack is invalid (mapped out).
!  */
! 4:
! 	bit	$1,r1		/ if (src&1 != dst&1)
! 	beq	5f		/	do bytes
! 	bit	$1,r2
! 	beq	1b		/ (src odd, dst even - do bytes)
! 	movb	(r1)+,(r2)+	/ copy leading odd byte
! 	dec	r0
! 	br	6f
! 5:
! 	bit	$1,r2
! 	bne	1b		/ (src even, dst odd - do bytes)
! 6:
! 	mov	r0,r4		/ save trailing byte indicator
! 	asr	r0		/ length >>= 1 (unsigned)
! 	asr	r0		/ if (length >>= 1, wasodd(length))
! 	bcc	7f		/	handle leading non multiple of four
! 	mov	(r1)+,(r2)+
! 7:
! 	asr	r0		/ if (length >>= 1, wasodd(length))
! 	bcc	8f		/	handle leading non multiple of eight
! 	mov	(r1)+,(r2)+
! 	mov	(r1)+,(r2)+
! 8:
! 	mov	(r1)+,(r2)+	/ do
! 	mov	(r1)+,(r2)+	/	move eight bytes
! 	mov	(r1)+,(r2)+
! 	mov	(r1)+,(r2)+
! 	sob	r0,8b		/ while (--length)
! 	asr	r4		/ if (odd trailing byte)
! 	bcc	2b
! 	movb	(r1)+,(r2)+	/	copy it
! 	br	2b		/ and return
*** /usr/src/sys/sys/init_main.c.old	Sun Jan  3 00:45:57 1993
--- /usr/src/sys/sys/init_main.c	Mon Mar 15 18:28:07 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)init_main.c	1.4 (2.11BSD GTE) 12/24/92
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)init_main.c	1.5 (2.11BSD GTE) 3/12/93
   */
  
  #include "param.h"
***************
*** 30,35 ****
--- 30,37 ----
  
  int	netoff = 1;
  int	cmask = CMASK;
+ extern	size_t physmem;
+ extern	struct	mapent _coremap[];
  
  /*
   * Initialization code.
***************
*** 90,96 ****
  	QUOTAMAP();
  	qtinit();
  	u.u_quota = getquota(0, 0, Q_NDQ);
- 	px_quota[0] = u.u_quota;
  	QUOTAUNMAP();
  #endif
  	nchinit();
--- 92,97 ----
***************
*** 180,185 ****
--- 181,203 ----
  	else
  		NETSTART();
  #endif
+ 
+ /*
+  * This came from pdp/machdep2.c because the memory available statements
+  * were being made _before_ memory for the networking code was allocated.
+  * A side effect of moving this code is that network "attach" and MSCP 
+  * "online" messages can appear before the memory sizes.  The (currently
+  * safe) assumption is made that no 'free' calls are made so that the
+  * size in the first entry of the core map is correct.
+ */
+ 	printf("\nphys mem  = %D\n", ctob((long)physmem));
+ 	printf("avail mem = %D\n", ctob((long)_coremap[0].m_size));
+ 	maxmem = MAXMEM;
+ 	printf("user mem  = %D\n", ctob((long)MAXMEM));
+ #if NRAM > 0
+ 	printf("ram disk  = %D\n", ctob((long)ramsize));
+ #endif
+ 	printf("\n");
  
  	/*
  	 * make init process
*** /usr/src/sys/sys/init_sysent.c.old	Thu Dec 24 16:40:57 1992
--- /usr/src/sys/sys/init_sysent.c	Fri Mar 12 18:58:45 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)init_sysent.c	1.2 (2.11BSD GTE) 12/24/92
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)init_sysent.c	1.3 (2.11BSD GTE) 3/10/93
   */
  
  /*
***************
*** 17,26 ****
  
  /* 1.1 processes and protection */
  int	sethostid(),gethostid(),sethostname(),gethostname(),getpid();
! int	fork(),rexit(),execv(),execve(),wait();
  int	getuid(),setreuid(),getgid(),getgroups(),setregid(),setgroups();
  int	getpgrp(),setpgrp();
! int	rtp(),ucall();					/* BSD2_10 calls */
  
  /* 1.2 memory management */
  int	sbrk();
--- 17,26 ----
  
  /* 1.1 processes and protection */
  int	sethostid(),gethostid(),sethostname(),gethostname(),getpid();
! int	fork(),rexit(),execv(),execve(),owait(),wait4();
  int	getuid(),setreuid(),getgid(),getgroups(),setregid(),setgroups();
  int	getpgrp(),setpgrp();
! int	ucall();					/* BSD2_10 calls */
  
  /* 1.2 memory management */
  int	sbrk();
***************
*** 112,118 ****
  	3, write,			/*   4 = write */
  	3, open,			/*   5 = open */
  	1, close,			/*   6 = close */
! 	0, nosys,			/*   7 = old wait */
  	2, creat,			/*   8 = creat */
  	2, link,			/*   9 = link */
  	1, unlink,			/*  10 = unlink */
--- 112,118 ----
  	3, write,			/*   4 = write */
  	3, open,			/*   5 = open */
  	1, close,			/*   6 = close */
! 	4, wait4,			/*   7 = wait4 */
  	2, creat,			/*   8 = creat */
  	2, link,			/*   9 = link */
  	1, unlink,			/*  10 = unlink */
***************
*** 189,195 ****
  	1, getpgrp,			/*  81 = getpgrp */
  	2, setpgrp,			/*  82 = setpgrp */
  	3, setitimer,			/*  83 = setitimer */
! 	0, wait,			/*  84 = wait */
  	0, nosys,			/*  85 = (4.3) swapon */
  	2, getitimer,			/*  86 = getitimer */
  	2, gethostname,			/*  87 = gethostname */
--- 189,195 ----
  	1, getpgrp,			/*  81 = getpgrp */
  	2, setpgrp,			/*  82 = setpgrp */
  	3, setitimer,			/*  83 = setitimer */
! 	0, owait,			/*  84 = wait,wait3 (compatibility) */
  	0, nosys,			/*  85 = (4.3) swapon */
  	2, getitimer,			/*  86 = getitimer */
  	2, gethostname,			/*  87 = gethostname */
***************
*** 263,271 ****
  	 */
  
  	/*
! 	 * BSD2_10 special calls
  	 */
! 	1, rtp,				/* 151 = rtp */
  	0, nostk,			/* 152 = nostk */
  	1, fetchi,			/* 153 = fetchi */
  	4, ucall,			/* 154 = ucall */
--- 263,271 ----
  	 */
  
  	/*
! 	 * BSD2_11 special calls
  	 */
! 	0, nosys,			/* 151 = unused (old 2.9 rtp) */
  	0, nostk,			/* 152 = nostk */
  	1, fetchi,			/* 153 = fetchi */
  	4, ucall,			/* 154 = ucall */
*** /usr/src/sys/sys/kern_acct.c.old	Sat Feb 22 14:02:40 1992
--- /usr/src/sys/sys/kern_acct.c	Wed Mar 10 23:46:52 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_acct.c	2.0 (2.11BSD) 2/21/92
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_acct.c	2.1 (2.11BSD) 3/10/93
   */
  
  #include "param.h"
***************
*** 81,87 ****
  }
  
  acctwatch(resettime)
! 	struct	timeval *resettime;
  {
  	register struct fs *fs;
  
--- 81,87 ----
  }
  
  acctwatch(resettime)
! 	register struct	timeval *resettime;
  {
  	register struct fs *fs;
  
*** /usr/src/sys/sys/kern_exit.c.old	Sat Apr 30 16:15:12 1988
--- /usr/src/sys/sys/kern_exit.c	Fri Mar 12 19:35:37 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_exit.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_exit.c	2.0 (2.11BSD GTE) 3/10/93
   */
  
  #include "param.h"
***************
*** 24,31 ****
  #endif
  
  /*
!  * exit system call:
!  * pass back caller's arg
   */
  rexit()
  {
--- 24,30 ----
  #endif
  
  /*
!  * exit system call: pass back caller's arg
   */
  rexit()
  {
***************
*** 33,70 ****
  		int	rval;
  	} *uap = (struct a *)u.u_ap;
  
! 	exit((uap->rval & 0377) << 8);
  }
  
  /*
!  * Release resources.
!  * Save u. area for parent to look at.
!  * Enter zombie state.
!  * Wake up parent and init processes,
!  * and dispose of children.
   */
  exit(rv)
  {
  	register int i;
  	register struct proc *p;
  
  	p = u.u_procp;
  	p->p_flag &= ~(STRC|SULOCK);
  	p->p_sigignore = ~0;
! 	for (i = 0; i < NSIG; i++)
! 		u.u_signal[i] = SIG_IGN;
  	/*
! 	 * 2.10 doesn't need to do this and it gets overwritten anyway.
  	 * p->p_realtimer.it_value = 0;
  	 */
- #ifdef CGL_RTP
- 	/*
- 	 * if this a "real time" process that is dying
- 	 * remove the rtpp flag.
- 	 */
- 	if (rtpp != NULL && rtpp == p)
- 		rtpp = NULL;
- #endif
  	for (i = 0; i <= u.u_lastfile; i++) {
  		register struct file *f;
  
--- 32,61 ----
  		int	rval;
  	} *uap = (struct a *)u.u_ap;
  
! 	exit(W_EXITCODE(uap->rval, 0));
! 	/* NOTREACHED */
  }
  
  /*
!  * Exit: deallocate address space and other resources,
!  * change proc state to zombie, and unlink proc from allproc
!  * list.  Save exit status and rusage for wait().
!  * Check for child processes and orphan them.
   */
  exit(rv)
  {
  	register int i;
  	register struct proc *p;
+ 	struct	proc **pp;
  
  	p = u.u_procp;
  	p->p_flag &= ~(STRC|SULOCK);
  	p->p_sigignore = ~0;
! 	p->p_sig = 0;
  	/*
! 	 * 2.11 doesn't need to do this and it gets overwritten anyway.
  	 * p->p_realtimer.it_value = 0;
  	 */
  	for (i = 0; i <= u.u_lastfile; i++) {
  		register struct file *f;
  
***************
*** 71,77 ****
  		f = u.u_ofile[i];
  		u.u_ofile[i] = NULL;
  		u.u_pofile[i] = 0;
! 		closef(f,1);
  	}
  	ilock(u.u_cdir);
  	iput(u.u_cdir);
--- 62,68 ----
  		f = u.u_ofile[i];
  		u.u_ofile[i] = NULL;
  		u.u_pofile[i] = 0;
! 		closef(f);
  	}
  	ilock(u.u_cdir);
  	iput(u.u_cdir);
***************
*** 80,86 ****
  		iput(u.u_rdir);
  	}
  	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
! 	acct();
  #ifdef QUOTA
  	QUOTAMAP();
  	qclean();
--- 71,77 ----
  		iput(u.u_rdir);
  	}
  	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
! 	(void) acct();
  #ifdef QUOTA
  	QUOTAMAP();
  	qclean();
***************
*** 99,104 ****
--- 90,98 ----
  		mfree(coremap, p->p_ssize, p->p_saddr);
  	}
  	mfree(coremap, USIZE, p->p_addr);
+ 
+ 	if (p->p_pid == 1)
+ 		panic("init died");
  	if (*p->p_prev = p->p_nxt)		/* off allproc queue */
  		p->p_nxt->p_prev = p->p_prev;
  	if (p->p_nxt = zombproc)		/* onto zombproc */
***************
*** 105,145 ****
  		p->p_nxt->p_prev = &p->p_nxt;
  	p->p_prev = &zombproc;
  	zombproc = p;
- #ifdef UCB_METER
- 	multprog--;
- #endif
  	p->p_stat = SZOMB;
  	noproc = 1;
! 	{
! 		register int x;
! 
! 		i = PIDHASH(p->p_pid);
! 		x = p - proc;
! 		if (pidhash[i] == x)
! 			pidhash[i] = p->p_idhash;
! 		else {
! 			for (i = pidhash[i]; i != 0; i = proc[i].p_idhash)
! 				if (proc[i].p_idhash == x) {
! 					proc[i].p_idhash = p->p_idhash;
! 					goto done;
! 				}
! 			panic("exit");
  		}
! 	}
! 	if (p->p_pid == 1) {
! 		/*
! 		 * If /etc/init is not found by the icode,
! 		 * the data size will still be zero when it exits.
! 		 * Don't panic: we're unlikely to find init after a reboot,
! 		 * either.
! 		 */
! 		if (u.u_dsize == 0) {
! 			printf("Can't exec /etc/init\n");
! 			for (;;)
! 				;
! 		} else
! 			panic("init died");
! 	}
  done:
  	/*
  	 * Overwrite p_alive substructure of proc - better not be anything
--- 99,112 ----
  		p->p_nxt->p_prev = &p->p_nxt;
  	p->p_prev = &zombproc;
  	zombproc = p;
  	p->p_stat = SZOMB;
  	noproc = 1;
! 	for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash)
! 		if (*pp == p) {
! 			*pp = p->p_hash;
! 			goto done;
  		}
! 	panic("exit");
  done:
  	/*
  	 * Overwrite p_alive substructure of proc - better not be anything
***************
*** 169,175 ****
  				/*
  				 * Protect this process from future
  				 * tty signals, clear TSTP/TTIN/TTOU if pending.
! 				 * 2.10 also sets SDETACH bit.
  				 */
  				spgrp(q);
  			}
--- 136,142 ----
  				/*
  				 * Protect this process from future
  				 * tty signals, clear TSTP/TTIN/TTOU if pending.
! 				 * 2.11 also sets SDETACH bit.
  				 */
  				spgrp(q);
  			}
***************
*** 182,223 ****
  	psignal(p->p_pptr, SIGCHLD);
  	wakeup((caddr_t)p->p_pptr);
  	swtch();
  }
  
! wait()
  {
! 	struct rusage ru, *rup;
  
  	if ((u.u_ar0[RPS] & PSL_ALLCC) != PSL_ALLCC) {
! 		u.u_error = wait1(0, (struct rusage *)0);
! 		return;
  	}
! 	rup = (struct rusage *)u.u_ar0[R1];
! 	u.u_error = wait1(u.u_ar0[R0], &ru);
! 	if (u.u_error)
! 		return;
! 	if (rup != (struct rusage *)0)
! 		u.u_error = copyout((caddr_t)&ru, (caddr_t)rup,
! 		    sizeof (struct rusage));
  }
  
  /*
!  * Wait system call.
!  * Search for a terminated (zombie) child,
!  * finally lay it to rest, and collect its status.
!  * Look also for stopped (traced) children,
!  * and pass back status from them.
   */
! wait1(options, ru)
! 	register int options;
! 	struct rusage *ru;
  {
! 	register f;
! 	register struct proc *p, *q;
  
! 	f = 0;
  loop:
! 	q = u.u_procp;
  	/*
  	 * 4.X has child links in the proc structure, so they consolidate
  	 * these two tests into one loop.  We only have the zombie chain
--- 149,219 ----
  	psignal(p->p_pptr, SIGCHLD);
  	wakeup((caddr_t)p->p_pptr);
  	swtch();
+ 	/* NOTREACHED */
  }
  
! 	struct	args
! 		{
! 		int pid;
! 		int *status;
! 		int options;
! 		struct rusage *rusage;
! 		int compat;
! 		};
! 
! owait()
  {
! 	int retval[2];
! 	register struct	args *uap = (struct args *)u.u_ap;
  
  	if ((u.u_ar0[RPS] & PSL_ALLCC) != PSL_ALLCC) {
! 		uap->options = 0;
! 		uap->rusage = 0;
! 	} else {
! 		uap->options = u.u_ar0[R0];
! 		uap->rusage = (struct rusage *)u.u_ar0[R1];
  	}
! 	uap->pid = WAIT_ANY;
! 	uap->status = 0;
! 	uap->compat = 1;
! 	u.u_error = wait1(u.u_procp, uap, retval);
! 	if (!u.u_error) {
! 		u.u_r.r_val1 = retval[0];
! 		u.u_r.r_val2 = retval[1];
! 	}
  }
  
+ wait4()
+ {
+ 	int retval[2];
+ 	register struct	args *uap = (struct args *)u.u_ap;
+ 
+ 	uap->compat = 0;
+ 	u.u_error = wait1(u.u_procp, uap, retval);
+ 	if (!u.u_error)
+ 		u.u_r.r_val1 = retval[0];
+ }
+ 
  /*
!  * Wait: check child processes to see if any have exited,
!  * stopped under trace or (optionally) stopped by a signal.
!  * Pass back status and make available for reuse the exited
!  * child's proc structure.
   */
! wait1(q, uap, retval)
! 	struct proc *q;
! 	register struct args *uap;
! 	int retval[];
  {
! 	int nfound, status;
! 	struct rusage ru;			/* used for local conversion */
! 	register struct proc *p;
! 	register int error;
  
! 	if (uap->pid == WAIT_MYPGRP)		/* == 0 */
! 		uap->pid = -q->p_pgrp;
  loop:
! 	nfound = 0;
  	/*
  	 * 4.X has child links in the proc structure, so they consolidate
  	 * these two tests into one loop.  We only have the zombie chain
***************
*** 226,272 ****
  	 * because they are more common, and, as the list is typically small,
  	 * a faster check.
  	 */
! 	for (p = zombproc; p;p = p->p_nxt)
! 		if (p->p_pptr == q) {
! 			u.u_r.r_val1 = p->p_pid;
! 			u.u_r.r_val2 = p->p_xstat;
! 			p->p_xstat = 0;
! 			if (ru)
! 				rucvt(ru, &p->p_ru);
! 			ruadd(&u.u_cru, &p->p_ru);
! 			p->p_stat = NULL;
! 			p->p_pid = 0;
! 			p->p_ppid = 0;
! 			if (*p->p_prev = p->p_nxt)	/* off zombproc */
! 				p->p_nxt->p_prev = p->p_prev;
! 			p->p_nxt = freeproc;		/* onto freeproc */
! 			freeproc = p;
! 			p->p_pptr = 0;
! 			p->p_sig = 0;
! 			p->p_sigcatch = 0;
! 			p->p_sigignore = 0;
! 			p->p_sigmask = 0;
! 			p->p_pgrp = 0;
! 			p->p_flag = 0;
! 			p->p_wchan = 0;
! 			p->p_cursig = 0;
! 			return (0);
  		}
! 	for (p = allproc; p;p = p->p_nxt)
! 		if (p->p_pptr == q) {
! 			++f;
! 			if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
! 			    (p->p_flag&STRC || options&WUNTRACED)) {
! 				p->p_flag |= SWTED;
! 				u.u_r.r_val1 = p->p_pid;
! 				u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
! 				return (0);
  			}
  		}
! 	if (f == 0)
  		return (ECHILD);
! 	if (options&WNOHANG) {
! 		u.u_r.r_val1 = 0;
  		return (0);
  	}
  	if (setjmp(&u.u_qsave)) {
--- 222,289 ----
  	 * because they are more common, and, as the list is typically small,
  	 * a faster check.
  	 */
! 	for (p = zombproc; p;p = p->p_nxt) {
! 		if (p->p_pptr != q)	/* are we the parent of this process? */
! 			continue;
! 		if (uap->pid != WAIT_ANY &&
! 		    p->p_pid != uap->pid && p->p_pgrp != -uap->pid)
! 			continue;
! 		retval[0] = p->p_pid;
! 		retval[1] = p->p_xstat;
! 		if (uap->status && (error = copyout(&p->p_xstat, uap->status,
! 						sizeof (uap->status))))
! 			return(error);
! 		if (uap->rusage) {
! 			rucvt(&ru, &p->p_ru);
! 			if (error = copyout(&ru, uap->rusage, sizeof (ru)))
! 				return(error);
  		}
! 		ruadd(&u.u_cru, &p->p_ru);
! 		p->p_xstat = 0;
! 		p->p_stat = NULL;
! 		p->p_pid = 0;
! 		p->p_ppid = 0;
! 		if (*p->p_prev = p->p_nxt)	/* off zombproc */
! 			p->p_nxt->p_prev = p->p_prev;
! 		p->p_nxt = freeproc;		/* onto freeproc */
! 		freeproc = p;
! 		p->p_pptr = 0;
! 		p->p_sig = 0;
! 		p->p_sigcatch = 0;
! 		p->p_sigignore = 0;
! 		p->p_sigmask = 0;
! 		p->p_pgrp = 0;
! 		p->p_flag = 0;
! 		p->p_wchan = 0;
! 		p->p_cursig = 0;
! 		return (0);
! 	}
! 	for (p = allproc; p;p = p->p_nxt) {
! 		if (p->p_pptr != q)
! 			continue;
! 		if (uap->pid != WAIT_ANY &&
! 		    p->p_pid != uap->pid && p->p_pgrp != -uap->pid)
! 			continue;
! 		++nfound;
! 		if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
! 		    (p->p_flag&STRC || uap->options&WUNTRACED)) {
! 			p->p_flag |= SWTED;
! 			retval[0] = p->p_pid;
! 			error = 0;
! 			if (uap->compat)
! 				retval[1] = W_STOPCODE(p->p_cursig);
! 			else if (uap->status) {
! 				status = W_STOPCODE(p->p_cursig);
! 				error = copyout(&status, uap->status,
! 						sizeof (status));
  			}
+ 			return (error);
  		}
! 	}
! 	if (nfound == 0)
  		return (ECHILD);
! 	if (uap->options&WNOHANG) {
! 		retval[0] = 0;
  		return (0);
  	}
  	if (setjmp(&u.u_qsave)) {
*** /usr/src/sys/sys/kern_fork.c.old	Sun Dec 27 18:28:47 1992
--- /usr/src/sys/sys/kern_fork.c	Fri Mar 12 19:38:02 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_fork.c	1.2 (2.11BSD GTE) 12/24/92
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_fork.c	1.3 (2.11BSD GTE) 3/10/93
   */
  
  #include "param.h"
***************
*** 157,164 ****
  	rip = u.u_procp;
  #ifdef QUOTA
  	QUOTAMAP();
! 	px_quota[rpp - proc] = px_quota[rip - proc];
! 	px_quota[rpp - proc]->q_cnt++;
  	QUOTAUNMAP();
  #endif
  	rpp->p_stat = SIDL;
--- 157,163 ----
  	rip = u.u_procp;
  #ifdef QUOTA
  	QUOTAMAP();
! 	u.u_quota->q_cnt++;
  	QUOTAUNMAP();
  #endif
  	rpp->p_stat = SIDL;
***************
*** 188,196 ****
  #endif
  	rpp->p_wchan = 0;
  	rpp->p_slptime = 0;
! 	n = PIDHASH(rpp->p_pid);
! 	rpp->p_idhash = pidhash[n];
! 	pidhash[n] = rpp - proc;
  	/*
  	 * some shuffling here -- in most UNIX kernels, the allproc assign
  	 * is done after grabbing the struct off of the freeproc list.  We
--- 187,198 ----
  #endif
  	rpp->p_wchan = 0;
  	rpp->p_slptime = 0;
! 	{
! 	struct proc **hash = &pidhash[PIDHASH(rpp->p_pid)];
! 
! 	rpp->p_hash = *hash;
! 	*hash = rpp;
! 	}
  	/*
  	 * some shuffling here -- in most UNIX kernels, the allproc assign
  	 * is done after grabbing the struct off of the freeproc list.  We
***************
*** 201,209 ****
  	rpp->p_nxt->p_prev = &rpp->p_nxt;	/*   (allproc is never NULL) */
  	rpp->p_prev = &allproc;
  	allproc = rpp;
- #ifdef UCB_METER
- 	multprog++;
- #endif
  
  	/*
  	 * Increase reference counts on shared objects.
--- 203,208 ----
***************
*** 264,279 ****
  		 * There is core, so just copy.
  		 */
  		rpp->p_addr = a[2];
- #ifdef CGL_RTP
- 		/*
- 		 * Copy is now a preemptable kernel process.
- 		 * The u. area is non-reentrant so copy it first
- 		 * in non-preemptable mode.
- 		 */
- 		copyu(rpp->p_addr);
- #else
  		copy(a1, rpp->p_addr, USIZE);
- #endif
  		u.u_procp = rip;
  		if (isvfork == 0) {
  			rpp->p_daddr = a[0];
--- 263,269 ----
*** /usr/src/sys/sys/kern_proc.c.old	Sat May 16 11:13:06 1987
--- /usr/src/sys/sys/kern_proc.c	Fri Mar 12 19:41:36 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_proc.c	1.1 (2.10BSD Berkeley) 12/1/86
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_proc.c	2.0 (2.11BSD GTE) 3/12/93
   */
  
  #include "param.h"
***************
*** 58,66 ****
  pfind(pid)
  	register int pid;
  {
! 	register struct proc *p;
  
! 	for (p = &proc[pidhash[PIDHASH(pid)]]; p != &proc[0]; p = &proc[p->p_idhash])
  		if (p->p_pid == pid)
  			return (p);
  	return ((struct proc *)0);
--- 58,66 ----
  pfind(pid)
  	register int pid;
  {
! 	register struct proc *p = pidhash[PIDHASH(pid)];
  
! 	for (; p; p = p->p_hash)
  		if (p->p_pid == pid)
  			return (p);
  	return ((struct proc *)0);
*** /usr/src/sys/sys/kern_resource.c.old	Sat Dec 26 19:57:04 1992
--- /usr/src/sys/sys/kern_resource.c	Wed Mar 10 23:08:51 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_resource.c	1.2 (2.11BSD GTE) 12/26/92
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)kern_resource.c	1.3 (2.11BSD GTE) 3/10/93
   */
  
  #include "param.h"
***************
*** 24,30 ****
  		int	who;
  	} *uap = (struct a *)u.u_ap;
  	register struct proc *p;
! 	int low = PRIO_MAX + 1;
  
  	switch (uap->which) {
  
--- 24,30 ----
  		int	who;
  	} *uap = (struct a *)u.u_ap;
  	register struct proc *p;
! 	register int low = PRIO_MAX + 1;
  
  	switch (uap->which) {
  
***************
*** 77,83 ****
  		int	prio;
  	} *uap = (struct a *)u.u_ap;
  	register struct proc *p;
! 	int found = 0;
  
  	switch (uap->which) {
  
--- 77,83 ----
  		int	prio;
  	} *uap = (struct a *)u.u_ap;
  	register struct proc *p;
! 	register int found = 0;
  
  	switch (uap->which) {
  
***************
*** 162,168 ****
  		return;
  	if (uap->which == RLIMIT_CPU) {
  		/*
! 		 * 2.10 stores RLIMIT_CPU as ticks to keep from making
  		 * hardclock() do long multiplication/division.
  		 */
  		if (alim.rlim_cur >= RLIM_INFINITY / LINEHZ)
--- 162,168 ----
  		return;
  	if (uap->which == RLIMIT_CPU) {
  		/*
! 		 * 2.11 stores RLIMIT_CPU as ticks to keep from making
  		 * hardclock() do long multiplication/division.
  		 */
  		if (alim.rlim_cur >= RLIM_INFINITY / LINEHZ)
*** /usr/src/sys/sys/kern_synch.c.old	Fri Jan  1 16:12:00 1993
--- /usr/src/sys/sys/kern_synch.c	Fri Mar 12 18:49:46 1993
***************
*** 234,243 ****
  				p->p_stat = SRUN;
  				if (p->p_flag & SLOAD)
  					setrq(p);
- #ifdef CGL_RTP
- 				if (p == rtpp)
- 					wantrtp++;
- #endif
  				/*
  				 * Since curpri is a usrpri,
  				 * p->p_pri is always better than curpri.
--- 234,239 ----
***************
*** 293,307 ****
  	if (p->p_flag & SLOAD)
  		setrq(p);
  	splx(s);
- #ifdef CGL_RTP
- 	if (p == rtpp)
- 		wantrtp++;
- 	if (p->p_pri < curpri || p == rtpp)
- 		runrun++;
- #else
  	if (p->p_pri < curpri)
  		runrun++;
- #endif
  	if ((p->p_flag&SLOAD) == 0) {
  		if (runout != 0) {
  			runout = 0;
--- 289,296 ----
***************
*** 383,407 ****
  	s = splhigh();
  	noproc = 0;
  	runrun = 0;
- #ifdef CGL_RTP
- 	/*
- 	 * Test for the presence of a "real time process".
- 	 * If there is one and it is runnable, give it top priority.
- 	 */
- 	if ((p = rtpp) && p->p_stat == SRUN && (p->p_flag & SLOAD)) {
- 		pq = NULL;
- 		for (q = qs;;q = q->p_link) {
- 			if (q == NULL)
- 				panic("rtp not found\n");
- 			if (q == p)
- 				break;
- 			pq = q;
- 		}
- 		n = PRTP;
- 		wantrtp = 0;
- 		goto runem;
- 	}
- #endif CGL_RTP
  #ifdef DIAGNOSTIC
  	for (p = qs; p; p = p->p_link)
  		if (p->p_stat != SRUN)
--- 372,377 ----
***************
*** 429,437 ****
  		idle();
  		goto loop;
  	}
- #ifdef CGL_RTP
- runem:
- #endif
  	if (pq)
  		pq->p_link = p->p_link;
  	else
--- 399,404 ----
*** /usr/src/sys/sys/quota_subr.c.old	Sat Apr 30 16:15:05 1988
--- /usr/src/sys/sys/quota_subr.c	Thu Mar 11 20:12:10 1993
***************
*** 52,63 ****
   */
  qclean()
  {
! 	register struct proc *p = u.u_procp;
! #ifdef BSD2_10
! 	register struct quota *q = px_quota[p - proc];
! #else
! 	register struct quota *q = p->p_quota;
! #endif
  
  	if (q == NOQUOTA)
  		return;
--- 52,58 ----
   */
  qclean()
  {
! 	register struct quota *q = u.u_quota;
  
  	if (q == NOQUOTA)
  		return;
***************
*** 72,82 ****
  	 * about to be given a new quota, which will just overwrite this
  	 * one).
  	 */
- #ifdef BSD2_10
- 	px_quota[u.u_procp - proc] = quota;
- #else
- 	p->p_quota = quota;
- #endif
  	u.u_quota = quota;
  	delquota(q);
  }
--- 67,72 ----
***************
*** 86,96 ****
  {
  
  	u.u_quota = q;
- #ifdef BSD2_10
- 	px_quota[u.u_procp - proc] = q;
- #else
- 	u.u_procp->p_quota = q;
- #endif
  }
  
  qwarn(dq)
--- 76,81 ----
*** /usr/src/sys/sys/vm_sched.c.old	Fri Mar 12 18:54:39 1993
--- /usr/src/sys/sys/vm_sched.c	Fri Mar 12 18:50:51 1993
***************
*** 120,131 ****
  			}
  		}
  		else if (l_maxsize == MINFINITY &&
! 		    (rp->p_stat == SRUN || rp->p_stat == SSLEEP)
! #ifdef CGL_RTP
! 		    /* can't swap processes preempted in copy/clear. */
! 		    && (rp->p_pri > PRTP + 1)
! #endif
! 		    ) {
  			register int rppri;
  
  			rppri = rp->p_time + rp->p_nice;
--- 120,126 ----
  			}
  		}
  		else if (l_maxsize == MINFINITY &&
! 		    (rp->p_stat == SRUN || rp->p_stat == SSLEEP)) {
  			register int rppri;
  
  			rppri = rp->p_time + rp->p_nice;
*** /usr/src/sys/sys/vm_swap.c.old	Sat Dec 26 19:57:52 1992
--- /usr/src/sys/sys/vm_swap.c	Wed Mar 10 20:25:33 1993
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)vm_swap.c	1.2 (2.11BSD GTE) 12/26/92
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)vm_swap.c	1.3 (2.11BSD GTE) 3/10/93
   */
  
  #include "param.h"
***************
*** 76,82 ****
  	p->p_flag |= SLOAD;
  	p->p_time = 0;
  #ifdef UCB_METER
- 	multprog++;
  	cnt.v_swpin++;
  #endif
  	return(1);
--- 76,81 ----
***************
*** 150,156 ****
  	p->p_time = 0;
  
  #ifdef UCB_METER
- 	multprog--;
  	cnt.v_swpout++;
  #endif
  
--- 149,154 ----
