Subject: sys_lwp_suspend split
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 12/22/2003 12:26:21
Hello

sys_lwp_continue is already split with a lwp_continue fonction to be
used from within the kernel. sys_lwp_suspend is not split, and the
problem with the current code is that there is no way to bypass the
checks in sys_lwp_suspend.

I propose the following change to make a lwp_suspend function easily
available from within the kernel too (an inline function so that there
is no function call cost): 

Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.16
diff -U4 -r1.16 kern_lwp.c
--- kern/kern_lwp.c     20 Dec 2003 18:22:17 -0000      1.16
+++ kern/kern_lwp.c     22 Dec 2003 11:21:14 -0000
@@ -176,10 +176,10 @@
                syscallarg(lwpid_t) target;
        } */ *uap = v;
        int target_lid;
        struct proc *p = l->l_proc;
-       struct lwp *t, *t2;
-       int s;
+       struct lwp *t;
+       struct lwp *t2;
 
        target_lid = SCARG(uap, target);
 
        LIST_FOREACH(t, &p->p_lwps, l_sibling)
@@ -200,13 +200,26 @@
                }
 
                if (t2 == NULL) /* All other LWPs are suspended */
                        return (EDEADLK);
+       }
+
+       return lwp_suspend(l, t);
+}
 
+inline int
+lwp_suspend(l, t)
+       struct lwp *l;
+       struct lwp *t;
+{
+       struct proc *p = t->l_proc;
+       int s;
+
+       if (t == l) {
                SCHED_LOCK(s);
                l->l_stat = LSSUSPENDED;
                /* XXX NJWLWP check if this makes sense here: */
-               l->l_proc->p_stats->p_ru.ru_nvcsw++;
+               p->p_stats->p_ru.ru_nvcsw++;
                mi_switch(l, NULL);
                SCHED_ASSERT_UNLOCKED();
                splx(s);
        } else {
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.15
diff -U4 -r1.15 lwp.h
--- sys/lwp.h   20 Dec 2003 18:22:16 -0000      1.15
+++ sys/lwp.h   22 Dec 2003 11:21:15 -0000
@@ -180,8 +180,9 @@
 void   upcallret(struct lwp *);
 void   lwp_exit (struct lwp *);
 void   lwp_exit2 (struct lwp *);
 struct lwp *proc_representative_lwp(struct proc *);
+inline int lwp_suspend(struct lwp *, struct lwp *);
 #endif /* _KERNEL */
 
 /* Flags for _lwp_create(), as per Solaris. */
 
-- 
Emmanuel Dreyfus
Il y a 10 sortes de personnes dans le monde: ceux qui comprennent 
le binaire et ceux qui ne le comprennent pas.
manu@netbsd.org