+[1.1 release]
+
+2003-09-27 Hans Boehm <Hans.Boehm@hp.com>
+ *src/atomic_ops.h: Define AO_CAN_EMUL_CAS for arm.
+ *src/atomic_ops/sysdeps/read_ordered.h: New file, extracted from
+ ordered_except_wr.h.
+ *src/atomic_ops/sysdeps/ordered_except_wr.h: include read_ordered.h
+ instead of duplicating it.
+ *src/atomic_ops/sysdeps/gcc/arm.h: Include read_ordered.h.
+
+2003-09-16 Hans Boehm <Hans.Boehm@hp.com>
+ *src/atomic_ops/sysdeps/gcc/arm.h: Replace the AO_test_and_set
+ definition with one that might actually work. (Thanks to Kazu
+ Hirata and Paul Brook.)
+
+2003-08-01 Hans Boehm <Hans.Boehm@hp.com>
+ *src/atomic_ops/Makefile.am: Change function naming from "byte" to
+ "char" (again).
+
+[1.0 release]
+
2005-03-21 Hans Boehm <Hans.Boehm@hp.com>
Fix various acquire_release_volatile.h files to reflect the fact
that both icc and gcc seem to reorder ordinary memory accesses around
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for libatomic_ops 1.0.
+# Generated by GNU Autoconf 2.59 for libatomic_ops 1.1.
#
# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# Identity of this package.
PACKAGE_NAME='libatomic_ops'
PACKAGE_TARNAME='libatomic_ops'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='libatomic_ops 1.0'
+PACKAGE_VERSION='1.1'
+PACKAGE_STRING='libatomic_ops 1.1'
PACKAGE_BUGREPORT=''
ac_unique_file="src/atomic_ops.c"
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libatomic_ops 1.0 to adapt to many kinds of systems.
+\`configure' configures libatomic_ops 1.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libatomic_ops 1.0:";;
+ short | recursive ) echo "Configuration of libatomic_ops 1.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-libatomic_ops configure 1.0
+libatomic_ops configure 1.1
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libatomic_ops $as_me 1.0, which was
+It was created by libatomic_ops $as_me 1.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='libatomic_ops'
- VERSION='1.0'
+ VERSION='1.1'
cat >>confdefs.h <<_ACEOF
} >&5
cat >&5 <<_CSEOF
-This file was extended by libatomic_ops $as_me 1.0, which was
+This file was extended by libatomic_ops $as_me 1.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-libatomic_ops config.status 1.0
+libatomic_ops config.status 1.1
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
# Process this file with autoconf to produce a configure script.
-AC_INIT([libatomic_ops],[1.0])
+AC_INIT([libatomic_ops],[1.1])
AC_CANONICAL_TARGET([])
AC_CONFIG_SRCDIR(src/atomic_ops.c)
AM_INIT_AUTOMAKE
# endif /* __powerpc__ */
# if defined(__arm__) && !defined(AO_USE_PTHREAD_DEFS)
# 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"
privatedir=${includedir}/atomic_ops/
generalize-small.h: generalize-small.template
- sed -e s:XSIZE:byte:g -e s:XCTYPE:char:g $? > $@
+ sed -e s:XSIZE:char:g -e s:XCTYPE:char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:int:g $? >> $@
generalize-small.h: generalize-small.template
- sed -e s:XSIZE:byte:g -e s:XCTYPE:char:g $? > $@
+ sed -e s:XSIZE:char:g -e s:XCTYPE:char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:int:g $? >> $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
all_acquire_release_volatile.h \
all_aligned_atomic_load_store.h \
all_atomic_load_store.h \
+ read_ordered.h \
ordered_except_wr.h \
ordered.h \
ao_t_is_int.h \
all_acquire_release_volatile.h \
all_aligned_atomic_load_store.h \
all_atomic_load_store.h \
+ read_ordered.h \
ordered_except_wr.h \
ordered.h \
ao_t_is_int.h \
*
*/
-/* FIXME. Very incomplete. No support for 64 bits. */
+/* There exist multiprocessor SoC ARM processors, so this may actually */
+/* matter. */
+/* I found a slide set that, if I read it correctly, claims that */
+/* Loads followed by either a Load or Store are ordered, but nothing */
+/* else is. */
+/* It appears that SWP is the only simple memory barrier. */
#include "../all_atomic_load_store.h"
+#include "../read_ordered.h"
+
#include "../test_and_set_t_is_ao_t.h" /* Probably suboptimal */
+
AO_INLINE AO_TS_VAL_t
AO_test_and_set_full(volatile AO_TS_t *addr) {
int oldval;
- int temp = 1; /* locked value */
-
- __asm__ __volatile__ (
- " l %0,0(%2)\n"
- "0: cs %0,%1,0(%2)\n"
- " jl 0b"
- : "=&d" (ret)
- : "d" (1), "a" (addr)
- : "cc", "memory");
+ /* SWP on ARM is very similar to XCHG on x86. */
+ /* The first operand is the result, the second the value */
+ /* to be stored. Both registers must be different from addr. */
+ /* Make the address operand an early clobber output so it */
+ /* doesn't overlap with the other operands. The early clobber*/
+ /* on oldval is neccessary to prevent the compiler allocating */
+ /* them to the same register if they are both unused. */
+ __asm__ __volatile__("swp %0, %2, [%3]"
+ : "=&r"(oldval), "=&r"(addr)
+ : "r"(1), "1"(addr)
+ : "memory");
return oldval;
}
* except apparently for some IDT WinChips, which we ignore.
*/
+#include "read_ordered.h"
+
AO_INLINE void
AO_nop_write()
{
#define AO_HAVE_NOP_WRITE
-AO_INLINE void
-AO_nop_read()
-{
- AO_compiler_barrier();
-}
-
-#define AO_HAVE_NOP_READ
-
-#ifdef AO_HAVE_load
-
-AO_INLINE AO_t
-AO_load_read(volatile AO_t *addr)
-{
- AO_t result = AO_load(addr);
- AO_compiler_barrier();
- return result;
-}
-#define AO_HAVE_load_read
-
-#define AO_load_acquire(addr) AO_load_read(addr)
-#define AO_HAVE_load_acquire
-
-#endif /* AO_HAVE_load */
-
-#ifdef AO_HAVE_char_load
-
-AO_INLINE AO_t
-AO_char_load_read(volatile unsigned char *addr)
-{
- AO_t result = AO_char_load(addr);
- AO_compiler_barrier();
- return result;
-}
-#define AO_HAVE_char_load_read
-
-#define AO_char_load_acquire(addr) AO_char_load_read(addr)
-#define AO_HAVE_char_load_acquire
-
-#endif /* AO_HAVE_char_load */
-
-#ifdef AO_HAVE_short_load
-
-AO_INLINE AO_t
-AO_short_load_read(volatile unsigned short *addr)
-{
- AO_t result = AO_short_load(addr);
- AO_compiler_barrier();
- return result;
-}
-#define AO_HAVE_short_load_read
-
-#define AO_short_load_acquire(addr) AO_short_load_read(addr)
-#define AO_HAVE_short_load_acquire
-
-#endif /* AO_HAVE_short_load */
-
-#ifdef AO_HAVE_int_load
-
-AO_INLINE AO_t
-AO_int_load_read(volatile unsigned int *addr)
-{
- AO_t result = AO_int_load(addr);
- AO_compiler_barrier();
- return result;
-}
-#define AO_HAVE_int_load_read
-
-#define AO_int_load_acquire(addr) AO_int_load_read(addr)
-#define AO_HAVE_int_load_acquire
-
-#endif /* AO_HAVE_int_load */
-
#if defined(AO_HAVE_store)
AO_INLINE void
--- /dev/null
+/*
+ * 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.
+ */
+
+/*
+ * These are common definitions for architectures that provide processor
+ * ordered memory operations except that a later read may pass an
+ * earlier write. Real x86 implementations seem to be in this category,
+ * except apparently for some IDT WinChips, which we ignore.
+ */
+
+AO_INLINE void
+AO_nop_read()
+{
+ AO_compiler_barrier();
+}
+
+#define AO_HAVE_NOP_READ
+
+#ifdef AO_HAVE_load
+
+AO_INLINE AO_t
+AO_load_read(volatile AO_t *addr)
+{
+ AO_t result = AO_load(addr);
+ AO_compiler_barrier();
+ return result;
+}
+#define AO_HAVE_load_read
+
+#define AO_load_acquire(addr) AO_load_read(addr)
+#define AO_HAVE_load_acquire
+
+#endif /* AO_HAVE_load */
+
+#ifdef AO_HAVE_char_load
+
+AO_INLINE AO_t
+AO_char_load_read(volatile unsigned char *addr)
+{
+ AO_t result = AO_char_load(addr);
+ AO_compiler_barrier();
+ return result;
+}
+#define AO_HAVE_char_load_read
+
+#define AO_char_load_acquire(addr) AO_char_load_read(addr)
+#define AO_HAVE_char_load_acquire
+
+#endif /* AO_HAVE_char_load */
+
+#ifdef AO_HAVE_short_load
+
+AO_INLINE AO_t
+AO_short_load_read(volatile unsigned short *addr)
+{
+ AO_t result = AO_short_load(addr);
+ AO_compiler_barrier();
+ return result;
+}
+#define AO_HAVE_short_load_read
+
+#define AO_short_load_acquire(addr) AO_short_load_read(addr)
+#define AO_HAVE_short_load_acquire
+
+#endif /* AO_HAVE_short_load */
+
+#ifdef AO_HAVE_int_load
+
+AO_INLINE AO_t
+AO_int_load_read(volatile unsigned int *addr)
+{
+ AO_t result = AO_int_load(addr);
+ AO_compiler_barrier();
+ return result;
+}
+#define AO_HAVE_int_load_read
+
+#define AO_int_load_acquire(addr) AO_int_load_read(addr)
+#define AO_HAVE_int_load_acquire
+
+#endif /* AO_HAVE_int_load */
+
+
}
else
{
- fprintf(stderr, "Usage: %s [max # of threads]\n");
+ fprintf(stderr, "Usage: %s [max # of threads]\n", argv[0]);
exit(1);
}
for (exper_n = 0; exper_n < N_EXPERIMENTS; ++ exper_n)