diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2009-12-29 15:02:00 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2009-12-29 15:02:00 +0000 |
commit | da0241f1e1ee47c73babe2c7e96fd89f7fef23c9 (patch) | |
tree | fe915c86b6626f5821eed0710f16383d673cc539 /sys | |
parent | 81c5e7cd03f5312802fd687b1299dcf49d3bbe29 (diff) |
Implement MP safe mutexes for hppa.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/hppa/hppa/mutex.c | 71 | ||||
-rw-r--r-- | sys/arch/hppa/include/mutex.h | 20 |
2 files changed, 64 insertions, 27 deletions
diff --git a/sys/arch/hppa/hppa/mutex.c b/sys/arch/hppa/hppa/mutex.c index 5a5750dd67c..2378f832add 100644 --- a/sys/arch/hppa/hppa/mutex.c +++ b/sys/arch/hppa/hppa/mutex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.c,v 1.5 2009/08/13 13:24:55 weingart Exp $ */ +/* $OpenBSD: mutex.c,v 1.6 2009/12/29 15:01:59 jsing Exp $ */ /* * Copyright (c) 2004 Artur Grabowski <art@openbsd.org> @@ -31,47 +31,82 @@ #include <machine/intr.h> -#ifdef MULTIPROCESSOR -#error This code needs more work +#include <ddb/db_output.h> + +static inline int +try_lock(struct mutex *mtx) +{ + volatile register_t ret = 0; + +#ifdef DIAGNOSTIC + if (((u_int32_t)(&mtx->mtx_lock) & 0xf) != 0) { + db_printf("mtx_lock is not 16-byte aligned\n"); + Debugger(); + } #endif -/* - * Single processor systems don't need any mutexes, but they need the spl - * raising semantics of the mutexes. - */ + /* Note: lock must be 16-byte aligned. */ + asm volatile ( + "ldcws 0(%2), %0" + : "=&r" (ret), "+m" (mtx->mtx_lock) + : "r" (&mtx->mtx_lock) + ); + + return ret; +} + void mtx_init(struct mutex *mtx, int wantipl) { - mtx->mtx_oldipl = 0; + mtx->mtx_lock = MUTEX_UNLOCKED; mtx->mtx_wantipl = wantipl; - mtx->mtx_lock = 0; + mtx->mtx_oldipl = IPL_NONE; } void mtx_enter(struct mutex *mtx) { - if (mtx->mtx_wantipl != IPL_NONE) - mtx->mtx_oldipl = splraise(mtx->mtx_wantipl); - MUTEX_ASSERT_UNLOCKED(mtx); - mtx->mtx_lock = 1; + int s; + + for (;;) { + if (mtx->mtx_wantipl != IPL_NONE) + s = splraise(mtx->mtx_wantipl); + if (try_lock(mtx)) { + if (mtx->mtx_wantipl != IPL_NONE) + mtx->mtx_oldipl = s; + mtx->mtx_owner = curcpu(); + return; + } + if (mtx->mtx_wantipl != IPL_NONE) + splx(s); + } } int mtx_enter_try(struct mutex *mtx) { + int s; + + if (mtx->mtx_wantipl != IPL_NONE) + s = splraise(mtx->mtx_wantipl); + if (try_lock(mtx)) { + if (mtx->mtx_wantipl != IPL_NONE) + mtx->mtx_oldipl = s; + mtx->mtx_owner = curcpu(); + return 1; + } if (mtx->mtx_wantipl != IPL_NONE) - mtx->mtx_oldipl = splraise(mtx->mtx_wantipl); - MUTEX_ASSERT_UNLOCKED(mtx); - mtx->mtx_lock = 1; + splx(s); - return 1; + return 0; } void mtx_leave(struct mutex *mtx) { MUTEX_ASSERT_LOCKED(mtx); - mtx->mtx_lock = 0; + mtx->mtx_lock = MUTEX_UNLOCKED; if (mtx->mtx_wantipl != IPL_NONE) splx(mtx->mtx_oldipl); + mtx->mtx_owner = NULL; } diff --git a/sys/arch/hppa/include/mutex.h b/sys/arch/hppa/include/mutex.h index e5d16258166..6bea7b9b110 100644 --- a/sys/arch/hppa/include/mutex.h +++ b/sys/arch/hppa/include/mutex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.h,v 1.2 2007/05/05 12:06:17 miod Exp $ */ +/* $OpenBSD: mutex.h,v 1.3 2009/12/29 15:01:59 jsing Exp $ */ /* * Copyright (c) 2004 Artur Grabowski <art@openbsd.org> @@ -28,27 +28,29 @@ #ifndef _MACHINE_MUTEX_H_ #define _MACHINE_MUTEX_H_ -/* - * Simple non-mp implementation. - */ +#define MUTEX_LOCKED 0 +#define MUTEX_UNLOCKED 1 + +/* Note: mtx_lock must be 16-byte aligned. */ struct mutex { - int mtx_lock; + volatile int mtx_lock; int mtx_wantipl; int mtx_oldipl; -}; + void *mtx_owner; +} __attribute__ ((__aligned__(16))); void mtx_init(struct mutex *, int); -#define MUTEX_INITIALIZER(ipl) { 0, (ipl), 0 } +#define MUTEX_INITIALIZER(ipl) { MUTEX_UNLOCKED, (ipl), 0, NULL } #ifdef DIAGNOSTIC #define MUTEX_ASSERT_LOCKED(mtx) do { \ - if ((mtx)->mtx_lock == 0) \ + if ((mtx)->mtx_lock != MUTEX_LOCKED) \ panic("mutex %p not held in %s", (mtx), __func__); \ } while (0) #define MUTEX_ASSERT_UNLOCKED(mtx) do { \ - if ((mtx)->mtx_lock != 0) \ + if ((mtx)->mtx_lock != MUTEX_UNLOCKED) \ panic("mutex %p held in %s", (mtx), __func__); \ } while (0) #else |