diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-12-23 18:50:24 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-12-23 18:50:24 +0000 |
commit | 009efda1e9489a8fbcb939a697474885db674e46 (patch) | |
tree | ac114ca3984979afc9350d1dcdd6d4a6f3c3dc1c | |
parent | 1e399dbf1c0d9f551cd3a7bcbb1ce778b8795c3e (diff) |
m68k support code for librthread; atomic lock routine borrowed from the
existing libpthread code.
-rw-r--r-- | lib/librthread/arch/m68k/_atomic_lock.c | 36 | ||||
-rw-r--r-- | lib/librthread/arch/m68k/rfork_thread.S | 70 |
2 files changed, 106 insertions, 0 deletions
diff --git a/lib/librthread/arch/m68k/_atomic_lock.c b/lib/librthread/arch/m68k/_atomic_lock.c new file mode 100644 index 00000000000..30f079c6204 --- /dev/null +++ b/lib/librthread/arch/m68k/_atomic_lock.c @@ -0,0 +1,36 @@ +/* $OpenBSD: _atomic_lock.c,v 1.1 2005/12/23 18:50:23 miod Exp $ */ +/* + * Atomic lock for m68k + */ + +#include "spinlock.h" + +int +_atomic_lock(volatile _spinlock_lock_t *lock) +{ + _spinlock_lock_t old; + + /* + * The Compare And Swap instruction (mc68020 and above) + * compares its first operand with the memory addressed by + * the third. If they are the same value, the second operand + * is stored at the address. Otherwise the 1st operand (register) + * is loaded with the contents of the 3rd operand. + * + * old = 0; + * CAS(old, 1, *lock); + * if (old == 1) { lock was acquired } + * + * From the MC68030 User's Manual (Motorola), page `3-13': + * CAS Dc,Du,<ea>: + * (<ea> - Dc) -> cc; + * if Z then Du -> <ea> + * else <ea> -> Dc; + */ + old = _SPINLOCK_UNLOCKED; + __asm__("casl %0, %2, %1" : "=d" (old), "=m" (*lock) + : "d" (_SPINLOCK_LOCKED), + "0" (old), "1" (*lock) + : "cc"); + return (old != _SPINLOCK_UNLOCKED); +} diff --git a/lib/librthread/arch/m68k/rfork_thread.S b/lib/librthread/arch/m68k/rfork_thread.S new file mode 100644 index 00000000000..e9b37eb2f8f --- /dev/null +++ b/lib/librthread/arch/m68k/rfork_thread.S @@ -0,0 +1,70 @@ +/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/23 18:50:23 miod Exp $ */ + +/* + * Copyright (c) 2005, Miodrag Vallat + * + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +#include "../../../libc/arch/m68k/SYS.h" + +/* + * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + */ +ENTRY(rfork_thread) + /* + * Set up the new thread's stack. + */ + movl sp@(8), a0 /* stack */ + movl sp@(16), a0@- /* arg */ + movl sp@(12), a1 /* func */ + + /* + * We did not create a frame, so the stack is ready for an immediate + * system call invocation. + */ + __DO_SYSCALL(rfork) + jcs 9f + + tstl d0 + jeq 1f + + /* + * parent process: just return. + */ + rts + +1: + /* + * child process: switch stacks, invoke function, then exit. + */ + movl a0, sp /* stack with arg pushed on it */ + jsr a1@ /* func */ + addq #4, sp + + __DO_SYSCALL(threxit) + +9: + /* + * system call failure. + */ + jra __cerror |