Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,229 @@
AM_CFLAGS=@PICFLAG@
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
include_HEADERS = atomic_ops.h atomic_ops_stack.h atomic_ops_malloc.h
lib_LTLIBRARIES = libatomic_ops.la libatomic_ops_gpl.la
if NEED_ASM
libatomic_ops_la_SOURCES = atomic_ops.c atomic_ops_sysdeps.S
else
libatomic_ops_la_SOURCES = atomic_ops.c
endif
libatomic_ops_la_LDFLAGS = -version-info 1:3:0 -no-undefined
libatomic_ops_gpl_la_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c
libatomic_ops_gpl_la_LDFLAGS = -version-info 1:3:0 -no-undefined
EXTRA_DIST = Makefile.msft atomic_ops/sysdeps/README \
atomic_ops/generalize-arithm.template \
atomic_ops/generalize-small.template \
atomic_ops/sysdeps/ao_t_is_int.template \
atomic_ops/sysdeps/gcc/generic-arithm.template \
atomic_ops/sysdeps/gcc/generic-small.template \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.template \
atomic_ops/sysdeps/loadstore/atomic_load.template \
atomic_ops/sysdeps/loadstore/atomic_store.template \
atomic_ops/sysdeps/loadstore/ordered_loads_only.template \
atomic_ops/sysdeps/loadstore/ordered_stores_only.template \
atomic_ops/sysdeps/sunc/sparc.S
BUILT_SOURCES = atomic_ops/generalize-arithm.h \
atomic_ops/generalize-small.h \
atomic_ops/sysdeps/ao_t_is_int.h \
atomic_ops/sysdeps/gcc/generic-arithm.h \
atomic_ops/sysdeps/gcc/generic-small.h \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.h \
atomic_ops/sysdeps/loadstore/atomic_load.h \
atomic_ops/sysdeps/loadstore/atomic_store.h \
atomic_ops/sysdeps/loadstore/char_acquire_release_volatile.h \
atomic_ops/sysdeps/loadstore/char_atomic_load.h \
atomic_ops/sysdeps/loadstore/char_atomic_store.h \
atomic_ops/sysdeps/loadstore/int_acquire_release_volatile.h \
atomic_ops/sysdeps/loadstore/int_atomic_load.h \
atomic_ops/sysdeps/loadstore/int_atomic_store.h \
atomic_ops/sysdeps/loadstore/ordered_loads_only.h \
atomic_ops/sysdeps/loadstore/ordered_stores_only.h \
atomic_ops/sysdeps/loadstore/short_acquire_release_volatile.h \
atomic_ops/sysdeps/loadstore/short_atomic_load.h \
atomic_ops/sysdeps/loadstore/short_atomic_store.h
#Private Headers
privatedir=${includedir}/
nobase_private_HEADERS = atomic_ops/ao_version.h \
atomic_ops/generalize.h \
$(BUILT_SOURCES) \
\
atomic_ops/sysdeps/all_acquire_release_volatile.h \
atomic_ops/sysdeps/all_aligned_atomic_load_store.h \
atomic_ops/sysdeps/all_atomic_load_store.h \
atomic_ops/sysdeps/all_atomic_only_load.h \
atomic_ops/sysdeps/emul_cas.h \
atomic_ops/sysdeps/generic_pthread.h \
atomic_ops/sysdeps/ordered.h \
atomic_ops/sysdeps/ordered_except_wr.h \
atomic_ops/sysdeps/read_ordered.h \
atomic_ops/sysdeps/standard_ao_double_t.h \
atomic_ops/sysdeps/test_and_set_t_is_ao_t.h \
atomic_ops/sysdeps/test_and_set_t_is_char.h \
\
atomic_ops/sysdeps/armcc/arm_v6.h \
\
atomic_ops/sysdeps/gcc/aarch64.h \
atomic_ops/sysdeps/gcc/alpha.h \
atomic_ops/sysdeps/gcc/arm.h \
atomic_ops/sysdeps/gcc/avr32.h \
atomic_ops/sysdeps/gcc/cris.h \
atomic_ops/sysdeps/gcc/generic.h \
atomic_ops/sysdeps/gcc/hexagon.h \
atomic_ops/sysdeps/gcc/hppa.h \
atomic_ops/sysdeps/gcc/ia64.h \
atomic_ops/sysdeps/gcc/m68k.h \
atomic_ops/sysdeps/gcc/mips.h \
atomic_ops/sysdeps/gcc/powerpc.h \
atomic_ops/sysdeps/gcc/s390.h \
atomic_ops/sysdeps/gcc/sh.h \
atomic_ops/sysdeps/gcc/sparc.h \
atomic_ops/sysdeps/gcc/x86.h \
\
atomic_ops/sysdeps/hpc/hppa.h \
atomic_ops/sysdeps/hpc/ia64.h \
\
atomic_ops/sysdeps/ibmc/powerpc.h \
\
atomic_ops/sysdeps/icc/ia64.h \
\
atomic_ops/sysdeps/loadstore/double_atomic_load_store.h \
\
atomic_ops/sysdeps/msftc/arm.h \
atomic_ops/sysdeps/msftc/common32_defs.h \
atomic_ops/sysdeps/msftc/x86.h \
atomic_ops/sysdeps/msftc/x86_64.h \
\
atomic_ops/sysdeps/sunc/sparc.h \
atomic_ops/sysdeps/sunc/x86.h
atomic_ops/generalize-small.h: atomic_ops/generalize-small.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XSIZE:double:g -e s:XCTYPE:AO_double_t:g $? >> $@
atomic_ops/generalize-arithm.h: atomic_ops/generalize-arithm.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
atomic_ops/sysdeps/ao_t_is_int.h: atomic_ops/sysdeps/ao_t_is_int.template
sed -e s:_XBAR::g $? > $@
sed -e s:XBAR:full:g $? >> $@
sed -e s:XBAR:acquire:g $? >> $@
sed -e s:XBAR:release:g $? >> $@
sed -e s:XBAR:write:g $? >> $@
sed -e s:XBAR:read:g $? >> $@
atomic_ops/sysdeps/gcc/generic-arithm.h: \
atomic_ops/sysdeps/gcc/generic-arithm.template
sed -e s:_XBAR::g -e s:XGCCBAR:RELAXED:g \
-e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:_XBAR::g -e s:XGCCBAR:RELAXED:g \
-e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:_XBAR::g -e s:XGCCBAR:RELAXED:g \
-e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:_XBAR::g -e s:XGCCBAR:RELAXED:g \
-e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XBAR:acquire:g -e s:XGCCBAR:ACQUIRE:g \
-e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? >> $@
sed -e s:XBAR:acquire:g -e s:XGCCBAR:ACQUIRE:g \
-e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XBAR:acquire:g -e s:XGCCBAR:ACQUIRE:g \
-e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XBAR:acquire:g -e s:XGCCBAR:ACQUIRE:g \
-e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XBAR:release:g -e s:XGCCBAR:RELEASE:g \
-e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? >> $@
sed -e s:XBAR:release:g -e s:XGCCBAR:RELEASE:g \
-e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XBAR:release:g -e s:XGCCBAR:RELEASE:g \
-e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XBAR:release:g -e s:XGCCBAR:RELEASE:g \
-e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XBAR:full:g -e s:XGCCBAR:SEQ_CST:g \
-e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? >> $@
sed -e s:XBAR:full:g -e s:XGCCBAR:SEQ_CST:g \
-e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XBAR:full:g -e s:XGCCBAR:SEQ_CST:g \
-e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XBAR:full:g -e s:XGCCBAR:SEQ_CST:g \
-e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
atomic_ops/sysdeps/gcc/generic-small.h: \
atomic_ops/sysdeps/gcc/generic-small.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
atomic_ops/sysdeps/loadstore/ordered_loads_only.h: \
atomic_ops/sysdeps/loadstore/ordered_loads_only.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XSIZE:double:g -e s:XCTYPE:AO_double_t:g $? >> $@
atomic_ops/sysdeps/loadstore/ordered_stores_only.h: \
atomic_ops/sysdeps/loadstore/ordered_stores_only.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? >> $@
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? >> $@
sed -e s:XSIZE:double:g -e s:XCTYPE:AO_double_t:g $? >> $@
atomic_ops/sysdeps/loadstore/acquire_release_volatile.h: \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.template
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? > $@
atomic_ops/sysdeps/loadstore/char_acquire_release_volatile.h: \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
atomic_ops/sysdeps/loadstore/int_acquire_release_volatile.h: \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.template
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? > $@
atomic_ops/sysdeps/loadstore/short_acquire_release_volatile.h: \
atomic_ops/sysdeps/loadstore/acquire_release_volatile.template
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? > $@
atomic_ops/sysdeps/loadstore/atomic_load.h: \
atomic_ops/sysdeps/loadstore/atomic_load.template
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? > $@
atomic_ops/sysdeps/loadstore/char_atomic_load.h: \
atomic_ops/sysdeps/loadstore/atomic_load.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
atomic_ops/sysdeps/loadstore/int_atomic_load.h: \
atomic_ops/sysdeps/loadstore/atomic_load.template
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? > $@
atomic_ops/sysdeps/loadstore/short_atomic_load.h: \
atomic_ops/sysdeps/loadstore/atomic_load.template
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? > $@
atomic_ops/sysdeps/loadstore/atomic_store.h: \
atomic_ops/sysdeps/loadstore/atomic_store.template
sed -e s:XSIZE_::g -e s:XCTYPE:AO_t:g $? > $@
atomic_ops/sysdeps/loadstore/char_atomic_store.h: \
atomic_ops/sysdeps/loadstore/atomic_store.template
sed -e s:XSIZE:char:g -e s:XCTYPE:unsigned/**/char:g $? > $@
atomic_ops/sysdeps/loadstore/int_atomic_store.h: \
atomic_ops/sysdeps/loadstore/atomic_store.template
sed -e s:XSIZE:int:g -e s:XCTYPE:unsigned:g $? > $@
atomic_ops/sysdeps/loadstore/short_atomic_store.h: \
atomic_ops/sysdeps/loadstore/atomic_store.template
sed -e s:XSIZE:short:g -e s:XCTYPE:unsigned/**/short:g $? > $@

