Date: Sat, 02 Jul 2011 10:57:14 +0000 From: rudot@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r223888 - soc2011/rudot/kern Message-ID: <20110702105714.8775A106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110702105714.8775A106564A>