From 50e0ce4bee6c6c87242a30935f4f9f855afa02bd Mon Sep 17 00:00:00 2001 From: beveloper Date: Thu, 21 Aug 2003 23:02:00 +0000 Subject: [PATCH] Implemented new syscalls for 32 and 64 bit atomic operations. They are only used if the architecture doesn't support them directly. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4360 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/ppc/arch_cpu.h | 2 + headers/private/kernel/arch/sh4/arch_cpu.h | 2 +- headers/private/kernel/arch/sh4/atomic.h | 65 ------ headers/private/kernel/ksyscalls.h | 24 +- headers/private/kernel/syscalls.h | 19 +- headers/private/kernel/user_atomic.h | 26 +++ src/kernel/core/arch/ppc/Jamfile | 1 + src/kernel/core/arch/ppc/arch_atomic.c | 245 +++++++++++++++++++++ src/kernel/core/syscalls.c | 68 ++++-- src/kernel/libroot/os/Jamfile | 1 + src/kernel/libroot/os/arch/sh4/atomic.c | 32 --- src/kernel/libroot/os/atomic.c | 86 ++++++++ src/kernel/libroot/os/syscalls.S | 20 +- 13 files changed, 453 insertions(+), 138 deletions(-) delete mode 100644 headers/private/kernel/arch/sh4/atomic.h create mode 100644 headers/private/kernel/user_atomic.h create mode 100644 src/kernel/core/arch/ppc/arch_atomic.c delete mode 100644 src/kernel/libroot/os/arch/sh4/atomic.c create mode 100644 src/kernel/libroot/os/atomic.c diff --git a/headers/private/kernel/arch/ppc/arch_cpu.h b/headers/private/kernel/arch/ppc/arch_cpu.h index 5537ef29bd..0800c4bc70 100644 --- a/headers/private/kernel/arch/ppc/arch_cpu.h +++ b/headers/private/kernel/arch/ppc/arch_cpu.h @@ -12,6 +12,8 @@ #define _BIG_ENDIAN 1 #define _LITTLE_ENDIAN 0 +#define ATOMIC64_FUNCS_ARE_SYSCALLS 1 + struct iframe { }; diff --git a/headers/private/kernel/arch/sh4/arch_cpu.h b/headers/private/kernel/arch/sh4/arch_cpu.h index 850348bff3..449c4c6082 100644 --- a/headers/private/kernel/arch/sh4/arch_cpu.h +++ b/headers/private/kernel/arch/sh4/arch_cpu.h @@ -1,6 +1,6 @@ /* ** Copyright 2003, Marcus Overhagen. All rights reserved. -** Distributed under the terms of the NewOS License. +** Distributed under the terms of the OpenBeOS license. */ #ifndef _KERNEL_ARCH_CPU_H #define _KERNEL_ARCH_CPU_H diff --git a/headers/private/kernel/arch/sh4/atomic.h b/headers/private/kernel/arch/sh4/atomic.h deleted file mode 100644 index c7243f3b8c..0000000000 --- a/headers/private/kernel/arch/sh4/atomic.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _KERNEL_ATOMIC_H -#define _KERNEL_ATOMIC_H - -#include - -/** - * @file kernel/atomic.h - * @brief Prototypes for kernel and user versions of atomic - * functions. - */ - -/** - * @defgroup Kernel_Atomic Atomic Operations - * @ingroup OpenBeOS_Kernel - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* atomic_add(), atomic_and(), atomic_or() must - * match the definitions in SupportDefs.h - */ - -/** - * Atomic add (user version) - * @param val Pointer to an integer - * @param incr The increment to add (may be -ve) - * @note Returns value of val before addition - */ -int32 user_atomic_add(vint32 *val, int32 incr); - -/** - * Atomic and (user version) - * @param val Pointer to an integer - * @param incr The increment to add (may be -ve) - * @note Returns value of val before addition - */ -int32 user_atomic_and(vint32 *val, int32 incr); - -/** - * Atomic or (user version) - * @param val Pointer to an integer - * @param incr The increment to add (may be -ve) - * @note Returns value of val before addition - */ -int32 user_atomic_or(vint32 *val, int32 incr); - -int32 user_atomic_set(vint32 *val, int32 set_to); - -/* Compare the value of val with test_val. If they - * are equal then set the value of 'val' to - * 'set_to' - * @note This is the user version and should not be used within - * the kernel. - */ -int32 user_atomic_test_and_set(vint32 *val, int32 set_to, int32 test_val); - -#ifdef __cplusplus -} -#endif -/** @} */ - -#endif /* _KERNEL_ATOMIC_H */ \ No newline at end of file diff --git a/headers/private/kernel/ksyscalls.h b/headers/private/kernel/ksyscalls.h index 1f3999c05f..12583a2536 100755 --- a/headers/private/kernel/ksyscalls.h +++ b/headers/private/kernel/ksyscalls.h @@ -75,11 +75,11 @@ enum { SYSCALL_GET_PROC_TABLE, SYSCALL_GETRLIMIT, SYSCALL_SETRLIMIT, - SYSCALL_ATOMIC_ADD, - SYSCALL_ATOMIC_AND, - SYSCALL_ATOMIC_OR, - SYSCALL_ATOMIC_SET, - SYSCALL_TEST_AND_SET, /* 70 */ + SYSCALL_unused_66, + SYSCALL_unused_67, + SYSCALL_unused_68, + SYSCALL_unused_69, + SYSCALL_unused_70, /* 70 */ SYSCALL_SYSCTL, SYSCALL_SOCKET, SYSCALL_ACCESS, @@ -113,7 +113,7 @@ enum { SYSCALL_REMOVE_ATTR, SYSCALL_RENAME_ATTR, SYSCALL_RETURN_FROM_SIGNAL, - SYSCALL_KILL, // obsolete + SYSCALL_unused_104, SYSCALL_SIGACTION, /* 105 */ SYSCALL_OPEN_INDEX_DIR, SYSCALL_CREATE_INDEX, @@ -135,6 +135,18 @@ enum { SYSCALL_SET_AREA_PROTECTION, SYSCALL_RESIZE_AREA, SYSCALL_AREA_FOR, /* 125 */ + SYSCALL_ATOMIC_SET, + SYSCALL_ATOMIC_TEST_AND_SET, + SYSCALL_ATOMIC_ADD, + SYSCALL_ATOMIC_AND, + SYSCALL_ATOMIC_OR, /* 130 */ + SYSCALL_ATOMIC_READ, + SYSCALL_ATOMIC_SET64, + SYSCALL_ATOMIC_TEST_AND_SET64, + SYSCALL_ATOMIC_ADD64, + SYSCALL_ATOMIC_AND64, /* 135 */ + SYSCALL_ATOMIC_OR64, + SYSCALL_ATOMIC_READ64, }; int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret); diff --git a/headers/private/kernel/syscalls.h b/headers/private/kernel/syscalls.h index b47a685442..3f840f7ea6 100644 --- a/headers/private/kernel/syscalls.h +++ b/headers/private/kernel/syscalls.h @@ -108,12 +108,19 @@ int sys_port_set_owner(port_id port, team_id team); int sys_port_write(port_id port, int32 msg_code, const void *msg_buffer, size_t buffer_size); int sys_port_write_etc(port_id port, int32 msg_code, const void *msg_buffer, size_t buffer_size, uint32 flags, bigtime_t timeout); -/* atomic_* ops (needed for cpus that dont support them directly) */ -int sys_atomic_add(int *val, int incr); -int sys_atomic_and(int *val, int incr); -int sys_atomic_or(int *val, int incr); -int sys_atomic_set(int *val, int set_to); -int sys_test_and_set(int *val, int set_to, int test_val); +/* atomic_* ops (needed for CPUs that don't support them directly) */ +int32 _kern_atomic_set(vint32 *value, int32 newValue); +int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst); +int32 _kern_atomic_add(vint32 *value, int32 addValue); +int32 _kern_atomic_and(vint32 *value, int32 andValue); +int32 _kern_atomic_or(vint32 *value, int32 orValue); +int32 _kern_atomic_read(vint32 *value); +int64 _kern_atomic_set64(vint64 *value, int64 newValue); +int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst); +int64 _kern_atomic_add64(vint64 *value, int64 addValue); +int64 _kern_atomic_and64(vint64 *value, int64 andValue); +int64 _kern_atomic_or64(vint64 *value, int64 orValue); +int64 _kern_atomic_read64(vint64 *value); int sys_sysctl(int *, uint, void *, size_t *, void *, size_t); int sys_socket(int, int, int); diff --git a/headers/private/kernel/user_atomic.h b/headers/private/kernel/user_atomic.h new file mode 100644 index 0000000000..b50a49b965 --- /dev/null +++ b/headers/private/kernel/user_atomic.h @@ -0,0 +1,26 @@ +/* +** Copyright 2003, Marcus Overhagen. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef _KERNEL_USER_ATOMIC_H +#define _KERNEL_USER_ATOMIC_H + +/* If the architecture doesn't support atomic functions + * in userspace, they are implemented as these syscalls. + */ + +int32 user_atomic_set(vint32 *value, int32 newValue); +int32 user_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst); +int32 user_atomic_add(vint32 *value, int32 addValue); +int32 user_atomic_and(vint32 *value, int32 andValue); +int32 user_atomic_or(vint32 *value, int32 orValue); +int32 user_atomic_read(vint32 *value); + +int64 user_atomic_set64(vint64 *value, int64 newValue); +int64 user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst); +int64 user_atomic_add64(vint64 *value, int64 addValue); +int64 user_atomic_and64(vint64 *value, int64 andValue); +int64 user_atomic_or64(vint64 *value, int64 orValue); +int64 user_atomic_read64(vint64 *value); + +#endif /* _KERNEL_USER_ATOMIC_H */ diff --git a/src/kernel/core/arch/ppc/Jamfile b/src/kernel/core/arch/ppc/Jamfile index 7314e7f02b..b9573ebc60 100644 --- a/src/kernel/core/arch/ppc/Jamfile +++ b/src/kernel/core/arch/ppc/Jamfile @@ -1,6 +1,7 @@ SubDir OBOS_TOP src kernel core arch ppc ; KernelStaticLibrary libppc : + <$(SOURCE_GRIST)>arch_atomic.c <$(SOURCE_GRIST)>arch_cpu.c <$(SOURCE_GRIST)>arch_dbg_console.c <$(SOURCE_GRIST)>arch_debug.c diff --git a/src/kernel/core/arch/ppc/arch_atomic.c b/src/kernel/core/arch/ppc/arch_atomic.c new file mode 100644 index 0000000000..f2cc4a1d74 --- /dev/null +++ b/src/kernel/core/arch/ppc/arch_atomic.c @@ -0,0 +1,245 @@ +/* + * Copyright 2003, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the OpenBeOS License. + */ + +#include +#include + +/* + * Emulation of 64 bit atomic functions. + * Slow, using spinlocks... + */ + +static spinlock kernel_lock = 0; +static spinlock user_lock = 0; + +int64 +atomic_set64(vint64 *value, int64 newValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + *value = newValue; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + if (*value == testAgainst) + *value = newValue; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +atomic_add64(vint64 *value, int64 addValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + *value += addValue; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +atomic_and64(vint64 *value, int64 andValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + *value &= andValue; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +atomic_or64(vint64 *value, int64 orValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + *value |= orValue; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +atomic_read64(vint64 *value) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&kernel_lock); + oldValue = *value; + release_spinlock(&kernel_lock); + restore_interrupts(status); + return oldValue; +} + +int64 +user_atomic_set64(vint64 *value, int64 newValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + if (user_memcpy(value, &newValue, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} + +int64 +user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + if (oldValue == testAgainst) + if (user_memcpy(value, &newValue, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} + +int64 +user_atomic_add64(vint64 *value, int64 addValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + addValue += oldValue; + if (user_memcpy(value, &addValue, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} + +int64 +user_atomic_and64(vint64 *value, int64 andValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + andValue &= oldValue; + if (user_memcpy(value, &andValue, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} + +int64 +user_atomic_or64(vint64 *value, int64 orValue) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + orValue |= oldValue; + if (user_memcpy(value, &orValue, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} + +int64 +user_atomic_read64(vint64 *value) +{ + cpu_status status; + int64 oldValue; + status = disable_interrupts(); + acquire_spinlock(&user_lock); + if ((addr)value < KERNEL_BASE || (addr)value > (KERNEL_TOP - 8)) + goto error; + if (user_memcpy(&oldValue, value, 8) < 0) + goto error; + release_spinlock(&user_lock); + restore_interrupts(status); + return oldValue; + +error: + release_spinlock(&user_lock); + restore_interrupts(status); + // XXX kill application + return -1; +} diff --git a/src/kernel/core/syscalls.c b/src/kernel/core/syscalls.c index 5c957511e6..a251855d5f 100644 --- a/src/kernel/core/syscalls.c +++ b/src/kernel/core/syscalls.c @@ -26,10 +26,7 @@ #include #include #include - -#ifdef ATOMIC_FUNCS_ARE_SYSCALLS -#include -#endif +#include #define INT32TOINT64(x, y) ((int64)(x) | ((int64)(y) << 32)) @@ -375,24 +372,6 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re *call_ret = user_setrlimit((int)arg0, (const struct rlimit *)arg1); break; -#ifdef ATOMIC_FUNCS_ARE_SYSCALLS - case SYSCALL_ATOMIC_ADD: - *call_ret = user_atomic_add((int32 *)arg0, (int32)arg1); - break; - case SYSCALL_ATOMIC_AND: - *call_ret = user_atomic_and((int32 *)arg0, (int32)arg1); - break; - case SYSCALL_ATOMIC_OR: - *call_ret = user_atomic_or((int32 *)arg0, (int32)arg1); - break; - case SYSCALL_ATOMIC_SET: - *call_ret = user_atomic_set((int32 *)arg0, (int32)arg1); - break; - case SYSCALL_TEST_AND_SET: - *call_ret = user_test_and_set((int32 *)arg0, (int32)arg1, (int32)arg2); - break; -#endif - // image calls case SYSCALL_REGISTER_IMAGE: *call_ret = user_register_image((image_info *)arg0, (size_t)arg1); @@ -458,6 +437,51 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re case SYSCALL_SET_ALARM: *call_ret = user_set_alarm((bigtime_t)INT32TOINT64(arg0, arg1), (uint32)arg2); break; + + // 32 bit atomic functions +#ifdef ATOMIC_FUNCS_ARE_SYSCALLS + case SYSCALL_ATOMIC_SET: + *call_ret = user_atomic_set((int32 *)arg0, (int32)arg1); + break; + case SYSCALL_ATOMIC_TEST_AND_SET: + *call_ret = user_atomic_test_and_set((int32 *)arg0, (int32)arg1, (int32)arg2); + break; + case SYSCALL_ATOMIC_ADD: + *call_ret = user_atomic_add((int32 *)arg0, (int32)arg1); + break; + case SYSCALL_ATOMIC_AND: + *call_ret = user_atomic_and((int32 *)arg0, (int32)arg1); + break; + case SYSCALL_ATOMIC_OR: + *call_ret = user_atomic_or((int32 *)arg0, (int32)arg1); + break; + case SYSCALL_ATOMIC_READ: + *call_ret = user_atomic_read((int32 *)arg0); + break; +#endif + + // 64 bit atomic functions +#ifdef ATOMIC64_FUNCS_ARE_SYSCALLS + case SYSCALL_ATOMIC_SET64: + *call_ret = user_atomic_set64((int64 *)arg0, INT32TOINT64(arg1, arg2)); + break; + case SYSCALL_ATOMIC_TEST_AND_SET64: + *call_ret = user_atomic_test_and_set64((int64 *)arg0, INT32TOINT64(arg1, arg2), INT32TOINT64(arg3, arg4)); + break; + case SYSCALL_ATOMIC_ADD64: + *call_ret = user_atomic_add64((int64 *)arg0, INT32TOINT64(arg1, arg2)); + break; + case SYSCALL_ATOMIC_AND64: + *call_ret = user_atomic_and64((int64 *)arg0, INT32TOINT64(arg1, arg2)); + break; + case SYSCALL_ATOMIC_OR64: + *call_ret = user_atomic_or64((int64 *)arg0, INT32TOINT64(arg1, arg2)); + break; + case SYSCALL_ATOMIC_READ64: + *call_ret = user_atomic_read64((int64 *)arg0); + break; +#endif + default: *call_ret = -1; } diff --git a/src/kernel/libroot/os/Jamfile b/src/kernel/libroot/os/Jamfile index dd35b69f46..c918d3f520 100644 --- a/src/kernel/libroot/os/Jamfile +++ b/src/kernel/libroot/os/Jamfile @@ -2,6 +2,7 @@ SubDir OBOS_TOP src kernel libroot os ; KernelMergeObject os_main.o : <$(SOURCE_GRIST)>area.c + <$(SOURCE_GRIST)>atomic.c <$(SOURCE_GRIST)>debug.c <$(SOURCE_GRIST)>driver_settings.c <$(SOURCE_GRIST)>fs_attr.c diff --git a/src/kernel/libroot/os/arch/sh4/atomic.c b/src/kernel/libroot/os/arch/sh4/atomic.c deleted file mode 100644 index dcb5522388..0000000000 --- a/src/kernel/libroot/os/arch/sh4/atomic.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -** Copyright 2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ -#include -#include - -int atomic_add(int *val, int incr) -{ - return sys_atomic_add(val, incr); -} - -int atomic_and(int *val, int incr) -{ - return sys_atomic_and(val, incr); -} - -int atomic_or(int *val, int incr) -{ - return sys_atomic_or(val, incr); -} - -int atomic_set(int *val, int set_to) -{ - return sys_atomic_set(val, set_to); -} - -int test_and_set(int *val, int set_to, int test_val) -{ - return sys_test_and_set(val, set_to, test_val); -} - diff --git a/src/kernel/libroot/os/atomic.c b/src/kernel/libroot/os/atomic.c new file mode 100644 index 0000000000..32b415898c --- /dev/null +++ b/src/kernel/libroot/os/atomic.c @@ -0,0 +1,86 @@ +/* +** Copyright 2003, Marcus Overhagen. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +#include + +#include +#include +#include + +#ifdef ATOMIC_FUNCS_ARE_SYSCALLS +int32 +atomic_set(vint32 *value, int32 newValue) +{ + return _kern_atomic_set(value, newValue); +} + +int32 +atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst) +{ + return _kern_atomic_test_and_set(value, newValue, testAgainst); +} + +int32 +atomic_add(vint32 *value, int32 addValue) +{ + return _kern_atomic_add(value, addValue); +} + +int32 +atomic_and(vint32 *value, int32 andValue) +{ + return _kern_atomic_and(value, andValue); +} + +int32 +atomic_or(vint32 *value, int32 orValue) +{ + return _kern_atomic_or(value, orValue); +} + +int32 +atomic_read(vint32 *value) +{ + return _kern_atomic_read(value); +} +#endif + +#ifdef ATOMIC64_FUNCS_ARE_SYSCALLS +int64 +atomic_set64(vint64 *value, int64 newValue) +{ + return _kern_atomic_set64(value, newValue); +} + +int64 +atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) +{ + return _kern_atomic_test_and_set64(value, newValue, testAgainst); +} + +int64 +atomic_add64(vint64 *value, int64 addValue) +{ + return _kern_atomic_add64(value, addValue); +} + +int64 +atomic_and64(vint64 *value, int64 andValue) +{ + return _kern_atomic_and64(value, andValue); +} + +int64 +atomic_or64(vint64 *value, int64 orValue) +{ + return _kern_atomic_or64(value, orValue); +} + +int64 +atomic_read64(vint64 *value) +{ + return _kern_atomic_read64(value); +} +#endif diff --git a/src/kernel/libroot/os/syscalls.S b/src/kernel/libroot/os/syscalls.S index 2711325b8b..e59fc9628d 100644 --- a/src/kernel/libroot/os/syscalls.S +++ b/src/kernel/libroot/os/syscalls.S @@ -157,19 +157,27 @@ SYSCALL0(sys_system_time, 16) //SYSCALL2(sys_team_get_table, 63) SYSCALL2(sys_getrlimit, 64) SYSCALL2(sys_setrlimit, 65) -SYSCALL2(sys_atomic_add, 66) -SYSCALL2(sys_atomic_and, 67) -SYSCALL2(sys_atomic_or, 68) -SYSCALL2(sys_atomic_set, 69) -SYSCALL3(sys_test_and_set, 70) SYSCALL6(sys_sysctl, 71) //SYSCALL3(sys_socket, 72) SYSCALL3(sys_setenv, 79) SYSCALL2(sys_getenv, 80) +/* atomic calls */ +SYSCALL2(_kern_atomic_set, 126) +SYSCALL3(_kern_atomic_test_and_set, 127) +SYSCALL2(_kern_atomic_add, 128) +SYSCALL2(_kern_atomic_and, 129) +SYSCALL2(_kern_atomic_or, 130) +SYSCALL1(_kern_atomic_read, 131) +SYSCALL3(_kern_atomic_set64, 132) +SYSCALL5(_kern_atomic_test_and_set64, 133) +SYSCALL3(_kern_atomic_add64, 134) +SYSCALL3(_kern_atomic_and64, 135) +SYSCALL3(_kern_atomic_or64, 136) +SYSCALL1(_kern_atomic_read64, 137) + /* Signal handling calls */ SYSCALL0(sys_return_from_signal, 103) SYSCALL3(sys_sigaction, 105) SYSCALL2(sys_send_signal, 110) SYSCALL3(sys_set_alarm, 111) -