View File

@@ -0,0 +1,60 @@
#
# Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
#
# The really trivial win32/VC++ Makefile. Note that atomic_ops.c defines
# only AO_pause (used by atomic_ops_stack).
# And we rely on a pre-built test_atomic_include.h and generalize-small.h,
# since we can't rely on sed. But we don't keep test_atomic_include.h in
# the development repository any longer, so if you want to do "make check"
# for the sources obtained from the repository then
# do "autoreconf -vif; ./configure; make check" in Cygwin first.
# Win32 clients only need to include the header files.
# To install, copy atomic_ops.h and the atomic_ops/... tree to your favorite
# include directory.
#MY_CPU=X86
#CPU=$(MY_CPU)
#!include <ntwin32.mak>
CFLAGS=-O2 -W3 -DAO_ASSUME_WINDOWS98
LIB_OBJS=atomic_ops.obj atomic_ops_malloc.obj atomic_ops_stack.obj
all: libatomic_ops_gpl.lib
atomic_ops.obj:
cl $(CFLAGS) -c atomic_ops.c
atomic_ops_stack.obj:
cl $(CFLAGS) -c atomic_ops_stack.c
atomic_ops_malloc.obj:
cl $(CFLAGS) -c atomic_ops_malloc.c
libatomic_ops_gpl.lib: $(LIB_OBJS)
lib /out:libatomic_ops_gpl.lib $(LIB_OBJS)
test_atomic: ..\tests\test_atomic.c ..\tests\test_atomic_include.h
cl $(CFLAGS) -I. ..\tests\test_atomic.c /Fo.\test_atomic
test_atomic_w95: ..\tests\test_atomic.c ..\tests\test_atomic_include.h
cl -W3 -O2 -I. ..\tests\test_atomic.c /Fo.\test_atomic_w95
test_malloc: ..\tests\test_malloc.c libatomic_ops_gpl.lib
cl $(CFLAGS) -I. ..\tests\test_malloc.c /Fo.\test_malloc \
libatomic_ops_gpl.lib
test_stack: ..\tests\test_stack.c libatomic_ops_gpl.lib
cl $(CFLAGS) -I. ..\tests\test_stack.c /Fo.\test_stack \
libatomic_ops_gpl.lib
check: test_atomic test_atomic_w95 test_malloc test_stack
@echo "The following will print lots of 'Missing ...' messages"
test_atomic_w95
@echo "The following will print some 'Missing ...' messages"
test_atomic
test_malloc
test_stack
clean:
del *.exe *.obj libatomic_ops_gpl.lib

