diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-12-25 16:00:03 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-12-25 16:00:03 +0000 |
commit | 3fbe984ca9978e039ef1d4c0ae1dbb5a874d23f8 (patch) | |
tree | bb859abaf09bb43573bf0fb789b1487ed7a27a8d /lib/librthread | |
parent | b4a39cb462aa7f31d401dc503c3a8a222db61aad (diff) |
sparc support code for librthread (_atomic_lock yanked from existing
libpthread code).
Diffstat (limited to 'lib/librthread')
-rw-r--r-- | lib/librthread/arch/sparc/_atomic_lock.c | 41 | ||||
-rw-r--r-- | lib/librthread/arch/sparc/rfork_thread.S | 73 |
2 files changed, 114 insertions, 0 deletions
diff --git a/lib/librthread/arch/sparc/_atomic_lock.c b/lib/librthread/arch/sparc/_atomic_lock.c new file mode 100644 index 00000000000..c791314c8d1 --- /dev/null +++ b/lib/librthread/arch/sparc/_atomic_lock.c @@ -0,0 +1,41 @@ +/* $OpenBSD: _atomic_lock.c,v 1.1 2005/12/25 16:00:02 miod Exp $ */ +/* + * Atomic lock for sparc + */ + +#include <machine/spinlock.h> + +int +_atomic_lock(volatile _spinlock_lock_t * lock) +{ + _spinlock_lock_t old; + + /* + * " ldstub [address], reg_rd + * + * The atomic load-store instructions copy a byte from memory + * into r[rd]m then rewrite the addressed byte in memory to all + * ones [_SPINLOCK_LOCKED]. The operation is performed + * atomically, that is, without allowing intervening interrupts + * or deferred traps. In a multiprocessor system, two or more + * processors executing atomic load-store unsigned byte [...] + * addressing the same byte [...] simultaneously are guaranteed + * to execute them in an undefined, but serial order." + * - p101, The SPARC Architecture Manual (version 8) Prentice-Hall + * + * "LDSTUB loads a byte value from memory to a register and writes + * the value FF_16 into the addressed byte atomically. LDSTUB + * is the classic test-and-set instruction. Like SWAP, it has + * a consensus number of two and so cannot resolve more than + * two contending processes in a wait-free fashion." + * - p129, The SPARC Architecture Manual (version 9) Prentice-Hall + * (See also section J.6 (spinlocks)) + * + * (No change to the condition codes are documented.) + */ + __asm__("ldstub %0,%1" + : "=m" (*lock), "=r" (old) + : "0" (*lock)); + + return (old == _SPINLOCK_LOCKED); +} diff --git a/lib/librthread/arch/sparc/rfork_thread.S b/lib/librthread/arch/sparc/rfork_thread.S new file mode 100644 index 00000000000..a7dc8135e88 --- /dev/null +++ b/lib/librthread/arch/sparc/rfork_thread.S @@ -0,0 +1,73 @@ +/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/25 16:00:02 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/sparc/SYS.h" + +/* + * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + */ +ENTRY(rfork_thread) + mov %o1, %o4 /* save stack */ + + /* + * We can not invoke rfork as a G2-style system call since we want + * different return paths. + */ + mov SYS_rfork, %g1 + t ST_SYSCALL + bcs 9f + nop + + cmp %o0, 0 + be 1f + nop + + /* + * In parent process: just return. + */ + retl + nop + +1: + /* + * In child process: switch stack, invoke function, then exit. + * Don't forget to allocate room for a window save on the new + * stack! + */ + sub %o4, 64, %sp /* stack */ + call %o2 /* func */ + mov %o3, %o0 /* arg */ + + mov SYS_threxit, %g1 + clr %o0 + t ST_SYSCALL /* will not return */ + +9: + /* + * System call failure. + */ + ERROR() |