summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-07-24 23:51:33 +0000
committerfsmp <fsmp@FreeBSD.org>1997-07-24 23:51:33 +0000
commit651e67a9c67ef527612e2216690de7138e458e5d (patch)
treea43df339543e83fa791971e95b8d11b18cceadb2
parent176a721ba4efc03de1362d80f5d54cedda5dfe38 (diff)
downloadFreeBSD-src-651e67a9c67ef527612e2216690de7138e458e5d.zip
FreeBSD-src-651e67a9c67ef527612e2216690de7138e458e5d.tar.gz
simplelock functions removed from apic_ipl.s.
ASM optimization by: Bruce Evans <bde@zeta.org.au>
-rw-r--r--sys/i386/i386/simplelock.s145
1 files changed, 145 insertions, 0 deletions
diff --git a/sys/i386/i386/simplelock.s b/sys/i386/i386/simplelock.s
new file mode 100644
index 0000000..9d5226d
--- /dev/null
+++ b/sys/i386/i386/simplelock.s
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 1997, by Steve Passe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the developer may NOT be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * credit to Bruce Evans <bde@zeta.org.au> for help with asm optimization.
+ */
+
+#include <machine/asmacros.h> /* miscellaneous macros */
+
+
+/*
+ * The following impliments the primitives described in i386/i386/param.h
+ * necessary for the Lite2 lock manager system.
+ */
+
+/*
+ * The simple-lock routines are the primitives out of which the lock
+ * package is built. The machine-dependent code must implement an
+ * atomic test_and_set operation that indivisibly sets the simple lock
+ * to non-zero and returns its old value. It also assumes that the
+ * setting of the lock to zero below is indivisible. Simple locks may
+ * only be used for exclusive locks.
+ *
+ * struct simplelock {
+ * int lock_data;
+ * };
+ */
+
+/*
+ * void
+ * s_lock_init(struct simplelock *lkp)
+ * {
+ * lkp->lock_data = 0;
+ * }
+ */
+ENTRY(s_lock_init)
+ movl 4(%esp), %eax /* get the address of the lock */
+ movl $0, (%eax)
+ ret
+
+
+/*
+ * void
+ * s_lock(__volatile struct simplelock *lkp)
+ * {
+ * while (test_and_set(&lkp->lock_data))
+ * continue;
+ * }
+ *
+ * Note:
+ * If the acquire fails we do a loop of reads waiting for the lock to
+ * become free instead of continually beating on the lock with btsl.
+ * The theory here is that the CPU will stay within its cache until
+ * a write by the other CPU updates it, instead of continually updating
+ * the local cache (and thus causing external bus writes) with repeated
+ * writes to the lock.
+ */
+ENTRY(s_lock)
+ movl 4(%esp), %eax /* get the address of the lock */
+ movl $1, %ecx
+setlock:
+ xchgl %ecx, (%eax)
+ testl %ecx, %ecx
+ jz gotit /* it was clear, return */
+wait:
+ cmpl $0, (%eax) /* wait to empty */
+ jne wait /* still set... */
+ jmp setlock /* empty again, try once more */
+gotit:
+ ret
+
+
+/*
+ * int
+ * s_lock_try(__volatile struct simplelock *lkp)
+ * {
+ * return (!test_and_set(&lkp->lock_data));
+ * }
+ */
+ENTRY(s_lock_try)
+ movl 4(%esp), %eax /* get the address of the lock */
+ movl $1, %ecx
+
+ xchgl %ecx, (%eax)
+ testl %ecx, %ecx
+ setz %al /* 1 if previous value was 0 */
+ movzbl %al, %eax /* convert to an int */
+
+ ret
+
+
+/*
+ * void
+ * s_unlock(__volatile struct simplelock *lkp)
+ * {
+ * lkp->lock_data = 0;
+ * }
+ */
+ENTRY(s_unlock)
+ movl 4(%esp), %eax /* get the address of the lock */
+ movl $0, (%eax)
+ ret
+
+
+#ifdef needed
+
+/*
+ * test_and_set(struct simplelock *lkp);
+ */
+ENTRY(test_and_set)
+ movl 4(%esp), %eax /* get the address of the lock */
+ movl $1, %ecx
+
+ xchgl %ecx, (%eax)
+ testl %ecx, %ecx
+ setz %al /* 1 if previous value was 0 */
+ movzbl %al, %eax /* convert to an int */
+
+ ret
+
+#endif /* needed */
OpenPOWER on IntegriCloud