On 23/03/16(Wed) 23:58, Alexandre Ratchov wrote:
> On Wed, Mar 23, 2016 at 09:35:50PM +0100, Mark Kettenis wrote:
> > >
> > > This doesn't only change the sched_yield() behaviour, but also
> > > modifies how in-kernel yield() calls behave for threaded processes.
> > > That is probably not right.
> >
> > So here is a diff that keeps yield() the same and adds the code in the
> > sched_yield(2) implementation instead. It also changes the logic that
> > picks the priority to walk the complete threads listand pick the
> > highest priotity of all the threads. That should be enough to make
> > sure the calling thread is scheduled behind all other threads from the
> > same process. That does require us to grab the kernel lock though.
> > So this removes NOLOCK from sched_yield(2). I don't think that is a
> > big issue.
>
> I used to think that this is a hack, but now i think this is
> necessary.
I agree, I think it's a step forward.
I realized that PUSER does not mean what I though, so I'd suggest
checking for P_SYSTEM to not duplicate the code.
As for the NOLOCK we could put it back by computing the lowest priority
in schedcpu() and storing it in the process.
Index: kern/sched_bsd.c
===================================================================
RCS file: /cvs/src/sys/kern/sched_bsd.c,v
retrieving revision 1.43
diff -u -p -r1.43 sched_bsd.c
--- kern/sched_bsd.c 9 Mar 2016 13:38:50 -0000 1.43
+++ kern/sched_bsd.c 24 Mar 2016 12:53:29 -0000
@@ -294,11 +294,20 @@ updatepri(struct proc *p)
void
yield(void)
{
- struct proc *p = curproc;
+ struct proc *q, *p = curproc;
int s;
SCHED_LOCK(s);
p->p_priority = p->p_usrpri;
+ /*
+ * If one of the threads of a multi-threaded process called
+ * sched_yield(2), drop its priority to ensure its siblings
+ * can make some progress.
+ */
+ if ((p->p_flag & P_SYSTEM) == 0) {
+ TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link)
+ p->p_priority = max(p->p_priority, q->p_priority);
+ }
p->p_stat = SRUN;
setrunqueue(p);
p->p_ru.ru_nvcsw++;
Index: kern/syscalls.master
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.167
diff -u -p -r1.167 syscalls.master
--- kern/syscalls.master 21 Mar 2016 22:41:29 -0000 1.167
+++ kern/syscalls.master 24 Mar 2016 12:23:20 -0000
@@ -514,7 +514,7 @@
#else
297 UNIMPL
#endif
-298 STD NOLOCK { int sys_sched_yield(void); }
+298 STD { int sys_sched_yield(void); }
299 STD NOLOCK { pid_t sys_getthrid(void); }
300 OBSOL t32___thrsleep
301 STD { int sys___thrwakeup(const volatile void *ident, \