View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Initialized data and out-of-line functions to support atomic_ops.h
* go here. Currently this is needed only for pthread-based atomics
* emulation, or for compare-and-swap emulation.
* Pthreads emulation isn't useful on a native Windows platform, and
* cas emulation is not needed. Thus we skip this on Windows.
*/
#if defined(HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined(__native_client__) && !defined(AO_USE_NO_SIGNALS) \
&& !defined(AO_USE_NANOSLEEP)
/* Since NaCl is not recognized by configure yet, we do it here. */
# define AO_USE_NO_SIGNALS
# define AO_USE_NANOSLEEP
#endif
#if defined(AO_USE_WIN32_PTHREADS) && !defined(AO_USE_NO_SIGNALS)
# define AO_USE_NO_SIGNALS
#endif
#undef AO_REQUIRE_CAS
#include "atomic_ops.h" /* Without cas emulation! */
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__BORLANDC__) \
|| defined(AO_USE_NO_SIGNALS)
#ifndef AO_NO_PTHREADS
# include <pthread.h>
#endif
#ifndef AO_USE_NO_SIGNALS
# include <signal.h>
#endif
#ifdef AO_USE_NANOSLEEP
/* This requires _POSIX_TIMERS feature. */
# include <sys/time.h>
# include <time.h>
#elif defined(AO_USE_WIN32_PTHREADS)
# include <windows.h> /* for Sleep() */
#elif defined(_HPUX_SOURCE)
# include <sys/time.h>
#else
# include <sys/select.h>
#endif
#ifndef AO_HAVE_double_t
# include "atomic_ops/sysdeps/standard_ao_double_t.h"
#endif
/* Lock for pthreads-based implementation. */
#ifndef AO_NO_PTHREADS
pthread_mutex_t AO_pt_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
/*
* Out of line compare-and-swap emulation based on test and set.
*
* We use a small table of locks for different compare_and_swap locations.
* Before we update perform a compare-and-swap, we grab the corresponding
* lock. Different locations may hash to the same lock, but since we
* never acquire more than one lock at a time, this can't deadlock.
* We explicitly disable signals while we perform this operation.
*
* TODO: Probably also support emulation based on Lamport
* locks, since we may not have test_and_set either.
*/
#define AO_HASH_SIZE 16
#define AO_HASH(x) (((unsigned long)(x) >> 12) & (AO_HASH_SIZE-1))
AO_TS_t AO_locks[AO_HASH_SIZE] = {
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
};
void AO_pause(int); /* defined below */
static void lock_ool(volatile AO_TS_t *l)
{
int i = 0;
while (AO_test_and_set_acquire(l) == AO_TS_SET)
AO_pause(++i);
}
AO_INLINE void lock(volatile AO_TS_t *l)
{
if (AO_EXPECT_FALSE(AO_test_and_set_acquire(l) == AO_TS_SET))
lock_ool(l);
}
AO_INLINE void unlock(volatile AO_TS_t *l)
{
AO_CLEAR(l);
}
#ifndef AO_USE_NO_SIGNALS
static sigset_t all_sigs;
static volatile AO_t initialized = 0;
static volatile AO_TS_t init_lock = AO_TS_INITIALIZER;
AO_INLINE void block_all_signals(sigset_t *old_sigs_ptr)
{
if (AO_EXPECT_FALSE(!AO_load_acquire(&initialized)))
{
lock(&init_lock);
if (!initialized)
sigfillset(&all_sigs);
unlock(&init_lock);
AO_store_release(&initialized, 1);
}
sigprocmask(SIG_BLOCK, &all_sigs, old_sigs_ptr);
/* Neither sigprocmask nor pthread_sigmask is 100% */
/* guaranteed to work here. Sigprocmask is not */
/* guaranteed be thread safe, and pthread_sigmask */
/* is not async-signal-safe. Under linuxthreads, */
/* sigprocmask may block some pthreads-internal */
/* signals. So long as we do that for short periods, */
/* we should be OK. */
}
#endif /* !AO_USE_NO_SIGNALS */
AO_t AO_fetch_compare_and_swap_emulation(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_TS_t *my_lock = AO_locks + AO_HASH(addr);
AO_t fetched_val;
# ifndef AO_USE_NO_SIGNALS
sigset_t old_sigs;
block_all_signals(&old_sigs);
# endif
lock(my_lock);
fetched_val = *addr;
if (fetched_val == old_val)
*addr = new_val;
unlock(my_lock);
# ifndef AO_USE_NO_SIGNALS
sigprocmask(SIG_SETMASK, &old_sigs, NULL);
# endif
return fetched_val;
}
int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2)
{
AO_TS_t *my_lock = AO_locks + AO_HASH(addr);
int result;
# ifndef AO_USE_NO_SIGNALS
sigset_t old_sigs;
block_all_signals(&old_sigs);
# endif
lock(my_lock);
if (addr -> AO_val1 == old_val1 && addr -> AO_val2 == old_val2)
{
addr -> AO_val1 = new_val1;
addr -> AO_val2 = new_val2;
result = 1;
}
else
result = 0;
unlock(my_lock);
# ifndef AO_USE_NO_SIGNALS
sigprocmask(SIG_SETMASK, &old_sigs, NULL);
# endif
return result;
}
void AO_store_full_emulation(volatile AO_t *addr, AO_t val)
{
AO_TS_t *my_lock = AO_locks + AO_HASH(addr);
lock(my_lock);
*addr = val;
unlock(my_lock);
}
#else /* Non-posix platform */
# include <windows.h>
# define AO_USE_WIN32_PTHREADS
/* define to use Sleep() */
extern int AO_non_posix_implementation_is_entirely_in_headers;
#endif
static AO_t spin_dummy = 1;
/* Spin for 2**n units. */
static void AO_spin(int n)
{
AO_t j = AO_load(&spin_dummy);
int i = 2 << n;
while (i-- > 0)
j += (j - 1) << 2;
/* Given 'spin_dummy' is initialized to 1, j is 1 after the loop. */
AO_store(&spin_dummy, j);
}
void AO_pause(int n)
{
if (n < 12)
AO_spin(n);
else
{
# ifdef AO_USE_NANOSLEEP
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = (n > 28 ? 100000 * 1000 : 1 << (n - 2));
nanosleep(&ts, 0);
# elif defined(AO_USE_WIN32_PTHREADS)
Sleep(n > 28 ? 100 : n < 22 ? 1 : 1 << (n - 22)); /* in millis */
# else
struct timeval tv;
/* Short async-signal-safe sleep. */
tv.tv_sec = 0;
tv.tv_usec = n > 28 ? 100000 : 1 << (n - 12);
select(0, 0, 0, 0, &tv);
# endif
}
}

View File

