summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2009-12-29 15:02:00 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2009-12-29 15:02:00 +0000
commitda0241f1e1ee47c73babe2c7e96fd89f7fef23c9 (patch)
treefe915c86b6626f5821eed0710f16383d673cc539 /sys
parent81c5e7cd03f5312802fd687b1299dcf49d3bbe29 (diff)
Implement MP safe mutexes for hppa.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hppa/hppa/mutex.c71
-rw-r--r--sys/arch/hppa/include/mutex.h20
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