socsvn commit: r223888 - soc2011/rudot/kern
rudot at FreeBSD.org
rudot at FreeBSD.org
Sat Jul 2 10:57:16 UTC 2011
Author: rudot
Date: Sat Jul 2 10:57:13 2011
New Revision: 223888
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223888
Log:
threads that wake up try to preempt a lower priority running thread
Modified:
soc2011/rudot/kern/sched_fbfs.c
Modified: soc2011/rudot/kern/sched_fbfs.c
==============================================================================
--- soc2011/rudot/kern/sched_fbfs.c Sat Jul 2 00:38:10 2011 (r223887)
+++ soc2011/rudot/kern/sched_fbfs.c Sat Jul 2 10:57:13 2011 (r223888)
@@ -116,6 +116,8 @@
static struct thread *edf_choose(struct rqhead * rqh);
static struct thread *runq_choose_bfs(struct runq * rq);
+static int preempt_lastcpu(struct thread *td);
+static struct thread *worst_running_thread(void);
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);
@@ -138,7 +140,7 @@
SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RD, 0, "Scheduler");
-SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "4BSD", 0,
+SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "FBFS", 0,
"Scheduler name");
SYSCTL_INT(_kern_sched, OID_AUTO, slice, CTLFLAG_RW, &sched_slice, 0,
@@ -592,10 +594,90 @@
MPASS(td->td_lock == &sched_lock);
}
+int
+preempt_lastcpu(struct thread *td)
+{
+ int cpri;
+ struct pcpu * pcpu;
+ struct td_sched *ts;
+ struct td_sched *tsc;
+ u_char c;
+
+ c = td->td_lastcpu;
+ if (c == NOCPU)
+ return (0);
+ pcpu = pcpu_find(c);
+ if (pcpu->pc_curthread == pcpu->pc_idlethread) {
+ if (PCPU_GET(cpuid) != c)
+ ipi_cpu(c, IPI_AST);
+ return (1);
+ }
+ cpri = pcpu->pc_curthread->td_priority;
+ if (cpri < td->td_priority)
+ return (0);
+ if (cpri > td->td_priority) {
+ pcpu->pc_curthread->td_flags |= TDF_NEEDRESCHED;
+ if (PCPU_GET(cpuid) != c)
+ ipi_cpu(c, IPI_AST);
+ return (1);
+ }
+ ts = td->td_sched;
+ tsc = pcpu->pc_curthread->td_sched;
+ if ((td->td_pri_class == PRI_TIMESHARE) ||
+ (td->td_pri_class == PRI_IDLE)) {
+ if (ts->ts_vdeadline >= tsc->ts_vdeadline)
+ return (0);
+ } else
+ return (0);
+ /*
+ * Here, the priorities of td, and current thread on td_lastcpu are
+ * equal. And their scheduling class is PRI_IDLE or PRI_TIMESHARE
+ * Further, the virtual deadline of td is lower. Therefore we
+ * reschedule the td_lastcpu.
+ */
+ pcpu->pc_curthread->td_flags |= TDF_NEEDRESCHED;
+ if (PCPU_GET(cpuid) != c)
+ ipi_cpu(c, IPI_AST);
+
+ return (1);
+}
+
+struct thread *
+worst_running_thread(void)
+{
+ struct td_sched *ts, *ts2;
+ struct thread *max_thread, *cthr;
+ struct pcpu *pc;
+ u_char max_prio;
+
+ max_thread = curthread;
+ max_prio = max_thread->td_priority;
+ ts = max_thread->td_sched;
+ SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
+ cthr = pc->pc_curthread;
+ if (max_prio < cthr->td_priority) {
+ max_thread = cthr;
+ max_prio = max_thread->td_priority;
+ ts = max_thread->td_sched;
+ } else if (max_prio == cthr->td_priority) {
+ ts2 = cthr->td_sched;
+ if (ts->ts_vdeadline > ts2->ts_vdeadline) {
+ max_thread = cthr;
+ ts = ts2;
+ }
+ }
+ }
+
+ return (max_thread);
+}
+
void
sched_wakeup(struct thread *td)
{
struct td_sched *ts;
+ struct thread *thr_worst;
+ cpumask_t dontuse, map, me;
+ u_char c;
THREAD_LOCK_ASSERT(td, MA_OWNED);
ts = td->td_sched;
@@ -603,6 +685,44 @@
td->td_slptick = 0;
ts->ts_slptime = 0;
sched_add(td, SRQ_BORING);
+
+ me = PCPU_GET(cpumask);
+ dontuse = me | stopped_cpus | hlt_cpus_mask;
+ map = idle_cpus_mask & ~dontuse;
+
+ /*
+ * Firstly check if we should reschedule the last cpu the thread
+ * run on.
+ */
+ if (preempt_lastcpu(td)) {
+ if (map)
+ ipi_selected(map, IPI_AST);
+ return;
+ }
+
+ if (map) {
+ ipi_selected(map, IPI_AST);
+ return;
+ }
+
+ /* We did not wake lastcpu and there is no suitable idle cpu */
+ thr_worst = worst_running_thread();
+ c = thr_worst->td_oncpu;
+ if (thr_worst->td_priority < td->td_priority)
+ return;
+ if (thr_worst->td_priority > td->td_priority) {
+ thr_worst->td_flags |= TDF_NEEDRESCHED;
+ if ((thr_worst != curthread) && (c != NOCPU))
+ ipi_cpu(c, IPI_AST);
+ return;
+ }
+
+ /* thr_worst->td_priority == td->td_priority */
+ if (ts->ts_vdeadline < thr_worst->td_sched->ts_vdeadline) {
+ thr_worst->td_flags |= TDF_NEEDRESCHED;
+ if ((thr_worst != curthread) && (c != NOCPU))
+ ipi_cpu(c, IPI_AST);
+ }
}
void
More information about the svn-soc-all
mailing list