@@ -0,0 +1,418 @@
/*
* Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef AO_ATOMIC_OPS_H
#define AO_ATOMIC_OPS_H
#include "atomic_ops/ao_version.h"
/* Define version numbers here to allow */
/* test on build machines for cross-builds. */
#include <assert.h>
#include <stddef.h>
/* We define various atomic operations on memory in a */
/* machine-specific way. Unfortunately, this is complicated */
/* by the fact that these may or may not be combined with */
/* various memory barriers. Thus the actual operations we */
/* define have the form AO_<atomic-op>_<barrier>, for all */
/* plausible combinations of <atomic-op> and <barrier>. */
/* This of course results in a mild combinatorial explosion. */
/* To deal with it, we try to generate derived */
/* definitions for as many of the combinations as we can, as */
/* automatically as possible. */
/* */
/* Our assumption throughout is that the programmer will */
/* specify the least demanding operation and memory barrier */
/* that will guarantee correctness for the implementation. */
/* Our job is to find the least expensive way to implement it */
/* on the applicable hardware. In many cases that will */
/* involve, for example, a stronger memory barrier, or a */
/* combination of hardware primitives. */
/* */
/* Conventions: */
/* "plain" atomic operations are not guaranteed to include */
/* a barrier. The suffix in the name specifies the barrier */
/* type. Suffixes are: */
/* _release: Earlier operations may not be delayed past it. */
/* _acquire: Later operations may not move ahead of it. */
/* _read: Subsequent reads must follow this operation and */
/* preceding reads. */
/* _write: Earlier writes precede both this operation and */
/* later writes. */
/* _full: Ordered with respect to both earlier and later memory */
/* operations. */
/* _release_write: Ordered with respect to earlier writes. */
/* _acquire_read: Ordered with respect to later reads. */
/* */
/* Currently we try to define the following atomic memory */
/* operations, in combination with the above barriers: */
/* AO_nop */
/* AO_load */
/* AO_store */
/* AO_test_and_set (binary) */
/* AO_fetch_and_add */
/* AO_fetch_and_add1 */
/* AO_fetch_and_sub1 */
/* AO_and */
/* AO_or */
/* AO_xor */
/* AO_compare_and_swap */
/* AO_fetch_compare_and_swap */
/* */
/* Note that atomicity guarantees are valid only if both */
/* readers and writers use AO_ operations to access the */
/* shared value, while ordering constraints are intended to */
/* apply all memory operations. If a location can potentially */
/* be accessed simultaneously from multiple threads, and one of */
/* those accesses may be a write access, then all such */
/* accesses to that location should be through AO_ primitives. */
/* However if AO_ operations enforce sufficient ordering to */
/* ensure that a location x cannot be accessed concurrently, */
/* or can only be read concurrently, then x can be accessed */
/* via ordinary references and assignments. */
/* */
/* AO_compare_and_swap takes an address and an expected old */
/* value and a new value, and returns an int. Non-zero result */
/* indicates that it succeeded. */
/* AO_fetch_compare_and_swap takes an address and an expected */
/* old value and a new value, and returns the real old value. */
/* The operation succeeded if and only if the expected old */
/* value matches the old value returned. */
/* */
/* Test_and_set takes an address, atomically replaces it by */
/* AO_TS_SET, and returns the prior value. */
/* An AO_TS_t location can be reset with the */
/* AO_CLEAR macro, which normally uses AO_store_release. */
/* AO_fetch_and_add takes an address and an AO_t increment */
/* value. The AO_fetch_and_add1 and AO_fetch_and_sub1 variants */
/* are provided, since they allow faster implementations on */
/* some hardware. AO_and, AO_or, AO_xor do atomically and, or, */
/* xor (respectively) an AO_t value into a memory location, */
/* but do not provide access to the original. */
/* */
/* We expect this list to grow slowly over time. */
/* */
/* Note that AO_nop_full is a full memory barrier. */
/* */
/* Note that if some data is initialized with */
/* data.x = ...; data.y = ...; ... */
/* AO_store_release_write(&data_is_initialized, 1) */
/* then data is guaranteed to be initialized after the test */
/* if (AO_load_acquire_read(&data_is_initialized)) ... */
/* succeeds. Furthermore, this should generate near-optimal */
/* code on all common platforms. */
/* */
/* All operations operate on unsigned AO_t, which */
/* is the natural word size, and usually unsigned long. */
/* It is possible to check whether a particular operation op */
/* is available on a particular platform by checking whether */
/* AO_HAVE_op is defined. We make heavy use of these macros */
/* internally. */
/* The rest of this file basically has three sections: */
/* */
/* Some utility and default definitions. */
/* */
/* The architecture dependent section: */
/* This defines atomic operations that have direct hardware */
/* support on a particular platform, mostly by including the */
/* appropriate compiler- and hardware-dependent file. */
/* */
/* The synthesis section: */
/* This tries to define other atomic operations in terms of */
/* those that are explicitly available on the platform. */
/* This section is hardware independent. */
/* We make no attempt to synthesize operations in ways that */
/* effectively introduce locks, except for the debugging/demo */
/* pthread-based implementation at the beginning. A more */
/* realistic implementation that falls back to locks could be */
/* added as a higher layer. But that would sacrifice */
/* usability from signal handlers. */
/* The synthesis section is implemented almost entirely in */
/* atomic_ops/generalize.h. */
/* Some common defaults. Overridden for some architectures. */
#define AO_t size_t
/* The test_and_set primitive returns an AO_TS_VAL_t value. */
/* AO_TS_t is the type of an in-memory test-and-set location. */
#define AO_TS_INITIALIZER (AO_t)AO_TS_CLEAR
/* Platform-dependent stuff: */
#if (defined(__GNUC__) || defined(_MSC_VER) || defined(__INTEL_COMPILER) \
|| defined(__DMC__) || defined(__WATCOMC__)) && !defined(AO_NO_INLINE)
# define AO_INLINE static __inline
#elif defined(__sun) && !defined(AO_NO_INLINE)
# define AO_INLINE static inline
#else
# define AO_INLINE static
#endif
#if __GNUC__ >= 3 && !defined(LINT2)
# define AO_EXPECT_FALSE(expr) __builtin_expect(expr, 0)
/* Equivalent to (expr) but predict that usually (expr) == 0. */
#else
# define AO_EXPECT_FALSE(expr) (expr)
#endif /* !__GNUC__ */
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
# define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory")
#elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
|| defined(__WATCOMC__)
# if defined(_AMD64_) || defined(_M_X64) || _MSC_VER >= 1400
# if defined(_WIN32_WCE)
/* # include <cmnintrin.h> */
# elif defined(_MSC_VER)
# include <intrin.h>
# endif
# pragma intrinsic(_ReadWriteBarrier)
# define AO_compiler_barrier() _ReadWriteBarrier()
/* We assume this does not generate a fence instruction. */
/* The documentation is a bit unclear. */
# else
# define AO_compiler_barrier() __asm { }
/* The preceding implementation may be preferable here too. */
/* But the documentation warns about VC++ 2003 and earlier. */
# endif
#elif defined(__INTEL_COMPILER)
# define AO_compiler_barrier() __memory_barrier()
/* FIXME: Too strong? IA64-only? */
#elif defined(_HPUX_SOURCE)
# if defined(__ia64)
# include <machine/sys/inline.h>
# define AO_compiler_barrier() _Asm_sched_fence()
# else
/* FIXME - We dont know how to do this. This is a guess. */
/* And probably a bad one. */
static volatile int AO_barrier_dummy;
# define AO_compiler_barrier() (void)(AO_barrier_dummy = AO_barrier_dummy)
# endif
#else
/* We conjecture that the following usually gives us the right */
/* semantics or an error. */
# define AO_compiler_barrier() asm("")
#endif
#if defined(AO_USE_PTHREAD_DEFS)
# include "atomic_ops/sysdeps/generic_pthread.h"
#endif /* AO_USE_PTHREAD_DEFS */
#if (defined(__CC_ARM) || defined(__ARMCC__)) && !defined(__GNUC__) \
&& !defined(AO_USE_PTHREAD_DEFS)
# include "atomic_ops/sysdeps/armcc/arm_v6.h"
# define AO_GENERALIZE_TWICE
#endif
#if defined(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS) \
&& !defined(__INTEL_COMPILER)
# if defined(__i386__)
/* We don't define AO_USE_SYNC_CAS_BUILTIN for x86 here because */
/* it might require specifying additional options (like -march) */
/* or additional link libraries (if -march is not specified). */
# include "atomic_ops/sysdeps/gcc/x86.h"
# endif /* __i386__ */
# if defined(__x86_64__)
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) \
&& !defined(AO_USE_SYNC_CAS_BUILTIN)
/* It is safe to use __sync CAS built-in on this architecture. */
# define AO_USE_SYNC_CAS_BUILTIN
# endif
# include "atomic_ops/sysdeps/gcc/x86.h"
# endif /* __x86_64__ */
# if defined(__ia64__)
# include "atomic_ops/sysdeps/gcc/ia64.h"
# define AO_GENERALIZE_TWICE
# endif /* __ia64__ */
# if defined(__hppa__)
# include "atomic_ops/sysdeps/gcc/hppa.h"
# define AO_CAN_EMUL_CAS
# endif /* __hppa__ */
# if defined(__alpha__)
# include "atomic_ops/sysdeps/gcc/alpha.h"
# define AO_GENERALIZE_TWICE
# endif /* __alpha__ */
# if defined(__s390__)
# include "atomic_ops/sysdeps/gcc/s390.h"
# endif /* __s390__ */
# if defined(__sparc__)
# include "atomic_ops/sysdeps/gcc/sparc.h"
# define AO_CAN_EMUL_CAS
# endif /* __sparc__ */
# if defined(__m68k__)
# include "atomic_ops/sysdeps/gcc/m68k.h"
# endif /* __m68k__ */
# if defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
|| defined(__powerpc64__) || defined(__ppc64__)
# include "atomic_ops/sysdeps/gcc/powerpc.h"
# endif /* __powerpc__ */
# if defined(__aarch64__)
# include "atomic_ops/sysdeps/gcc/aarch64.h"
# define AO_CAN_EMUL_CAS
# endif /* __aarch64__ */
# if defined(__arm__)
# include "atomic_ops/sysdeps/gcc/arm.h"
# define AO_CAN_EMUL_CAS
# endif /* __arm__ */
# if defined(__cris__) || defined(CRIS)
# include "atomic_ops/sysdeps/gcc/cris.h"
# define AO_GENERALIZE_TWICE
# endif
# if defined(__mips__)
# include "atomic_ops/sysdeps/gcc/mips.h"
# endif /* __mips__ */
# if defined(__sh__) || defined(SH4)
# include "atomic_ops/sysdeps/gcc/sh.h"
# define AO_CAN_EMUL_CAS
# endif /* __sh__ */
# if defined(__avr32__)
# include "atomic_ops/sysdeps/gcc/avr32.h"
# endif
# if defined(__hexagon__)
# include "atomic_ops/sysdeps/gcc/hexagon.h"
# endif
#endif /* __GNUC__ && !AO_USE_PTHREAD_DEFS */
#if (defined(__IBMC__) || defined(__IBMCPP__)) && !defined(__GNUC__) \
&& !defined(AO_USE_PTHREAD_DEFS)
# if defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) \
|| defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) \
|| defined(_ARCH_PWR)
# include "atomic_ops/sysdeps/ibmc/powerpc.h"
# define AO_GENERALIZE_TWICE
# endif
#endif
#if defined(__INTEL_COMPILER) && !defined(AO_USE_PTHREAD_DEFS)
# if defined(__ia64__)
# include "atomic_ops/sysdeps/icc/ia64.h"
# define AO_GENERALIZE_TWICE
# endif
# if defined(__GNUC__)
/* Intel Compiler in GCC compatible mode */
# if defined(__i386__)
# include "atomic_ops/sysdeps/gcc/x86.h"
# endif /* __i386__ */
# if defined(__x86_64__)
# if (__INTEL_COMPILER > 1110) && !defined(AO_USE_SYNC_CAS_BUILTIN)
# define AO_USE_SYNC_CAS_BUILTIN
# endif
# include "atomic_ops/sysdeps/gcc/x86.h"
# endif /* __x86_64__ */
# endif
#endif
#if defined(_HPUX_SOURCE) && !defined(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS)
# if defined(__ia64)
# include "atomic_ops/sysdeps/hpc/ia64.h"
# define AO_GENERALIZE_TWICE
# else
# include "atomic_ops/sysdeps/hpc/hppa.h"
# define AO_CAN_EMUL_CAS
# endif
#endif
#if defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
|| (defined(__WATCOMC__) && defined(__NT__))
# if defined(_AMD64_) || defined(_M_X64) || defined(_M_ARM64)
# include "atomic_ops/sysdeps/msftc/x86_64.h"
# elif defined(_M_IX86) || defined(x86)
# include "atomic_ops/sysdeps/msftc/x86.h"
# elif defined(_M_ARM) || defined(ARM) || defined(_ARM_)
# include "atomic_ops/sysdeps/msftc/arm.h"
# define AO_GENERALIZE_TWICE
# endif
#endif
#if defined(__sun) && !defined(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS)
/* Note: use -DAO_USE_PTHREAD_DEFS if Sun CC does not handle inline asm. */
# if defined(__i386) || defined(__x86_64) || defined(__amd64)
# include "atomic_ops/sysdeps/sunc/x86.h"
# endif
#endif
#if !defined(__GNUC__) && (defined(sparc) || defined(__sparc)) \
&& !defined(AO_USE_PTHREAD_DEFS)
# include "atomic_ops/sysdeps/sunc/sparc.h"
# define AO_CAN_EMUL_CAS
#endif
#if defined(AO_REQUIRE_CAS) && !defined(AO_HAVE_compare_and_swap) \
&& !defined(AO_HAVE_fetch_compare_and_swap) \
&& !defined(AO_HAVE_compare_and_swap_full) \
&& !defined(AO_HAVE_fetch_compare_and_swap_full) \
&& !defined(AO_HAVE_compare_and_swap_acquire) \
&& !defined(AO_HAVE_fetch_compare_and_swap_acquire)
# if defined(AO_CAN_EMUL_CAS)
# include "atomic_ops/sysdeps/emul_cas.h"
# else
# error Cannot implement AO_compare_and_swap_full on this architecture.
# endif
#endif /* AO_REQUIRE_CAS && !AO_HAVE_compare_and_swap ... */
/* The most common way to clear a test-and-set location */
/* at the end of a critical section. */
#if AO_AO_TS_T && !defined(AO_CLEAR)
# define AO_CLEAR(addr) AO_store_release((AO_TS_t *)(addr), AO_TS_CLEAR)
#endif
#if AO_CHAR_TS_T && !defined(AO_CLEAR)
# define AO_CLEAR(addr) AO_char_store_release((AO_TS_t *)(addr), AO_TS_CLEAR)
#endif
/* The generalization section. */
#if !defined(AO_GENERALIZE_TWICE) && defined(AO_CAN_EMUL_CAS) \
&& !defined(AO_HAVE_compare_and_swap_full) \
&& !defined(AO_HAVE_fetch_compare_and_swap_full)
# define AO_GENERALIZE_TWICE
#endif
/* Theoretically we should repeatedly include atomic_ops/generalize.h. */
/* In fact, we observe that this converges after a small fixed number */
/* of iterations, usually one. */
#include "atomic_ops/generalize.h"
#if !defined(AO_GENERALIZE_TWICE) \
&& defined(AO_HAVE_compare_double_and_swap_double) \
&& (!defined(AO_HAVE_double_load) || !defined(AO_HAVE_double_store))
# define AO_GENERALIZE_TWICE
#endif
#ifdef AO_T_IS_INT
/* Included after the first generalization pass. */
# include "atomic_ops/sysdeps/ao_t_is_int.h"
# ifndef AO_GENERALIZE_TWICE
/* Always generalize again. */
# define AO_GENERALIZE_TWICE
# endif
#endif /* AO_T_IS_INT */
#ifdef AO_GENERALIZE_TWICE
# include "atomic_ops/generalize.h"
#endif
/* For compatibility with version 0.4 and earlier */
#define AO_TS_T AO_TS_t
#define AO_T AO_t
#define AO_TS_VAL AO_TS_VAL_t
#endif /* !AO_ATOMIC_OPS_H */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef AO_ATOMIC_OPS_H
# error This file should not be included directly.
#endif
/* The policy regarding version numbers: development code has odd */
/* "minor" number (and "micro" part is 0); when development is finished */
/* and a release is prepared, "minor" number is incremented (keeping */
/* "micro" number still zero), whenever a defect is fixed a new release */
/* is prepared incrementing "micro" part to odd value (the most stable */
/* release has the biggest "micro" number). */
/* The version here should match that in configure.ac and README. */
#define AO_VERSION_MAJOR 7
#define AO_VERSION_MINOR 4
#define AO_VERSION_MICRO 2 /* 7.4.2 */

