Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern move priority inheritance code to separate functions



details:   https://anonhg.NetBSD.org/src/rev/e96027d98855
branches:  trunk
changeset: 771743:e96027d98855
user:      yamt <yamt%NetBSD.org@localhost>
date:      Fri Dec 02 12:31:53 2011 +0000

description:
move priority inheritance code to separate functions

diffstat:

 sys/kern/kern_turnstile.c |  264 +++++++++++++++++++++++++--------------------
 1 files changed, 144 insertions(+), 120 deletions(-)

diffs (truncated from 312 to 300 lines):

diff -r 026f865aaa31 -r e96027d98855 sys/kern/kern_turnstile.c
--- a/sys/kern/kern_turnstile.c Fri Dec 02 12:31:03 2011 +0000
+++ b/sys/kern/kern_turnstile.c Fri Dec 02 12:31:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_turnstile.c,v 1.30 2011/07/27 14:35:34 uebayasi Exp $     */
+/*     $NetBSD: kern_turnstile.c,v 1.31 2011/12/02 12:31:53 yamt Exp $ */
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2009 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.30 2011/07/27 14:35:34 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.31 2011/12/02 12:31:53 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/lockdebug.h>
@@ -195,87 +195,31 @@
 }
 
 /*
- * turnstile_block:
+ * turnstile_lendpri:
  *
- *      Enter an object into the turnstile chain and prepare the current
- *      LWP for sleep.
+ *     Lend our priority to lwps on the blocking chain.
+ *
+ *
  */
-void
-turnstile_block(turnstile_t *ts, int q, wchan_t obj, syncobj_t *sobj)
-{
-       lwp_t *l;
-       lwp_t *cur; /* cached curlwp */
-       lwp_t *owner;
-       turnstile_t *ots;
-       tschain_t *tc;
-       sleepq_t *sq;
-       pri_t prio, obase;
-
-       tc = &turnstile_tab[TS_HASH(obj)];
-       l = cur = curlwp;
-
-       KASSERT(q == TS_READER_Q || q == TS_WRITER_Q);
-       KASSERT(mutex_owned(tc->tc_mutex));
-       KASSERT(l != NULL && l->l_ts != NULL);
 
-       if (ts == NULL) {
-               /*
-                * We are the first thread to wait for this object;
-                * lend our turnstile to it.
-                */
-               ts = l->l_ts;
-               KASSERT(TS_ALL_WAITERS(ts) == 0);
-               KASSERT(TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) &&
-                       TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q]));
-               ts->ts_obj = obj;
-               ts->ts_inheritor = NULL;
-               LIST_INSERT_HEAD(&tc->tc_chain, ts, ts_chain);
-       } else {
-               /*
-                * Object already has a turnstile.  Put our turnstile
-                * onto the free list, and reference the existing
-                * turnstile instead.
-                */
-               ots = l->l_ts;
-               KASSERT(ots->ts_free == NULL);
-               ots->ts_free = ts->ts_free;
-               ts->ts_free = ots;
-               l->l_ts = ts;
-
-               KASSERT(ts->ts_obj == obj);
-               KASSERT(TS_ALL_WAITERS(ts) != 0);
-               KASSERT(!TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) ||
-                       !TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q]));
-       }
-
-       sq = &ts->ts_sleepq[q];
-       ts->ts_waiters[q]++;
-       sleepq_enter(sq, l, tc->tc_mutex);
-       LOCKDEBUG_BARRIER(tc->tc_mutex, 1);
-       l->l_kpriority = true;
-       obase = l->l_kpribase;
-       if (obase < PRI_KTHREAD)
-               l->l_kpribase = PRI_KTHREAD;
-       sleepq_enqueue(sq, obj, "tstile", sobj);
+static void
+turnstile_lendpri(lwp_t *cur)
+{
+       lwp_t * l = cur;
+       pri_t prio;
 
        /*
-        * Disable preemption across this entire block, as we may drop
-        * scheduler locks (allowing preemption), and would prefer not
-        * to be interrupted while in a state of flux.
-        */
-       KPREEMPT_DISABLE(l);
-
-       /*
-        * Lend our priority to lwps on the blocking chain.
-        *
         * NOTE: if you get a panic in this code block, it is likely that
         * a lock has been destroyed or corrupted while still in use.  Try
         * compiling a kernel with LOCKDEBUG to pinpoint the problem.
         */
+
+       LOCKDEBUG_BARRIER(l->l_mutex, 1);
+       KASSERT(l == curlwp);
        prio = lwp_eprio(l);
-       KASSERT(cur == l);
-       KASSERT(tc->tc_mutex == cur->l_mutex);
        for (;;) {
+               lwp_t *owner;
+               turnstile_t *ts;
                bool dolock;
 
                if (l->l_wchan == NULL)
@@ -337,10 +281,135 @@
                lwp_lock(cur);
        }
        LOCKDEBUG_BARRIER(cur->l_mutex, 1);
+}
 
