summaryrefslogtreecommitdiffstats
path: root/sys/kern/sched_ule.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2003-03-04 02:45:59 +0000
committerjeff <jeff@FreeBSD.org>2003-03-04 02:45:59 +0000
commit8f4d53e3aa80442c6cb4b4a1d0a512c2dfef79ca (patch)
tree8f87aecf23007f6be8ba131d3898ebaccf5d7806 /sys/kern/sched_ule.c
parent4de0ae322cb45ae3620fef3a8fcf76d44208ee44 (diff)
downloadFreeBSD-src-8f4d53e3aa80442c6cb4b4a1d0a512c2dfef79ca.zip
FreeBSD-src-8f4d53e3aa80442c6cb4b4a1d0a512c2dfef79ca.tar.gz
- Create a function sched_interact_score() which decides on the
interactivity of a kseg and assigns it a value of 0 through 100. - Use sched_interact_score() to determine the dynamic priority. - Define SCHED_CURR() in terms of sched_interact_score(). - Adjust the maximum slice back down to 100ms. - Remove redundant clearing of ke_runq in sched_wakeup() - Clean up #defines and comment them.
Diffstat (limited to 'sys/kern/sched_ule.c')
-rw-r--r--sys/kern/sched_ule.c156
1 files changed, 86 insertions, 70 deletions
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 6379608..2fad6a6 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -57,6 +57,8 @@ SYSCTL_INT(_kern, OID_AUTO, ccpu, CTLFLAG_RD, &ccpu, 0, "");
static void sched_setup(void *dummy);
SYSINIT(sched_setup, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, sched_setup, NULL)
+int realstathz;
+
#define SCHED_STRICT_RESCHED 1
/*
@@ -110,38 +112,40 @@ struct td_sched *thread0_sched = &td_sched;
/*
* This priority range has 20 priorities on either end that are reachable
* only through nice values.
+ *
+ * PRI_RANGE: Total priority range for timeshare threads.
+ * PRI_NRESV: Reserved priorities for nice.
+ * PRI_BASE: The start of the dynamic range.
+ * DYN_RANGE: Number of priorities that are available int the dynamic
+ * priority range.
+ * DYN_HALF: Half of DYN_RANGE for convenience elsewhere.
+ * PRI_DYN: The dynamic priority which is derived from the number of ticks
+ * running vs the total number of ticks.
*/
-#define SCHED_PRI_RANGE (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE + 1)
-#define SCHED_PRI_NRESV 40
-#define SCHED_PRI_BASE (SCHED_PRI_NRESV / 2)
-#define SCHED_PRI_DYN (SCHED_PRI_RANGE - SCHED_PRI_NRESV)
-#define SCHED_PRI_DYN_HALF (SCHED_PRI_DYN / 2)
+#define SCHED_PRI_RANGE (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE + 1)
+#define SCHED_PRI_NRESV 40
+#define SCHED_PRI_BASE ((SCHED_PRI_NRESV / 2) + PRI_MIN_TIMESHARE)
+#define SCHED_DYN_RANGE (SCHED_PRI_RANGE - SCHED_PRI_NRESV)
+#define SCHED_DYN_HALF (SCHED_DYN_RANGE / 2)
+#define SCHED_PRI_DYN(run, total) (((run) * SCHED_DYN_RANGE) / (total))
+
/*
- * These determine how sleep time effects the priority of a process.
+ * These determine the interactivity of a process.
*
* SLP_RUN_MAX: Maximum amount of sleep time + run time we'll accumulate
* before throttling back.
- * SLP_RUN_THORTTLE: Divisor for reducing slp/run time.
- * SLP_RATIO: Compute a bounded ratio of slp time vs run time.
- * SLP_TOPRI: Convert a number of ticks slept and ticks ran into a priority
+ * SLP_RUN_THROTTLE: Divisor for reducing slp/run time.
+ * INTERACT_RANGE: Range of interactivity values. Smaller is better.
+ * INTERACT_HALF: Convenience define, half of the interactivity range.
+ * INTERACT_THRESH: Threshhold for placement on the current runq.
*/
-#define SCHED_SLP_RUN_MAX ((hz * 30) * 1024)
+#define SCHED_SLP_RUN_MAX ((hz * 30) << 10)
#define SCHED_SLP_RUN_THROTTLE (10)
-static __inline int
-sched_slp_ratio(int b, int s)
-{
- b /= SCHED_PRI_DYN_HALF;
- if (b == 0)
- return (0);
- s /= b;
- return (s);
-}
-#define SCHED_SLP_TOPRI(slp, run) \
- ((((slp) > (run))? \
- sched_slp_ratio((slp), (run)): \
- SCHED_PRI_DYN_HALF + (SCHED_PRI_DYN_HALF - sched_slp_ratio((run), (slp))))+ \
- SCHED_PRI_NRESV / 2)
+#define SCHED_INTERACT_RANGE (100)
+#define SCHED_INTERACT_HALF (SCHED_INTERACT_RANGE / 2)
+#define SCHED_INTERACT_THRESH (10)
+
/*
* These parameters and macros determine the size of the time slice that is
* granted to each thread.
@@ -151,23 +155,23 @@ sched_slp_ratio(int b, int s)
* SLICE_RANGE: Range of available time slices scaled by hz.
* SLICE_SCALE: The number slices granted per unit of pri or slp.
* PRI_TOSLICE: Compute a slice size that is proportional to the priority.
- * SLP_TOSLICE: Compute a slice size that is inversely proportional to the
- * amount of time slept. (smaller slices for interactive ksegs)
+ * INTERACT_TOSLICE: Compute a slice size that is inversely proportional to
+ * the amount of time slept. (smaller slices for interactive ksegs)
* PRI_COMP: This determines what fraction of the actual slice comes from
* the slice size computed from the priority.
- * SLP_COMP: This determines what component of the actual slice comes from
- * the slize size computed from the sleep time.
+ * INTERACT_COMP:This determines what component of the actual slice comes from
+ * the slize size computed from the interactivity score.
*/
-#define SCHED_SLICE_MIN (hz / 100)
-#define SCHED_SLICE_MAX (hz / 4)
-#define SCHED_SLICE_RANGE (SCHED_SLICE_MAX - SCHED_SLICE_MIN + 1)
+#define SCHED_SLICE_MIN (hz / 100)
+#define SCHED_SLICE_MAX (hz / 10)
+#define SCHED_SLICE_RANGE (SCHED_SLICE_MAX - SCHED_SLICE_MIN + 1)
#define SCHED_SLICE_SCALE(val, max) (((val) * SCHED_SLICE_RANGE) / (max))
+#define SCHED_INTERACT_COMP(slice) ((slice) / 2) /* 50% */
+#define SCHED_PRI_COMP(slice) ((slice) / 2) /* 50% */
#define SCHED_PRI_TOSLICE(pri) \
(SCHED_SLICE_MAX - SCHED_SLICE_SCALE((pri), SCHED_PRI_RANGE))
-#define SCHED_SLP_TOSLICE(slp) \
- (SCHED_SLICE_MAX - SCHED_SLICE_SCALE((slp), SCHED_PRI_DYN))
-#define SCHED_SLP_COMP(slice) (((slice) / 5) * 3) /* 60% */
-#define SCHED_PRI_COMP(slice) (((slice) / 5) * 2) /* 40% */
+#define SCHED_INTERACT_TOSLICE(score) \
+ (SCHED_SLICE_SCALE((score), SCHED_INTERACT_RANGE))
/*
* This macro determines whether or not the kse belongs on the current or
@@ -175,8 +179,7 @@ sched_slp_ratio(int b, int s)
*
* XXX nice value should effect how interactive a kg is.
*/
-#define SCHED_CURR(kg) (((kg)->kg_slptime > (kg)->kg_runtime && \
- sched_slp_ratio((kg)->kg_slptime, (kg)->kg_runtime) > 4))
+#define SCHED_CURR(kg) (sched_interact_score(kg) < SCHED_INTERACT_THRESH)
/*
* Cpu percentage computation macros and defines.
@@ -218,6 +221,7 @@ struct kseq kseq_cpu;
static int sched_slice(struct ksegrp *kg);
static int sched_priority(struct ksegrp *kg);
+static int sched_interact_score(struct ksegrp *kg);
void sched_pctcpu_update(struct kse *ke);
int sched_pickcpu(void);
@@ -327,6 +331,8 @@ sched_setup(void *dummy)
{
int i;
+ realstathz = stathz ? stathz : hz;
+
mtx_lock_spin(&sched_lock);
/* init kseqs */
for (i = 0; i < MAXCPU; i++)
@@ -346,11 +352,8 @@ sched_priority(struct ksegrp *kg)
if (kg->kg_pri_class != PRI_TIMESHARE)
return (kg->kg_user_pri);
- pri = SCHED_SLP_TOPRI(kg->kg_slptime, kg->kg_runtime);
- CTR2(KTR_RUNQ, "sched_priority: slptime: %d\tpri: %d",
- kg->kg_slptime, pri);
-
- pri += PRI_MIN_TIMESHARE;
+ pri = sched_interact_score(kg) * SCHED_DYN_RANGE / SCHED_INTERACT_RANGE;
+ pri += SCHED_PRI_BASE;
pri += kg->kg_nice;
if (pri > PRI_MAX_TIMESHARE)
@@ -370,23 +373,15 @@ static int
sched_slice(struct ksegrp *kg)
{
int pslice;
- int sslice;
+ int islice;
int slice;
int pri;
pri = kg->kg_user_pri;
pri -= PRI_MIN_TIMESHARE;
pslice = SCHED_PRI_TOSLICE(pri);
- sslice = SCHED_PRI_TOSLICE(SCHED_SLP_TOPRI(kg->kg_slptime, kg->kg_runtime));
-/*
-SCHED_SLP_TOSLICE(SCHED_SLP_RATIO(
- kg->kg_slptime, kg->kg_runtime));
-*/
- slice = SCHED_SLP_COMP(sslice) + SCHED_PRI_COMP(pslice);
-
- CTR4(KTR_RUNQ,
- "sched_slice: pri: %d\tsslice: %d\tpslice: %d\tslice: %d",
- pri, sslice, pslice, slice);
+ islice = SCHED_INTERACT_TOSLICE(sched_interact_score(kg));
+ slice = SCHED_INTERACT_COMP(islice) + SCHED_PRI_COMP(pslice);
if (slice < SCHED_SLICE_MIN)
slice = SCHED_SLICE_MIN;
@@ -406,6 +401,34 @@ SCHED_SLP_TOSLICE(SCHED_SLP_RATIO(
return (slice);
}
+static int
+sched_interact_score(struct ksegrp *kg)
+{
+ int big;
+ int small;
+ int base;
+
+ if (kg->kg_runtime > kg->kg_slptime) {
+ big = kg->kg_runtime;
+ small = kg->kg_slptime;
+ base = SCHED_INTERACT_HALF;
+ } else {
+ big = kg->kg_slptime;
+ small = kg->kg_runtime;
+ base = 0;
+ }
+
+ big /= SCHED_INTERACT_HALF;
+ if (big != 0)
+ small /= big;
+ else
+ small = 0;
+
+ small += base;
+ /* XXX Factor in nice */
+ return (small);
+}
+
int
sched_rr_interval(void)
{
@@ -502,8 +525,8 @@ sched_switchout(struct thread *td)
if (TD_IS_RUNNING(td)) {
setrunqueue(td);
return;
- } else
- td->td_kse->ke_runq = NULL;
+ }
+ td->td_kse->ke_runq = NULL;
/*
* We will not be on the run queue. So we must be
@@ -547,13 +570,6 @@ sched_sleep(struct thread *td, u_char prio)
td->td_slptime = ticks;
td->td_priority = prio;
- /*
- * If this is an interactive task clear its queue so it moves back
- * on to curr when it wakes up. Otherwise let it stay on the queue
- * that it was assigned to.
- */
- if (SCHED_CURR(td->td_kse->ke_ksegrp))
- td->td_kse->ke_runq = NULL;
#ifdef SMP
if (td->td_priority < PZERO) {
kseq_sleep(KSEQ_CPU(td->td_kse->ke_cpu), td->td_kse);
@@ -575,7 +591,7 @@ sched_wakeup(struct thread *td)
struct ksegrp *kg;
kg = td->td_ksegrp;
- kg->kg_slptime += (ticks - td->td_slptime) * 1024;
+ kg->kg_slptime += (ticks - td->td_slptime) << 10;
sched_priority(kg);
td->td_slptime = 0;
}
@@ -608,11 +624,11 @@ sched_fork(struct ksegrp *kg, struct ksegrp *child)
/* XXX Need something better here */
if (kg->kg_slptime > kg->kg_runtime) {
- child->kg_slptime = SCHED_PRI_DYN;
- child->kg_runtime = kg->kg_slptime / SCHED_PRI_DYN;
+ child->kg_slptime = SCHED_DYN_RANGE;
+ child->kg_runtime = kg->kg_slptime / SCHED_DYN_RANGE;
} else {
- child->kg_runtime = SCHED_PRI_DYN;
- child->kg_slptime = kg->kg_runtime / SCHED_PRI_DYN;
+ child->kg_runtime = SCHED_DYN_RANGE;
+ child->kg_slptime = kg->kg_runtime / SCHED_DYN_RANGE;
}
#if 0
child->kg_slptime = kg->kg_slptime;
@@ -696,7 +712,7 @@ sched_clock(struct thread *td)
* We used a tick charge it to the ksegrp so that we can compute our
* "interactivity".
*/
- kg->kg_runtime += 1024;
+ kg->kg_runtime += 1 << 10;
/*
* We used up one time slice.
@@ -705,8 +721,8 @@ sched_clock(struct thread *td)
/*
* We're out of time, recompute priorities and requeue
*/
- if (ke->ke_slice == 0) {
- td->td_priority = sched_priority(kg);
+ if (ke->ke_slice <= 0) {
+ sched_priority(kg);
ke->ke_slice = sched_slice(kg);
td->td_flags |= TDF_NEEDRESCHED;
ke->ke_runq = NULL;
OpenPOWER on IntegriCloud