diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2012-06-05 11:43:42 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2012-06-05 11:43:42 +0000 |
commit | 91393253a24ddbd8c05f031910774cca4697fe98 (patch) | |
tree | 6f6c09f6e9789ce2a4fba49134f250035fed2401 /sys/arch | |
parent | 5e39bad13789bed23a7c87fb229dd09eeb9849e2 (diff) |
Implement actual mutexes for hppa64.
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa64/hppa64/mutex.c | 82 | ||||
-rw-r--r-- | sys/arch/hppa64/include/mutex.h | 17 |
2 files changed, 68 insertions, 31 deletions
diff --git a/sys/arch/hppa64/hppa64/mutex.c b/sys/arch/hppa64/hppa64/mutex.c index c51aa9a31c7..a6206e0817f 100644 --- a/sys/arch/hppa64/hppa64/mutex.c +++ b/sys/arch/hppa64/hppa64/mutex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.c,v 1.7 2011/04/21 04:34:12 miod Exp $ */ +/* $OpenBSD: mutex.c,v 1.8 2012/06/05 11:43:41 jsing Exp $ */ /* * Copyright (c) 2004 Artur Grabowski <art@openbsd.org> @@ -29,56 +29,92 @@ #include <sys/mutex.h> #include <sys/systm.h> -#ifdef MULTIPROCESSOR -#error This code needs more work -#endif +#include <machine/intr.h> + +#include <ddb/db_output.h> + +static inline int +try_lock(struct mutex *mtx) +{ + volatile int *lock = &mtx->mtx_lock; + volatile register_t ret = 0; + + asm volatile ( + "ldcw,co 0(%2), %0" + : "=&r" (ret), "+m" (lock) + : "r" (lock) + ); + + return ret; +} -/* - * Single processor systems don't need any mutexes, but they need the spl - * raising semantics of the mutexes. - */ 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(); #ifdef DIAGNOSTIC - curcpu()->ci_mutex_level++; + curcpu()->ci_mutex_level++; #endif + return; + } + if (mtx->mtx_wantipl != IPL_NONE) + splx(s); + } } int mtx_enter_try(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; + + 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(); #ifdef DIAGNOSTIC - curcpu()->ci_mutex_level++; + curcpu()->ci_mutex_level++; #endif + return 1; + } + if (mtx->mtx_wantipl != IPL_NONE) + splx(s); - return 1; + return 0; } void mtx_leave(struct mutex *mtx) { + int s; + MUTEX_ASSERT_LOCKED(mtx); + #ifdef DIAGNOSTIC curcpu()->ci_mutex_level--; #endif - mtx->mtx_lock = 0; + s = mtx->mtx_oldipl; + mtx->mtx_owner = NULL; + + mtx->mtx_lock = MUTEX_UNLOCKED; + if (mtx->mtx_wantipl != IPL_NONE) - splx(mtx->mtx_oldipl); + splx(s); } diff --git a/sys/arch/hppa64/include/mutex.h b/sys/arch/hppa64/include/mutex.h index 714f2d165d5..6f20f5cb85b 100644 --- a/sys/arch/hppa64/include/mutex.h +++ b/sys/arch/hppa64/include/mutex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.h,v 1.1 2007/10/06 14:54:38 kettenis Exp $ */ +/* $OpenBSD: mutex.h,v 1.2 2012/06/05 11:43:41 jsing Exp $ */ /* * Copyright (c) 2004 Artur Grabowski <art@openbsd.org> @@ -28,27 +28,28 @@ #ifndef _MACHINE_MUTEX_H_ #define _MACHINE_MUTEX_H_ -/* - * Simple non-mp implementation. - */ +#define MUTEX_LOCKED 0 +#define MUTEX_UNLOCKED 1 + struct mutex { - int mtx_lock; + volatile int mtx_lock; int mtx_wantipl; int mtx_oldipl; + void *mtx_owner; }; 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[0] != MUTEX_UNLOCKED) \ panic("mutex %p held in %s", (mtx), __func__); \ } while (0) #else |