summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>2009-08-13 13:24:56 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>2009-08-13 13:24:56 +0000
commit12e07bde626971f0b6038b2e0779443ce161e178 (patch)
treed88677388bcf55b9698dc17194f0de869a2f4c60 /sys
parent29809d2f1e8c02ea2b0ede0ef698eeadae085716 (diff)
A new(er) mtx_enter_try().
Ok oga@, "the time is now" deraadt@.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/alpha/alpha/mutex.c13
-rw-r--r--sys/arch/amd64/amd64/mutex.S45
-rw-r--r--sys/arch/arm/s3c2xx0/s3c2xx0_mutex.c14
-rw-r--r--sys/arch/arm/xscale/i80321_mutex.c14
-rw-r--r--sys/arch/arm/xscale/pxa2x0_mutex.c13
-rw-r--r--sys/arch/hppa/hppa/mutex.c13
-rw-r--r--sys/arch/hppa64/hppa64/mutex.c13
-rw-r--r--sys/arch/i386/i386/mutex.S47
-rw-r--r--sys/arch/m68k/m68k/mutex.c13
-rw-r--r--sys/arch/m88k/m88k/mutex.S86
-rw-r--r--sys/arch/powerpc/powerpc/mutex.S57
-rw-r--r--sys/arch/sgi/sgi/mutex.c13
-rw-r--r--sys/arch/sh/sh/mutex.c13
-rw-r--r--sys/arch/sparc/sparc/mutex.c20
-rw-r--r--sys/arch/sparc64/sparc64/mutex.S29
-rw-r--r--sys/arch/vax/vax/mutex.c13
-rw-r--r--sys/sys/mutex.h3
17 files changed, 401 insertions, 18 deletions
diff --git a/sys/arch/alpha/alpha/mutex.c b/sys/arch/alpha/alpha/mutex.c
index 0be19335328..82e98c164d1 100644
--- a/sys/arch/alpha/alpha/mutex.c
+++ b/sys/arch/alpha/alpha/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -56,6 +56,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+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;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/amd64/amd64/mutex.S b/sys/arch/amd64/amd64/mutex.S
index 2a9472021a9..38a381b0aef 100644
--- a/sys/arch/amd64/amd64/mutex.S
+++ b/sys/arch/amd64/amd64/mutex.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.S,v 1.6 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.S,v 1.7 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -84,7 +84,48 @@ ENTRY(mtx_enter)
call _C_LABEL(panic)
5: .asciz "mtx_enter: locking against myself"
#endif
-
+
+ENTRY(mtx_enter_try)
+1: movl MTX_WANTIPL(%rdi), %eax
+ movq CPUVAR(SELF), %rcx
+ movl CPU_INFO_ILEVEL(%rcx), %edx # oipl = cpl;
+ cmpl %eax, %edx # if (cpl < mtx->mtx_wantipl)
+ cmovge %edx, %eax
+ movl %eax, CPU_INFO_ILEVEL(%rcx) # cpl = mtx->mtx_wantipl;
+ /*
+ * %edx - the old ipl
+ * %rcx - curcpu()
+ */
+ xorq %rax, %rax
+#ifdef MULTIPROCESSOR
+ lock
+#endif
+ cmpxchgq %rcx, MTX_OWNER(%rdi) # test_and_set(mtx->mtx_owner)
+ jne 2f
+ movl %edx, MTX_OLDIPL(%rdi)
+ movq $1, %rax
+ ret
+
+ /* We failed to obtain the lock. splx and return 0. */
+2: pushq %rdi
+ movl %edx, %edi
+ call _C_LABEL(spllower)
+ popq %rdi
+#ifdef DIAGNOSTIC
+ movq CPUVAR(SELF), %rcx
+ cmpq MTX_OWNER(%rdi), %rcx
+ je 3f
+#endif
+ xorq %rax, %rax
+ ret
+
+#ifdef DIAGNOSTIC
+3: movq $4f, %rdi
+ call _C_LABEL(panic)
+4: .asciz "mtx_enter: locking against myself"
+#endif
+
+
ENTRY(mtx_leave)
movq %rdi, %rax
xorq %rcx, %rcx
diff --git a/sys/arch/arm/s3c2xx0/s3c2xx0_mutex.c b/sys/arch/arm/s3c2xx0/s3c2xx0_mutex.c
index 04c3332a1e5..e186a756ca7 100644
--- a/sys/arch/arm/s3c2xx0/s3c2xx0_mutex.c
+++ b/sys/arch/arm/s3c2xx0/s3c2xx0_mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3c2xx0_mutex.c,v 1.1 2008/11/26 14:39:14 drahn Exp $ */
+/* $OpenBSD: s3c2xx0_mutex.c,v 1.2 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -58,6 +58,18 @@ mtx_enter(struct mutex *mtx)
}
void
+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;
+
+ return 1;
+}
+
+void
mtx_leave(struct mutex *mtx)
{
MUTEX_ASSERT_LOCKED(mtx);
diff --git a/sys/arch/arm/xscale/i80321_mutex.c b/sys/arch/arm/xscale/i80321_mutex.c
index c19da126124..9271d29c5ad 100644
--- a/sys/arch/arm/xscale/i80321_mutex.c
+++ b/sys/arch/arm/xscale/i80321_mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i80321_mutex.c,v 1.1 2007/05/15 05:26:44 miod Exp $ */
+/* $OpenBSD: i80321_mutex.c,v 1.2 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -58,6 +58,18 @@ mtx_enter(struct mutex *mtx)
}
void
+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;
+
+ return 1;
+}
+
+void
mtx_leave(struct mutex *mtx)
{
MUTEX_ASSERT_LOCKED(mtx);
diff --git a/sys/arch/arm/xscale/pxa2x0_mutex.c b/sys/arch/arm/xscale/pxa2x0_mutex.c
index 605f9b02b56..6952105a8d6 100644
--- a/sys/arch/arm/xscale/pxa2x0_mutex.c
+++ b/sys/arch/arm/xscale/pxa2x0_mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_mutex.c,v 1.1 2007/05/15 05:26:44 miod Exp $ */
+/* $OpenBSD: pxa2x0_mutex.c,v 1.2 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -57,6 +57,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+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;
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/hppa/hppa/mutex.c b/sys/arch/hppa/hppa/mutex.c
index 77c6cd782d2..5a5750dd67c 100644
--- a/sys/arch/hppa/hppa/mutex.c
+++ b/sys/arch/hppa/hppa/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.4 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.5 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -56,6 +56,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+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;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/hppa64/hppa64/mutex.c b/sys/arch/hppa64/hppa64/mutex.c
index 0752b964669..8f9d5ebf9a4 100644
--- a/sys/arch/hppa64/hppa64/mutex.c
+++ b/sys/arch/hppa64/hppa64/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -54,6 +54,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+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;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/i386/i386/mutex.S b/sys/arch/i386/i386/mutex.S
index 9428e5b9e35..b82363e1779 100644
--- a/sys/arch/i386/i386/mutex.S
+++ b/sys/arch/i386/i386/mutex.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.S,v 1.6 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.S,v 1.7 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -88,6 +88,51 @@ ENTRY(mtx_enter)
call _C_LABEL(panic)
6: .asciz "mtx_enter: locking against myself"
#endif
+
+ENTRY(mtx_enter_try)
+ pushl %ebp
+ movl %esp, %ebp
+1: movl SOFF(%ebp), %ecx
+ movl MTX_WANTIPL(%ecx), %eax
+ movl CPL, %edx # oipl = cpl;
+ cmpl %edx, %eax # if (cpl < mtx->mtx_wantipl)
+ jle 2f
+ movl %eax, CPL # cpl = mtx->mtx_wantipl;
+2: /*
+ * %edx now contains the oldipl.
+ * %ecx contains the mtx.
+ */
+ movl $1, %eax
+ xchgl %eax, MTX_LOCK(%ecx) # test_and_set(mtx->mtx_lock)
+ testl %eax, %eax # if (already held)
+ jnz 3f
+ movl CPUVAR(SELF), %eax
+ movl %eax, MTX_OWNER(%ecx)
+ movl %edx, MTX_OLDIPL(%ecx)
+ movl $1, %eax
+ leave
+ ret
+
+ /* We failed to obtain the lock. splx and return zero. */
+3: pushl %edx
+ call _C_LABEL(splx)
+ movl %ebp, %esp
+ movl SOFF(%ebp), %ecx # %ecx clobbered
+#ifdef DIAGNOSTIC
+ movl CPUVAR(SELF), %edx
+ cmpl MTX_OWNER(%ecx), %edx
+ je 4f
+#endif
+ xorl %eax, %eax
+ leave
+ ret
+
+#ifdef DIAGNOSTIC
+4: pushl $5f
+ call _C_LABEL(panic)
+5: .asciz "mtx_enter: locking against myself"
+#endif
+
ENTRY(mtx_leave)
pushl %ebp
diff --git a/sys/arch/m68k/m68k/mutex.c b/sys/arch/m68k/m68k/mutex.c
index d15931ef804..60943202b0d 100644
--- a/sys/arch/m68k/m68k/mutex.c
+++ b/sys/arch/m68k/m68k/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -58,6 +58,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ if (mtx->mtx_wantipl != IPL_NONE)
+ mtx->mtx_oldipl = _splraise(IPLTOPSL(mtx->mtx_wantipl));
+ MUTEX_ASSERT_UNLOCKED(mtx);
+ mtx->mtx_lock = 1;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/m88k/m88k/mutex.S b/sys/arch/m88k/m88k/mutex.S
index 630805ca1be..78c3e2b9791 100644
--- a/sys/arch/m88k/m88k/mutex.S
+++ b/sys/arch/m88k/m88k/mutex.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.S,v 1.7 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.S,v 1.8 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2005, Miodrag Vallat.
@@ -126,6 +126,90 @@ enter_panic:
#endif /* MULTIPROCESSOR */
/*
+ * int mtx_enter_try(struct mutex *mtx)
+ */
+ENTRY(mtx_enter_try)
+ subu r31, r31, 8
+ st r1, r31, 4 /* save return address */
+
+#ifdef MULTIPROCESSOR
+
+ st r2, r31, 0 /* save mtx */
+enter_try_again:
+ ld r2, r2, MTX_WANTIPL
+ bcnd eq0, r2, 1f
+ bsr _C_LABEL(raiseipl) /* raiseipl(mtx->mtx_wantipl) */
+1:
+ ld r4, r31, 0
+ or r3, r0, 1
+ xmem r3, r4, r0 /* attempt to claim the lock, old */
+ bcnd ne0, r3, enter_try_failed /* mtx->mtx_lock is 0 if successful*/
+
+ ldcr r3, CPU
+ st r2, r4, MTX_OLDIPL /* save into mtx_oldipl */
+ st r3, r4, MTX_CPU /* mtx->mtx_cpu = curcpu() */
+
+ ld r1, r31, 4
+ or r2, r0, 1 /* return nonzero */
+ jmp.n r1
+ addu r31, r31, 8
+
+enter_try_failed: /* the lock is not ours... */
+ ld r3, r4, MTX_WANTIPL
+ bcnd eq0, r3, 2f
+ bcnd ne0, r2, 1f /* splx(oldipl) */
+ bsr.n _C_LABEL(spl0)
+ addu r1, r1, 2f - . - 4
+1:
+ bsr _C_LABEL(setipl)
+2:
+#ifdef DIAGNOSTIC
+ ld r2, r31, 0 /* restore mtx */
+ ldcr r3, CPU
+ ld r4, r2, MTX_CPU
+ cmp r5, r3, r4
+ bcnd eq0, r5, enter_try_panic
+#endif
+ or r2, r0, r0 /* return zero */
+ jmp.n r1
+ addu r31, r31, 8
+
+#ifdef DIAGNOSTIC
+enter_try_panic:
+ or.u r2, r0, hi16(9f)
+ bsr.n _C_LABEL(panic)
+ or r2, r2, lo16(9f)
+
+ data
+9:
+ string "mtx_enter_try: humpaan itsekseni"
+#endif
+
+#else /* MULTIPROCESSOR */
+
+ st r2, r31, 0 /* save mtx */
+ ld r2, r2, MTX_WANTIPL
+ bcnd eq0, r2, 1f
+ bsr _C_LABEL(raiseipl) /* raiseipl(mtx->mtx_wantipl) */
+1:
+ ld r4, r31, 0
+ ldcr r3, CPU
+ st r3, r4, MTX_LOCK /* locked! */
+
+ st r2, r4, MTX_OLDIPL /* save into mtx_oldipl */
+
+#ifdef DIAGNOSTIC /* necessary for MUTEX_ASSERT_LOCKED */
+ st r3, r4, MTX_CPU /* mtx->mtx_cpu = curcpu() */
+#endif
+
+ ld r1, r31, 4
+ or r2, r0, 1 /* return nonzero */
+ jmp.n r1
+ addu r31, r31, 8
+
+#endif /* MULTIPROCESSOR */
+
+/*
* void mtx_leave(struct mutex *mtx)
*/
ENTRY(mtx_leave)
diff --git a/sys/arch/powerpc/powerpc/mutex.S b/sys/arch/powerpc/powerpc/mutex.S
index 06279171751..079d50aa3b2 100644
--- a/sys/arch/powerpc/powerpc/mutex.S
+++ b/sys/arch/powerpc/powerpc/mutex.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.S,v 1.9 2009/06/09 01:12:38 deraadt Exp $ */
+/* $OpenBSD: mutex.S,v 1.10 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2007 Dale Rahn
@@ -83,6 +83,61 @@ ENTRY(mtx_enter)
#endif
+ENTRY(mtx_enter_try)
+ stwu %r1,-32(%r1) # reserve stack
+ mflr %r0
+ stw %r0,36(%r1) # save return address
+ GET_CPUINFO(%r4)
+ lwz %r5,MTX_WANTIPL(%r3) # load new ipl
+ lis %r6,_C_LABEL(imask)@ha # convert into cpl
+ slwi %r5,%r5,2
+ addi %r5,%r5,_C_LABEL(imask)@l
+ lwzx %r5,%r5,%r6
+ lwz %r7,CI_CPL(%r4) # load current cpl
+ or %r6,%r5,%r7 # raise cpl
+ stw %r6,CI_CPL(%r4) # store new cpl
+ li %r5,MTX_OWNER # load offset constant
+ lwarx %r6,%r5,%r3 # load reserve owner
+ cmpwi 0,%r6,0 # test owner == 0
+ beq+ 0,.L_mutex_try_free # if owner == 0 branch free
+.L_mutex_try_locked:
+#ifdef DIAGNOSTIC
+ cmpl 0,%r4,%r6
+ beq- .L_mutex_try_selflocked
+#endif
+ stw %r3,28(%r1) # save mtx during lcsplx
+ la %r4,28(%r1)
+ stwcx. %r3,0,%r4 # unreserve owner
+ mr %r3,%r7 # move old cpl to arg0
+ bl _C_LABEL(lcsplx) # call splx on old cpl
+
+ lwz %r0,36(%r1) # load return address
+ mtlr %r0
+ addi %r1,%r1,32 # restore stack
+ li %r2,0 # return zero
+ blr
+
+.L_mutex_try_free:
+ stwcx. %r4,%r5,%r3 # old owner was 0 cond store
+ bne- .L_mutex_try_locked # branch if reserve cancelled
+ stw %r7,MTX_OLDCPL(%r3) # save old ipl
+ lwz %r0,36(%r1) # load return address
+ mtlr %r0
+ addi %r1,%r1,32 # restore stack
+ li %r2,1 # return nonzero
+ blr
+
+#ifdef DIAGNOSTIC
+.L_mutex_try_selflocked:
+ mr %r5, %r3
+ lis %r3,.L_panictrylocked@ha
+ la %r3,.L_panictrylocked@l(%r3)
+ bl panic
+.L_panictrylocked:
+ .string "mtx_enter_try: recursed %x %x\n"
+#endif
+
+
ENTRY(mtx_leave)
#ifdef DIAGNOSTIC
lwz %r6,MTX_OWNER(%r3)
diff --git a/sys/arch/sgi/sgi/mutex.c b/sys/arch/sgi/sgi/mutex.c
index b13f3104921..687f0cb1486 100644
--- a/sys/arch/sgi/sgi/mutex.c
+++ b/sys/arch/sgi/sgi/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.4 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.5 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -58,6 +58,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ if (mtx->mtx_wantipl != IPL_NONE)
+ mtx->mtx_oldipl = splraise(imask[mtx->mtx_wantipl]);
+ MUTEX_ASSERT_UNLOCKED(mtx);
+ mtx->mtx_lock = 1;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/sh/sh/mutex.c b/sys/arch/sh/sh/mutex.c
index 591b434417f..66f08391e9b 100644
--- a/sys/arch/sh/sh/mutex.c
+++ b/sys/arch/sh/sh/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -57,6 +57,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ if (mtx->mtx_wantipl != IPL_NONE)
+ mtx->mtx_oldipl = _cpu_intr_raise(mtx->mtx_wantipl);
+ MUTEX_ASSERT_UNLOCKED(mtx);
+ mtx->mtx_lock = 1;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/sparc/sparc/mutex.c b/sys/arch/sparc/sparc/mutex.c
index 98880e1e509..33605dcf826 100644
--- a/sys/arch/sparc/sparc/mutex.c
+++ b/sys/arch/sparc/sparc/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -63,6 +63,24 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ int psr;
+
+ if (mtx->mtx_wantipl != IPL_NONE << 8) {
+ psr = getpsr();
+ mtx->mtx_oldipl = psr & PSR_PIL;
+ if (mtx->mtx_oldipl < mtx->mtx_wantipl)
+ setpsr((psr & ~PSR_PIL) | mtx->mtx_wantipl);
+ }
+
+ MUTEX_ASSERT_UNLOCKED(mtx);
+ mtx->mtx_lock = 1;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/arch/sparc64/sparc64/mutex.S b/sys/arch/sparc64/sparc64/mutex.S
index c7d085cdced..5ae4267c361 100644
--- a/sys/arch/sparc64/sparc64/mutex.S
+++ b/sys/arch/sparc64/sparc64/mutex.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.S,v 1.5 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.S,v 1.6 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2007 Mark Kettenis
@@ -75,6 +75,33 @@ ENTRY(mtx_enter)
retl
membar #LoadLoad | #LoadStore
+ENTRY(mtx_enter_try)
+ rdpr %pil, %g4
+ GET_CURCPU(%g1)
+1:
+ ld [%o0 + MTX_WANTIPL], %g5
+ bge 2f
+ nop
+ wrpr %g5, %pil
+2:
+ mov %g1, %g5
+/*
+ * The assembler doesn't like the next line, even if MTX_OWNER is 0.
+ */
+! casx [%o0 + MTX_OWNER], %g0, %g5
+ casx [%o0], %g0, %g5
+ tst %g5
+ be 3f
+ nop
+ wrpr %g4, %pil
+ retl
+ mov 0, %o0
+3:
+ stw %g4, [%o0 + MTX_OLDIPL]
+ membar #LoadLoad | #LoadStore
+ retl
+ mov 1, %o0
+
ENTRY(mtx_leave)
ld [%o0 + MTX_OLDIPL], %g1
membar #StoreStore | #LoadStore
diff --git a/sys/arch/vax/vax/mutex.c b/sys/arch/vax/vax/mutex.c
index 28e30677000..4b1ba96ae0e 100644
--- a/sys/arch/vax/vax/mutex.c
+++ b/sys/arch/vax/vax/mutex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.c,v 1.3 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.c,v 1.4 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -57,6 +57,17 @@ mtx_enter(struct mutex *mtx)
mtx->mtx_lock = 1;
}
+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;
+
+ return 1;
+}
+
void
mtx_leave(struct mutex *mtx)
{
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index 76f4e00f22e..227470f5d70 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.h,v 1.6 2009/04/27 21:48:56 kettenis Exp $ */
+/* $OpenBSD: mutex.h,v 1.7 2009/08/13 13:24:55 weingart Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -52,5 +52,6 @@ void mtx_init(struct mutex *, int);
#endif
void mtx_enter(struct mutex *);
void mtx_leave(struct mutex *);
+int mtx_enter_try(struct mutex *);
#endif