vkernel - Unbreak 32-bit vkernel builds by fixing broken assertion
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 1 Jan 2012 23:08:37 +0000 (15:08 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 1 Jan 2012 23:08:37 +0000 (15:08 -0800)
* [ASSERT_]MP_LOCK_HELD() was not properly handling the new token
  t_count format.

* Rename and document the functions a bit better.  Currently our
  more expansive token test for (shared or exclusive) is not
  a perfect test because we don't want to eat cpu time iterating
  the thread's token array to check for shared tokens.  So we just
  check for a shared count.

  Works well for assertions, wouldn't work very well for conditional
  acquisition (of a shared token).

* Exclusive token tests are perfect.

Reported-by: tuxillo
sys/sys/mplock2.h
sys/sys/thread.h
sys/sys/thread2.h

index 7a1a7ad..1e13c15 100644 (file)
@@ -26,8 +26,8 @@
 
 void cpu_get_initial_mplock(void);
 
-#define MP_LOCK_HELD()         LWKT_TOKEN_HELD(&mp_token)
-#define ASSERT_MP_LOCK_HELD()  ASSERT_LWKT_TOKEN_HELD(&mp_token)
+#define MP_LOCK_HELD()         LWKT_TOKEN_HELD_EXCL(&mp_token)
+#define ASSERT_MP_LOCK_HELD()  ASSERT_LWKT_TOKEN_HELD_EXCL(&mp_token)
 
 #else
 
index b4cc199..0d9c444 100644 (file)
@@ -137,10 +137,14 @@ typedef struct lwkt_token {
 /*
  * Assert that a particular token is held
  */
-#define LWKT_TOKEN_HELD(tok)           _lwkt_token_held(tok, curthread)
+#define LWKT_TOKEN_HELD_ANY(tok)       _lwkt_token_held_any(tok, curthread)
+#define LWKT_TOKEN_HELD_EXCL(tok)      _lwkt_token_held_excl(tok, curthread)
 
-#define ASSERT_LWKT_TOKEN_HELD(tok)    \
-       KKASSERT(LWKT_TOKEN_HELD(tok))
+#define ASSERT_LWKT_TOKEN_HELD(tok)            \
+       KKASSERT(LWKT_TOKEN_HELD_ANY(tok))
+
+#define ASSERT_LWKT_TOKEN_HELD_EXCL(tok)       \
+       KKASSERT(LWKT_TOKEN_HELD_EXCL(tok))
 
 #define ASSERT_NO_TOKENS_HELD(td)      \
        KKASSERT((td)->td_toks_stop == &td->td_toks_array[0])
index acf848f..13bbff0 100644 (file)
 #include <machine/cpufunc.h>
 
 /*
+ * Is a token held either by the specified thread or held shared?
+ *
+ * We can't inexpensively validate the thread for a shared token
+ * without iterating td->td_toks, so this isn't a perfect test.
+ */
+static __inline int
+_lwkt_token_held_any(lwkt_token_t tok, thread_t td)
+{
+       long count = tok->t_count;
+
+       cpu_ccfence();
+       if (tok->t_ref >= &td->td_toks_base && tok->t_ref < td->td_toks_stop)
+               return TRUE;
+       if ((count & TOK_EXCLUSIVE) == 0 &&
+           (count & ~(TOK_EXCLUSIVE|TOK_EXCLREQ))) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/*
  * Is a token held by the specified thread?
  */
 static __inline int
-_lwkt_token_held(lwkt_token_t tok, thread_t td)
+_lwkt_token_held_excl(lwkt_token_t tok, thread_t td)
 {
-       return ((tok->t_count & ~(TOK_EXCLUSIVE|TOK_EXCLREQ)) ||
-               (tok->t_ref >= &td->td_toks_base &&
+       return ((tok->t_ref >= &td->td_toks_base &&
                 tok->t_ref < td->td_toks_stop));
 }