From 74aad02bacc0789b77be30effb26121dedbd9f1a Mon Sep 17 00:00:00 2001 From: beveloper Date: Wed, 20 Aug 2003 02:13:45 +0000 Subject: [PATCH] SH4 needs atomic operations to be implemented as syscalls, other architecture can do this better. Removed from generic cpu.c file. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4330 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/arch/sh4/arch_atomic.c | 148 +++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/kernel/core/arch/sh4/arch_atomic.c diff --git a/src/kernel/core/arch/sh4/arch_atomic.c b/src/kernel/core/arch/sh4/arch_atomic.c new file mode 100644 index 0000000000..2efee59044 --- /dev/null +++ b/src/kernel/core/arch/sh4/arch_atomic.c @@ -0,0 +1,148 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#include + + +int32 +user_atomic_add(vint32 *uval, int32 incr) +{ + int32 val; + int32 ret; + + if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP) + goto error; + + if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0) + goto error; + + // XXX broken on non SH4-systems, or when interrupts are enabled + // XXX x86 must use the assembly functions directly in userspace and not this ones + ret = val; + val += incr; + + if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0) + goto error; + + return ret; + +error: + // XXX kill the app + return -1; +} + + +int32 +user_atomic_and(vint32 *uval, int32 incr) +{ + int val; + int ret; + + if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP) + goto error; + + if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0) + goto error; + + // XXX broken on non SH4-systems, or when interrupts are enabled + // XXX x86 must use the assembly functions directly in userspace and not this ones + ret = val; + val &= incr; + + if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0) + goto error; + + return ret; + +error: + // XXX kill the app + return -1; +} + + +int32 +user_atomic_or(vint32 *uval, int32 incr) +{ + int val; + int ret; + + if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP) + goto error; + + if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0) + goto error; + + // XXX broken on non SH4-systems, or when interrupts are enabled + // XXX x86 must use the assembly functions directly in userspace and not this ones + ret = val; + val |= incr; + + if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0) + goto error; + + return ret; + +error: + // XXX kill the app + return -1; +} + + +int32 +user_atomic_set(vint32 *uval, int32 set_to) +{ + int val; + int ret; + + if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP) + goto error; + + if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0) + goto error; + + // XXX broken on non SH4-systems, or when interrupts are enabled + // XXX x86 must use the assembly functions directly in userspace and not this ones + ret = val; + val = set_to; + + if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0) + goto error; + + return ret; + +error: + // XXX kill the app + return -1; +} + + +int32 +user_atomic_test_and_set(vint32 *uval, int32 set_to, int32 test_val) +{ + int val; + int ret; + + if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP) + goto error; + + if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0) + goto error; + + // XXX broken on non SH4-systems, or when interrupts are enabled + // XXX x86 must use the assembly functions directly in userspace and not this ones + ret = val; + if (val == test_val) { + val = set_to; + if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0) + goto error; + } + + return ret; + +error: + // XXX kill the app + return -1; +} +