View File

@@ -0,0 +1 @@
e925b10f01c9a0375674d9dd01387fd376777f32

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
There are two kinds of entities in this directory:
- Subdirectories corresponding to specific compilers (or compiler/OS combinations).
Each of these includes one or more architecture-specific headers.
- More generic header files corresponding to a particular ordering and/or
atomicity property that might be shared by multiple hardware platforms.

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Describes architectures on which volatile AO_t, unsigned char, */
/* unsigned short, and unsigned int loads and stores have */
/* acquire/release semantics for all normally legal alignments. */
#include "loadstore/acquire_release_volatile.h"
#include "loadstore/char_acquire_release_volatile.h"
#include "loadstore/short_acquire_release_volatile.h"
#include "loadstore/int_acquire_release_volatile.h"

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Describes architectures on which AO_t, unsigned char, unsigned */
/* short, and unsigned int loads and stores are atomic but only if data */
/* is suitably aligned. */
#define AO_ACCESS_CHECK_ALIGNED
/* Check for char type is a misnomer. */
#define AO_ACCESS_short_CHECK_ALIGNED
#define AO_ACCESS_int_CHECK_ALIGNED
#include "all_atomic_load_store.h"

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Describes architectures on which AO_t, unsigned char, unsigned */
/* short, and unsigned int loads and stores are atomic for all normally */
/* legal alignments. */
#include "all_atomic_only_load.h"
#include "loadstore/atomic_store.h"
#include "loadstore/char_atomic_store.h"
#include "loadstore/short_atomic_store.h"
#include "loadstore/int_atomic_store.h"

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Describes architectures on which AO_t, unsigned char, unsigned */
/* short, and unsigned int loads are atomic for all normally legal */
/* alignments. */
#include "loadstore/atomic_load.h"
#include "loadstore/char_atomic_load.h"
#include "loadstore/short_atomic_load.h"
#include "loadstore/int_atomic_load.h"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Inclusion of this file signifies that AO_t is in fact int. */
/* Hence any AO_... operation can also serve as AO_int_... operation. */
#if defined(AO_HAVE_load_XBAR) && !defined(AO_HAVE_int_load_XBAR)
# define AO_int_load_XBAR(addr) \
(unsigned)AO_load_XBAR((const volatile AO_t *)(addr))
# define AO_HAVE_int_load_XBAR
#endif
#if defined(AO_HAVE_store_XBAR) && !defined(AO_HAVE_int_store_XBAR)
# define AO_int_store_XBAR(addr, val) \
AO_store_XBAR((volatile AO_t *)(addr), (AO_t)(val))
# define AO_HAVE_int_store_XBAR
#endif
#if defined(AO_HAVE_fetch_and_add_XBAR) \
&& !defined(AO_HAVE_int_fetch_and_add_XBAR)
# define AO_int_fetch_and_add_XBAR(addr, incr) \
(unsigned)AO_fetch_and_add_XBAR((volatile AO_t *)(addr), \
(AO_t)(incr))
# define AO_HAVE_int_fetch_and_add_XBAR
#endif
#if defined(AO_HAVE_fetch_and_add1_XBAR) \
&& !defined(AO_HAVE_int_fetch_and_add1_XBAR)
# define AO_int_fetch_and_add1_XBAR(addr) \
(unsigned)AO_fetch_and_add1_XBAR((volatile AO_t *)(addr))
# define AO_HAVE_int_fetch_and_add1_XBAR
#endif
#if defined(AO_HAVE_fetch_and_sub1_XBAR) \
&& !defined(AO_HAVE_int_fetch_and_sub1_XBAR)
# define AO_int_fetch_and_sub1_XBAR(addr) \
(unsigned)AO_fetch_and_sub1_XBAR((volatile AO_t *)(addr))
# define AO_HAVE_int_fetch_and_sub1_XBAR
#endif
#if defined(AO_HAVE_and_XBAR) && !defined(AO_HAVE_int_and_XBAR)
# define AO_int_and_XBAR(addr, val) \
AO_and_XBAR((volatile AO_t *)(addr), (AO_t)(val))
# define AO_HAVE_int_and_XBAR
#endif
#if defined(AO_HAVE_or_XBAR) && !defined(AO_HAVE_int_or_XBAR)
# define AO_int_or_XBAR(addr, val) \
AO_or_XBAR((volatile AO_t *)(addr), (AO_t)(val))
# define AO_HAVE_int_or_XBAR
#endif
#if defined(AO_HAVE_xor_XBAR) && !defined(AO_HAVE_int_xor_XBAR)
# define AO_int_xor_XBAR(addr, val) \
AO_xor_XBAR((volatile AO_t *)(addr), (AO_t)(val))
# define AO_HAVE_int_xor_XBAR
#endif
#if defined(AO_HAVE_fetch_compare_and_swap_XBAR) \
&& !defined(AO_HAVE_int_fetch_compare_and_swap_XBAR)
# define AO_int_fetch_compare_and_swap_XBAR(addr, old, new_val) \
(unsigned)AO_fetch_compare_and_swap_XBAR((volatile AO_t *)(addr), \
(AO_t)(old), (AO_t)(new_val))
# define AO_HAVE_int_fetch_compare_and_swap_XBAR
#endif
#if defined(AO_HAVE_compare_and_swap_XBAR) \
&& !defined(AO_HAVE_int_compare_and_swap_XBAR)
# define AO_int_compare_and_swap_XBAR(addr, old, new_val) \
AO_compare_and_swap_XBAR((volatile AO_t *)(addr), \
(AO_t)(old), (AO_t)(new_val))
# define AO_HAVE_int_compare_and_swap_XBAR
#endif

View File

@@ -0,0 +1,263 @@
/*
* Copyright (c) 2007 by NEC LE-IT: All rights reserved.
* A transcription of ARMv6 atomic operations for the ARM Realview Toolchain.
* This code works with armcc from RVDS 3.1
* This is based on work in gcc/arm.h by
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
* Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
* Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved.
*
*
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
* Permission is hereby granted to use or copy this program
* for any purpose, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#include "../test_and_set_t_is_ao_t.h" /* Probably suboptimal */
#if __TARGET_ARCH_ARM < 6
Dont use with ARM instruction sets lower than v6
#else
#define AO_ACCESS_CHECK_ALIGNED
#define AO_ACCESS_short_CHECK_ALIGNED
#define AO_ACCESS_int_CHECK_ALIGNED
#include "../all_atomic_only_load.h"
#include "../standard_ao_double_t.h"
/* NEC LE-IT: ARMv6 is the first architecture providing support for simple LL/SC
* A data memory barrier must be raised via CP15 command (see documentation).
*
* ARMv7 is compatible to ARMv6 but has a simpler command for issuing a
* memory barrier (DMB). Raising it via CP15 should still work as told me by the
* support engineers. If it turns out to be much quicker than we should implement
* custom code for ARMv7 using the asm { dmb } command.
*
* If only a single processor is used, we can define AO_UNIPROCESSOR
* and do not need to access CP15 for ensuring a DMB at all.
*/
AO_INLINE void
AO_nop_full(void)
{
# ifndef AO_UNIPROCESSOR
unsigned int dest=0;
/* issue an data memory barrier (keeps ordering of memory transactions */
/* before and after this operation) */
__asm {
mcr p15,0,dest,c7,c10,5
};
# else
AO_compiler_barrier();
# endif
}
#define AO_HAVE_nop_full
/* NEC LE-IT: atomic "store" - according to ARM documentation this is
* the only safe way to set variables also used in LL/SC environment.
* A direct write won't be recognized by the LL/SC construct in other CPUs.
*
* HB: Based on subsequent discussion, I think it would be OK to use an
* ordinary store here if we knew that interrupt handlers always cleared
* the reservation. They should, but there is some doubt that this is
* currently always the case for e.g. Linux.
*/
AO_INLINE void AO_store(volatile AO_t *addr, AO_t value)
{
unsigned long tmp;
retry:
__asm {
ldrex tmp, [addr]
strex tmp, value, [addr]
teq tmp, #0
bne retry
};
}
#define AO_HAVE_store
/* NEC LE-IT: replace the SWAP as recommended by ARM:
"Applies to: ARM11 Cores
Though the SWP instruction will still work with ARM V6 cores, it is recommended
to use the new V6 synchronization instructions. The SWP instruction produces
locked read and write accesses which are atomic, i.e. another operation cannot
be done between these locked accesses which ties up external bus (AHB,AXI)
bandwidth and can increase worst case interrupt latencies. LDREX,STREX are
more flexible, other instructions can be done between the LDREX and STREX accesses.
"
*/
#ifndef AO_PREFER_GENERALIZED
AO_INLINE AO_TS_VAL_t
AO_test_and_set(volatile AO_TS_t *addr) {
AO_TS_VAL_t oldval;
unsigned long tmp;
unsigned long one = 1;
retry:
__asm {
ldrex oldval, [addr]
strex tmp, one, [addr]
teq tmp, #0
bne retry
}
return oldval;
}
#define AO_HAVE_test_and_set
AO_INLINE AO_t
AO_fetch_and_add(volatile AO_t *p, AO_t incr)
{
unsigned long tmp,tmp2;
AO_t result;
retry:
__asm {
ldrex result, [p]
add tmp, incr, result
strex tmp2, tmp, [p]
teq tmp2, #0
bne retry
}
return result;
}
#define AO_HAVE_fetch_and_add
AO_INLINE AO_t
AO_fetch_and_add1(volatile AO_t *p)
{
unsigned long tmp,tmp2;
AO_t result;
retry:
__asm {
ldrex result, [p]
add tmp, result, #1
strex tmp2, tmp, [p]
teq tmp2, #0
bne retry
}
return result;
}
#define AO_HAVE_fetch_and_add1
AO_INLINE AO_t
AO_fetch_and_sub1(volatile AO_t *p)
{
unsigned long tmp,tmp2;
AO_t result;
retry:
__asm {
ldrex result, [p]
sub tmp, result, #1
strex tmp2, tmp, [p]
teq tmp2, #0
bne retry
}
return result;
}
#define AO_HAVE_fetch_and_sub1
#endif /* !AO_PREFER_GENERALIZED */
#ifndef AO_GENERALIZE_ASM_BOOL_CAS
/* Returns nonzero if the comparison succeeded. */
AO_INLINE int
AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
{
AO_t result, tmp;
retry:
__asm__ {
mov result, #2
ldrex tmp, [addr]
teq tmp, old_val
# ifdef __thumb__
it eq
# endif
strexeq result, new_val, [addr]
teq result, #1
beq retry
}
return !(result&2);
}
# define AO_HAVE_compare_and_swap
#endif /* !AO_GENERALIZE_ASM_BOOL_CAS */
AO_INLINE AO_t
AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
{
AO_t fetched_val, tmp;
retry:
__asm__ {
mov tmp, #2
ldrex fetched_val, [addr]
teq fetched_val, old_val
# ifdef __thumb__
it eq
# endif
strexeq tmp, new_val, [addr]
teq tmp, #1
beq retry
}
return fetched_val;
}
#define AO_HAVE_fetch_compare_and_swap
/* helper functions for the Realview compiler: LDREXD is not usable
* with inline assembler, so use the "embedded" assembler as
* suggested by ARM Dev. support (June 2008). */
__asm inline double_ptr_storage AO_load_ex(const volatile AO_double_t *addr) {
LDREXD r0,r1,[r0]
}
__asm inline int AO_store_ex(AO_t val1, AO_t val2, volatile AO_double_t *addr) {
STREXD r3,r0,r1,[r2]
MOV r0,r3
}
AO_INLINE AO_double_t
AO_double_load(const volatile AO_double_t *addr)
{
AO_double_t result;
result.AO_whole = AO_load_ex(addr);
return result;
}
#define AO_HAVE_double_load
AO_INLINE int
AO_compare_double_and_swap_double(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2)
{
double_ptr_storage old_val =
((double_ptr_storage)old_val2 << 32) | old_val1;
double_ptr_storage tmp;
int result;
while(1) {
tmp = AO_load_ex(addr);
if(tmp != old_val) return 0;
result = AO_store_ex(new_val1, new_val2, addr);
if(!result) return 1;
}
}
#define AO_HAVE_compare_double_and_swap_double
#endif /* __TARGET_ARCH_ARM >= 6 */
#define AO_T_IS_INT

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Ensure, if at all possible, that AO_compare_and_swap_full() is
* available. The emulation should be brute-force signal-safe, even
* though it actually blocks.
* Including this file will generate an error if AO_compare_and_swap_full()
* cannot be made available.
* This will be included from platform-specific atomic_ops files
* if appropriate, and if AO_REQUIRE_CAS is defined. It should not be
* included directly, especially since it affects the implementation
* of other atomic update primitives.
* The implementation assumes that only AO_store_XXX and AO_test_and_set_XXX
* variants are defined, and that AO_test_and_set_XXX is not used to
* operate on compare_and_swap locations.
*/
#ifndef AO_ATOMIC_OPS_H
# error This file should not be included directly.
#endif
#ifndef AO_HAVE_double_t
# include "standard_ao_double_t.h"
#endif
AO_t AO_fetch_compare_and_swap_emulation(volatile AO_t *addr, AO_t old_val,
AO_t new_val);
int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2);
void AO_store_full_emulation(volatile AO_t *addr, AO_t val);
#ifndef AO_HAVE_fetch_compare_and_swap_full
# define AO_fetch_compare_and_swap_full(addr, old, newval) \
AO_fetch_compare_and_swap_emulation(addr, old, newval)
# define AO_HAVE_fetch_compare_and_swap_full
#endif
#ifndef AO_HAVE_compare_double_and_swap_double_full
# define AO_compare_double_and_swap_double_full(addr, old1, old2, \
newval1, newval2) \
AO_compare_double_and_swap_double_emulation(addr, old1, old2, \
newval1, newval2)
# define AO_HAVE_compare_double_and_swap_double_full
#endif
#undef AO_store
#undef AO_HAVE_store
#undef AO_store_write
#undef AO_HAVE_store_write
#undef AO_store_release
#undef AO_HAVE_store_release
#undef AO_store_full
#undef AO_HAVE_store_full
#define AO_store_full(addr, val) AO_store_full_emulation(addr, val)
#define AO_HAVE_store_full

View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
* Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
* Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved.
*
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
* Permission is hereby granted to use or copy this program
* for any purpose, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#include "../test_and_set_t_is_ao_t.h"
#include "../standard_ao_double_t.h"
#ifndef AO_UNIPROCESSOR
AO_INLINE void
AO_nop_write(void)
{
__asm__ __volatile__("dmb st" : : : "memory");
}
# define AO_HAVE_nop_write
#endif
/* TODO: Adjust version check on fixing double-wide AO support in GCC. */
#if __GNUC__ == 4
AO_INLINE AO_double_t
AO_double_load(const volatile AO_double_t *addr)
{
AO_double_t result;
int status;
/* Note that STXP cannot be discarded because LD[A]XP is not */
/* single-copy atomic (unlike LDREXD for 32-bit ARM). */
do {
__asm__ __volatile__("//AO_double_load\n"
" ldxp %0, %1, %3\n"
" stxp %w2, %0, %1, %3"
: "=&r" (result.AO_val1), "=&r" (result.AO_val2), "=&r" (status)
: "Q" (*addr));
} while (AO_EXPECT_FALSE(status));
return result;
}
# define AO_HAVE_double_load
AO_INLINE AO_double_t
AO_double_load_acquire(const volatile AO_double_t *addr)
{
AO_double_t result;
int status;
do {
__asm__ __volatile__("//AO_double_load_acquire\n"
" ldaxp %0, %1, %3\n"
" stxp %w2, %0, %1, %3"
: "=&r" (result.AO_val1), "=&r" (result.AO_val2), "=&r" (status)
: "Q" (*addr));
} while (AO_EXPECT_FALSE(status));
return result;
}
# define AO_HAVE_double_load_acquire
AO_INLINE void
AO_double_store(volatile AO_double_t *addr, AO_double_t value)
{
AO_double_t old_val;
int status;
do {
__asm__ __volatile__("//AO_double_store\n"
" ldxp %0, %1, %3\n"
" stxp %w2, %4, %5, %3"
: "=&r" (old_val.AO_val1), "=&r" (old_val.AO_val2), "=&r" (status),
"=Q" (*addr)
: "r" (value.AO_val1), "r" (value.AO_val2));
/* Compared to the arm.h implementation, the 'cc' (flags) are not */
/* clobbered because A64 has no concept of conditional execution. */
} while (AO_EXPECT_FALSE(status));
}
# define AO_HAVE_double_store
AO_INLINE void
AO_double_store_release(volatile AO_double_t *addr, AO_double_t value)
{
AO_double_t old_val;
int status;
do {
__asm__ __volatile__("//AO_double_store_release\n"
" ldxp %0, %1, %3\n"
" stlxp %w2, %4, %5, %3"
: "=&r" (old_val.AO_val1), "=&r" (old_val.AO_val2), "=&r" (status),
"=Q" (*addr)
: "r" (value.AO_val1), "r" (value.AO_val2));
} while (AO_EXPECT_FALSE(status));
}
# define AO_HAVE_double_store_release
AO_INLINE int
AO_double_compare_and_swap(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_double_t tmp;
int result = 1;
do {
__asm__ __volatile__("//AO_double_compare_and_swap\n"
" ldxp %0, %1, %2\n"
: "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
: "Q" (*addr));
if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
break;
__asm__ __volatile__(
" stxp %w0, %2, %3, %1\n"
: "=&r" (result), "=Q" (*addr)
: "r" (new_val.AO_val1), "r" (new_val.AO_val2));
} while (AO_EXPECT_FALSE(result));
return !result;
}
# define AO_HAVE_double_compare_and_swap
AO_INLINE int
AO_double_compare_and_swap_acquire(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_double_t tmp;
int result = 1;
do {
__asm__ __volatile__("//AO_double_compare_and_swap_acquire\n"
" ldaxp %0, %1, %2\n"
: "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
: "Q" (*addr));
if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
break;
__asm__ __volatile__(
" stxp %w0, %2, %3, %1\n"
: "=&r" (result), "=Q" (*addr)
: "r" (new_val.AO_val1), "r" (new_val.AO_val2));
} while (AO_EXPECT_FALSE(result));
return !result;
}
# define AO_HAVE_double_compare_and_swap_acquire
AO_INLINE int
AO_double_compare_and_swap_release(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_double_t tmp;
int result = 1;
do {
__asm__ __volatile__("//AO_double_compare_and_swap_release\n"
" ldxp %0, %1, %2\n"
: "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
: "Q" (*addr));
if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
break;
__asm__ __volatile__(
" stlxp %w0, %2, %3, %1\n"
: "=&r" (result), "=Q" (*addr)
: "r" (new_val.AO_val1), "r" (new_val.AO_val2));
} while (AO_EXPECT_FALSE(result));
return !result;
}
# define AO_HAVE_double_compare_and_swap_release
AO_INLINE int
AO_double_compare_and_swap_full(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_double_t tmp;
int result = 1;
do {
__asm__ __volatile__("//AO_double_compare_and_swap_full\n"
" ldaxp %0, %1, %2\n"
: "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
: "Q" (*addr));
if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
break;
__asm__ __volatile__(
" stlxp %w0, %2, %3, %1\n"
: "=&r" (result), "=Q" (*addr)
: "r" (new_val.AO_val1), "r" (new_val.AO_val2));
} while (AO_EXPECT_FALSE(result));
return !result;
}
# define AO_HAVE_double_compare_and_swap_full
#endif /* __GNUC__ == 4 */
#include "generic.h"

Some files were not shown because too many files have changed in this diff Show More