Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Reimplement VP donation such that multiple unblocked upc...
details: https://anonhg.NetBSD.org/src/rev/3199ea0446ed
branches: trunk
changeset: 554894:3199ea0446ed
user: cl <cl%NetBSD.org@localhost>
date: Mon Nov 03 22:34:51 2003 +0000
description:
Reimplement VP donation such that multiple unblocked upcalls can be
combined. Also prepare for adding VP repossession later.
- kern_sa.c: sa_yield/sa_switch: detect if there are pending unblocked
upcalls.
- kern_sa.c: sa_unblock_userret/sa_setwoken: queue LWPs about to invoke
an unblocked upcall on the sa_wokenq. put queued LWPs in a state where
they can be put in the cache. notify LWP on the VP about pending
upcalls.
- kern_sa.c: sa_upcall_userret: check sa_wokenq for pending upcalls,
generate unblocked upcalls with multiple event sas
- kern_sa.c: sa_vp_repossess/sa_vp_donate: g/c, restore original
sa_vp_repossess
diffstat:
sys/kern/kern_exit.c | 10 +-
sys/kern/kern_sa.c | 513 ++++++++++++++++++++++++++++----------------------
sys/kern/kern_sig.c | 9 +-
sys/sys/lwp.h | 3 +-
sys/sys/savar.h | 7 +-
5 files changed, 297 insertions(+), 245 deletions(-)
diffs (truncated from 815 to 300 lines):
diff -r e2b593b4e81e -r 3199ea0446ed sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c Mon Nov 03 22:17:42 2003 +0000
+++ b/sys/kern/kern_exit.c Mon Nov 03 22:34:51 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_exit.c,v 1.124 2003/09/16 13:46:24 cl Exp $ */
+/* $NetBSD: kern_exit.c,v 1.125 2003/11/03 22:34:51 cl Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.124 2003/09/16 13:46:24 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.125 2003/11/03 22:34:51 cl Exp $");
#include "opt_ktrace.h"
#include "opt_perfctrs.h"
@@ -491,14 +491,8 @@
* them) and then wait for everyone else to finish.
*/
LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
-#if 0
l2->l_flag &= ~(L_DETACHED|L_SA);
-#endif
- l2->l_flag &= ~(L_DETACHED);
- if(l2->l_flag & L_SA_WANTS_VP)
- wakeup(l2);
-
if (l2->l_wchan == &l2->l_upcallstack)
wakeup(&l2->l_upcallstack);
diff -r e2b593b4e81e -r 3199ea0446ed sys/kern/kern_sa.c
--- a/sys/kern/kern_sa.c Mon Nov 03 22:17:42 2003 +0000
+++ b/sys/kern/kern_sa.c Mon Nov 03 22:34:51 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sa.c,v 1.38 2003/11/02 17:04:05 jdolecek Exp $ */
+/* $NetBSD: kern_sa.c,v 1.39 2003/11/03 22:34:51 cl Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.38 2003/11/02 17:04:05 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.39 2003/11/03 22:34:51 cl Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -53,7 +53,7 @@
#include <uvm/uvm_extern.h>
-static void sa_vp_donate(struct lwp *);
+static void sa_setwoken(struct lwp *);
static int sa_newcachelwp(struct lwp *);
static struct lwp *sa_vp_repossess(struct lwp *l);
@@ -150,8 +150,7 @@
simple_lock_init(&sa->sa_lock);
sa->sa_flag = SCARG(uap, flags) & SA_FLAG_ALL;
sa->sa_vp = NULL;
- sa->sa_old_lwp = NULL;
- sa->sa_vp_wait_count = 0;
+ sa->sa_wokenq_head = NULL;
sa->sa_concurrency = 1;
sa->sa_stacks = malloc(sizeof(stack_t) * SA_NUMSTACKS,
M_SA, M_WAITOK);
@@ -215,7 +214,7 @@
}
}
- if ((sa->sa_nstacks == 0) && (sa->sa_vp_wait_count != 0))
+ if ((sa->sa_nstacks == 0) && (sa->sa_wokenq_head != NULL))
l->l_flag |= L_SA_UPCALL;
/*
@@ -334,64 +333,47 @@
void
sa_yield(struct lwp *l)
{
-#if 0
- struct lwp *l2;
-#endif
struct proc *p = l->l_proc;
#ifdef DEBUG
struct sadata *sa = p->p_sa;
#endif
int ret, s;
-
+
+#if defined(MULTIPROCESSOR)
+ KDASSERT(l->l_flag & L_BIGLOCK);
+#endif
/*
* If we're the last running LWP, stick around to recieve
* signals.
*/
-#if 0
- if (p->p_nrlwps == 1) {
-#endif
- DPRINTFN(1,("sa_yield(%d.%d) going dormant\n",
- p->p_pid, l->l_lid));
- /*
- * A signal will probably wake us up. Worst case, the upcall
- * happens and just causes the process to yield again.
- */
- SCHED_ASSERT_UNLOCKED();
-
- sa_vp_donate(l);
-
- SCHED_ASSERT_UNLOCKED();
-
- s = splsched(); /* Protect from timer expirations */
+ KDASSERT((l->l_flag & L_SA_YIELD) == 0);
+ DPRINTFN(1,("sa_yield(%d.%d) going dormant\n",
+ p->p_pid, l->l_lid));
+ /*
+ * A signal will probably wake us up. Worst case, the upcall
+ * happens and just causes the process to yield again.
+ */
+ s = splsched(); /* Protect from timer expirations */
+ KDASSERT(sa->sa_vp == l);
+ /*
+ * If we were told to make an upcall or exit before
+ * the splsched(), make sure we process it instead of
+ * going to sleep. It might make more sense for this to
+ * be handled inside of tsleep....
+ */
+ ret = 0;
+ while (ret == 0 && p->p_userret == NULL &&
+ (l->l_flag & L_SA_UPCALL) == 0) {
+ l->l_flag |= L_SA_YIELD;
+ ret = tsleep((caddr_t) l, PUSER | PCATCH, "sawait", 0);
+ l->l_flag &= ~L_SA_YIELD;
+ if (p->p_flag & P_WEXIT)
+ lwp_exit(l);
KDASSERT(sa->sa_vp == l);
- /*
- * If we were told to make an upcall or exit before
- * the splsched(), make sure we process it instead of
- * going to sleep. It might make more sense for this to
- * be handled inside of tsleep....
- */
- ret = 0;
-
- while ((ret == 0) && (p->p_userret == NULL)) {
- l->l_flag |= L_SA_YIELD;
- ret = tsleep((caddr_t) l, PUSER | PCATCH, "sawait", 0);
- l->l_flag &= ~L_SA_YIELD;
- if (p->p_flag & P_WEXIT)
- lwp_exit(l);
- KDASSERT(sa->sa_vp == l);
-
- splx(s);
- sa_vp_donate(l);
- KDASSERT(sa->sa_vp == l);
- s = splsched(); /* Protect from timer expirations */
- }
- l->l_flag |= L_SA_UPCALL;
- splx(s);
- DPRINTFN(1,("sa_yield(%d.%d) returned\n",
- p->p_pid, l->l_lid));
-#if 0
}
-#endif
+ splx(s);
+ DPRINTFN(1,("sa_yield(%d.%d) returned\n",
+ p->p_pid, l->l_lid));
}
@@ -726,8 +708,10 @@
/*
* Case 0: we're blocking in sa_yield
*/
- l->l_flag |= L_SA_IDLE;
- mi_switch(l, NULL);
+ if (sa->sa_wokenq_head == NULL) {
+ l->l_flag |= L_SA_IDLE;
+ mi_switch(l, NULL);
+ }
return;
} else if (sa->sa_vp == l) {
/*
@@ -849,62 +833,26 @@
l2 = NULL;
}
} else {
-#if 0
- /*
- * Case 3: The VP is empty. As in case 2, we were
- * woken up and called tsleep again, but additionally,
- * the running LWP called sa_yield() between our wakeup() and
- * when we got to run again (in fact, it probably was
- * responsible for switching to us, via sa_woken).
- * The right thing is to pull a LWP off the cache and have
- * it jump straight back into sa_yield.
- */
- l2 = sa_getcachelwp(p);
- if (l2 == NULL) {
-#ifdef DIAGNOSTIC
- printf("sa_switch(%d.%d): no cached LWP for reidling.\n",
- p->p_pid, l->l_lid);
-#endif
- mi_switch(l, NULL);
- return;
- }
-#else
- mi_switch(l, NULL);
- return;
-#endif
-
+ /* NOTREACHED */
+ panic("sa_vp empty");
+
sa_upcall_failed:
-#if 0
cpu_setfunc(l2, sa_yieldcall, l2);
l2->l_priority = l2->l_usrpri;
setrunnable(l2);
PRELE(l2); /* Remove the artificial hold-count */
-#else
- /* sa_putcachelwp does not block because we have a hold count on l2 */
- sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
-
- mi_switch(l, NULL);
- return;
-#endif
}
DPRINTFN(4,("sa_switch(%d.%d) switching to LWP %d.\n",
p->p_pid, l->l_lid, l2 ? l2->l_lid : 0));
mi_switch(l, l2);
- DPRINTFN(4,("sa_switch(%d.%d flag %x) returned.\n", p->p_pid, l->l_lid, l->l_flag));
+ DPRINTFN(4,("sa_switch(%d.%d flag %x) returned.\n",
+ p->p_pid, l->l_lid, l->l_flag));
KDASSERT(l->l_wchan == 0);
SCHED_ASSERT_UNLOCKED();
-
- /*
- * The process is trying to exit. In this case, the last thing
- * we want to do is put something back on the cache list.
- * It's also not useful to make the upcall at all, so just punt.
- */
- if (p->p_flag & P_WEXIT)
- return;
}
void
@@ -933,7 +881,6 @@
upcallret(l);
}
-#if 0
void
sa_yieldcall(void *arg)
{
@@ -958,7 +905,6 @@
sa_yield(l);
upcallret(l);
}
-#endif
static int
sa_newcachelwp(struct lwp *l)
@@ -1094,6 +1040,10 @@
if (l->l_flag & L_SA_BLOCKING) {
/* Invoke an "unblocked" upcall */
+
+ sa_setwoken(l);
+ /* maybe NOTREACHED */
+
DPRINTFN(8,("sa_unblock_userret(%d.%d) unblocking\n",
p->p_pid, l->l_lid));
@@ -1112,7 +1062,7 @@
sadata_upcall_free(sau);
lwp_exit(l);
}
-
+
KDASSERT(sa->sa_nstacks > 0);
st = sa->sa_stacks[--sa->sa_nstacks];
DPRINTFN(9,("sa_unblock_userret(%d.%d) nstacks-- = %2d\n",
@@ -1151,15 +1101,18 @@
void
sa_upcall_userret(struct lwp *l)
{
+ struct lwp *l2, *eventq;
struct proc *p;
struct sadata *sa;
struct sa_t **sapp, *sap;
struct sadata_upcall *sau;
Home |
Main Index |
Thread Index |
Old Index