aboutsummaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_aout.c6
-rw-r--r--sys/kern/init_main.c34
-rw-r--r--sys/kern/init_sysent.c8
-rw-r--r--sys/kern/kern_acct.c2
-rw-r--r--sys/kern/kern_clock.c608
-rw-r--r--sys/kern/kern_descrip.c4
-rw-r--r--sys/kern/kern_execve.c45
-rw-r--r--sys/kern/kern_exit.c5
-rw-r--r--sys/kern/kern_fork.c10
-rw-r--r--sys/kern/kern_malloc.c74
-rw-r--r--sys/kern/kern_ntptime.c267
-rw-r--r--sys/kern/kern_physio.c105
-rw-r--r--sys/kern/kern_prot.c2
-rw-r--r--sys/kern/kern_resource.c2
-rw-r--r--sys/kern/kern_sig.c12
-rw-r--r--sys/kern/kern_subr.c2
-rw-r--r--sys/kern/kern_synch.c4
-rw-r--r--sys/kern/kern_time.c6
-rw-r--r--sys/kern/makesyscalls.sh4
-rw-r--r--sys/kern/spec_vnops.c4
-rw-r--r--sys/kern/subr_prf.c11
-rw-r--r--sys/kern/subr_rand.c100
-rw-r--r--sys/kern/sys_process.c2
-rw-r--r--sys/kern/syscalls.c6
-rw-r--r--sys/kern/syscalls.master6
-rw-r--r--sys/kern/sysv_msg.c6
-rw-r--r--sys/kern/sysv_sem.c12
-rw-r--r--sys/kern/sysv_shm.c14
-rw-r--r--sys/kern/tty.c545
-rw-r--r--sys/kern/tty_conf.c6
-rw-r--r--sys/kern/tty_pty.c155
-rw-r--r--sys/kern/uipc_mbuf.c17
-rw-r--r--sys/kern/vfs__bio.c95
-rw-r--r--sys/kern/vfs_lookup.c15
-rw-r--r--sys/kern/vfs_subr.c25
-rw-r--r--sys/kern/vfs_syscalls.c7
-rw-r--r--sys/kern/vfs_vnops.c3
37 files changed, 1661 insertions, 568 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index 8bfb19cfe28d..8837764c2735 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: imgact_aout.c,v 1.3 1993/12/30 01:39:29 davidg Exp $
+ * $Id: imgact_aout.c,v 1.4 1994/03/17 22:21:02 davidg Exp $
*/
#include "param.h"
@@ -151,9 +151,7 @@ exec_aout_imgact(iparams)
&vmaddr,
a_out->a_data,
VM_PROT_READ | VM_PROT_WRITE | (a_out->a_text ? 0 : VM_PROT_EXECUTE),
- VM_PROT_READ | VM_PROT_WRITE | (a_out->a_text ? 0 : VM_PROT_EXECUTE),
- MAP_FILE | MAP_PRIVATE | MAP_FIXED,
- iparams->vnodep,
+ VM_PROT_ALL, MAP_FILE | MAP_PRIVATE | MAP_FIXED, iparams->vnodep,
file_offset + a_out->a_text);
if (error)
return (error);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index ce2f1bf8065f..9624bb3482b3 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)init_main.c 7.41 (Berkeley) 5/15/91
- * $Id: init_main.c,v 1.14 1994/01/14 16:24:45 davidg Exp $
+ * $Id: init_main.c,v 1.18 1994/06/16 02:55:28 davidg Exp $
*/
#include "param.h"
@@ -77,7 +77,7 @@ struct filedesc0 filedesc0;
struct plimit limit0;
struct vmspace vmspace0;
struct proc *curproc = &proc0;
-struct proc *initproc, *pageproc;
+struct proc *initproc, *pageproc, *pagescanproc, *updateproc;
int cmask = CMASK;
extern struct user *proc0paddr;
@@ -86,8 +86,6 @@ extern int (*mountroot)();
struct vnode *rootvp, *swapdev_vp;
int boothowto;
-struct proc *updateproc;
-
#if __GNUC__ >= 2
void __main() {}
#endif
@@ -96,6 +94,10 @@ void __main() {}
* This table is filled in by the linker with functions that need to be
* called to initialize various pseudo-devices and whatnot.
*/
+
+static void dummyinit() {}
+TEXT_SET(pseudo_set, dummyinit);
+
typedef void (*pseudo_func_t)(void);
extern const struct linker_set pseudo_set;
static const pseudo_func_t *pseudos =
@@ -351,7 +353,7 @@ main()
* Start up pageout daemon (process 2).
*/
if (fork(p, (void *) NULL, rval))
- panic("fork pager");
+ panic("failed fork pageout daemon");
if (rval[1]) {
/*
* Now in process 2.
@@ -364,11 +366,28 @@ main()
/*NOTREACHED*/
}
+#if 0
+ /*
+ * Start page scanner daemon (process 3).
+ */
+ if (fork(p, (void *) NULL, rval))
+ panic("failed fork page scanner daemon");
+ if (rval[1]) {
+ p = curproc;
+ pagescanproc = p;
+ p->p_flag |= SLOAD|SSYS;
+ bcopy("pagescan", p->p_comm, sizeof("pagescan"));
+ vm_pagescan();
+ /*NOTREACHED*/
+ }
+#endif
+
/*
- * Start update daemon (process 3).
+ * Start update daemon (process 4).
*/
+#ifndef LAPTOP
if (fork(p, (void *) NULL, rval))
- panic("fork update");
+ panic("failed fork update daemon");
if (rval[1]) {
p = curproc;
updateproc = p;
@@ -377,6 +396,7 @@ main()
vfs_update();
/*NOTREACHED*/
}
+#endif
/*
* enter scheduling loop
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 97056b0c3bbc..55a5b1e3263f 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -2,7 +2,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from $Id: syscalls.master,v 1.8 1994/01/31 10:27:25 davidg Exp $
+ * created from $Id: syscalls.master,v 1.9 1994/03/15 01:58:33 wollman Exp $
*/
#include "param.h"
@@ -174,6 +174,8 @@ int msgsys();
int shmsys();
#else
#endif
+int ntp_gettime();
+int ntp_adjtime();
#ifdef MACHVMCOMPAT
int svm_allocate();
int svm_deallocate();
@@ -453,8 +455,8 @@ struct sysent sysent[] = {
0, nosys, /* 172 = nosys */
0, nosys, /* 173 = nosys */
0, nosys, /* 174 = nosys */
- 0, nosys, /* 175 = nosys */
- 0, nosys, /* 176 = nosys */
+ 1, ntp_gettime, /* 175 = ntp_gettime */
+ 1, ntp_adjtime, /* 176 = ntp_adjtime */
#ifdef MACHVMCOMPAT
4, svm_allocate, /* 177 = vm_allocate */
3, svm_deallocate, /* 178 = vm_deallocate */
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index 6d2c0e6536c7..386886e9926a 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_acct.c 7.18 (Berkeley) 5/11/91
- * $Id: kern_acct.c,v 1.9.2.1 1994/05/04 07:54:32 rgrimes Exp $
+ * $Id: kern_acct.c,v 1.10 1994/05/04 08:26:46 rgrimes Exp $
*/
#include "param.h"
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 44a334e00ebc..8df606e4dc72 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -31,9 +31,27 @@
* SUCH DAMAGE.
*
* from: @(#)kern_clock.c 7.16 (Berkeley) 5/9/91
- * $Id: kern_clock.c,v 1.11 1993/12/19 00:51:20 wollman Exp $
+ * $Id: kern_clock.c,v 1.16 1994/04/21 20:39:30 wollman Exp $
*/
+/* Portions of this software are covered by the following: */
+/******************************************************************************
+ * *
+ * Copyright (c) David L. Mills 1993, 1994 *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, provided *
+ * that the above copyright notice appears in all copies and that both the *
+ * copyright notice and this permission notice appear in supporting *
+ * documentation, and that the name University of Delaware not be used in *
+ * advertising or publicity pertaining to distribution of the software *
+ * without specific, written prior permission. The University of Delaware *
+ * makes no representations about the suitability this software for any *
+ * purpose. It is provided "as is" without express or implied warranty. *
+ * *
+ *****************************************************************************/
+
+
#include "param.h"
#include "systm.h"
#include "dkstat.h"
@@ -42,6 +60,7 @@
#include "proc.h"
#include "signalvar.h"
#include "resourcevar.h"
+#include "timex.h"
#include "machine/cpu.h"
@@ -93,6 +112,238 @@ int ncallout;
}
/*
+ * Phase-lock loop (PLL) definitions
+ *
+ * The following variables are read and set by the ntp_adjtime() system
+ * call.
+ *
+ * time_state shows the state of the system clock, with values defined
+ * in the timex.h header file.
+ *
+ * time_status shows the status of the system clock, with bits defined
+ * in the timex.h header file.
+ *
+ * time_offset is used by the PLL to adjust the system time in small
+ * increments.
+ *
+ * time_constant determines the bandwidth or "stiffness" of the PLL.
+ *
+ * time_tolerance determines maximum frequency error or tolerance of the
+ * CPU clock oscillator and is a property of the architecture; however,
+ * in principle it could change as result of the presence of external
+ * discipline signals, for instance.
+ *
+ * time_precision is usually equal to the kernel tick variable; however,
+ * in cases where a precision clock counter or external clock is
+ * available, the resolution can be much less than this and depend on
+ * whether the external clock is working or not.
+ *
+ * time_maxerror is initialized by a ntp_adjtime() call and increased by
+ * the kernel once each second to reflect the maximum error
+ * bound growth.
+ *
+ * time_esterror is set and read by the ntp_adjtime() call, but
+ * otherwise not used by the kernel.
+ */
+int time_status = STA_UNSYNC; /* clock status bits */
+int time_state = TIME_OK; /* clock state */
+long time_offset = 0; /* time offset (us) */
+long time_constant = 0; /* pll time constant */
+long time_tolerance = MAXFREQ; /* frequency tolerance (scaled ppm) */
+long time_precision = 1; /* clock precision (us) */
+long time_maxerror = MAXPHASE; /* maximum error (us) */
+long time_esterror = MAXPHASE; /* estimated error (us) */
+
+/*
+ * The following variables establish the state of the PLL and the
+ * residual time and frequency offset of the local clock. The scale
+ * factors are defined in the timex.h header file.
+ *
+ * time_phase and time_freq are the phase increment and the frequency
+ * increment, respectively, of the kernel time variable at each tick of
+ * the clock.
+ *
+ * time_freq is set via ntp_adjtime() from a value stored in a file when
+ * the synchronization daemon is first started. Its value is retrieved
+ * via ntp_adjtime() and written to the file about once per hour by the
+ * daemon.
+ *
+ * time_adj is the adjustment added to the value of tick at each timer
+ * interrupt and is recomputed at each timer interrupt.
+ *
+ * time_reftime is the second's portion of the system time on the last
+ * call to ntp_adjtime(). It is used to adjust the time_freq variable
+ * and to increase the time_maxerror as the time since last update
+ * increases.
+ */
+long time_phase = 0; /* phase offset (scaled us) */
+long time_freq = 0; /* frequency offset (scaled ppm) */
+long time_adj = 0; /* tick adjust (scaled 1 / hz) */
+long time_reftime = 0; /* time at last adjustment (s) */
+
+#ifdef PPS_SYNC
+/*
+ * The following variables are used only if the if the kernel PPS
+ * discipline code is configured (PPS_SYNC). The scale factors are
+ * defined in the timex.h header file.
+ *
+ * pps_time contains the time at each calibration interval, as read by
+ * microtime().
+ *
+ * pps_offset is the time offset produced by the time median filter
+ * pps_tf[], while pps_jitter is the dispersion measured by this
+ * filter.
+ *
+ * pps_freq is the frequency offset produced by the frequency median
+ * filter pps_ff[], while pps_stabil is the dispersion measured by
+ * this filter.
+ *
+ * pps_usec is latched from a high resolution counter or external clock
+ * at pps_time. Here we want the hardware counter contents only, not the
+ * contents plus the time_tv.usec as usual.
+ *
+ * pps_valid counts the number of seconds since the last PPS update. It
+ * is used as a watchdog timer to disable the PPS discipline should the
+ * PPS signal be lost.
+ *
+ * pps_glitch counts the number of seconds since the beginning of an
+ * offset burst more than tick/2 from current nominal offset. It is used
+ * mainly to suppress error bursts due to priority conflicts between the
+ * PPS interrupt and timer interrupt.
+ *
+ * pps_count counts the seconds of the calibration interval, the
+ * duration of which is pps_shift in powers of two.
+ *
+ * pps_intcnt counts the calibration intervals for use in the interval-
+ * adaptation algorithm. It's just too complicated for words.
+ */
+struct timeval pps_time; /* kernel time at last interval */
+long pps_offset = 0; /* pps time offset (us) */
+long pps_jitter = MAXTIME; /* pps time dispersion (jitter) (us) */
+long pps_tf[] = {0, 0, 0}; /* pps time offset median filter (us) */
+long pps_freq = 0; /* frequency offset (scaled ppm) */
+long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */
+long pps_ff[] = {0, 0, 0}; /* frequency offset median filter */
+long pps_usec = 0; /* microsec counter at last interval */
+long pps_valid = PPS_VALID; /* pps signal watchdog counter */
+int pps_glitch = 0; /* pps signal glitch counter */
+int pps_count = 0; /* calibration interval counter (s) */
+int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */
+int pps_intcnt = 0; /* intervals at current duration */
+
+/*
+ * PPS signal quality monitors
+ *
+ * pps_jitcnt counts the seconds that have been discarded because the
+ * jitter measured by the time median filter exceeds the limit MAXTIME
+ * (100 us).
+ *
+ * pps_calcnt counts the frequency calibration intervals, which are
+ * variable from 4 s to 256 s.
+ *
+ * pps_errcnt counts the calibration intervals which have been discarded
+ * because the wander exceeds the limit MAXFREQ (100 ppm) or where the
+ * calibration interval jitter exceeds two ticks.
+ *
+ * pps_stbcnt counts the calibration intervals that have been discarded
+ * because the frequency wander exceeds the limit MAXFREQ / 4 (25 us).
+ */
+long pps_jitcnt = 0; /* jitter limit exceeded */
+long pps_calcnt = 0; /* calibration intervals */
+long pps_errcnt = 0; /* calibration errors */
+long pps_stbcnt = 0; /* stability limit exceeded */
+#endif /* PPS_SYNC */
+
+/* XXX none of this stuff works under FreeBSD */
+#ifdef EXT_CLOCK
+/*
+ * External clock definitions
+ *
+ * The following definitions and declarations are used only if an
+ * external clock (HIGHBALL or TPRO) is configured on the system.
+ */
+#define CLOCK_INTERVAL 30 /* CPU clock update interval (s) */
+
+/*
+ * The clock_count variable is set to CLOCK_INTERVAL at each PPS
+ * interrupt and decremented once each second.
+ */
+int clock_count = 0; /* CPU clock counter */
+
+#ifdef HIGHBALL
+/*
+ * The clock_offset and clock_cpu variables are used by the HIGHBALL
+ * interface. The clock_offset variable defines the offset between
+ * system time and the HIGBALL counters. The clock_cpu variable contains
+ * the offset between the system clock and the HIGHBALL clock for use in
+ * disciplining the kernel time variable.
+ */
+extern struct timeval clock_offset; /* Highball clock offset */
+long clock_cpu = 0; /* CPU clock adjust */
+#endif /* HIGHBALL */
+#endif /* EXT_CLOCK */
+
+/*
+ * hardupdate() - local clock update
+ *
+ * This routine is called by ntp_adjtime() to update the local clock
+ * phase and frequency. This is used to implement an adaptive-parameter,
+ * first-order, type-II phase-lock loop. The code computes new time and
+ * frequency offsets each time it is called. The hardclock() routine
+ * amortizes these offsets at each tick interrupt. If the kernel PPS
+ * discipline code is configured (PPS_SYNC), the PPS signal itself
+ * determines the new time offset, instead of the calling argument.
+ * Presumably, calls to ntp_adjtime() occur only when the caller
+ * believes the local clock is valid within some bound (+-128 ms with
+ * NTP). If the caller's time is far different than the PPS time, an
+ * argument will ensue, and it's not clear who will lose.
+ *
+ * For default SHIFT_UPDATE = 12, the offset is limited to +-512 ms, the
+ * maximum interval between updates is 4096 s and the maximum frequency
+ * offset is +-31.25 ms/s.
+ *
+ * Note: splclock() is in effect.
+ */
+void
+hardupdate(offset)
+ long offset;
+{
+ long ltemp, mtemp;
+
+ if (!(time_status & STA_PLL) && !(time_status & STA_PPSTIME))
+ return;
+ ltemp = offset;
+#ifdef PPS_SYNC
+ if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)
+ ltemp = pps_offset;
+#endif /* PPS_SYNC */
+ if (ltemp > MAXPHASE)
+ time_offset = MAXPHASE << SHIFT_UPDATE;
+ else if (ltemp < -MAXPHASE)
+ time_offset = -(MAXPHASE << SHIFT_UPDATE);
+ else
+ time_offset = ltemp << SHIFT_UPDATE;
+ mtemp = time.tv_sec - time_reftime;
+ time_reftime = time.tv_sec;
+ if (mtemp > MAXSEC)
+ mtemp = 0;
+
+ /* ugly multiply should be replaced */
+ if (ltemp < 0)
+ time_freq -= (-ltemp * mtemp) >> (time_constant +
+ time_constant + SHIFT_KF - SHIFT_USEC);
+ else
+ time_freq += (ltemp * mtemp) >> (time_constant +
+ time_constant + SHIFT_KF - SHIFT_USEC);
+ if (time_freq > time_tolerance)
+ time_freq = time_tolerance;
+ else if (time_freq < -time_tolerance)
+ time_freq = -time_tolerance;
+}
+
+
+
+/*
* The hz hardware interval timer.
* We update the events relating to real time.
* If this timer is also being used to gather statistics,
@@ -111,6 +362,7 @@ hardclock(frame)
int needsoft = 0;
extern int tickdelta;
extern long timedelta;
+ long ltemp, time_update = 0;
/*
* Update real-time timeout queue.
@@ -234,49 +486,164 @@ hardclock(frame)
* so we don't keep the relatively high clock interrupt
* priority any longer than necessary.
*/
- if (timedelta == 0)
- BUMPTIME(&time, tick)
- else {
- register delta;
-
- if (timedelta < 0) {
- delta = tick - tickdelta;
- timedelta += tickdelta;
+ {
+ int time_update;
+ if (timedelta == 0) {
+ time_update = tick;
} else {
- delta = tick + tickdelta;
- timedelta -= tickdelta;
+ if (timedelta < 0) {
+ time_update = tick - tickdelta;
+ timedelta += tickdelta;
+ } else {
+ time_update = tick + tickdelta;
+ timedelta -= tickdelta;
+ }
+ }
+ /*
+ * Compute the phase adjustment. If the low-order bits
+ * (time_phase) of the update overflow, bump the high-order bits
+ * (time_update).
+ */
+ time_phase += time_adj;
+ if (time_phase <= -FINEUSEC) {
+ ltemp = -time_phase >> SHIFT_SCALE;
+ time_phase += ltemp << SHIFT_SCALE;
+ time_update -= ltemp;
+ }
+ else if (time_phase >= FINEUSEC) {
+ ltemp = time_phase >> SHIFT_SCALE;
+ time_phase -= ltemp << SHIFT_SCALE;
+ time_update += ltemp;
+ }
+
+ time.tv_usec += time_update;
+ /*
+ * On rollover of the second the phase adjustment to be used for
+ * the next second is calculated. Also, the maximum error is
+ * increased by the tolerance. If the PPS frequency discipline
+ * code is present, the phase is increased to compensate for the
+ * CPU clock oscillator frequency error.
+ *
+ * With SHIFT_SCALE = 23, the maximum frequency adjustment is
+ * +-256 us per tick, or 25.6 ms/s at a clock frequency of 100
+ * Hz. The time contribution is shifted right a minimum of two
+ * bits, while the frequency contribution is a right shift.
+ * Thus, overflow is prevented if the frequency contribution is
+ * limited to half the maximum or 15.625 ms/s.
+ */
+ if (time.tv_usec >= 1000000) {
+ time.tv_usec -= 1000000;
+ time.tv_sec++;
+ time_maxerror += time_tolerance >> SHIFT_USEC;
+ if (time_offset < 0) {
+ ltemp = -time_offset >>
+ (SHIFT_KG + time_constant);
+ time_offset += ltemp;
+ time_adj = -ltemp <<
+ (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+ } else {
+ ltemp = time_offset >>
+ (SHIFT_KG + time_constant);
+ time_offset -= ltemp;
+ time_adj = ltemp <<
+ (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+ }
+#ifdef PPS_SYNC
+ /*
+ * Gnaw on the watchdog counter and update the frequency
+ * computed by the pll and the PPS signal.
+ */
+ pps_valid++;
+ if (pps_valid == PPS_VALID) {
+ pps_jitter = MAXTIME;
+ pps_stabil = MAXFREQ;
+ time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+ STA_PPSWANDER | STA_PPSERROR);
+ }
+ ltemp = time_freq + pps_freq;
+#else
+ ltemp = time_freq;
+#endif /* PPS_SYNC */
+ if (ltemp < 0)
+ time_adj -= -ltemp >>
+ (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+ else
+ time_adj += ltemp >>
+ (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+
+ /*
+ * When the CPU clock oscillator frequency is not a
+ * power of two in Hz, the SHIFT_HZ is only an
+ * approximate scale factor. In the SunOS kernel, this
+ * results in a PLL gain factor of 1/1.28 = 0.78 what it
+ * should be. In the following code the overall gain is
+ * increased by a factor of 1.25, which results in a
+ * residual error less than 3 percent.
+ */
+ /* Same thing applies for FreeBSD --GAW */
+ if (hz == 100) {
+ if (time_adj < 0)
+ time_adj -= -time_adj >> 2;
+ else
+ time_adj += time_adj >> 2;
+ }
+
+ /* XXX - this is really bogus, but can't be fixed until
+ xntpd's idea of the system clock is fixed to know how
+ the user wants leap seconds handled; in the mean time,
+ we assume that users of NTP are running without proper
+ leap second support (this is now the default anyway) */
+ /*
+ * Leap second processing. If in leap-insert state at
+ * the end of the day, the system clock is set back one
+ * second; if in leap-delete state, the system clock is
+ * set ahead one second. The microtime() routine or
+ * external clock driver will insure that reported time
+ * is always monotonic. The ugly divides should be
+ * replaced.
+ */
+ switch (time_state) {
+
+ case TIME_OK:
+ if (time_status & STA_INS)
+ time_state = TIME_INS;
+ else if (time_status & STA_DEL)
+ time_state = TIME_DEL;
+ break;
+
+ case TIME_INS:
+ if (time.tv_sec % 86400 == 0) {
+ time.tv_sec--;
+ time_state = TIME_OOP;
+ }
+ break;
+
+ case TIME_DEL:
+ if ((time.tv_sec + 1) % 86400 == 0) {
+ time.tv_sec++;
+ time_state = TIME_WAIT;
+ }
+ break;
+
+ case TIME_OOP:
+ time_state = TIME_WAIT;
+ break;
+
+ case TIME_WAIT:
+ if (!(time_status & (STA_INS | STA_DEL)))
+ time_state = TIME_OK;
+ }
}
- BUMPTIME(&time, delta);
}
-#ifdef DCFCLK
- /*
- * This is lousy, but until I can get the $&^%&^(!!! signal onto one
- * of the interrupt's I'll have to poll it. No, it will not work if
- * you attempt -DHZ=1000, things break.
- * But keep the NDCFCLK low, to avoid waste of cycles...
- * phk@data.fls.dk
- */
- dcfclk_worker();
-#endif
if (needsoft) {
-#if 0
-/*
- * XXX - hardclock runs at splhigh, so the splsoftclock is useless and
- * softclock runs at splhigh as well if we do this. It is not much of
- * an optimization, since the "software interrupt" is done with a call
- * from doreti, and the overhead of checking there is sometimes less
- * than checking here. Moreover, the whole %$$%$^ frame is passed by
- * value here.
- */
if (CLKF_BASEPRI(&frame)) {
/*
* Save the overhead of a software interrupt;
* it will happen as soon as we return, so do it now.
*/
(void) splsoftclock();
- softclock(frame);
+ softclock(CLKF_USERMODE(&frame));
} else
-#endif
setsoftclock();
}
}
@@ -322,7 +689,7 @@ gatherstats(framep)
cpstate = CP_SYS;
if (curproc == NULL && CLKF_BASEPRI(framep))
cpstate = CP_IDLE;
-#ifdef GPROF
+#if defined(GPROF) && !defined(GUPROF)
s = (u_long) CLKF_PC(framep) - (u_long) s_lowpc;
if (profiling < 2 && s < s_textsize)
kcount[s / (HISTFRACTION * sizeof (*kcount))]++;
@@ -343,10 +710,9 @@ gatherstats(framep)
* Software priority level clock interrupt.
* Run periodic events from timeout queue.
*/
-/*ARGSUSED*/
void
-softclock(frame)
- clockframe frame;
+softclock(usermode)
+ int usermode;
{
for (;;) {
@@ -377,11 +743,11 @@ softclock(frame)
* If trapped user-mode and profiling, give it
* a profiling tick.
*/
- if (CLKF_USERMODE(&frame)) {
+ if (usermode) {
register struct proc *p = curproc;
if (p->p_stats->p_prof.pr_scale)
- profile_tick(p, &frame);
+ profile_tick(p, unused was &frame);
/*
* Check to see if process has accumulated
* more than 10 minutes of user time. If so
@@ -515,3 +881,167 @@ hzto(tv)
ticks = CLOCK_T_MAX;
return (ticks);
}
+
+#ifdef PPS_SYNC
+/*
+ * hardpps() - discipline CPU clock oscillator to external pps signal
+ *
+ * This routine is called at each PPS interrupt in order to discipline
+ * the CPU clock oscillator to the PPS signal. It integrates successive
+ * phase differences between the two oscillators and calculates the
+ * frequency offset. This is used in hardclock() to discipline the CPU
+ * clock oscillator so that intrinsic frequency error is cancelled out.
+ * The code requires the caller to capture the time and hardware
+ * counter value at the designated PPS signal transition.
+ */
+void
+hardpps(tvp, usec)
+ struct timeval *tvp; /* time at PPS */
+ long usec; /* hardware counter at PPS */
+{
+ long u_usec, v_usec, bigtick;
+ long cal_sec, cal_usec;
+
+ /*
+ * During the calibration interval adjust the starting time when
+ * the tick overflows. At the end of the interval compute the
+ * duration of the interval and the difference of the hardware
+ * counters at the beginning and end of the interval. This code
+ * is deliciously complicated by the fact valid differences may
+ * exceed the value of tick when using long calibration
+ * intervals and small ticks. Note that the counter can be
+ * greater than tick if caught at just the wrong instant, but
+ * the values returned and used here are correct.
+ */
+ bigtick = (long)tick << SHIFT_USEC;
+ pps_usec -= ntp_pll.ybar;
+ if (pps_usec >= bigtick)
+ pps_usec -= bigtick;
+ if (pps_usec < 0)
+ pps_usec += bigtick;
+ pps_time.tv_sec++;
+ pps_count++;
+ if (pps_count < (1 << pps_shift))
+ return;
+ pps_count = 0;
+ ntp_pll.calcnt++;
+ u_usec = usec << SHIFT_USEC;
+ v_usec = pps_usec - u_usec;
+ if (v_usec >= bigtick >> 1)
+ v_usec -= bigtick;
+ if (v_usec < -(bigtick >> 1))
+ v_usec += bigtick;
+ if (v_usec < 0)
+ v_usec = -(-v_usec >> ntp_pll.shift);
+ else
+ v_usec = v_usec >> ntp_pll.shift;
+ pps_usec = u_usec;
+ cal_sec = tvp->tv_sec;
+ cal_usec = tvp->tv_usec;
+ cal_sec -= pps_time.tv_sec;
+ cal_usec -= pps_time.tv_usec;
+ if (cal_usec < 0) {
+ cal_usec += 1000000;
+ cal_sec--;
+ }
+ pps_time = *tvp;
+
+ /*
+ * Check for lost interrupts, noise, excessive jitter and
+ * excessive frequency error. The number of timer ticks during
+ * the interval may vary +-1 tick. Add to this a margin of one
+ * tick for the PPS signal jitter and maximum frequency
+ * deviation. If the limits are exceeded, the calibration
+ * interval is reset to the minimum and we start over.
+ */
+ u_usec = (long)tick << 1;
+ if (!((cal_sec == -1 && cal_usec > (1000000 - u_usec))
+ || (cal_sec == 0 && cal_usec < u_usec))
+ || v_usec > ntp_pll.tolerance || v_usec < -ntp_pll.tolerance) {
+ ntp_pll.jitcnt++;
+ ntp_pll.shift = NTP_PLL.SHIFT;
+ pps_dispinc = PPS_DISPINC;
+ ntp_pll.intcnt = 0;
+ return;
+ }
+
+ /*
+ * A three-stage median filter is used to help deglitch the pps
+ * signal. The median sample becomes the offset estimate; the
+ * difference between the other two samples becomes the
+ * dispersion estimate.
+ */
+ pps_mf[2] = pps_mf[1];
+ pps_mf[1] = pps_mf[0];
+ pps_mf[0] = v_usec;
+ if (pps_mf[0] > pps_mf[1]) {
+ if (pps_mf[1] > pps_mf[2]) {
+ u_usec = pps_mf[1]; /* 0 1 2 */
+ v_usec = pps_mf[0] - pps_mf[2];
+ } else if (pps_mf[2] > pps_mf[0]) {
+ u_usec = pps_mf[0]; /* 2 0 1 */
+ v_usec = pps_mf[2] - pps_mf[1];
+ } else {
+ u_usec = pps_mf[2]; /* 0 2 1 */
+ v_usec = pps_mf[0] - pps_mf[1];
+ }
+ } else {
+ if (pps_mf[1] < pps_mf[2]) {
+ u_usec = pps_mf[1]; /* 2 1 0 */
+ v_usec = pps_mf[2] - pps_mf[0];
+ } else if (pps_mf[2] < pps_mf[0]) {
+ u_usec = pps_mf[0]; /* 1 0 2 */
+ v_usec = pps_mf[1] - pps_mf[2];
+ } else {
+ u_usec = pps_mf[2]; /* 1 2 0 */
+ v_usec = pps_mf[1] - pps_mf[0];
+ }
+ }
+
+ /*
+ * Here the dispersion average is updated. If it is less than
+ * the threshold pps_dispmax, the frequency average is updated
+ * as well, but clamped to the tolerance.
+ */
+ v_usec = (v_usec >> 1) - ntp_pll.disp;
+ if (v_usec < 0)
+ ntp_pll.disp -= -v_usec >> PPS_AVG;
+ else
+ ntp_pll.disp += v_usec >> PPS_AVG;
+ if (ntp_pll.disp > pps_dispmax) {
+ ntp_pll.discnt++;
+ return;
+ }
+ if (u_usec < 0) {
+ ntp_pll.ybar -= -u_usec >> PPS_AVG;
+ if (ntp_pll.ybar < -ntp_pll.tolerance)
+ ntp_pll.ybar = -ntp_pll.tolerance;
+ u_usec = -u_usec;
+ } else {
+ ntp_pll.ybar += u_usec >> PPS_AVG;
+ if (ntp_pll.ybar > ntp_pll.tolerance)
+ ntp_pll.ybar = ntp_pll.tolerance;
+ }
+
+ /*
+ * Here the calibration interval is adjusted. If the maximum
+ * time difference is greater than tick/4, reduce the interval
+ * by half. If this is not the case for four consecutive
+ * intervals, double the interval.
+ */
+ if (u_usec << ntp_pll.shift > bigtick >> 2) {
+ ntp_pll.intcnt = 0;
+ if (ntp_pll.shift > NTP_PLL.SHIFT) {
+ ntp_pll.shift--;
+ pps_dispinc <<= 1;
+ }
+ } else if (ntp_pll.intcnt >= 4) {
+ ntp_pll.intcnt = 0;
+ if (ntp_pll.shift < NTP_PLL.SHIFTMAX) {
+ ntp_pll.shift++;
+ pps_dispinc >>= 1;
+ }
+ } else
+ ntp_pll.intcnt++;
+}
+#endif /* PPS_SYNC */
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index d28faac16cbe..7ad2e2946f6a 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_descrip.c 7.28 (Berkeley) 6/25/91
- * $Id: kern_descrip.c,v 1.6.2.1 1994/05/04 07:54:36 rgrimes Exp $
+ * $Id: kern_descrip.c,v 1.8 1994/05/04 08:26:49 rgrimes Exp $
*/
#include "param.h"
@@ -100,10 +100,12 @@ dup(p, uap, retval)
struct file *fp;
int fd, error;
+#if 0
/*
* XXX Compatibility
*/
if (uap->i &~ 077) { uap->i &= 077; return (dup2(p, uap, retval)); }
+#endif
if ((unsigned)uap->i >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->i]) == NULL)
diff --git a/sys/kern/kern_execve.c b/sys/kern/kern_execve.c
index 5e0aa6565d3d..f72948400f1e 100644
--- a/sys/kern/kern_execve.c
+++ b/sys/kern/kern_execve.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_execve.c,v 1.15.2.2 1994/03/24 08:57:16 rgrimes Exp $
+ * $Id: kern_execve.c,v 1.20 1994/03/26 12:24:27 davidg Exp $
*/
#include "param.h"
@@ -78,9 +78,6 @@ execve(p, uap, retval)
char *stringbase, *stringp;
int *stack_base;
int error, resid, len, i;
-#if 0
- char image_header[256];
-#endif
struct image_params image_params, *iparams;
struct vnode *vnodep;
struct vattr attr;
@@ -147,33 +144,13 @@ interpret:
if (error)
goto exec_fail_dealloc;
-#if 0
- /*
- * Read the image header from the file.
- */
- error = vn_rdwr(UIO_READ,
- vnodep,
- image_header,
- sizeof(image_header),
- 0,
- UIO_SYSSPACE, IO_NODELOCKED,
- p->p_ucred,
- &resid,
- p);
- if (error)
- goto exec_fail_dealloc;
-
- /* Clear out junk in image_header if a partial read (small file) */
- if (resid)
- bzero(image_header + (sizeof(image_header) - resid), resid);
-#endif
/*
* Map the image header (first page) of the file into
* kernel address space
*/
error = vm_mmap(kernel_map, /* map */
(vm_offset_t *)&image_header, /* address */
- NBPG, /* size */
+ PAGE_SIZE, /* size */
VM_PROT_READ, /* protection */
VM_PROT_READ, /* max protection */
MAP_FILE, /* flags */
@@ -208,7 +185,7 @@ interpret:
vput(ndp->ni_vp);
FREE(ndp->ni_pnbuf, M_NAMEI);
if (vm_deallocate(kernel_map,
- (vm_offset_t)image_header, NBPG))
+ (vm_offset_t)image_header, PAGE_SIZE))
panic("execve: header dealloc failed (1)");
/* set new name to that of the interpreter */
@@ -231,14 +208,15 @@ interpret:
stack_base = exec_copyout_strings(iparams);
p->p_vmspace->vm_minsaddr = (char *)stack_base;
-
/*
* Stuff argument count as first item on stack
*/
*(--stack_base) = iparams->argc;
- /* close files on exec, fixup signals */
+ /* close files on exec */
fdcloseexec(p);
+
+ /* reset caught signals */
execsigs(p);
/* name this process - nameiexec(p, ndp) */
@@ -269,12 +247,12 @@ interpret:
vrele(p->p_tracep);
p->p_tracep = 0;
}
- if ((attr.va_mode&VSUID) && (p->p_flag & STRC) == 0) {
+ if ((attr.va_mode & VSUID) && (p->p_flag & STRC) == 0) {
p->p_ucred = crcopy(p->p_ucred);
p->p_ucred->cr_uid = attr.va_uid;
p->p_flag |= SUGID;
}
- if ((attr.va_mode&VSGID) && (p->p_flag & STRC) == 0) {
+ if ((attr.va_mode & VSGID) && (p->p_flag & STRC) == 0) {
p->p_ucred = crcopy(p->p_ucred);
p->p_ucred->cr_groups[0] = attr.va_gid;
p->p_flag |= SUGID;
@@ -305,10 +283,9 @@ interpret:
/*
* free various allocated resources
*/
- if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase,
- ARG_MAX))
+ if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, ARG_MAX))
panic("execve: string buffer dealloc failed (1)");
- if (vm_deallocate(kernel_map, (vm_offset_t)image_header, NBPG))
+ if (vm_deallocate(kernel_map, (vm_offset_t)image_header, PAGE_SIZE))
panic("execve: header dealloc failed (2)");
vput(ndp->ni_vp);
FREE(ndp->ni_pnbuf, M_NAMEI);
@@ -322,7 +299,7 @@ exec_fail_dealloc:
panic("execve: string buffer dealloc failed (2)");
if (iparams->image_header && iparams->image_header != (char *)-1)
if (vm_deallocate(kernel_map,
- (vm_offset_t)iparams->image_header, NBPG))
+ (vm_offset_t)iparams->image_header, PAGE_SIZE))
panic("execve: header dealloc failed (3)");
vput(ndp->ni_vp);
FREE(ndp->ni_pnbuf, M_NAMEI);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index e1deb4d855fe..a6cf4c732390 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_exit.c 7.35 (Berkeley) 6/27/91
- * $Id: kern_exit.c,v 1.14 1994/01/29 04:04:23 davidg Exp $
+ * $Id: kern_exit.c,v 1.15 1994/03/14 21:54:13 davidg Exp $
*/
#include "param.h"
@@ -353,6 +353,9 @@ loop:
continue;
nfound++;
if (p->p_stat == SZOMB) {
+ /* charge childs cpu usage to parent */
+ if( curproc->p_pid != 1)
+ curproc->p_cpu += p->p_cpu;
retval[0] = p->p_pid;
#ifdef COMPAT_43
if (uap->compat)
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 5ca1d910f937..b9088766dd8b 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_fork.c 7.29 (Berkeley) 5/15/91
- * $Id: kern_fork.c,v 1.6.2.1 1994/05/04 07:54:38 rgrimes Exp $
+ * $Id: kern_fork.c,v 1.8 1994/05/04 08:26:54 rgrimes Exp $
*/
#include "param.h"
@@ -246,6 +246,11 @@ again:
#endif
/*
+ * set priority of child to be that of parent
+ */
+ p2->p_cpu = p1->p_cpu;
+
+ /*
* This begins the section where we must prevent the parent
* from being swapped.
*/
@@ -268,6 +273,9 @@ again:
p2->p_stats->p_start = time;
(void) spl0();
p2->p_acflag = AFORK;
+/*
+ vm_map_init_pmap(&p2->p_vmspace->vm_map);
+*/
return (0);
}
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 6841827446d0..ce3243a30367 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_malloc.c 7.25 (Berkeley) 5/8/91
- * $Id: kern_malloc.c,v 1.8 1994/02/10 08:04:07 davidg Exp $
+ * $Id: kern_malloc.c,v 1.9 1994/04/13 00:54:59 ache Exp $
*/
#include "param.h"
@@ -259,3 +259,75 @@ kmeminit()
kmemstats[M_MBUF].ks_limit = (vm_page_count * NBPG) / 16;
#endif
}
+
+void *
+contigmalloc(size, type, flags, maxpa, alignmask, boundarymask)
+ unsigned long size;
+ int type;
+ int flags;
+ unsigned long maxpa; /* e.g. 16M - 1 for isa dma */
+ unsigned long alignmask; /* e.g. 1M - 1 for M boundary */
+ unsigned long boundarymask; /* e.g. 64K - 1 for 8-bit isa dma */
+{
+ unsigned long skipsize;
+ void *skipva;
+
+ size = round_page(size);
+ if (size == 0 || size > boundarymask + 1)
+ return (NULL);
+
+ /*
+ * Attempt to push the physical address to a suitable boundary by
+ * skipping some memory. We could be cleverer here. E.g., mallocate
+ * lots of single pages and then free the ones that we hope to use.
+ * flags == M_WAIT is likely to hang the system.
+ */
+ for (skipsize = 0, skipva = NULL; ; skipsize += NBPG) {
+ unsigned long off;
+ unsigned long pa;
+ unsigned long prevpa;
+ void *va;
+
+ if (skipsize != 0) {
+ skipva = malloc(skipsize, type, flags);
+ if (skipva == NULL) {
+#ifdef DEBUG
+ printf("contigmalloc: skipva NULL on try %d\n",
+ 1 + skipsize / NBPG);
+#endif
+ return (NULL);
+ }
+ }
+ va = malloc(size, type, flags);
+ if (skipsize != 0)
+ free(skipva, type);
+ if (va == NULL) {
+#ifdef DEBUG
+ printf("contigmalloc: va NULL on try %d\n",
+ 1 + skipsize / NBPG);
+#endif
+ return (NULL);
+ }
+ for (off = 0, prevpa = 0; off < size; off += NBPG, prevpa = pa)
+ {
+ pa = pmap_extract(pmap_kernel(), (vm_offset_t)va + off);
+ if (pa + NBPG - 1 > maxpa
+ || off == 0 && pa & alignmask
+ || off != 0
+ && (pa != prevpa + NBPG
+ || (pa & boundarymask) == 0))
+ goto fail;
+ }
+#ifdef DEBUG
+ printf("contigmalloc: success at va %lx pa %lx on try %d\n",
+ (unsigned long)va,
+ pmap_extract(pmap_kernel(), (unsigned long)va),
+ 1 + skipsize / NBPG);
+#endif
+ return (va);
+fail:
+ free(va, type);
+ }
+}
+
+
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
new file mode 100644
index 000000000000..9e50a42df282
--- /dev/null
+++ b/sys/kern/kern_ntptime.c
@@ -0,0 +1,267 @@
+/******************************************************************************
+ * *
+ * Copyright (c) David L. Mills 1993, 1994 *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, provided *
+ * that the above copyright notice appears in all copies and that both the *
+ * copyright notice and this permission notice appear in supporting *
+ * documentation, and that the name University of Delaware not be used in *
+ * advertising or publicity pertaining to distribution of the software *
+ * without specific, written prior permission. The University of Delaware *
+ * makes no representations about the suitability this software for any *
+ * purpose. It is provided "as is" without express or implied warranty. *
+ * *
+ ******************************************************************************/
+
+/*
+ * Modification history kern_ntptime.c
+ *
+ * 24 Mar 94 David L. Mills
+ * Revised syscall interface to include new variables for PPS
+ * time discipline.
+ *
+ * 14 Feb 94 David L. Mills
+ * Added code for external clock
+ *
+ * 28 Nov 93 David L. Mills
+ * Revised frequency scaling to conform with adjusted parameters
+ *
+ * 17 Sep 93 David L. Mills
+ * Created file
+ */
+/*
+ * ntp_gettime(), ntp_adjtime() - precision time interface for SunOS
+ * 4.1.1 and 4.1.3
+ *
+ * These routines consitute the Network Time Protocol (NTP) interfaces
+ * for user and daemon application programs. The ntp_gettime() routine
+ * provides the time, maximum error (synch distance) and estimated error
+ * (dispersion) to client user application programs. The ntp_adjtime()
+ * routine is used by the NTP daemon to adjust the system clock to an
+ * externally derived time. The time offset and related variables set by
+ * this routine are used by hardclock() to adjust the phase and
+ * frequency of the phase-lock loop which controls the system clock.
+ */
+#include "param.h"
+#include "systm.h"
+#include "kernel.h"
+#include "proc.h"
+#include "timex.h"
+
+/*
+ * The following variables are used by the hardclock() routine in the
+ * kern_clock.c module and are described in that module.
+ */
+extern struct timeval time; /* kernel time variable */
+extern int time_state; /* clock state */
+extern int time_status; /* clock status bits */
+extern long time_offset; /* time adjustment (us) */
+extern long time_freq; /* frequency offset (scaled ppm) */
+extern long time_maxerror; /* maximum error (us) */
+extern long time_esterror; /* estimated error (us) */
+extern long time_constant; /* pll time constant */
+extern long time_precision; /* clock precision (us) */
+extern long time_tolerance; /* frequency tolerance (scaled ppm) */
+
+#ifdef PPS_SYNC
+/*
+ * The following variables are used only if the PPS signal discipline
+ * is configured in the kernel.
+ */
+extern int pps_shift; /* interval duration (s) (shift) */
+extern long pps_freq; /* pps frequency offset (scaled ppm) */
+extern long pps_jitter; /* pps jitter (us) */
+extern long pps_stabil; /* pps stability (scaled ppm) */
+extern long pps_jitcnt; /* jitter limit exceeded */
+extern long pps_calcnt; /* calibration intervals */
+extern long pps_errcnt; /* calibration errors */
+extern long pps_stbcnt; /* stability limit exceeded */
+#endif /* PPS_SYNC */
+
+/*
+ * ntp_gettime() - NTP user application interface
+ */
+struct ntp_gettime_args {
+ struct ntptimeval *tp;
+};
+
+int
+ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, int *retval)
+{
+ struct timeval atv;
+ struct ntptimeval ntv;
+ int s;
+ int error = 0;
+
+ if (uap->tp) {
+ s = splclock();
+#ifdef EXT_CLOCK
+ /*
+ * The microtime() external clock routine returns a
+ * status code. If less than zero, we declare an error
+ * in the clock status word and return the kernel
+ * (software) time variable. While there are other
+ * places that call microtime(), this is the only place
+ * that matters from an application point of view.
+ */
+ if (microtime(&atv) < 0) {
+ time_status |= STA_CLOCKERR;
+ ntv.time = time;
+ } else
+ time_status &= ~STA_CLOCKERR;
+#else /* EXT_CLOCK */
+ microtime(&atv);
+#endif /* EXT_CLOCK */
+ ntv.time = atv;
+ ntv.maxerror = time_maxerror;
+ ntv.esterror = time_esterror;
+ (void) splx(s);
+
+ error = copyout((caddr_t)&ntv, (caddr_t)uap->tp,
+ sizeof (ntv));
+ }
+ if (!error) {
+ *retval = time_state;
+
+ /*
+ * Status word error decode. If any of these conditions
+ * occur, an error is returned, instead of the status
+ * word. Most applications will care only about the fact
+ * the system clock may not be trusted, not about the
+ * details.
+ *
+ * Hardware or software error
+ */
+ if (time_status & (STA_UNSYNC | STA_CLOCKERR))
+ *retval = TIME_ERROR;
+
+ /*
+ * PPS signal lost when either time or frequency
+ * synchronization requested
+ */
+ if (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
+ !(time_status & STA_PPSSIGNAL))
+ *retval = TIME_ERROR;
+
+ /*
+ * PPS jitter exceeded when time synchronization
+ * requested
+ */
+ if (time_status & STA_PPSTIME &&
+ time_status & STA_PPSJITTER)
+ *retval = TIME_ERROR;
+
+ /*
+ * PPS wander exceeded or calibration error when
+ * frequency synchronization requested
+ */
+ if (time_status & STA_PPSFREQ &&
+ time_status & (STA_PPSWANDER | STA_PPSERROR))
+ *retval = TIME_ERROR;
+ }
+ return error;
+}
+
+/*
+ * ntp_adjtime() - NTP daemon application interface
+ */
+struct ntp_adjtime_args {
+ struct timex *tp;
+};
+
+int
+ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, int *retval)
+{
+ struct timex ntv;
+ int modes;
+ int s;
+ int error;
+
+ error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv));
+ if (error)
+ return error;
+
+ /*
+ * Update selected clock variables - only the superuser can
+ * change anything. Note that there is no error checking here on
+ * the assumption the superuser should know what it is doing.
+ */
+ modes = ntv.modes;
+ if ((modes != 0)
+ && (error = suser(p->p_cred->pc_ucred, &p->p_acflag)))
+ return error;
+
+ s = splclock();
+ if (modes & MOD_FREQUENCY)
+#ifdef PPS_SYNC
+ time_freq = ntv.freq - pps_freq;
+#else /* PPS_SYNC */
+ time_freq = ntv.freq;
+#endif /* PPS_SYNC */
+ if (modes & MOD_MAXERROR)
+ time_maxerror = ntv.maxerror;
+ if (modes & MOD_ESTERROR)
+ time_esterror = ntv.esterror;
+ if (modes & MOD_STATUS) {
+ time_status &= STA_RONLY;
+ time_status |= ntv.status & ~STA_RONLY;
+ }
+ if (modes & MOD_TIMECONST)
+ time_constant = ntv.constant;
+ if (modes & MOD_OFFSET)
+ hardupdate(ntv.offset);
+
+ /*
+ * Retrieve all clock variables
+ */
+ if (time_offset < 0)
+ ntv.offset = -(-time_offset >> SHIFT_UPDATE);
+ else
+ ntv.offset = time_offset >> SHIFT_UPDATE;
+#ifdef PPS_SYNC
+ ntv.freq = time_freq + pps_freq;
+#else /* PPS_SYNC */
+ ntv.freq = time_freq;
+#endif /* PPS_SYNC */
+ ntv.maxerror = time_maxerror;
+ ntv.esterror = time_esterror;
+ ntv.status = time_status;
+ ntv.constant = time_constant;
+ ntv.precision = time_precision;
+ ntv.tolerance = time_tolerance;
+#ifdef PPS_SYNC
+ ntv.shift = pps_shift;
+ ntv.ppsfreq = pps_freq;
+ ntv.jitter = pps_jitter >> PPS_AVG;
+ ntv.stabil = pps_stabil;
+ ntv.calcnt = pps_calcnt;
+ ntv.errcnt = pps_errcnt;
+ ntv.jitcnt = pps_jitcnt;
+ ntv.stbcnt = pps_stbcnt;
+#endif /* PPS_SYNC */
+ (void)splx(s);
+
+ error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv));
+ if (!error) {
+ /*
+ * Status word error decode. See comments in
+ * ntp_gettime() routine.
+ */
+ retval[0] = time_state;
+ if (time_status & (STA_UNSYNC | STA_CLOCKERR))
+ retval[0] = TIME_ERROR;
+ if (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
+ !(time_status & STA_PPSSIGNAL))
+ retval[0] = TIME_ERROR;
+ if (time_status & STA_PPSTIME &&
+ time_status & STA_PPSJITTER)
+ retval[0] = TIME_ERROR;
+ if (time_status & STA_PPSFREQ &&
+ time_status & (STA_PPSWANDER | STA_PPSERROR))
+ retval[0] = TIME_ERROR;
+ }
+ return error;
+}
+
+
diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c
index cf76f80ae202..bc02348f73a9 100644
--- a/sys/kern/kern_physio.c
+++ b/sys/kern/kern_physio.c
@@ -45,7 +45,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_physio.c,v 1.1.2.2 1994/05/01 18:59:48 rgrimes Exp $
+ * $Id: kern_physio.c,v 1.7 1994/04/25 23:48:29 davidg Exp $
*/
#include "param.h"
@@ -56,8 +56,11 @@
#include "malloc.h"
#include "vnode.h"
#include "vm/vm.h"
+#include "vm/vm_page.h"
#include "specdev.h"
+#define HOLD_WORKS_FOR_SHARING
+
/*
* Driver interface to do "raw" I/O in the address space of a
* user process directly for read and write operations..
@@ -79,6 +82,13 @@ rawwrite(dev, uio)
(caddr_t) (u_long) dev, uio));
}
+static void
+physwakeup(bp)
+ struct buf *bp;
+{
+ wakeup((caddr_t) bp);
+ bp->b_flags &= ~B_CALL;
+}
int physio(strat, dev, bp, off, rw, base, len, p)
d_strategy_t strat;
@@ -92,7 +102,7 @@ int physio(strat, dev, bp, off, rw, base, len, p)
int amttodo = *len;
int error, amtdone;
vm_prot_t ftype;
- vm_offset_t v, lastv;
+ vm_offset_t v, lastv, pa;
caddr_t adr;
int oldflags;
int s;
@@ -122,7 +132,6 @@ int physio(strat, dev, bp, off, rw, base, len, p)
splx(s);
}
- bp->b_flags = B_BUSY | B_PHYS | rw;
bp->b_proc = p;
bp->b_dev = dev;
bp->b_error = 0;
@@ -131,17 +140,25 @@ int physio(strat, dev, bp, off, rw, base, len, p)
/* iteratively do I/O on as large a chunk as possible */
do {
- bp->b_flags &= ~B_DONE;
+ bp->b_flags = B_BUSY | B_PHYS | B_CALL | rw;
+ bp->b_iodone = physwakeup;
bp->b_un.b_addr = base;
- /* XXX limit */
+ /*
+ * Notice that b_bufsize is more owned by the buffer
+ * allocating entity, while b_bcount might be modified
+ * by the called I/O routines. So after I/O is complete
+ * the only thing guaranteed to be unchanged is
+ * b_bufsize.
+ */
bp->b_bcount = min (256*1024, amttodo);
+ bp->b_bufsize = bp->b_bcount;
/* first, check if accessible */
- if (rw == B_READ && !useracc(base, bp->b_bcount, B_WRITE)) {
+ if (rw == B_READ && !useracc(base, bp->b_bufsize, B_WRITE)) {
error = EFAULT;
goto errrtn;
}
- if (rw == B_WRITE && !useracc(base, bp->b_bcount, B_READ)) {
+ if (rw == B_WRITE && !useracc(base, bp->b_bufsize, B_READ)) {
error = EFAULT;
goto errrtn;
}
@@ -153,16 +170,17 @@ int physio(strat, dev, bp, off, rw, base, len, p)
ftype = VM_PROT_READ;
lastv = 0;
- for (adr = (caddr_t)trunc_page(base); adr < base + bp->b_bcount;
+ for (adr = (caddr_t)trunc_page(base); adr < base + bp->b_bufsize;
adr += NBPG) {
/*
- * make sure that the pde is valid and wired
+ * make sure that the pde is valid and held
*/
v = trunc_page(((vm_offset_t)vtopte(adr)));
if (v != lastv) {
- vm_map_pageable(&p->p_vmspace->vm_map, v,
- round_page(v+1), FALSE);
+ vm_fault_quick(v, VM_PROT_READ);
+ pa = pmap_extract(&p->p_vmspace->vm_pmap, v);
+ vm_page_hold(PHYS_TO_VM_PAGE(pa));
lastv = v;
}
@@ -170,65 +188,48 @@ int physio(strat, dev, bp, off, rw, base, len, p)
* do the vm_fault if needed, do the copy-on-write thing when
* reading stuff off device into memory.
*/
- if (ftype & VM_PROT_WRITE) {
- /*
- * properly handle copy-on-write
- */
-#if 0
- *(volatile int *) adr += 0;
-#endif
- vm_fault(&curproc->p_vmspace->vm_map,
- (vm_offset_t) adr,
- VM_PROT_READ|VM_PROT_WRITE, FALSE);
- }
-#if 0
- else {
- /*
- * this clause is not really necessary because
- * vslock does a vm_map_pageable FALSE.
- * It is not optimally efficient to reference the
- * page with the possiblity of it being paged out, but
- * if this page is faulted here, it will be placed on the
- * active queue, with the probability of it being paged
- * out being very very low. This is here primarily for
- * "symmetry".
- */
- *(volatile int *) adr;
- }
-#endif
- }
+ vm_fault_quick(adr, ftype);
+ pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t) adr);
/*
- * if the process has been blocked by the wiring of the page table pages
- * above or faults of other pages, then the vm_map_pageable contained in the
- * vslock will fault the pages back in if they have been paged out since
- * being referenced in the loop above. (vm_map_pageable calls vm_fault_wire
- * which calls vm_fault to get the pages if needed.)
+ * hold the data page
*/
+ vm_page_hold(PHYS_TO_VM_PAGE(pa));
+ }
- /* lock in core (perform vm_map_pageable, FALSE) */
- vslock (base, bp->b_bcount);
+ vmapbuf(bp);
/* perform transfer */
- physstrat(bp, strat, PRIBIO);
+ (*strat)(bp);
- /* unlock (perform vm_map_pageable, TRUE) */
- vsunlock (base, bp->b_bcount, 0);
+ /* pageout daemon doesn't wait for pushed pages */
+ s = splbio();
+ while ((bp->b_flags & B_DONE) == 0)
+ tsleep((caddr_t)bp, PRIBIO, "physstr", 0);
+ splx(s);
- lastv = 0;
+ vunmapbuf(bp);
/*
- * unwire the pde
+ * unhold the pde, and data pages
*/
- for (adr = (caddr_t)trunc_page(base); adr < base + bp->b_bcount;
+ lastv = 0;
+ for (adr = (caddr_t)trunc_page(base); adr < base + bp->b_bufsize;
adr += NBPG) {
v = trunc_page(((vm_offset_t)vtopte(adr)));
if (v != lastv) {
- vm_map_pageable(&p->p_vmspace->vm_map, v, round_page(v+1), TRUE);
+ pa = pmap_extract(&p->p_vmspace->vm_pmap, v);
+ vm_page_unhold(PHYS_TO_VM_PAGE(pa));
lastv = v;
}
+ pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t) adr);
+ vm_page_unhold(PHYS_TO_VM_PAGE(pa));
}
+ /*
+ * in this case, we need to use b_bcount instead of
+ * b_bufsize.
+ */
amtdone = bp->b_bcount - bp->b_resid;
amttodo -= amtdone;
base += amtdone;
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 2d1d7db1ce4e..48ea1cc33d06 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_prot.c 7.21 (Berkeley) 5/3/91
- * $Id: kern_prot.c,v 1.5.2.2 1994/05/04 07:54:41 rgrimes Exp $
+ * $Id: kern_prot.c,v 1.7 1994/05/04 08:26:59 rgrimes Exp $
*/
/*
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 941ead222a34..caaf6a5953a5 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_resource.c 7.13 (Berkeley) 5/9/91
- * $Id: kern_resource.c,v 1.7.2.1 1994/05/04 07:54:43 rgrimes Exp $
+ * $Id: kern_resource.c,v 1.8 1994/05/04 08:27:01 rgrimes Exp $
*/
#include "param.h"
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 8450e1c2f588..f57966f8fbb6 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_sig.c 7.35 (Berkeley) 6/28/91
- * $Id: kern_sig.c,v 1.9 1993/12/19 00:51:30 wollman Exp $
+ * $Id: kern_sig.c,v 1.12 1994/05/25 19:49:38 csgr Exp $
*/
#define SIGPROP /* include signal properties table */
@@ -43,6 +43,7 @@
#include "mount.h"
#include "filedesc.h"
#include "proc.h"
+#include "ucred.h"
#include "systm.h"
#include "timeb.h"
#include "times.h"
@@ -52,6 +53,7 @@
#include "kernel.h"
#include "wait.h"
#include "ktrace.h"
+#include "syslog.h"
#include "machine/cpu.h"
@@ -1044,6 +1046,14 @@ sigexit(p, sig)
p->p_acflag |= AXSIG;
if (sigprop[sig] & SA_CORE) {
p->p_sigacts->ps_sig = sig;
+ /*
+ * Log signals which would cause core dumps
+ * (Log as LOG_INFO to appease those who don't want
+ * these messages.)
+ * XXX : Todo, as well as euid, write out ruid too
+ */
+ log(LOG_INFO, "pid %d: %s: uid %d: exited on signal %d\n",
+ p->p_pid, p->p_comm, p->p_ucred->cr_uid, sig);
if (coredump(p) == 0)
sig |= WCOREFLAG;
}
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index bb860d2ca6bd..47af2d75b472 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_subr.c 7.7 (Berkeley) 4/15/91
- * $Id: kern_subr.c,v 1.5.2.1 1994/05/04 07:54:46 rgrimes Exp $
+ * $Id: kern_subr.c,v 1.6 1994/05/04 08:27:05 rgrimes Exp $
*/
#include "param.h"
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 554d38b004c4..67bd7e4786d8 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_synch.c 7.18 (Berkeley) 6/27/91
- * $Id: kern_synch.c,v 1.4 1994/02/11 21:14:28 guido Exp $
+ * $Id: kern_synch.c,v 1.5 1994/03/20 00:33:06 wollman Exp $
*/
#include "param.h"
@@ -381,7 +381,7 @@ endtsleep(arg1, dummy)
splx(s);
}
-#if 1 /* XXX this should go away... */
+#if 0 /* This is obsolete, use tsleep(). */
/*
* Short-term, non-interruptable sleep.
*/
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index a0c4a117bb2f..3be34ee22d8e 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)kern_time.c 7.15 (Berkeley) 3/17/91
- * $Id: kern_time.c,v 1.4 1993/11/25 01:33:14 wollman Exp $
+ * $Id: kern_time.c,v 1.5 1994/06/22 05:52:47 jkh Exp $
*/
#include "param.h"
@@ -103,7 +103,9 @@ settimeofday(p, uap, retval)
return (error);
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
boottime.tv_sec += atv.tv_sec - time.tv_sec;
- s = splhigh(); time = atv; splx(s);
+ s = splclock();
+ time.tv_sec = atv.tv_sec; /* XXX avoid skew in tv_usec */
+ splx(s);
resettodr();
}
if (uap->tzp && (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh
index 77f61280c1bd..60826dfc4106 100644
--- a/sys/kern/makesyscalls.sh
+++ b/sys/kern/makesyscalls.sh
@@ -1,6 +1,6 @@
#! /bin/sh -
# from: @(#)makesyscalls.sh 7.6 (Berkeley) 4/20/91
-# $Id: makesyscalls.sh,v 1.3 1993/11/07 21:22:30 wollman Exp $
+# $Id: makesyscalls.sh,v 1.4 1994/06/01 21:13:53 phk Exp $
set -e
@@ -162,7 +162,7 @@ awk < $1 "
printf("\n#else /* %s */\n", compat) > syscompat
printf("#define compat(n, name) 0, nosys\n") > syscompat
printf("#endif /* %s */\n\n", compat) > syscompat
- printf("#endif /* _SYS_SYSCALL_H_ */") > syshdr
+ printf("#endif /* _SYS_SYSCALL_H_ */\n") > syshdr
printf("};\n\n") > sysent
printf("int\tnsysent = sizeof(sysent) / sizeof(sysent[0]);\n") > sysent
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c
index dd7a7c8be283..13ea715bef69 100644
--- a/sys/kern/spec_vnops.c
+++ b/sys/kern/spec_vnops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)spec_vnops.c 7.37 (Berkeley) 5/30/91
- * $Id: spec_vnops.c,v 1.3 1993/11/25 01:33:15 wollman Exp $
+ * $Id: spec_vnops.c,v 1.4 1994/05/30 03:20:08 ache Exp $
*/
#include "param.h"
@@ -137,7 +137,9 @@ spec_open(vp, mode, cred, p)
if ((u_int)maj >= nchrdev)
return (ENXIO);
VOP_UNLOCK(vp);
+ vp->v_opencount++;
error = (*cdevsw[maj].d_open)(dev, mode, S_IFCHR, p);
+ --vp->v_opencount;
VOP_LOCK(vp);
return (error);
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 6d4a61735965..afe2ddc99f36 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)subr_prf.c 7.30 (Berkeley) 6/29/91
- * $Id: subr_prf.c,v 1.6.2.1 1994/05/04 07:54:49 rgrimes Exp $
+ * $Id: subr_prf.c,v 1.8 1994/05/04 08:27:06 rgrimes Exp $
*/
#include "param.h"
@@ -87,7 +87,6 @@ static void logpri __P((int level));
static void putchar __P((int ch, int flags, struct tty *tp));
static char *ksprintn __P((u_long num, int base, int *len));
void kprintf __P((const char *fmt, int flags, struct tty *tp, va_list));
-volatile void boot(int bootopt);
/*
* Variable panicstr contains argument to first call to panic; used
@@ -106,14 +105,8 @@ int msgbufmapped;
* and then reboots. If we are called twice, then we avoid trying to sync
* the disks as this often leads to recursive panics.
*/
-#ifdef __STDC__
-volatile void
-panic(const char *msg)
-#else
void
-panic(msg)
- char *msg;
-#endif
+panic(const char *msg)
{
int bootopt = RB_AUTOBOOT | RB_DUMP;
diff --git a/sys/kern/subr_rand.c b/sys/kern/subr_rand.c
new file mode 100644
index 000000000000..09f36a7d630a
--- /dev/null
+++ b/sys/kern/subr_rand.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1993 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * LBL BSD kernel random number generator (used by statclock).
+ *
+ * Written by Steve McCanne & Chris Torek (mccanne@ee.lbl.gov,
+ * torek@ee.lbl.gov), November, 1992.
+ *
+ * This implementation is based on ``Two Fast Implementations of
+ * the "Minimal Standard" Random Number Generator", David G. Carta,
+ * Communications of the ACM, Jan 1990, Vol 33 No 1.
+ */
+
+#ifdef sparc
+asm("\
+ .global _kernrand ;\
+_kernrand: ;\
+ sethi %hi(16807), %o1 ;\
+ wr %o1, %lo(16807), %y ;\
+ set 0xffff, %o4 ;\
+ andcc %g0, 0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %o0, %o2 ;\
+ mulscc %o2, %g0, %o2 ;\
+ rd %y, %o3 ;\
+ srl %o2, 16, %o1 ;\
+ and %o4, %o2, %o0 ;\
+ sll %o0, 15, %o0 ;\
+ srl %o3, 17, %o3 ;\
+ or %o3, %o0, %o0 ;\
+ addcc %o0, %o1, %o0 ;\
+ bl 1f ;\
+ sethi %hi(0x7fffffff), %o1 ;\
+ retl ;\
+ nop ;\
+1: ;\
+ or %o1, %lo(0x7fffffff), %o1 ;\
+ add %o0, 1, %o0 ;\
+ retl ;\
+ and %o1, %o0, %o0 ");
+#else
+long
+kernrand(x)
+ register long x;
+{
+ register long hi, lo, t;
+
+ hi = x / 127773;
+ lo = x % 127773;
+ t = 16807 * lo - 2836 * hi;
+ if (t > 0)
+ return (t);
+ else
+ return (t + 0x7fffffff);
+}
+#endif
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index b129f4f4d5bd..43f036c62568 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)sys_process.c 7.22 (Berkeley) 5/11/91
- * $Id: sys_process.c,v 1.9.2.2 1994/05/03 20:44:01 rgrimes Exp $
+ * $Id: sys_process.c,v 1.11 1994/04/02 23:03:01 jkh Exp $
*/
#include "param.h"
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 2f624acebcf7..1a65f4f70a44 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -2,7 +2,7 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from $Id: syscalls.master,v 1.8 1994/01/31 10:27:25 davidg Exp $
+ * created from $Id: syscalls.master,v 1.9 1994/03/15 01:58:33 wollman Exp $
*/
char *syscallnames[] = {
@@ -218,8 +218,8 @@ char *syscallnames[] = {
"#172", /* 172 = nosys */
"#173", /* 173 = nosys */
"#174", /* 174 = nosys */
- "#175", /* 175 = nosys */
- "#176", /* 176 = nosys */
+ "ntp_gettime", /* 175 = ntp_gettime */
+ "ntp_adjtime", /* 176 = ntp_adjtime */
#ifdef MACHVMCOMPAT
"vm_allocate", /* 177 = vm_allocate */
"vm_deallocate", /* 178 = vm_deallocate */
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index a43845ebd1a4..db30a9330979 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
- $Id: syscalls.master,v 1.8 1994/01/31 10:27:25 davidg Exp $
+ $Id: syscalls.master,v 1.9 1994/03/15 01:58:33 wollman Exp $
; from: @(#)syscalls.master 7.26 (Berkeley) 3/25/91
; System call name/number master file.
; Processed to created init_sysent.c, syscalls.c and syscall.h.
@@ -243,8 +243,8 @@
172 UNIMPL 0 nosys
173 UNIMPL 0 nosys
174 UNIMPL 0 nosys
-175 UNIMPL 0 nosys
-176 UNIMPL 0 nosys
+175 STD 1 ntp_gettime
+176 STD 1 ntp_adjtime
#ifdef MACHVMCOMPAT
177 STD 4 svm_allocate vm_allocate
178 STD 3 svm_deallocate vm_deallocate
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index f861f53ece52..ff442d05b2cb 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -149,7 +149,7 @@ struct msgctl_args {
struct msqid_ds *user_msqptr;
};
-int
+static int
msgctl(p, uap, retval)
struct proc *p;
register struct msgctl_args *uap;
@@ -309,7 +309,7 @@ struct msgget_args {
int msgflg;
};
-int
+static int
msgget(p, uap, retval)
struct proc *p;
register struct msgget_args *uap;
@@ -766,7 +766,7 @@ struct msgrcv_args {
int msgflg;
};
-int
+static int
msgrcv(p, uap, retval)
struct proc *p;
register struct msgrcv_args *uap;
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 6344018d9514..dbada0d09aad 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -62,7 +62,7 @@ semsys(p, uap, retval)
{
while ( semlock_holder != NULL && semlock_holder != p ) {
/* printf("semaphore facility locked - sleeping ...\n"); */
- sleep( (caddr_t)&semlock_holder, (PZERO - 4) );
+ tsleep( (caddr_t)&semlock_holder, (PZERO - 4), "semsys", 0 );
}
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
@@ -89,7 +89,7 @@ struct semconfig_args {
semconfig_ctl_t flag;
};
-int
+static int
semconfig(p, uap, retval)
struct proc *p;
struct semconfig_args *uap;
@@ -324,7 +324,7 @@ struct semctl_args {
union semun *arg;
};
-int
+static int
semctl(p, uap, retval)
struct proc *p;
register struct semctl_args *uap;
@@ -556,7 +556,7 @@ struct semget_args {
int semflg;
};
-int
+static int
semget(p, uap, retval)
struct proc *p;
register struct semget_args *uap;
@@ -676,7 +676,7 @@ struct semop_args {
int nsops;
};
-int
+static int
semop(p, uap, retval)
struct proc *p;
register struct semop_args *uap;
@@ -1007,7 +1007,7 @@ semexit(p)
#ifdef SEM_DEBUG
printf("semaphore facility locked - sleeping ...\n");
#endif
- sleep( (caddr_t)&semlock_holder, (PZERO - 4) );
+ tsleep( (caddr_t)&semlock_holder, (PZERO - 4), "semexit", 0 );
}
did_something = 0;
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 00f123f529c5..3c7a45749583 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -37,7 +37,7 @@
*
* from: Utah $Hdr: uipc_shm.c 1.9 89/08/14$
* from: @(#)sysv_shm.c 7.15 (Berkeley) 5/13/91
- * $Id: sysv_shm.c,v 1.9 1994/01/21 09:56:31 davidg Exp $
+ * $Id: sysv_shm.c,v 1.12 1994/03/08 14:08:14 ats Exp $
*/
/*
@@ -69,7 +69,7 @@
struct shmid_ds *shmsegs;
struct shminfo shminfo;
-int shmat(), shmctl(), shmdt(), shmget(); /* XXX */
+static int shmat(), shmctl(), shmdt(), shmget(); /* XXX */
int (*shmcalls[])() = { shmat, shmctl, shmdt, shmget }; /* XXX */
int shmtot = 0;
@@ -90,7 +90,7 @@ struct shmhandle {
caddr_t shmh_id;
};
-static int ipcaccess(struct ipc_perm *, int, struct ucred *);
+extern int ipcaccess(struct ipc_perm *, int, struct ucred *);
static void shmufree(struct proc *, struct shmdesc *);
static void shmfree(struct shmid_ds *);
static int shmvalid(int);
@@ -146,7 +146,7 @@ struct shmget_args {
int shmflg;
};
-int
+static int
shmget(p, uap, retval)
struct proc *p;
register struct shmget_args *uap;
@@ -244,7 +244,7 @@ struct shmctl_args {
};
/* ARGSUSED */
-int
+static int
shmctl(p, uap, retval)
struct proc *p;
register struct shmctl_args *uap;
@@ -316,7 +316,7 @@ struct shmat_args {
int shmflg;
};
-int
+static int
shmat(p, uap, retval)
struct proc *p;
register struct shmat_args *uap;
@@ -402,7 +402,7 @@ struct shmdt_args {
};
/* ARGSUSED */
-int
+static int
shmdt(p, uap, retval)
struct proc *p;
struct shmdt_args *uap;
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 519b910ccfdb..146aa1545efe 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -32,7 +32,22 @@
* SUCH DAMAGE.
*
* from: @(#)tty.c 7.44 (Berkeley) 5/28/91
- * $Id: tty.c,v 1.19.2.1 1994/03/24 08:19:44 rgrimes Exp $
+ * $Id: tty.c,v 1.32 1994/05/30 21:53:17 ache Exp $
+ */
+
+/*-
+ * TODO:
+ * o Fix races for sending the start char in ttyflush().
+ * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttselect().
+ * With luck, there will be MIN chars before select() returns().
+ * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
+ * o Don't allow input in TS_ZOMBIE case. It would be visible through
+ * FIONREAD.
+ * o Do the new sio locking stuff here and use it to avoid special
+ * case for EXTPROC?
+ * o Lock PENDIN too?
+ * o Move EXTPROC and/or PENDIN to t_state?
+ * o Wrap most of ttioctl in spltty/splx.
*/
#include "param.h"
@@ -47,6 +62,7 @@
#include "dkstat.h"
#include "uio.h"
#include "kernel.h"
+#include "malloc.h"
#include "vnode.h"
#include "syslog.h"
#include "signalvar.h"
@@ -64,11 +80,12 @@
#define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
/* XXX RB_LEN() is too slow. */
-#define INPUT_LEN(tp) (RB_LEN(&(tp)->t_can) + RB_LEN(&(tp)->t_raw))
+#define INPUT_LEN(tp) (RB_LEN((tp)->t_can) + RB_LEN((tp)->t_raw))
#undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
#define MAX_INPUT TTYHOG
static int proc_compare __P((struct proc *p1, struct proc *p2));
+static int ttnread(struct tty *tp);
static void ttyblock __P((struct tty *tp));
static void ttyecho __P((int c, struct tty *tp));
static int ttyoutput __P((int c, register struct tty *tp));
@@ -79,14 +96,6 @@ static void ttyrub __P((int c, struct tty *tp));
static void ttyrubo __P((struct tty *tp, int cnt));
static void ttyunblock __P((struct tty *tp));
-/* symbolic sleep message strings */
-const char ttyin[] = "ttyin";
-const char ttyout[] = "ttyout";
-const char ttopen[] = "ttyopn";
-const char ttclos[] = "ttycls";
-const char ttybg[] = "ttybg";
-const char ttybuf[] = "ttybuf";
-
/*
* Table giving parity for characters and indicating
* character classes to tty driver. The 8th bit
@@ -172,11 +181,19 @@ extern int nldisp;
(c) == cc[VEOL] || (c) == cc[VEOL2]) && (c) != _POSIX_VDISABLE)
void
+termioschars(t)
+ struct termios *t;
+{
+
+ bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
+}
+
+void
ttychars(tp)
struct tty *tp;
{
- bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
+ termioschars(&tp->t_termios);
}
/*
@@ -202,36 +219,18 @@ ttywait(tp)
{
int error = 0, s = spltty();
- while ((RB_LEN(&tp->t_out) || tp->t_state&TS_BUSY) &&
- (tp->t_state&TS_CARR_ON || tp->t_cflag&CLOCAL) &&
- tp->t_oproc) {
- /*
- * XXX temporary fix for deadlock.
- *
- * If two processes wait for output to drain from the same
- * tty, and the amount of output to drain is > 0 and
- * <= tp->t_lowat, then the processes will take turns
- * uselessly waking each other up until the output drains,
- * with cpl higher than spltty() throughout.
- *
- * The sleep address and TS_ASLEEP flag ought to be different
- * for the different events (output done) and (output almost
- * done).
- */
- tp->t_lowat = 0;
-
+ while ((RB_LEN(tp->t_out) || tp->t_state&TS_BUSY) &&
+ CAN_DO_IO(tp) && tp->t_oproc) {
(*tp->t_oproc)(tp);
- if ((RB_LEN(&tp->t_out) || tp->t_state&TS_BUSY) &&
- (tp->t_state&TS_CARR_ON || tp->t_cflag&CLOCAL)) {
- tp->t_state |= TS_ASLEEP;
- if (error = ttysleep(tp, (caddr_t)&tp->t_out,
+ if ((RB_LEN(tp->t_out) || tp->t_state&TS_BUSY) &&
+ CAN_DO_IO(tp)) {
+ tp->t_state |= TS_SO_OCOMPLETE;
+ if (error = ttysleep(tp, TSA_OCOMPLETE(tp),
TTOPRI | PCATCH, "ttywai", 0))
break;
} else
break;
}
- if (tp->t_lowat == 0)
- ttsetwater(tp);
splx(s);
return (error);
}
@@ -257,21 +256,17 @@ ttyflush(tp, rw)
tp->t_state &= ~TS_TTSTOP;
(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
if (rw & FREAD) {
- flushq(&tp->t_can);
- flushq(&tp->t_raw);
+ flushq(tp->t_can);
+ flushq(tp->t_raw);
+ tp->t_lflag &= ~PENDIN;
tp->t_rocount = 0;
tp->t_rocol = 0;
tp->t_state &= ~TS_LOCAL;
ttwakeup(tp);
}
if (rw & FWRITE) {
- flushq(&tp->t_out);
- wakeup((caddr_t)&tp->t_out);
- if (tp->t_wsel) {
- selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
- tp->t_wsel = 0;
- tp->t_state &= ~TS_WCOLL;
- }
+ flushq(tp->t_out);
+ ttwwakeup(tp);
}
if (rw & FREAD) {
if (tp->t_state & (TS_TBLOCK | TS_HW_IFLOW)
@@ -286,16 +281,19 @@ ttyflush(tp, rw)
* is still tricky because we don't want to add a
* new obstruction to draining the output queue.
*/
- out_cc = RB_LEN(&tp->t_out);
+ out_cc = RB_LEN(tp->t_out);
t_state = tp->t_state;
ttyunblock(tp);
tp->t_state &= ~TS_TBLOCK;
- if (t_state & TS_TBLOCK && RB_LEN(&tp->t_out) != 0)
- ttysleep(tp, (caddr_t)&tp->t_out, TTIPRI,
+ if (t_state & TS_TBLOCK && RB_LEN(tp->t_out) != 0) {
+ tp->t_state |= TS_SO_OCOMPLETE;
+ ttysleep(tp, TSA_OCOMPLETE(tp), TTIPRI,
"ttyfls", hz / 10);
- if (out_cc == 0 && RB_LEN(&tp->t_out) != 0) {
+ }
+ if (out_cc != 0 && RB_LEN(tp->t_out) != 0) {
(*cdevsw[major(tp->t_dev)].d_stop)(tp, FWRITE);
- flushq(&tp->t_out);
+ flushq(tp->t_out);
+ ttwwakeup(tp);
}
}
}
@@ -314,7 +312,7 @@ ttyblock(tp)
if ((tp->t_state & TS_TBLOCK) == 0
&& tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && putc(tp->t_cc[VSTOP], &tp->t_out) == 0)
+ && putc(tp->t_cc[VSTOP], tp->t_out) == 0)
tp->t_state |= TS_TBLOCK;
if (tp->t_cflag & CDTR_IFLOW)
tp->t_state |= TS_DTR_IFLOW;
@@ -334,7 +332,7 @@ ttyunblock(tp)
if (tp->t_state & TS_TBLOCK
&& tp->t_cc[VSTART] != _POSIX_VDISABLE
- && putc(tp->t_cc[VSTART], &tp->t_out) == 0)
+ && putc(tp->t_cc[VSTART], tp->t_out) == 0)
tp->t_state &= ~TS_TBLOCK;
tp->t_state &= ~TS_HW_IFLOW;
ttstart(tp);
@@ -413,7 +411,7 @@ ttioctl(tp, com, data, flag)
(p->p_sigmask & sigmask(SIGTTOU)) == 0) {
pgsignal(p->p_pgrp, SIGTTOU, 1);
if (error = ttysleep(tp, (caddr_t)&lbolt,
- TTOPRI | PCATCH, ttybg, 0))
+ TTOPRI | PCATCH, "ttybg1", 0))
return (error);
}
break;
@@ -490,11 +488,15 @@ ttioctl(tp, com, data, flag)
/* return number of characters immediately available */
case FIONREAD:
+ s = spltty();
*(off_t *)data = ttnread(tp);
+ splx(s);
break;
case TIOCOUTQ:
- *(int *)data = RB_LEN(&tp->t_out);
+ s = spltty();
+ *(int *)data = RB_LEN(tp->t_out);
+ splx(s);
break;
case TIOCSTOP:
@@ -555,47 +557,27 @@ ttioctl(tp, com, data, flag)
if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
splx(s);
return (error);
- } else {
- /*
- * XXX doubtful. We mostly check both CLOCAL
- * and TS_CARR_ON before doing anything, and
- * changing TS_ISOPEN here just give another
- * flag to worry about, and is probably
- * inconsistent with not changing TS_ISOPEN
- * when carrier drops or CLOCAL rises. OTOH
- * we should maintain a flag to keep track
- * of the combination of CLOCAL and TS_CARR_ON.
- * This could be just TS_CARR_ON (if we don't
- * need to
- *
- * XXX ttselect() doesn't worry about
- * TS_ISOPEN, so it is inconsistent with
- * ttread() after TS_ISOPEN gets cleared here.
- */
- if ((tp->t_state&TS_CARR_ON) == 0 &&
- (tp->t_cflag&CLOCAL) &&
- (t->c_cflag&CLOCAL) == 0) {
- tp->t_state &= ~TS_ISOPEN;
- tp->t_state |= TS_WOPEN;
- ttwakeup(tp);
- }
- tp->t_cflag = t->c_cflag;
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
}
+ if (t->c_cflag & CLOCAL && !(tp->t_cflag & CLOCAL)) {
+ wakeup(TSA_CARR_ON(tp));
+ ttwakeup(tp);
+ ttwwakeup(tp);
+ }
+ tp->t_cflag = t->c_cflag;
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
ttsetwater(tp);
}
- if (com != TIOCSETAF) {
- if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON))
- if (t->c_lflag&ICANON) {
- tp->t_lflag |= PENDIN;
- ttwakeup(tp);
- }
+ if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON) &&
+ com != TIOCSETAF) {
+ if (t->c_lflag&ICANON)
+ t->c_lflag |= PENDIN;
else {
- catb(&tp->t_raw, &tp->t_can);
- catb(&tp->t_can, &tp->t_raw);
+ catb(tp->t_raw, tp->t_can);
+ catb(tp->t_can, tp->t_raw);
}
- }
+ ttwakeup(tp);
+ }
tp->t_iflag = t->c_iflag;
tp->t_oflag = t->c_oflag;
/*
@@ -606,6 +588,9 @@ ttioctl(tp, com, data, flag)
else
t->c_lflag &= ~EXTPROC;
tp->t_lflag = t->c_lflag;
+ if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
+ t->c_cc[VTIME] != tp->t_cc[VTIME])
+ ttwakeup(tp);
bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
splx(s);
break;
@@ -640,7 +625,13 @@ ttioctl(tp, com, data, flag)
case TIOCSPGRP: {
register struct pgrp *pgrp = pgfind(*(int *)data);
+#ifdef broken_for_F_SETOWN
+ if (!suser(p->p_ucred, &p->p_acflag))
+ ;
+ else if (!isctty(p, tp))
+#else
if (!isctty(p, tp))
+#endif
return (ENOTTY);
else if (pgrp == NULL || pgrp->pg_session != p->p_session)
return (EPERM);
@@ -668,9 +659,7 @@ ttioctl(tp, com, data, flag)
case TIOCCONS:
if (*(int *)data) {
- if (constty && constty != tp &&
- (constty->t_state & (TS_CARR_ON|TS_ISOPEN)) ==
- (TS_CARR_ON|TS_ISOPEN))
+ if (constty && constty != tp && CAN_DO_IO(constty))
return (EBUSY);
#ifndef UCONSOLE
if (error = suser(p->p_ucred, &p->p_acflag))
@@ -696,19 +685,21 @@ ttioctl(tp, com, data, flag)
return (0);
}
-int
+/*
+ * Call at spltty().
+ */
+static int
ttnread(tp)
struct tty *tp;
{
int nread = 0;
- /* XXX races. */
if (tp->t_lflag & PENDIN)
ttypend(tp);
- nread = RB_LEN(&tp->t_can);
+ nread = RB_LEN(tp->t_can);
if ((tp->t_lflag & ICANON) == 0) {
- nread += RB_LEN(&tp->t_raw);
- if (nread < tp->t_cc[VMIN])
+ nread += RB_LEN(tp->t_raw);
+ if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
nread = 0;
}
return (nread);
@@ -720,17 +711,14 @@ ttselect(dev, rw, p)
int rw;
struct proc *p;
{
- register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
- int nread;
+ register struct tty *tp = cdevsw[major(dev)].d_ttys[minor(dev)];
int s = spltty();
struct proc *selp;
switch (rw) {
case FREAD:
- nread = ttnread(tp);
- if (nread > 0 ||
- ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
+ if (ttnread(tp) > 0 || tp->t_state & TS_ZOMBIE)
goto win;
if (tp->t_rsel && (selp = pfind(tp->t_rsel)) && selp->p_wchan == (caddr_t)&selwait)
tp->t_state |= TS_RCOLL;
@@ -739,7 +727,8 @@ ttselect(dev, rw, p)
break;
case FWRITE:
- if (RB_LEN(&tp->t_out) <= tp->t_lowat)
+ if (RB_LEN(tp->t_out) <= tp->t_lowat && CAN_DO_IO(tp)
+ || tp->t_state & TS_ZOMBIE)
goto win;
if (tp->t_wsel && (selp = pfind(tp->t_wsel)) && selp->p_wchan == (caddr_t)&selwait)
tp->t_state |= TS_WCOLL;
@@ -766,12 +755,11 @@ ttyopen(dev, tp, dummy)
tp->t_dev = dev;
- tp->t_state &= ~TS_WOPEN;
if ((tp->t_state & TS_ISOPEN) == 0) {
tp->t_state |= TS_ISOPEN;
- initrb(&tp->t_raw);
- initrb(&tp->t_can);
- initrb(&tp->t_out);
+ initrb(tp->t_raw);
+ initrb(tp->t_can);
+ initrb(tp->t_out);
bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
}
return (0);
@@ -793,7 +781,7 @@ ttylclose(tp, flag)
}
/*
- * Handle close() on a tty line: flush and set to initial state,
+ * Handle close() on a tty line: set to initial state,
* bumping generation number so that pending read/write calls
* can detect recycling of the tty.
*/
@@ -803,7 +791,6 @@ ttyclose(tp)
{
if (constty == tp)
constty = NULL;
- ttyflush(tp, FREAD|FWRITE);
tp->t_session = NULL;
tp->t_pgrp = NULL;
tp->t_state = 0;
@@ -822,7 +809,7 @@ ttymodem(tp, flag)
int flag;
{
- if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag&MDMBUF)) {
+ if (tp->t_state & TS_CARR_ON && tp->t_lflag & MDMBUF) {
/*
* MDMBUF: do flow control according to carrier flag
*/
@@ -839,6 +826,7 @@ ttymodem(tp, flag)
*/
tp->t_state &= ~TS_CARR_ON;
if (tp->t_state&TS_ISOPEN && (tp->t_cflag&CLOCAL) == 0) {
+ tp->t_state |= TS_ZOMBIE;
if (tp->t_session && tp->t_session->s_leader)
psignal(tp->t_session->s_leader, SIGHUP);
ttyflush(tp, FREAD|FWRITE);
@@ -849,30 +837,9 @@ ttymodem(tp, flag)
* Carrier now on.
*/
tp->t_state |= TS_CARR_ON;
+ wakeup(TSA_CARR_ON(tp));
ttwakeup(tp);
- }
- return (1);
-}
-
-/*
- * Default modem control routine (for other line disciplines).
- * Return argument flag, to turn off device on carrier drop.
- */
-int
-nullmodem(tp, flag)
- register struct tty *tp;
- int flag;
-{
-
- if (flag)
- tp->t_state |= TS_CARR_ON;
- else {
- tp->t_state &= ~TS_CARR_ON;
- if ((tp->t_cflag&CLOCAL) == 0) {
- if (tp->t_session && tp->t_session->s_leader)
- psignal(tp->t_session->s_leader, SIGHUP);
- return (0);
- }
+ ttwwakeup(tp);
}
return (1);
}
@@ -889,12 +856,12 @@ ttypend(tp)
tp->t_lflag &= ~PENDIN;
tp->t_state |= TS_TYPEN;
- hd = tp->t_raw.rb_hd;
- tl = tp->t_raw.rb_tl;
- flushq(&tp->t_raw);
+ hd = tp->t_raw->rb_hd;
+ tl = tp->t_raw->rb_tl;
+ flushq(tp->t_raw);
while (hd != tl) {
ttyinput(*hd, tp);
- hd = RB_SUCC(&tp->t_raw, hd);
+ hd = RB_SUCC(tp->t_raw, hd);
}
tp->t_state &= ~TS_TYPEN;
}
@@ -937,7 +904,7 @@ ttyinput(c, tp)
if ((iflag & IXOFF && (tp->t_state & TS_TBLOCK) == 0
|| tp->t_cflag & TS_HW_IFLOW && (tp->t_state & TS_HW_IFLOW) == 0)
&& INPUT_LEN(tp) > I_HIGH_WATER - 3
- && ((lflag & ICANON) == 0 || RB_LEN(&tp->t_can) != 0))
+ && ((lflag & ICANON) == 0 || RB_LEN(tp->t_can) != 0))
ttyblock(tp);
/*
* Handle exceptional conditions (break, parity, framing).
@@ -959,9 +926,9 @@ ttyinput(c, tp)
parmrk:
if (INPUT_LEN(tp) > MAX_INPUT - 3)
goto input_overflow;
- putc(0377|TTY_QUOTE, &tp->t_raw);
- putc(0|TTY_QUOTE, &tp->t_raw);
- putc(c|TTY_QUOTE, &tp->t_raw);
+ putc(0377|TTY_QUOTE, tp->t_raw);
+ putc(0|TTY_QUOTE, tp->t_raw);
+ putc(c|TTY_QUOTE, tp->t_raw);
goto endcase;
} else
c = 0;
@@ -1074,23 +1041,23 @@ parmrk:
* erase (^H / ^?)
*/
if (CCEQ(cc[VERASE], c)) {
- if (RB_LEN(&tp->t_raw))
- ttyrub(unputc(&tp->t_raw), tp);
+ if (RB_LEN(tp->t_raw))
+ ttyrub(unputc(tp->t_raw), tp);
goto endcase;
}
/*
* kill (^U)
*/
if (CCEQ(cc[VKILL], c)) {
- if (lflag&ECHOKE && RB_LEN(&tp->t_raw) == tp->t_rocount &&
+ if (lflag&ECHOKE && RB_LEN(tp->t_raw) == tp->t_rocount &&
(lflag&ECHOPRT) == 0) {
- while (RB_LEN(&tp->t_raw))
- ttyrub(unputc(&tp->t_raw), tp);
+ while (RB_LEN(tp->t_raw))
+ ttyrub(unputc(tp->t_raw), tp);
} else {
ttyecho(c, tp);
if (lflag&ECHOK || lflag&ECHOKE)
ttyecho('\n', tp);
- while (getc(&tp->t_raw) > 0)
+ while (getc(tp->t_raw) > 0)
;
tp->t_rocount = 0;
}
@@ -1106,7 +1073,7 @@ parmrk:
/*
* erase whitespace
*/
- while ((c = unputc(&tp->t_raw)) == ' ' || c == '\t')
+ while ((c = unputc(tp->t_raw)) == ' ' || c == '\t')
ttyrub(c, tp);
if (c == -1)
goto endcase;
@@ -1115,14 +1082,14 @@ parmrk:
* next chars type (for ALTWERASE)
*/
ttyrub(c, tp);
- c = unputc(&tp->t_raw);
+ c = unputc(tp->t_raw);
if (c == -1)
goto endcase;
/*
* Handle one-letter word cases.
*/
if (c == ' ' || c == '\t') {
- putc(c, &tp->t_raw);
+ putc(c, tp->t_raw);
goto endcase;
}
ctype = ISALPHA(c);
@@ -1131,13 +1098,13 @@ parmrk:
*/
do {
ttyrub(c, tp);
- c = unputc(&tp->t_raw);
+ c = unputc(tp->t_raw);
if (c == -1)
goto endcase;
} while (c != ' ' && c != '\t' &&
((lflag & ALTWERASE) == 0
|| ISALPHA(c) == ctype));
- (void) putc(c, &tp->t_raw);
+ (void) putc(c, tp->t_raw);
goto endcase;
}
/*
@@ -1163,7 +1130,7 @@ parmrk:
if (INPUT_LEN(tp) >= MAX_INPUT) {
input_overflow:
if (iflag&IMAXBEL) {
- if (RB_LEN(&tp->t_out) < tp->t_hiwat)
+ if (RB_LEN(tp->t_out) < tp->t_hiwat)
(void) ttyoutput(CTRL('g'), tp);
} else
ttyflush(tp, FREAD);
@@ -1173,7 +1140,7 @@ input_overflow:
* Put data char in q for user and
* wakeup on seeing a line delimiter.
*/
- if (putc(c, &tp->t_raw) >= 0) {
+ if (putc(c, tp->t_raw) >= 0) {
if ((lflag&ICANON) == 0) {
ttwakeup(tp);
ttyecho(c, tp);
@@ -1181,7 +1148,7 @@ input_overflow:
}
if (ttbreakc(c)) {
tp->t_rocount = 0;
- catb(&tp->t_raw, &tp->t_can);
+ catb(tp->t_raw, tp->t_can);
ttwakeup(tp);
} else if (tp->t_rocount++ == 0)
tp->t_rocol = tp->t_col;
@@ -1236,7 +1203,7 @@ ttyoutput(c, tp)
if ((oflag&OPOST) == 0) {
if (tp->t_lflag&FLUSHO)
return (-1);
- if (putc(c, &tp->t_out))
+ if (putc(c, tp->t_out))
return (c);
tk_nout++;
tp->t_outcc++;
@@ -1261,17 +1228,17 @@ ttyoutput(c, tp)
#ifdef was
c -= b_to_q(" ", c, &tp->t_outq);
#else
- i = imin(c, RB_CONTIGPUT(&tp->t_out));
- bcopy(" ", tp->t_out.rb_tl, i);
- tp->t_out.rb_tl =
- RB_ROLLOVER(&tp->t_out, tp->t_out.rb_tl+i);
- i = imin(c - i, RB_CONTIGPUT(&tp->t_out));
+ i = imin(c, RB_CONTIGPUT(tp->t_out));
+ bcopy(" ", tp->t_out->rb_tl, i);
+ tp->t_out->rb_tl =
+ RB_ROLLOVER(tp->t_out, tp->t_out->rb_tl+i);
+ i = imin(c - i, RB_CONTIGPUT(tp->t_out));
/* off end and still have space? */
if (i) {
- bcopy(" ", tp->t_out.rb_tl, i);
- tp->t_out.rb_tl =
- RB_ROLLOVER(&tp->t_out, tp->t_out.rb_tl+i);
+ bcopy(" ", tp->t_out->rb_tl, i);
+ tp->t_out->rb_tl =
+ RB_ROLLOVER(tp->t_out, tp->t_out->rb_tl+i);
}
#endif
tk_nout += c;
@@ -1291,7 +1258,7 @@ ttyoutput(c, tp)
*/
if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0)
return (c);
- if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_out))
+ if ((tp->t_lflag&FLUSHO) == 0 && putc(c, tp->t_out))
return (c);
col = tp->t_col;
@@ -1342,8 +1309,8 @@ ttread(tp, uio, flag)
long slp = 0; /* XXX this should be renamed `timo'. */
loop:
- lflag = tp->t_lflag;
s = spltty();
+ lflag = tp->t_lflag;
/*
* take pending input first
*/
@@ -1351,6 +1318,7 @@ loop:
ttypend(tp);
splx(s); /* reduce latency */
s = spltty();
+ lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
}
/*
@@ -1364,18 +1332,32 @@ loop:
return (EIO);
pgsignal(p->p_pgrp, SIGTTIN, 1);
if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH,
- ttybg, 0))
+ "ttybg2", 0))
return (error);
goto loop;
}
+ if (tp->t_state & TS_ZOMBIE) {
+ splx(s);
+ return (0); /* EOF */
+ }
+
/*
* If canonical, use the canonical queue,
* else use the raw queue.
*/
- qp = lflag&ICANON ? &tp->t_can : &tp->t_raw;
+ qp = lflag&ICANON ? tp->t_can : tp->t_raw;
rblen = RB_LEN(qp);
-
+ if (flag & IO_NDELAY) {
+ if (rblen > 0)
+ goto read;
+ if ((lflag & ICANON) == 0 && cc[VMIN] == 0) {
+ splx(s);
+ return (0);
+ }
+ splx(s);
+ return (EWOULDBLOCK);
+ }
if ((lflag & ICANON) == 0) {
int m = cc[VMIN];
long t = cc[VTIME];
@@ -1460,45 +1442,24 @@ loop:
goto sleep;
}
if (rblen <= 0) {
- int carrier;
-
sleep:
/*
- * If there is no input, sleep on rawq
- * awaiting hardware receipt and notification.
- * If we have data, we don't need to check for carrier.
+ * There is no input, or not enough input and we can block.
*/
- carrier = (tp->t_state&TS_CARR_ON) || (tp->t_cflag&CLOCAL);
- if (!carrier && tp->t_state&TS_ISOPEN) {
- splx(s);
- return (0); /* EOF */
- }
- if (flag & IO_NDELAY) {
- splx(s);
- return (EWOULDBLOCK);
- }
- if (slp) {
- /*
- * Use plain wakeup() not ttwakeup().
- * XXX why not use the timeout built into tsleep?
- */
- timeout((timeout_func_t)wakeup, (caddr_t)qp, (int)slp);
- }
- error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
- carrier ? ttyin : ttopen, 0);
- if (slp) {
- slp = 0;
- untimeout((timeout_func_t)wakeup, (caddr_t)qp);
- }
+ error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
+ CAN_DO_IO(tp) ? "ttyin" : "ttyhup", (int)slp);
splx(s);
- if (error)
+ if (error == EWOULDBLOCK)
+ error = 0;
+ else if (error)
return (error);
/*
- * XXX what happens if ICANON, MIN or TIME changes or
- * another process eats some input while we are asleep
- * (not just here)? It would be safest to detect changes
- * and reset our state variables (has_stime and last_cc).
+ * XXX what happens if another process eats some input
+ * while we are asleep (not just here)? It would be
+ * safest to detect changes and reset our state variables
+ * (has_stime and last_cc).
*/
+ slp = 0;
goto loop;
}
@@ -1548,7 +1509,8 @@ slowcase:
pgsignal(tp->t_pgrp, SIGTSTP, 1);
if (first) {
if (error = ttysleep(tp, (caddr_t)&lbolt,
- TTIPRI | PCATCH, ttybg, 0))
+ TTIPRI | PCATCH, "ttybg3",
+ 0))
break;
goto loop;
}
@@ -1612,17 +1574,17 @@ ttycheckoutq(tp, wait)
oldsig = curproc->p_sig;
else
oldsig = 0;
- if (RB_LEN(&tp->t_out) > hiwat + 200)
- while (RB_LEN(&tp->t_out) > hiwat) {
+ if (RB_LEN(tp->t_out) > hiwat + 200)
+ while (RB_LEN(tp->t_out) > hiwat) {
ttstart(tp);
+ if (RB_LEN(tp->t_out) <= hiwat)
+ break;
if (wait == 0 || (curproc && curproc->p_sig != oldsig)) {
splx(s);
return (0);
}
- timeout((timeout_func_t)wakeup, (caddr_t)&tp->t_out,
- hz); /* XXX */
- tp->t_state |= TS_ASLEEP;
- tsleep((caddr_t)&tp->t_out, PZERO - 1, "ttchout", 0);
+ tp->t_state |= TS_SO_OLOWAT;
+ tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttchout", hz);
}
splx(s);
return (1);
@@ -1648,20 +1610,20 @@ ttwrite(tp, uio, flag)
error = 0;
loop:
s = spltty();
- if ((tp->t_state&TS_CARR_ON) == 0 && (tp->t_cflag&CLOCAL) == 0) {
- if (tp->t_state&TS_ISOPEN) {
- splx(s);
- return (EIO);
- } else if (flag & IO_NDELAY) {
+ if (tp->t_state & TS_ZOMBIE) {
+ splx(s);
+ if (uio->uio_resid == cnt)
+ error = EIO;
+ goto out;
+ }
+ if (!CAN_DO_IO(tp)) {
+ if (flag & IO_NDELAY) {
splx(s);
error = EWOULDBLOCK;
goto out;
} else {
- /*
- * sleep awaiting carrier
- */
- error = ttysleep(tp, (caddr_t)&tp->t_raw,
- TTIPRI | PCATCH,ttopen, 0);
+ error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
+ "ttydcd", 0);
splx(s);
if (error)
goto out;
@@ -1679,7 +1641,7 @@ loop:
p->p_pgrp->pg_jobc) {
pgsignal(p->p_pgrp, SIGTTOU, 1);
if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH,
- ttybg, 0))
+ "ttybg4", 0))
goto out;
goto loop;
}
@@ -1704,7 +1666,7 @@ loop:
* to fix this is messy because of all the gotos.
*/
s = spltty();
- if (RB_LEN(&tp->t_out) > hiwat) {
+ if (RB_LEN(tp->t_out) > hiwat) {
splx(s);
goto ovhiwat;
}
@@ -1748,14 +1710,14 @@ loop:
ttstart(tp);
if (error = ttysleep(tp,
(caddr_t)&lbolt,
- TTOPRI | PCATCH, ttybuf, 0))
+ TTOPRI | PCATCH, "ttybf1", 0))
break;
goto loop;
}
cp++, cc--;
s = spltty();
if ((tp->t_lflag&FLUSHO) ||
- RB_LEN(&tp->t_out) > hiwat) {
+ RB_LEN(tp->t_out) > hiwat) {
splx(s);
goto ovhiwat;
}
@@ -1778,18 +1740,18 @@ loop:
#else
i = ce;
s = spltty();
- ce = imin(ce, RB_CONTIGPUT(&tp->t_out));
- bcopy(cp, tp->t_out.rb_tl, ce);
- tp->t_out.rb_tl = RB_ROLLOVER(&tp->t_out,
- tp->t_out.rb_tl + ce);
+ ce = imin(ce, RB_CONTIGPUT(tp->t_out));
+ bcopy(cp, tp->t_out->rb_tl, ce);
+ tp->t_out->rb_tl = RB_ROLLOVER(tp->t_out,
+ tp->t_out->rb_tl + ce);
i -= ce;
if (i > 0) {
int ii;
- ii = imin(i, RB_CONTIGPUT(&tp->t_out));
- bcopy(cp + ce, tp->t_out.rb_tl, ii);
- tp->t_out.rb_tl = RB_ROLLOVER(&tp->t_out,
- tp->t_out.rb_tl + ii);
+ ii = imin(i, RB_CONTIGPUT(tp->t_out));
+ bcopy(cp + ce, tp->t_out->rb_tl, ii);
+ tp->t_out->rb_tl = RB_ROLLOVER(tp->t_out,
+ tp->t_out->rb_tl + ii);
i -= ii;
ce += ii;
}
@@ -1801,14 +1763,15 @@ loop:
if (i > 0) {
ttstart(tp);
s = spltty();
- if (RB_CONTIGPUT(&tp->t_out) > 0) {
+ if (RB_CONTIGPUT(tp->t_out) > 0) {
splx(s);
goto loop; /* synchronous/fast */
}
/* out of space, wait a bit */
- tp->t_state |= TS_ASLEEP;
- if (error = ttysleep(tp, (caddr_t)&tp->t_out,
- TTOPRI | PCATCH, ttybuf, 0)) {
+ tp->t_state |= TS_SO_OLOWAT;
+ if (error = ttysleep(tp, TSA_OLOWAT(tp),
+ TTOPRI | PCATCH, "ttybf2",
+ 0)) {
splx(s);
break;
}
@@ -1816,7 +1779,7 @@ loop:
goto loop;
}
s = spltty();
- if (tp->t_lflag&FLUSHO || RB_LEN(&tp->t_out) > hiwat) {
+ if (tp->t_lflag&FLUSHO || RB_LEN(tp->t_out) > hiwat) {
splx(s);
break;
}
@@ -1841,7 +1804,7 @@ ovhiwat:
* This can only occur if FLUSHO is set in t_lflag,
* or if ttstart/oproc is synchronous (or very fast).
*/
- if (RB_LEN(&tp->t_out) <= hiwat) {
+ if (RB_LEN(tp->t_out) <= hiwat) {
splx(s);
goto loop;
}
@@ -1852,8 +1815,8 @@ ovhiwat:
return (EWOULDBLOCK);
return (0);
}
- tp->t_state |= TS_ASLEEP;
- error = ttysleep(tp, (caddr_t)&tp->t_out, TTOPRI | PCATCH, ttyout, 0);
+ tp->t_state |= TS_SO_OLOWAT;
+ error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttyout", 0);
splx(s);
if (error)
goto out;
@@ -1904,7 +1867,7 @@ ttyrub(c, tp)
case TAB: {
int c;
- if (tp->t_rocount < RB_LEN(&tp->t_raw)) {
+ if (tp->t_rocount < RB_LEN(tp->t_raw)) {
ttyretype(tp);
return;
}
@@ -1913,9 +1876,9 @@ ttyrub(c, tp)
tp->t_state |= TS_CNTTB;
tp->t_lflag |= FLUSHO;
tp->t_col = tp->t_rocol;
- cp = tp->t_raw.rb_hd;
- for (c = nextc(&cp, &tp->t_raw); c ;
- c = nextc(&cp, &tp->t_raw))
+ cp = tp->t_raw->rb_hd;
+ for (c = nextc(&cp, tp->t_raw); c ;
+ c = nextc(&cp, tp->t_raw))
ttyecho(c, tp);
tp->t_lflag &= ~FLUSHO;
tp->t_state &= ~TS_CNTTB;
@@ -1979,16 +1942,16 @@ ttyretype(tp)
(void) ttyoutput('\n', tp);
s = spltty();
- cp = tp->t_can.rb_hd;
- for (c = nextc(&cp, &tp->t_can); c ; c = nextc(&cp, &tp->t_can))
+ cp = tp->t_can->rb_hd;
+ for (c = nextc(&cp, tp->t_can); c ; c = nextc(&cp, tp->t_can))
ttyecho(c, tp);
- cp = tp->t_raw.rb_hd;
- for (c = nextc(&cp, &tp->t_raw); c ; c = nextc(&cp, &tp->t_raw))
+ cp = tp->t_raw->rb_hd;
+ for (c = nextc(&cp, tp->t_raw); c ; c = nextc(&cp, tp->t_raw))
ttyecho(c, tp);
tp->t_state &= ~TS_ERASE;
splx(s);
- tp->t_rocount = RB_LEN(&tp->t_raw);
+ tp->t_rocount = RB_LEN(tp->t_raw);
tp->t_rocol = 0;
}
@@ -2049,7 +2012,31 @@ ttwakeup(tp)
}
if (tp->t_state & TS_ASYNC)
pgsignal(tp->t_pgrp, SIGIO, 1);
- wakeup((caddr_t)&tp->t_raw);
+ wakeup(TSA_HUP_OR_INPUT(tp));
+}
+
+/*
+ * Wake up any writers on a tty.
+ */
+void
+ttwwakeup(tp)
+ register struct tty *tp;
+{
+ if (RB_LEN(tp->t_out) <= tp->t_lowat) {
+ if (tp->t_state & TS_SO_OCOMPLETE && RB_LEN(tp->t_out) == 0) {
+ tp->t_state &= ~TS_SO_OCOMPLETE;
+ wakeup(TSA_OCOMPLETE(tp));
+ }
+ if (tp->t_state & TS_SO_OLOWAT) {
+ tp->t_state &= ~TS_SO_OLOWAT;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ if (tp->t_wsel) {
+ selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
+ tp->t_wsel = 0;
+ tp->t_state &= ~TS_WCOLL;
+ }
+ }
}
/*
@@ -2099,7 +2086,7 @@ ttyinfo(tp)
{
register struct proc *p, *pick;
struct timeval utime, stime;
- int loadtmp;
+ int loadtmp, tmp;
if (ttycheckoutq(tp,0) == 0)
return;
@@ -2152,8 +2139,13 @@ ttyinfo(tp)
* Lock out clock if process is running; get user/system
* cpu time.
*/
+ tmp = 0;
+ if (curproc == pick)
+ tmp = splclock();
utime = pick->p_utime;
stime = pick->p_stime;
+ if (curproc == pick)
+ splx(tmp);
ttyprintf(tp, " cmd: %s %d [%s] ", comm, pid, wmesg);
@@ -2258,7 +2250,7 @@ tputchar(c, tp)
{
register s = spltty();
- if ((tp->t_state & (TS_CARR_ON|TS_ISOPEN)) == (TS_CARR_ON|TS_ISOPEN)) {
+ if (CAN_DO_IO(tp)) {
if (c == '\n')
(void) ttyoutput('\r', tp);
(void) ttyoutput(c, tp);
@@ -2293,3 +2285,56 @@ ttysleep(tp, chan, pri, wmesg, timo)
return (ERESTART);
return (0);
}
+
+/*
+ * Allocate a tty structure and its associated buffers.
+ */
+struct tty *
+ttymalloc(itp)
+ struct tty *itp;
+{
+ struct tty *tp;
+
+#ifndef broken
+ /*
+ * Note that the itp input is not necessary when we can dealloc
+ * the struct tty.
+ */
+ if(itp == NULL) {
+ MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
+ bzero(tp, sizeof *tp);
+ } else {
+ tp = itp;
+ }
+#endif
+ if(tp->t_raw == NULL) {
+ MALLOC(tp->t_raw, struct ringb *, sizeof(struct ringb), M_TTYS, M_WAITOK);
+ bzero(tp->t_raw, sizeof *tp->t_raw);
+ }
+ if(tp->t_can == NULL) {
+ MALLOC(tp->t_can, struct ringb *, sizeof(struct ringb), M_TTYS, M_WAITOK);
+ bzero(tp->t_can, sizeof *tp->t_can);
+ }
+ if(tp->t_out == NULL) {
+ MALLOC(tp->t_out, struct ringb *, sizeof(struct ringb), M_TTYS, M_WAITOK);
+ bzero(tp->t_out, sizeof *tp->t_out);
+ }
+ return(tp);
+}
+
+/*
+ * Free a tty structure and its buffers.
+ */
+void
+ttyfree(tp)
+struct tty *tp;
+{
+ FREE(tp->t_raw, M_TTYS);
+ FREE(tp->t_can, M_TTYS);
+ FREE(tp->t_out, M_TTYS);
+ tp->t_raw = tp->t_can = tp->t_out = NULL;
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+ /* also set tp to NULL when this isn't broken anymore */
+ FREE(tp, M_TTYS);
+#endif
+}
diff --git a/sys/kern/tty_conf.c b/sys/kern/tty_conf.c
index 6b9ad4917460..ce7016415a5c 100644
--- a/sys/kern/tty_conf.c
+++ b/sys/kern/tty_conf.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)tty_conf.c 7.6 (Berkeley) 5/9/91
- * $Id: tty_conf.c,v 1.6.2.1 1994/05/04 07:54:52 rgrimes Exp $
+ * $Id: tty_conf.c,v 1.9 1994/05/30 03:23:14 ache Exp $
*/
#include "param.h"
@@ -85,14 +85,14 @@ struct linesw linesw[] =
#if NTB > 0
tbopen, tbclose, tbread, IE(enodev), tbioctl,
- tbinput, enodev, nullop, ttstart, nullmodem, /* 3- TABLDISC */
+ tbinput, enodev, nullop, ttstart, ttymodem, /* 3- TABLDISC */
#else
IE(enodev), VE(enodev), IE(enodev), IE(enodev), IE(enodev),
VE(enodev), IE(enodev), IE(enodev), VE(enodev), IE(enodev),
#endif
#if NSL > 0
slopen, VE(slclose), IE(enodev), IE(enodev), sltioctl,
- VE(slinput), enodev, nullop, VE(slstart), nullmodem, /* 4- SLIPDISC */
+ VE(slinput), enodev, nullop, VE(slstart), ttymodem, /* 4- SLIPDISC */
#else
IE(enodev), VE(enodev), IE(enodev), IE(enodev), IE(enodev),
VE(enodev), IE(enodev), IE(enodev), VE(enodev), IE(enodev),
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 0e99e9329e0a..8039fa952b94 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tty_pty.c 7.21 (Berkeley) 5/30/91
- * $Id: tty_pty.c,v 1.9 1994/01/29 04:04:26 davidg Exp $
+ * $Id: tty_pty.c,v 1.14 1994/05/30 03:22:34 ache Exp $
*/
/*
@@ -66,7 +66,7 @@ static void ptcwakeup(struct tty *, int);
* pts == /dev/tty[pqrs]?
* ptc == /dev/pty[pqrs]?
*/
-struct tty pt_tty[NPTY];
+struct tty *pt_tty[NPTY];
struct pt_ioctl {
int pt_flags;
pid_t pt_selr, pt_selw;
@@ -75,13 +75,15 @@ struct pt_ioctl {
} pt_ioctl[NPTY];
int npty = NPTY; /* for pstat -t */
-#define PF_RCOLL 0x01
-#define PF_WCOLL 0x02
-#define PF_PKT 0x08 /* packet mode */
-#define PF_STOPPED 0x10 /* user told stopped */
-#define PF_REMOTE 0x20 /* remote and flow controlled input */
-#define PF_NOSTOP 0x40
-#define PF_UCNTL 0x80 /* user control mode */
+#define PF_RCOLL 0x0001
+#define PF_WCOLL 0x0002
+#define PF_PKT 0x0008 /* packet mode */
+#define PF_STOPPED 0x0010 /* user told stopped */
+#define PF_REMOTE 0x0020 /* remote and flow controlled input */
+#define PF_NOSTOP 0x0040
+#define PF_UCNTL 0x0080 /* user control mode */
+#define PF_COPEN 0x0100 /* master open */
+#define PF_SOPEN 0x0200 /* slave open */
/*ARGSUSED*/
int
@@ -99,9 +101,8 @@ ptsopen(dev, flag, devtype, p)
#endif
if (minor(dev) >= NPTY)
return (ENXIO);
- tp = &pt_tty[minor(dev)];
+ tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]);
if ((tp->t_state & TS_ISOPEN) == 0) {
- tp->t_state |= TS_WOPEN;
ttychars(tp); /* Set up default chars */
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
@@ -114,15 +115,17 @@ ptsopen(dev, flag, devtype, p)
if (tp->t_oproc) /* Ctrlr still around. */
tp->t_state |= TS_CARR_ON;
while ((tp->t_state & TS_CARR_ON) == 0) {
- tp->t_state |= TS_WOPEN;
if (flag&FNONBLOCK)
break;
- if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
- ttopen, 0))
+ if (error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
+ "ptsopn", 0))
return (error);
}
error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
- ptcwakeup(tp, FREAD|FWRITE);
+ if (error == 0) {
+ ptcwakeup(tp, FREAD|FWRITE);
+ pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN;
+ }
return (error);
}
@@ -134,10 +137,17 @@ ptsclose(dev, flag, mode, p)
{
register struct tty *tp;
- tp = &pt_tty[minor(dev)];
+ tp = pt_tty[minor(dev)];
+ ptcwakeup(tp, FREAD|FWRITE);
(*linesw[tp->t_line].l_close)(tp, flag);
ttyclose(tp);
- ptcwakeup(tp, FREAD|FWRITE);
+ pt_ioctl[minor(dev)].pt_flags &= ~PF_SOPEN;
+ if ((pt_ioctl[minor(dev)].pt_flags & PF_COPEN) == 0) {
+ ttyfree(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+ pt_tty[minor(dev)] = (struct tty *)NULL;
+#endif
+ }
return(0);
}
@@ -148,7 +158,7 @@ ptsread(dev, uio, flag)
int flag;
{
struct proc *p = curproc;
- register struct tty *tp = &pt_tty[minor(dev)];
+ register struct tty *tp = pt_tty[minor(dev)];
register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
int error = 0;
@@ -162,25 +172,25 @@ again:
return (EIO);
pgsignal(p->p_pgrp, SIGTTIN, 1);
if (error = ttysleep(tp, (caddr_t)&lbolt,
- TTIPRI | PCATCH, ttybg, 0))
+ TTIPRI | PCATCH, "ptsbg", 0))
return (error);
}
- if (RB_LEN(&tp->t_can) == 0) {
+ if (RB_LEN(tp->t_can) == 0) {
if (flag & IO_NDELAY)
return (EWOULDBLOCK);
- if (error = ttysleep(tp, (caddr_t)&tp->t_can,
- TTIPRI | PCATCH, ttyin, 0))
+ if (error = ttysleep(tp, (caddr_t)tp->t_can,
+ TTIPRI | PCATCH, "ptsin", 0))
return (error);
goto again;
}
- while (RB_LEN(&tp->t_can) > 1 && uio->uio_resid > 0)
- if (ureadc(getc(&tp->t_can), uio) < 0) {
+ while (RB_LEN(tp->t_can) > 1 && uio->uio_resid > 0)
+ if (ureadc(getc(tp->t_can), uio) < 0) {
error = EFAULT;
break;
}
- if (RB_LEN(&tp->t_can) == 1)
- (void) getc(&tp->t_can);
- if (RB_LEN(&tp->t_can))
+ if (RB_LEN(tp->t_can) == 1)
+ (void) getc(tp->t_can);
+ if (RB_LEN(tp->t_can))
return (error);
} else
if (tp->t_oproc)
@@ -202,7 +212,7 @@ ptswrite(dev, uio, flag)
{
register struct tty *tp;
- tp = &pt_tty[minor(dev)];
+ tp = pt_tty[minor(dev)];
if (tp->t_oproc == 0)
return (EIO);
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
@@ -240,7 +250,7 @@ ptcwakeup(tp, flag)
pti->pt_selr = 0;
pti->pt_flags &= ~PF_RCOLL;
}
- wakeup((caddr_t)&tp->t_out.rb_tl);
+ wakeup(TSA_PTC_READ(tp));
}
if (flag & FWRITE) {
if (pti->pt_selw) {
@@ -248,7 +258,7 @@ ptcwakeup(tp, flag)
pti->pt_selw = 0;
pti->pt_flags &= ~PF_WCOLL;
}
- wakeup((caddr_t)&tp->t_raw.rb_hd);
+ wakeup(TSA_PTC_WRITE(tp));
}
}
@@ -268,14 +278,15 @@ ptcopen(dev, flag, devtype, p)
if (minor(dev) >= NPTY)
return (ENXIO);
- tp = &pt_tty[minor(dev)];
+ tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]);
if (tp->t_oproc)
return (EIO);
tp->t_oproc = ptsstart;
(void)(*linesw[tp->t_line].l_modem)(tp, 1);
tp->t_lflag &= ~EXTPROC;
pti = &pt_ioctl[minor(dev)];
- pti->pt_flags = 0;
+ pti->pt_flags &= PF_SOPEN;
+ pti->pt_flags |= PF_COPEN;
pti->pt_send = 0;
pti->pt_ucntl = 0;
return (0);
@@ -289,7 +300,7 @@ ptcclose(dev)
{
register struct tty *tp;
- tp = &pt_tty[minor(dev)];
+ tp = pt_tty[minor(dev)];
(void)(*linesw[tp->t_line].l_modem)(tp, 0);
tp->t_state &= ~TS_CARR_ON;
tp->t_oproc = 0; /* mark closed */
@@ -298,6 +309,13 @@ ptcclose(dev)
if (constty==tp)
constty = 0;
+ pt_ioctl[minor(dev)].pt_flags &= ~PF_COPEN;
+ if ((pt_ioctl[minor(dev)].pt_flags & PF_SOPEN) == 0) {
+ ttyfree(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+ pt_tty[minor(dev)] = (struct tty *)NULL;
+#endif
+ }
return (0);
}
@@ -307,7 +325,7 @@ ptcread(dev, uio, flag)
struct uio *uio;
int flag;
{
- register struct tty *tp = &pt_tty[minor(dev)];
+ register struct tty *tp = pt_tty[minor(dev)];
struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
char buf[BUFSIZ];
int error = 0, cc;
@@ -339,15 +357,15 @@ ptcread(dev, uio, flag)
pti->pt_ucntl = 0;
return (0);
}
- if (RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0)
+ if (RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0)
break;
}
if ((tp->t_state&TS_CARR_ON) == 0)
return (0); /* EOF */
if (flag & IO_NDELAY)
return (EWOULDBLOCK);
- if (error = tsleep((caddr_t)&tp->t_out.rb_tl, TTIPRI | PCATCH,
- ttyin, 0))
+ if (error = tsleep(TSA_PTC_READ(tp), TTIPRI | PCATCH,
+ "ptcin", 0))
return (error);
}
if (pti->pt_flags & (PF_PKT|PF_UCNTL))
@@ -356,28 +374,19 @@ ptcread(dev, uio, flag)
#ifdef was
cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ));
#else
- cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(&tp->t_out));
+ cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(tp->t_out));
if (cc) {
- bcopy(tp->t_out.rb_hd, buf, cc);
- tp->t_out.rb_hd =
- RB_ROLLOVER(&tp->t_out, tp->t_out.rb_hd+cc);
+ bcopy(tp->t_out->rb_hd, buf, cc);
+ tp->t_out->rb_hd =
+ RB_ROLLOVER(tp->t_out, tp->t_out->rb_hd+cc);
}
#endif
if (cc <= 0)
break;
error = uiomove(buf, cc, uio);
}
- if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
- if (tp->t_state&TS_ASLEEP) {
- tp->t_state &= ~TS_ASLEEP;
- wakeup((caddr_t)&tp->t_out);
- }
- if (tp->t_wsel) {
- selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
- tp->t_wsel = 0;
- tp->t_state &= ~TS_WCOLL;
- }
- }
+ if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
+ ttwwakeup(tp);
return (error);
}
@@ -411,7 +420,7 @@ ptcselect(dev, rw, p)
int rw;
struct proc *p;
{
- register struct tty *tp = &pt_tty[minor(dev)];
+ register struct tty *tp = pt_tty[minor(dev)];
struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
struct proc *prev;
int s;
@@ -426,7 +435,7 @@ ptcselect(dev, rw, p)
*/
s = spltty();
if ((tp->t_state&TS_ISOPEN) &&
- RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) {
+ RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) {
splx(s);
return (1);
}
@@ -448,12 +457,12 @@ ptcselect(dev, rw, p)
case FWRITE:
if (tp->t_state&TS_ISOPEN) {
if (pti->pt_flags & PF_REMOTE) {
- if (RB_LEN(&tp->t_can) == 0)
+ if (RB_LEN(tp->t_can) == 0)
return (1);
} else {
- if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can) < TTYHOG-2)
+ if (RB_LEN(tp->t_raw) + RB_LEN(tp->t_can) < TTYHOG-2)
return (1);
- if (RB_LEN(&tp->t_can) == 0 && (tp->t_iflag&ICANON))
+ if (RB_LEN(tp->t_can) == 0 && (tp->t_iflag&ICANON))
return (1);
}
}
@@ -473,7 +482,7 @@ ptcwrite(dev, uio, flag)
register struct uio *uio;
int flag;
{
- register struct tty *tp = &pt_tty[minor(dev)];
+ register struct tty *tp = pt_tty[minor(dev)];
register u_char *cp = 0;
register int cc = 0;
u_char locbuf[BUFSIZ];
@@ -485,12 +494,12 @@ again:
if ((tp->t_state&TS_ISOPEN) == 0)
goto block;
if (pti->pt_flags & PF_REMOTE) {
- if (RB_LEN(&tp->t_can))
+ if (RB_LEN(tp->t_can))
goto block;
- while (uio->uio_resid > 0 && RB_LEN(&tp->t_can) < TTYHOG - 1) {
+ while (uio->uio_resid > 0 && RB_LEN(tp->t_can) < TTYHOG - 1) {
if (cc == 0) {
cc = min(uio->uio_resid, BUFSIZ);
- cc = min(cc, RB_CONTIGPUT(&tp->t_can));
+ cc = min(cc, RB_CONTIGPUT(tp->t_can));
cp = locbuf;
error = uiomove((caddr_t)cp, cc, uio);
if (error)
@@ -504,16 +513,16 @@ again:
(void) b_to_q((char *)cp, cc, &tp->t_canq);
#else
if (cc) {
- bcopy(cp, tp->t_can.rb_tl, cc);
- tp->t_can.rb_tl =
- RB_ROLLOVER(&tp->t_can, tp->t_can.rb_tl+cc);
+ bcopy(cp, tp->t_can->rb_tl, cc);
+ tp->t_can->rb_tl =
+ RB_ROLLOVER(tp->t_can, tp->t_can->rb_tl+cc);
}
#endif
cc = 0;
}
- (void) putc(0, &tp->t_can);
+ (void) putc(0, tp->t_can);
ttwakeup(tp);
- wakeup((caddr_t)&tp->t_can);
+ wakeup((caddr_t)tp->t_can);
return (0);
}
while (uio->uio_resid > 0) {
@@ -528,9 +537,9 @@ again:
return (EIO);
}
while (cc > 0) {
- if ((RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can)) >= TTYHOG - 2 &&
- (RB_LEN(&tp->t_can) > 0 || !(tp->t_iflag&ICANON))) {
- wakeup((caddr_t)&tp->t_raw);
+ if ((RB_LEN(tp->t_raw) + RB_LEN(tp->t_can)) >= TTYHOG - 2 &&
+ (RB_LEN(tp->t_can) > 0 || !(tp->t_iflag&ICANON))) {
+ wakeup(TSA_HUP_OR_INPUT(tp));
goto block;
}
(*linesw[tp->t_line].l_rint)(*cp++, tp);
@@ -554,8 +563,8 @@ block:
return (EWOULDBLOCK);
return (0);
}
- if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH,
- ttyout, 0)) {
+ if (error = tsleep(TSA_PTC_WRITE(tp), TTOPRI | PCATCH,
+ "ptcout", 0)) {
/* adjust for data copied in but not written */
uio->uio_resid += cc;
return (error);
@@ -571,7 +580,7 @@ ptyioctl(dev, cmd, data, flag)
dev_t dev;
int flag;
{
- register struct tty *tp = &pt_tty[minor(dev)];
+ register struct tty *tp = pt_tty[minor(dev)];
register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
register u_char *cc = tp->t_cc;
int stop, error;
@@ -648,7 +657,7 @@ ptyioctl(dev, cmd, data, flag)
case TIOCSETA:
case TIOCSETAW:
case TIOCSETAF:
- while (getc(&tp->t_out) >= 0)
+ while (getc(tp->t_out) >= 0)
;
break;
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index c0cf7a4c68cd..b735b0269666 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)uipc_mbuf.c 7.19 (Berkeley) 4/20/91
- * $Id: uipc_mbuf.c,v 1.6 1993/12/19 00:51:44 wollman Exp $
+ * $Id: uipc_mbuf.c,v 1.9 1994/06/11 23:06:35 paul Exp $
*/
#include "param.h"
@@ -312,7 +312,8 @@ m_copym(m, off0, len, wait)
n->m_len = MIN(len, m->m_len - off);
if (m->m_flags & M_EXT) {
n->m_data = m->m_data + off;
- mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ if (m->m_ext.ext_free == (void (*)())0)
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
n->m_ext = m->m_ext;
n->m_flags |= M_EXT;
} else
@@ -441,8 +442,8 @@ m_adj(mp, req_len)
}
if (m->m_len >= len) {
m->m_len -= len;
- if ((mp = m)->m_flags & M_PKTHDR)
- m->m_pkthdr.len -= len;
+ if (mp->m_flags & M_PKTHDR)
+ mp->m_pkthdr.len -= len;
return;
}
count -= len;
@@ -639,7 +640,8 @@ extpacket:
if (m -> m_flags & M_EXT) {
n -> m_flags |= M_EXT;
n -> m_ext = m -> m_ext;
- mclrefcnt[mtocl (m -> m_ext.ext_buf)]++;
+ if (m->m_ext.ext_free == (void (*)())0)
+ mclrefcnt[mtocl (m -> m_ext.ext_buf)]++;
n -> m_data = m -> m_data + len;
} else {
bcopy (mtod (m, caddr_t) + len, mtod (n, caddr_t), remain);
@@ -724,11 +726,6 @@ m_compress(in, out)
(*out)->m_act = 0;
while (in) {
- if (in->m_flags & M_EXT) {
-#ifdef DEBUG
- ASSERT(in->m_len == 0);
-#endif
- }
if ( in->m_len == 0) {
in = in->m_next;
continue;
diff --git a/sys/kern/vfs__bio.c b/sys/kern/vfs__bio.c
index 2ccf2e6126b7..6868618e9293 100644
--- a/sys/kern/vfs__bio.c
+++ b/sys/kern/vfs__bio.c
@@ -45,7 +45,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: vfs__bio.c,v 1.15 1994/01/31 05:57:45 davidg Exp $
+ * $Id: vfs__bio.c,v 1.21 1994/05/29 18:06:31 ats Exp $
*/
#include "param.h"
@@ -73,7 +73,13 @@ struct buf bswlist; /* head of free swap header list */
struct buf *bclnlist; /* head of cleaned page list */
static struct buf *getnewbuf(int);
-extern vm_map_t buffer_map;
+extern vm_map_t buffer_map, io_map;
+
+/*
+ * Internel update daemon, process 3
+ * The variable vfs_update_wakeup allows for internal syncs.
+ */
+int vfs_update_wakeup;
/*
* Initialize buffer headers and related structures.
@@ -353,18 +359,8 @@ start:
&& bfreelist[BQ_EMPTY].av_forw != (struct buf *)bfreelist+BQ_EMPTY) {
caddr_t addr;
-/*#define notyet*/
-#ifndef notyet
- if ((addr = malloc (sz, M_IOBUF, M_WAITOK)) == 0) goto tryfree;
-#else /* notyet */
- /* get new memory buffer */
- if (round_page(sz) == sz)
- addr = (caddr_t) kmem_alloc_wired_wait(buffer_map, sz);
- else
- addr = (caddr_t) malloc (sz, M_IOBUF, M_WAITOK);
- /*if ((addr = malloc (sz, M_IOBUF, M_NOWAIT)) == 0) goto tryfree;*/
- bzero(addr, sz);
-#endif /* notyet */
+ if ((addr = malloc (sz, M_IOBUF, M_NOWAIT)) == 0)
+ goto tryfree;
freebufspace -= sz;
allocbufspace += sz;
@@ -476,7 +472,14 @@ loop:
/* if (bp->b_bufsize != size) allocbuf(bp, size); */
} else {
- if ((bp = getnewbuf(size)) == 0) goto loop;
+ if ((bp = getnewbuf(size)) == 0)
+ goto loop;
+ if ( incore(vp, blkno)) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ goto loop;
+ }
+
bp->b_blkno = bp->b_lblkno = blkno;
bgetvp(vp, bp);
bh = BUFHASH(vp, blkno);
@@ -521,27 +524,13 @@ allocbuf(register struct buf *bp, int size)
caddr_t newcontents;
/* get new memory buffer */
-#ifndef notyet
newcontents = (caddr_t) malloc (size, M_IOBUF, M_WAITOK);
-#else /* notyet */
- if (round_page(size) == size)
- newcontents = (caddr_t) kmem_alloc_wired_wait(buffer_map, size);
- else
- newcontents = (caddr_t) malloc (size, M_IOBUF, M_WAITOK);
-#endif /* notyet */
/* copy the old into the new, up to the maximum that will fit */
bcopy (bp->b_un.b_addr, newcontents, min(bp->b_bufsize, size));
/* return old contents to free heap */
-#ifndef notyet
free (bp->b_un.b_addr, M_IOBUF);
-#else /* notyet */
- if (round_page(bp->b_bufsize) == bp->b_bufsize)
- kmem_free_wakeup(buffer_map, bp->b_un.b_addr, bp->b_bufsize);
- else
- free (bp->b_un.b_addr, M_IOBUF);
-#endif /* notyet */
/* adjust buffer cache's idea of memory allocated to buffer contents */
freebufspace -= size - bp->b_bufsize;
@@ -593,6 +582,39 @@ biowait(register struct buf *bp)
void
biodone(register struct buf *bp)
{
+ int s;
+ s = splbio();
+ if (bp->b_flags & B_CLUSTER) {
+ struct buf *tbp;
+ bp->b_resid = bp->b_bcount;
+ while ( tbp = bp->b_clusterf) {
+ bp->b_clusterf = tbp->av_forw;
+ bp->b_resid -= tbp->b_bcount;
+ tbp->b_resid = 0;
+ if( bp->b_resid <= 0) {
+ tbp->b_error = bp->b_error;
+ tbp->b_flags |= (bp->b_flags & B_ERROR);
+ tbp->b_resid = -bp->b_resid;
+ bp->b_resid = 0;
+ }
+/*
+ printf("rdc (%d,%d,%d) ", tbp->b_blkno, tbp->b_bcount, tbp->b_resid);
+*/
+
+ biodone(tbp);
+ }
+#ifndef NOBOUNCE
+ vm_bounce_kva_free( bp->b_un.b_addr, bp->b_bufsize, 0);
+#endif
+ relpbuf(bp);
+ splx(s);
+ return;
+ }
+
+#ifndef NOBOUNCE
+ if (bp->b_flags & B_BOUNCE)
+ vm_bounce_free(bp);
+#endif
bp->b_flags |= B_DONE;
if ((bp->b_flags & B_READ) == 0) {
@@ -603,6 +625,7 @@ biodone(register struct buf *bp)
if (bp->b_flags & B_CALL) {
bp->b_flags &= ~B_CALL;
(*bp->b_iodone)(bp);
+ splx(s);
return;
}
@@ -618,19 +641,21 @@ biodone(register struct buf *bp)
bp->b_flags &= ~B_WANTED;
wakeup((caddr_t) bp);
}
+ splx(s);
}
-/*
- * Internel update daemon, process 3
- * The variable vfs_update_wakeup allows for internal syncs.
- */
-int vfs_update_wakeup;
+#ifndef UPDATE_INTERVAL
+int vfs_update_interval = 30;
+#else
+int vfs_update_interval = UPDATE_INTERVAL;
+#endif
void
vfs_update() {
(void) spl0();
while(1) {
- tsleep((caddr_t)&vfs_update_wakeup, PRIBIO, "update", hz*30);
+ tsleep((caddr_t)&vfs_update_wakeup, PRIBIO, "update",
+ hz * vfs_update_interval);
vfs_update_wakeup = 0;
sync(curproc, NULL, NULL);
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index f35002a9460f..37a406d6651e 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vfs_lookup.c 7.32 (Berkeley) 5/21/91
- * $Id: vfs_lookup.c,v 1.5.2.1 1994/05/04 07:54:56 rgrimes Exp $
+ * $Id: vfs_lookup.c,v 1.9 1994/06/02 06:53:37 ache Exp $
*/
#include "param.h"
@@ -106,6 +106,13 @@ namei(ndp, p)
else
error = copyinstr(ndp->ni_dirp, ndp->ni_pnbuf,
MAXPATHLEN, (u_int *)&ndp->ni_pathlen);
+#if 0
+ /*
+ * Don't allow empty pathname.
+ */
+ if (!error && *ndp->ni_pnbuf == '\0')
+ error = ENOENT;
+#endif
if (error) {
free(ndp->ni_pnbuf, M_NAMEI);
ndp->ni_vp = NULL;
@@ -284,10 +291,10 @@ dirloop:
* responsibility for freeing the pathname buffer.
*/
ndp->ni_hash = 0;
- for (cp = ndp->ni_ptr; *cp != 0 && *cp != '/'; cp++)
+ for (cp = ndp->ni_ptr; *cp != '\0' && *cp != '/'; cp++)
ndp->ni_hash += (unsigned char)*cp;
ndp->ni_namelen = cp - ndp->ni_ptr;
- if (ndp->ni_namelen >= NAME_MAX) {
+ if (ndp->ni_namelen > NAME_MAX) {
error = ENAMETOOLONG;
goto bad;
}
@@ -367,7 +374,7 @@ dirloop:
printf("not found\n");
#endif
if (flag == LOOKUP || flag == DELETE ||
- error != ENOENT || *cp != 0)
+ error != ENOENT || *cp != '\0')
goto bad;
/*
* If creating and at end of pathname, then can consider
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 024c5679000b..5525022e9811 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vfs_subr.c 7.60 (Berkeley) 6/21/91
- * $Id: vfs_subr.c,v 1.7.2.2 1994/05/04 07:55:00 rgrimes Exp $
+ * $Id: vfs_subr.c,v 1.13 1994/06/14 03:41:00 davidg Exp $
*/
/*
@@ -57,6 +57,9 @@
#include "buf.h"
#include "errno.h"
#include "malloc.h"
+#include "vm/vm.h"
+#include "vm/vm_object.h"
+#include "vm/vm_pager.h"
static void insmntque(struct vnode *, struct mount *);
@@ -441,6 +444,8 @@ vinvalbuf(vp, save)
register struct buf *bp;
struct buf *nbp, *blist;
int s, dirty = 0;
+ vm_pager_t pager;
+ vm_object_t object;
for (;;) {
if (blist = vp->v_dirtyblkhd)
@@ -473,6 +478,20 @@ vinvalbuf(vp, save)
brelse(bp);
}
}
+
+ pager = (vm_pager_t)vp->v_vmdata;
+ if (pager != NULL) {
+ object = vm_object_lookup(pager);
+ if (object) {
+ vm_object_lock(object);
+ if (save)
+ vm_object_page_clean(object, 0, 0);
+ vm_object_page_remove(object, 0, object->size);
+ vm_object_unlock(object);
+ vm_object_deallocate(object);
+ }
+ }
+
if (vp->v_dirtyblkhd || vp->v_cleanblkhd)
panic("vinvalbuf: flush failed");
return (dirty);
@@ -645,6 +664,7 @@ loop:
nvp->v_hashchain = vpp;
nvp->v_specnext = *vpp;
nvp->v_specflags = 0;
+ nvp->v_opencount = 0;
*vpp = nvp;
if (vp != NULL) {
nvp->v_flag |= VALIASED;
@@ -1068,6 +1088,7 @@ vfinddev(dev, type, vpp)
/*
* Calculate the total number of references to a special device.
+ * Not counting sleeping openers.
*/
int
vcount(vp)
@@ -1089,7 +1110,7 @@ loop:
vgone(vq);
goto loop;
}
- count += vq->v_usecount;
+ count += vq->v_usecount - vq->v_opencount;
}
return (count);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 396bd6326f98..b218ab6dd380 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)vfs_syscalls.c 7.74 (Berkeley) 6/21/91
- * $Id: vfs_syscalls.c,v 1.10 1994/01/19 21:09:13 jtc Exp $
+ * $Id: vfs_syscalls.c,v 1.17 1994/05/26 05:32:05 ache Exp $
*/
#include "param.h"
@@ -841,9 +841,10 @@ link(p, uap, retval)
if (error = namei(ndp, p))
return (error);
vp = ndp->ni_vp;
- if (vp->v_type == VDIR &&
- (error = suser(p->p_ucred, &p->p_acflag)))
+ if (vp->v_type == VDIR) {
+ error = EPERM;
goto out1;
+ }
ndp->ni_nameiop = CREATE | LOCKPARENT;
ndp->ni_dirp = (caddr_t)uap->linkname;
if (error = namei(ndp, p))
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index b273dc8b3604..a9c03b99d6ad 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vfs_vnops.c 7.33 (Berkeley) 6/27/91
- * $Id: vfs_vnops.c,v 1.4.2.2 1994/05/04 07:55:04 rgrimes Exp $
+ * $Id: vfs_vnops.c,v 1.7 1994/05/04 08:27:20 rgrimes Exp $
*/
#include "param.h"
@@ -388,6 +388,7 @@ vn_ioctl(fp, com, data, p)
default:
return (ENOTTY);
+ case VPROC:
case VFIFO:
case VCHR:
case VBLK: