summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2009-11-04 02:26:25 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2009-11-04 02:26:25 +0000
commit3d5a41d84c152c2cfffa1ae5b2ba1192b9addc26 (patch)
tree705c6b970db20c94a8b215399c873fe463fe67c9 /sys
parentcffd0fa24819a270c24547bf9c00b476505d2063 (diff)
MP safe mutex.
ok miod@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sgi/include/mutex.h3
-rw-r--r--sys/arch/sgi/sgi/mutex.c66
2 files changed, 52 insertions, 17 deletions
diff --git a/sys/arch/sgi/include/mutex.h b/sys/arch/sgi/include/mutex.h
index df505d80ba8..1d84c23882d 100644
--- a/sys/arch/sgi/include/mutex.h
+++ b/sys/arch/sgi/include/mutex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.h,v 1.4 2009/10/22 22:08:54 miod Exp $ */
+/* $OpenBSD: mutex.h,v 1.5 2009/11/04 02:26:24 syuu Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -35,6 +35,7 @@ struct mutex {
int mtx_lock;
int mtx_wantipl;
int mtx_oldipl;
+ void *mtx_owner;
};
void mtx_init(struct mutex *, int);
diff --git a/sys/arch/sgi/sgi/mutex.c b/sys/arch/sgi/sgi/mutex.c
index 9b431010b5b..03b3aa0389c 100644
--- a/sys/arch/sgi/sgi/mutex.c
+++ b/sys/arch/sgi/sgi/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.7 2009/10/22 22:08:54 miod Exp $ */
+/* $OpenBSD: mutex.c,v 1.8 2009/11/04 02:26:24 syuu Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -31,14 +31,31 @@
#include <machine/intr.h>
+static inline int
+try_lock(struct mutex *mtx)
+{
#ifdef MULTIPROCESSOR
-#error This code needs more work
-#endif
+ int tmp, ret = 0;
+
+ asm volatile (
+ ".set noreorder\n"
+ "ll %0, %2\n"
+ "bnez %0, 1f\n"
+ "nop\n"
+ "li %1, 1\n"
+ "sc %1, %2\n"
+ "1:\n"
+ ".set reorder\n"
+ : "+r"(tmp), "+r"(ret)
+ : "m"(mtx->mtx_lock));
+
+ return ret;
+#else /* MULTIPROCESSOR */
+ mtx->mtx_lock = 1;
+ return 1;
+#endif /* MULTIPROCESSOR */
+}
-/*
- * 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)
{
@@ -50,22 +67,38 @@ mtx_init(struct mutex *mtx, int wantipl)
void
mtx_enter(struct mutex *mtx)
{
- if (mtx->mtx_wantipl != IPL_NONE)
- mtx->mtx_oldipl = splraise(mtx->mtx_wantipl);
+ int s;
- MUTEX_ASSERT_UNLOCKED(mtx);
- mtx->mtx_lock = 1;
+ 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;
-
- return 1;
+ splx(s);
+ return 0;
}
void
@@ -75,4 +108,5 @@ mtx_leave(struct mutex *mtx)
mtx->mtx_lock = 0;
if (mtx->mtx_wantipl != IPL_NONE)
splx(mtx->mtx_oldipl);
+ mtx->mtx_owner = NULL;
}