socsvn commit: r223695 - soc2011/rudot/kern
rudot at FreeBSD.org
rudot at FreeBSD.org
Sat Jun 25 10:22:21 UTC 2011
Author: rudot
Date: Sat Jun 25 10:22:18 2011
New Revision: 223695
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223695
Log:
time slice remembered from previous run
idle threads also chosen according to the virtual deadline
Modified:
soc2011/rudot/kern/sched_fbfs.c
Modified: soc2011/rudot/kern/sched_fbfs.c
==============================================================================
--- soc2011/rudot/kern/sched_fbfs.c Sat Jun 25 03:43:58 2011 (r223694)
+++ soc2011/rudot/kern/sched_fbfs.c Sat Jun 25 10:22:18 2011 (r223695)
@@ -68,22 +68,11 @@
dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
#endif
-/*
- * INVERSE_ESTCPU_WEIGHT is only suitable for statclock() frequencies in
- * the range 100-256 Hz (approximately).
- */
-#define ESTCPULIM(e) \
- min((e), INVERSE_ESTCPU_WEIGHT * (NICE_WEIGHT * (PRIO_MAX - PRIO_MIN) - \
- RQ_PPQ) + INVERSE_ESTCPU_WEIGHT - 1)
-#ifdef SMP
-#define INVERSE_ESTCPU_WEIGHT (8 * smp_cpus)
-#else
-#define INVERSE_ESTCPU_WEIGHT 8 /* 1 / (priorities per estcpu level). */
-#endif
-#define NICE_WEIGHT 1 /* Priorities per nice level. */
-
#define TS_NAME_LEN (MAXCOMLEN + sizeof(" td ") + sizeof(__XSTRING(UINT_MAX)))
+static int realstathz;
+static int sched_slice = 1;
+
/*
* The schedulable entity that runs a context.
* This is an extension to the thread structure and is tailored to
@@ -95,6 +84,7 @@
int ts_slptime; /* (j) Seconds !RUNNING. */
int ts_flags;
int ts_vdeadline; /* virtual deadline. */
+ int ts_slice; /* Remaining slice in number of ticks */
struct runq *ts_runq; /* runq the thread is currently on */
#ifdef KTR
char ts_name[TS_NAME_LEN];
@@ -118,17 +108,17 @@
struct mtx sched_lock;
static int sched_tdcnt; /* Total runnable threads in the system. */
-static int sched_quantum; /* Roundrobin scheduling quantum in ticks. */
-#define SCHED_QUANTUM (hz / 10) /* Default sched quantum */
static void setup_runqs(void);
static void sched_priority(struct thread *td, u_char prio);
static void sched_setup(void *dummy);
+static void sched_initticks(void *dummy);
static struct thread *edf_choose(struct rqhead * rqh);
static struct thread *runq_choose_bfs(struct runq * rq);
SYSINIT(sched_setup, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, sched_setup, NULL);
+SYSINIT(sched_initticks, SI_SUB_CLOCKS, SI_ORDER_THIRD, sched_initticks, NULL);
/*
* Global run queue.
@@ -146,80 +136,14 @@
runq_init(&runq);
}
-static int
-sysctl_kern_quantum(SYSCTL_HANDLER_ARGS)
-{
- int error, new_val;
-
- new_val = sched_quantum * tick;
- error = sysctl_handle_int(oidp, &new_val, 0, req);
- if (error != 0 || req->newptr == NULL)
- return (error);
- if (new_val < tick)
- return (EINVAL);
- sched_quantum = new_val / tick;
- hogticks = 2 * sched_quantum;
- return (0);
-}
-
SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RD, 0, "Scheduler");
SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "4BSD", 0,
"Scheduler name");
-SYSCTL_PROC(_kern_sched, OID_AUTO, quantum, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof sched_quantum, sysctl_kern_quantum, "I",
- "Roundrobin scheduling quantum in microseconds");
-
-#ifdef SMP
-/* Enable forwarding of wakeups to all other cpus */
-SYSCTL_NODE(_kern_sched, OID_AUTO, ipiwakeup, CTLFLAG_RD, NULL, "Kernel SMP");
-
-static int runq_fuzz = 1;
-SYSCTL_INT(_kern_sched, OID_AUTO, runq_fuzz, CTLFLAG_RW, &runq_fuzz, 0, "");
-
-static int forward_wakeup_enabled = 1;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, enabled, CTLFLAG_RW,
- &forward_wakeup_enabled, 0,
- "Forwarding of wakeup to idle CPUs");
-
-static int forward_wakeups_requested = 0;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, requested, CTLFLAG_RD,
- &forward_wakeups_requested, 0,
- "Requests for Forwarding of wakeup to idle CPUs");
-
-static int forward_wakeups_delivered = 0;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, delivered, CTLFLAG_RD,
- &forward_wakeups_delivered, 0,
- "Completed Forwarding of wakeup to idle CPUs");
-
-static int forward_wakeup_use_mask = 1;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, usemask, CTLFLAG_RW,
- &forward_wakeup_use_mask, 0,
- "Use the mask of idle cpus");
-
-static int forward_wakeup_use_loop = 0;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, useloop, CTLFLAG_RW,
- &forward_wakeup_use_loop, 0,
- "Use a loop to find idle cpus");
-
-static int forward_wakeup_use_single = 0;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, onecpu, CTLFLAG_RW,
- &forward_wakeup_use_single, 0,
- "Only signal one idle cpu");
-
-static int forward_wakeup_use_htt = 0;
-SYSCTL_INT(_kern_sched_ipiwakeup, OID_AUTO, htt2, CTLFLAG_RW,
- &forward_wakeup_use_htt, 0,
- "account for htt");
+SYSCTL_INT(_kern_sched, OID_AUTO, slice, CTLFLAG_RW, &sched_slice, 0,
+ "Slice size for timeshare threads");
-#endif
-#if 0
-static int sched_followon = 0;
-SYSCTL_INT(_kern_sched, OID_AUTO, followon, CTLFLAG_RW,
- &sched_followon, 0,
- "allow threads to share a quantum");
-#endif
static __inline void
sched_load_add(void)
@@ -247,13 +171,11 @@
int
maybe_preempt(struct thread *td)
{
-#ifdef PREEMPTION
-#endif
return (0);
}
/* I keep it here because the top command wants it. */
-static fixpt_t ccpu = 0.95122942450071400909 * FSCALE; /* exp(-1/20) */
+static fixpt_t ccpu = 0;
SYSCTL_INT(_kern, OID_AUTO, ccpu, CTLFLAG_RD, &ccpu, 0, "");
/* ARGSUSED */
@@ -262,6 +184,9 @@
{
int i;
+ realstathz = hz;
+ sched_slice = (realstathz/10);
+
prio_ratios[0] = 128;
for (i = 1; i <= PRIO_MAX - PRIO_MIN; ++i) {
prio_ratios[i] = prio_ratios[i - 1] * 11 / 10;
@@ -269,14 +194,17 @@
setup_runqs();
- if (sched_quantum == 0)
- sched_quantum = SCHED_QUANTUM;
- hogticks = 2 * sched_quantum;
-
/* Account for thread0. */
sched_load_add();
}
+static void
+sched_initticks(void *dummy)
+{
+ realstathz = stathz ? stathz : hz;
+ sched_slice = (realstathz/10); /* ~100ms */
+}
+
/* External interfaces start here */
/*
@@ -295,6 +223,7 @@
thread0.td_sched = &td_sched0;
thread0.td_lock = &sched_lock;
mtx_init(&sched_lock, "sched lock", NULL, MTX_SPIN | MTX_RECURSE);
+ td_sched0.ts_slice = sched_slice;
}
int
@@ -306,25 +235,9 @@
int
sched_rr_interval(void)
{
- if (sched_quantum == 0)
- sched_quantum = SCHED_QUANTUM;
- return (sched_quantum);
+ return (hz/(realstathz/sched_slice));
}
-/*
- * We adjust the priority of the current process. The priority of
- * a process gets worse as it accumulates CPU time. The cpu usage
- * estimator (td_estcpu) is increased here. resetpriority() will
- * compute a different priority each time td_estcpu increases by
- * INVERSE_ESTCPU_WEIGHT
- * (until MAXPRI is reached). The cpu usage estimator ramps up
- * quite quickly when the process is running (linearly), and decays
- * away exponentially, at a rate which is proportionally slower when
- * the system is busy. The basic principle is that the system will
- * 90% forget that the process used a lot of CPU time in 5 * loadav
- * seconds. This causes the system to favor processes which haven't
- * run much recently, and to round-robin among other processes.
- */
void
sched_clock(struct thread *td)
{
@@ -334,26 +247,23 @@
ts = td->td_sched;
ts->ts_cpticks++;
- td->td_estcpu = ESTCPULIM(td->td_estcpu + 1);
- /*
- * Force a context switch if the current thread has used up a full
- * quantum (default quantum is 100ms).
- */
- if (!TD_IS_IDLETHREAD(td) &&
- ticks - PCPU_GET(switchticks) >= sched_quantum) {
- td->td_flags |= TDF_NEEDRESCHED;
- ts->ts_vdeadline = ticks + sched_quantum *
- prio_ratios[td->td_proc->p_nice - PRIO_MIN] / 128;
-
- CTR4(KTR_SCHED, "timeslice fill: t: %d, i: %d, r: %d, d: %d",
- ticks, td->td_proc->p_nice - PRIO_MIN,
- prio_ratios[td->td_proc->p_nice - PRIO_MIN],
- ts->ts_vdeadline
- );
+ if (--ts->ts_slice > 0)
+ return;
+
+ ts->ts_vdeadline = ticks + sched_slice *
+ prio_ratios[td->td_proc->p_nice - PRIO_MIN] / 128;
+ ts->ts_slice = sched_slice;
+ td->td_flags |= TDF_NEEDRESCHED;
+
+ CTR4(KTR_SCHED, "timeslice fill: t: %d, i: %d, r: %d, d: %d",
+ ticks, td->td_proc->p_nice - PRIO_MIN,
+ prio_ratios[td->td_proc->p_nice - PRIO_MIN],
+ ts->ts_vdeadline
+ );
- CTR1(KTR_SCHED, "queue number: %d", td->td_rqindex);
- }
+ CTR1(KTR_SCHED, "queue number: %d", td->td_rqindex);
+ CTR1(KTR_SCHED, "thread: 0x%x", td);
}
/*
@@ -377,7 +287,6 @@
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "exit",
"prio:%d", child->td_priority);
thread_lock(td);
- td->td_estcpu = ESTCPULIM(td->td_estcpu + child->td_estcpu);
thread_unlock(td);
mtx_lock_spin(&sched_lock);
if ((child->td_proc->p_flag & P_NOLOAD) == 0)
@@ -396,12 +305,14 @@
{
struct td_sched *ts;
- childtd->td_estcpu = td->td_estcpu;
childtd->td_lock = &sched_lock;
childtd->td_cpuset = cpuset_ref(td->td_cpuset);
ts = childtd->td_sched;
bzero(ts, sizeof(*ts));
+ td->td_sched->ts_slice /= 2;
ts->ts_flags |= (td->td_sched->ts_flags & TSF_AFFINITY);
+ ts->ts_vdeadline = td->td_sched->ts_vdeadline;
+ ts->ts_slice = td->td_sched->ts_slice;
}
void
@@ -789,7 +700,7 @@
if (rqb->rqb_bits[i] == 0)
continue;
pri = RQB_FFS(rqb->rqb_bits[i]) + (i << RQB_L2BPW);
- if (pri == RQ_TIMESHARE) {
+ if ((pri == RQ_TIMESHARE) || (pri == RQ_IDLE)) {
td = edf_choose(&rq->rq_queues[pri]);
return (td);
}
More information about the svn-soc-all
mailing list