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, \

Reply via email to