summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2012-06-05 11:43:42 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2012-06-05 11:43:42 +0000
commit91393253a24ddbd8c05f031910774cca4697fe98 (patch)
tree6f6c09f6e9789ce2a4fba49134f250035fed2401 /sys/arch
parent5e39bad13789bed23a7c87fb229dd09eeb9849e2 (diff)
Implement actual mutexes for hppa64.
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa64/hppa64/mutex.c82
-rw-r--r--sys/arch/hppa64/include/mutex.h17
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