summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRicardo M. Correia <[email protected]>2010-11-22 00:20:58 -0800
committerBrian Behlendorf <[email protected]>2010-11-29 11:25:32 -0800
commitc2f997b0b3b9a79b7146c8883aa09326e5def253 (patch)
tree6dc6bdb814f441bb5d6e567d9b786fe200aed3ad /include
parent058de03caaefe63086559662f2abaed1edf0e086 (diff)
Make kmutex_t typesafe in all cases.
When HAVE_MUTEX_OWNER and CONFIG_SMP are defined, kmutex_t is just a typedef for struct mutex. This is generally OK but has the downside that it can make mistakes such as mutex_lock(&kmutex_var) to pass by unnoticed until someone compiles the code without HAVE_MUTEX_OWNER or CONFIG_SMP (in which case kmutex_t is a real struct). Note that the correct API to call should have been mutex_enter() rather than mutex_lock(). We prevent these kind of mistakes by making kmutex_t a real structure with only one field. This makes kmutex_t typesafe and it shouldn't have any impact on the generated assembly code. Signed-off-by: Ricardo M. Correia <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'include')
-rw-r--r--include/sys/mutex.h32
1 files changed, 19 insertions, 13 deletions
diff --git a/include/sys/mutex.h b/include/sys/mutex.h
index 1a8b25813..ebf9151f1 100644
--- a/include/sys/mutex.h
+++ b/include/sys/mutex.h
@@ -37,14 +37,20 @@ typedef enum {
#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP)
-typedef struct mutex kmutex_t;
+/*
+ * We define a 1-field struct rather than a straight typedef to enforce type
+ * safety.
+ */
+typedef struct {
+ struct mutex m;
+} kmutex_t;
static inline kthread_t *
mutex_owner(kmutex_t *mp)
{
- struct thread_info *owner;
+ struct thread_info *owner;
- owner = ACCESS_ONCE(mp->owner);
+ owner = ACCESS_ONCE(mp->m.owner);
if (owner)
return owner->task;
@@ -54,7 +60,7 @@ mutex_owner(kmutex_t *mp)
static inline int
mutex_owned(kmutex_t *mp)
{
- return (ACCESS_ONCE(mp->owner) == current_thread_info());
+ return (ACCESS_ONCE(mp->m.owner) == current_thread_info());
}
#define MUTEX_HELD(mp) mutex_owned(mp)
@@ -65,31 +71,31 @@ mutex_owned(kmutex_t *mp)
static struct lock_class_key __key; \
ASSERT(type == MUTEX_DEFAULT); \
\
- __mutex_init((mp), #mp, &__key); \
+ __mutex_init(&(mp)->m, #mp, &__key); \
})
#undef mutex_destroy
#define mutex_destroy(mp) \
({ \
- VERIFY3P(mutex_owner(mp), ==, NULL); \
+ VERIFY3P(mutex_owner(mp), ==, NULL); \
})
-#define mutex_tryenter(mp) mutex_trylock(mp)
-#define mutex_enter(mp) mutex_lock(mp)
+#define mutex_tryenter(mp) mutex_trylock(&(mp)->m)
+#define mutex_enter(mp) mutex_lock(&(mp)->m)
/* mutex->owner is not cleared when CONFIG_DEBUG_MUTEXES is set */
#ifdef CONFIG_DEBUG_MUTEXES
# define mutex_exit(mp) \
({ \
- mutex_unlock(mp); \
- (mp)->owner = NULL; \
+ mutex_unlock(&(mp)->m); \
+ (mp)->m.owner = NULL; \
})
#else
-# define mutex_exit(mp) mutex_unlock(mp)
+# define mutex_exit(mp) mutex_unlock(&(mp)->m)
#endif /* CONFIG_DEBUG_MUTEXES */
#ifdef HAVE_GPL_ONLY_SYMBOLS
-# define mutex_enter_nested(mp, sc) mutex_lock_nested(mp, sc)
+# define mutex_enter_nested(mp, sc) mutex_lock_nested(&(mp)->m, sc)
#else
# define mutex_enter_nested(mp, sc) mutex_enter(mp)
#endif /* HAVE_GPL_ONLY_SYMBOLS */
@@ -172,7 +178,7 @@ mutex_owner(kmutex_t *mp)
#undef mutex_destroy
#define mutex_destroy(mp) \
({ \
- VERIFY3P(mutex_owner(mp), ==, NULL); \
+ VERIFY3P(mutex_owner(mp), ==, NULL); \
})
#define mutex_tryenter(mp) \