summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2001-10-20 16:07:17 +0000
committeriedowse <iedowse@FreeBSD.org>2001-10-20 16:07:17 +0000
commitaf95e6836c1ffe802ed807f7c425961054d25670 (patch)
tree270dcc454a0ad1c223ab1b90e91344faec00aa71 /sys/kern/kern_synch.c
parentcb7ca29ccfb777175e9f35287c61d53617f45a36 (diff)
downloadFreeBSD-src-af95e6836c1ffe802ed807f7c425961054d25670.zip
FreeBSD-src-af95e6836c1ffe802ed807f7c425961054d25670.tar.gz
Introduce some jitter to the timing of the samples that determine
the system load average. Previously, the load average measurement was susceptible to synchronisation with processes that run at regular intervals such as the system bufdaemon process. Each interval is now chosen at random within the range of 4 to 6 seconds. This large variation is chosen so that over the shorter 5-minute load average timescale there is a good dispersion of samples across the 5-second sample period (the time to perform 60 5-second samples now has a standard deviation of approx 4.5 seconds).
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index db5d51a..348e57a 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -74,6 +74,7 @@ int hogticks;
int lbolt;
int sched_quantum; /* Roundrobin scheduling quantum in ticks. */
+static struct callout loadav_callout;
static struct callout schedcpu_callout;
static struct callout roundrobin_callout;
@@ -90,7 +91,7 @@ static fixpt_t cexp[3] = {
};
static void endtsleep __P((void *));
-static void loadav __P((struct loadavg *));
+static void loadav __P((void *arg));
static void roundrobin __P((void *arg));
static void schedcpu __P((void *arg));
@@ -339,8 +340,6 @@ schedcpu(arg)
mtx_unlock_spin(&sched_lock);
} /* end of process loop */
sx_sunlock(&allproc_lock);
- if (time_second % 5 == 0)
- loadav(&averunnable);
wakeup((caddr_t)&lbolt);
callout_reset(&schedcpu_callout, hz, schedcpu, NULL);
}
@@ -863,12 +862,14 @@ resetpriority(kg)
* Completely Bogus.. only works with 1:1 (but compiles ok now :-)
*/
static void
-loadav(struct loadavg *avg)
+loadav(void *arg)
{
int i, nrun;
+ struct loadavg *avg;
struct proc *p;
struct ksegrp *kg;
+ avg = &averunnable;
sx_slock(&allproc_lock);
nrun = 0;
FOREACH_PROC_IN_SYSTEM(p) {
@@ -888,6 +889,14 @@ nextproc:
for (i = 0; i < 3; i++)
avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
+
+ /*
+ * Schedule the next update to occur after 5 seconds, but add a
+ * random variation to avoid synchronisation with processes that
+ * run at regular intervals.
+ */
+ callout_reset(&loadav_callout, hz * 4 + (int)(random() % (hz * 2 + 1)),
+ loadav, NULL);
}
/* ARGSUSED */
@@ -898,10 +907,12 @@ sched_setup(dummy)
callout_init(&schedcpu_callout, 1);
callout_init(&roundrobin_callout, 0);
+ callout_init(&loadav_callout, 0);
/* Kick off timeout driven events by calling first time. */
roundrobin(NULL);
schedcpu(NULL);
+ loadav(NULL);
}
/*
OpenPOWER on IntegriCloud