diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-04 02:26:25 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-04 02:26:25 +0000 |
commit | 3d5a41d84c152c2cfffa1ae5b2ba1192b9addc26 (patch) | |
tree | 705c6b970db20c94a8b215399c873fe463fe67c9 /sys | |
parent | cffd0fa24819a270c24547bf9c00b476505d2063 (diff) |
MP safe mutex.
ok miod@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sgi/include/mutex.h | 3 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/mutex.c | 66 |
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; } |