+/*
+ * turnstile_unlendpri: undo turnstile_lendpri
+ */
+
+static void
+turnstile_unlendpri(turnstile_t *ts)
+{
+       lwp_t * const l = curlwp;
+       turnstile_t *iter;
+       turnstile_t *next;
+       turnstile_t *prev = NULL;
+       pri_t prio;
+       bool dolock;
+
+       KASSERT(ts->ts_inheritor != NULL);
+       ts->ts_inheritor = NULL;
+       dolock = l->l_mutex == l->l_cpu->ci_schedstate.spc_lwplock;
+       if (dolock) {
+               lwp_lock(l);
+       }
+
+       /*
+        * the following loop does two things.
+        *
+        * - remove ts from the list.
+        *
+        * - from the rest of the list, find the highest priority.
+        */
+
+       prio = -1;
+       KASSERT(!SLIST_EMPTY(&l->l_pi_lenders));
+       for (iter = SLIST_FIRST(&l->l_pi_lenders);
+           iter != NULL; iter = next) {
+               KASSERT(lwp_eprio(l) >= ts->ts_eprio);
+               next = SLIST_NEXT(iter, ts_pichain);
+               if (iter == ts) {
+                       if (prev == NULL) {
+                               SLIST_REMOVE_HEAD(&l->l_pi_lenders,
+                                   ts_pichain);
+                       } else {
+                               SLIST_REMOVE_AFTER(prev, ts_pichain);
+                       }
+               } else if (prio < iter->ts_eprio) {
+                       prio = iter->ts_eprio;
+               }
+               prev = iter;
+       }
+
+       lwp_lendpri(l, prio);
+
+       if (dolock) {
+               lwp_unlock(l);
+       }
+}
+
+/*
+ * turnstile_block:
+ *
+ *      Enter an object into the turnstile chain and prepare the current
+ *      LWP for sleep.
+ */
+void
+turnstile_block(turnstile_t *ts, int q, wchan_t obj, syncobj_t *sobj)
+{
+       lwp_t * const l = curlwp; /* cached curlwp */
+       turnstile_t *ots;
+       tschain_t *tc;
+       sleepq_t *sq;
+       pri_t obase;
+
+       tc = &turnstile_tab[TS_HASH(obj)];
+
+       KASSERT(q == TS_READER_Q || q == TS_WRITER_Q);
+       KASSERT(mutex_owned(tc->tc_mutex));
+       KASSERT(l != NULL && l->l_ts != NULL);
+
+       if (ts == NULL) {
+               /*
+                * We are the first thread to wait for this object;
+                * lend our turnstile to it.
+                */
+               ts = l->l_ts;
+               KASSERT(TS_ALL_WAITERS(ts) == 0);
+               KASSERT(TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) &&
+                       TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q]));
+               ts->ts_obj = obj;
+               ts->ts_inheritor = NULL;
+               LIST_INSERT_HEAD(&tc->tc_chain, ts, ts_chain);
+       } else {
+               /*
+                * Object already has a turnstile.  Put our turnstile
+                * onto the free list, and reference the existing
+                * turnstile instead.
+                */
+               ots = l->l_ts;
+               KASSERT(ots->ts_free == NULL);
+               ots->ts_free = ts->ts_free;
+               ts->ts_free = ots;
+               l->l_ts = ts;
+
+               KASSERT(ts->ts_obj == obj);
+               KASSERT(TS_ALL_WAITERS(ts) != 0);
+               KASSERT(!TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) ||
+                       !TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q]));
+       }
+
+       sq = &ts->ts_sleepq[q];
+       ts->ts_waiters[q]++;
+       sleepq_enter(sq, l, tc->tc_mutex);
+       LOCKDEBUG_BARRIER(tc->tc_mutex, 1);
+       l->l_kpriority = true;
+       obase = l->l_kpribase;
+       if (obase < PRI_KTHREAD)
+               l->l_kpribase = PRI_KTHREAD;
+       sleepq_enqueue(sq, obj, "tstile", sobj);
+
+       /*
+        * Disable preemption across this entire block, as we may drop
+        * scheduler locks (allowing preemption), and would prefer not
+        * to be interrupted while in a state of flux.
+        */
+       KPREEMPT_DISABLE(l);
+       KASSERT(tc->tc_mutex == l->l_mutex);
+       turnstile_lendpri(l);
        sleepq_block(0, false);
-       cur->l_kpribase = obase;
-       KPREEMPT_ENABLE(cur);
+       l->l_kpribase = obase;
+       KPREEMPT_ENABLE(l);
 }
 
 /*
@@ -369,52 +438,7 @@
         */
 
        if (ts->ts_inheritor != NULL) {
-               turnstile_t *iter;
-               turnstile_t *next;
-               turnstile_t *prev = NULL;
-               pri_t prio;
-               bool dolock;
-
-               ts->ts_inheritor = NULL;
-               l = curlwp;
-
-               dolock = l->l_mutex == l->l_cpu->ci_schedstate.spc_lwplock;
-               if (dolock) {
-                       lwp_lock(l);
-               }
-
-               /*
-                * the following loop does two things.
-                *
-                * - remove ts from the list.
-                *
-                * - from the rest of the list, find the highest priority.
-                */
-
-               prio = -1;
-               KASSERT(!SLIST_EMPTY(&l->l_pi_lenders));
-               for (iter = SLIST_FIRST(&l->l_pi_lenders);
-                   iter != NULL; iter = next) {
-                       KASSERT(lwp_eprio(l) >= ts->ts_eprio);
-                       next = SLIST_NEXT(iter, ts_pichain);
-                       if (iter == ts) {
-                               if (prev == NULL) {
-                                       SLIST_REMOVE_HEAD(&l->l_pi_lenders,
-                                           ts_pichain);
-                               } else {
-                                       SLIST_REMOVE_AFTER(prev, ts_pichain);
-                               }
-                       } else if (prio < iter->ts_eprio) {
-                               prio = iter->ts_eprio;
-                       }



Home | Main Index | Thread Index | Old Index