diff options
author | Ricardo M. Correia <[email protected]> | 2010-11-22 00:20:58 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2010-11-29 11:25:32 -0800 |
commit | c2f997b0b3b9a79b7146c8883aa09326e5def253 (patch) | |
tree | 6dc6bdb814f441bb5d6e567d9b786fe200aed3ad /include/sys | |
parent | 058de03caaefe63086559662f2abaed1edf0e086 (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/sys')
-rw-r--r-- | include/sys/mutex.h | 32 |
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) \ |