summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-07-25 14:02:53 +0400
committerIvan Maidanski <ivmai@mail.ru>2011-07-25 14:12:43 +0400
commit1dc2fb35335ad4fad0eaf3555bf078aed0ab88e6 (patch)
tree8071766b491247638ce0823cf5f8ece69733fb0a /src
parent1fc6ca5b3a64342986e6492fd3fd592440d236e5 (diff)
downloadlibatomic_ops-1dc2fb35335ad4fad0eaf3555bf078aed0ab88e6.tar.gz
libatomic_ops-1.0 tarball importlibatomic_ops-1_0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am16
-rw-r--r--src/Makefile.in597
-rw-r--r--src/Makefile.msft45
-rw-r--r--src/atomic_ops.c225
-rwxr-xr-xsrc/atomic_ops.h288
-rw-r--r--src/atomic_ops/Makefile.am12
-rw-r--r--src/atomic_ops/Makefile.in480
-rw-r--r--src/atomic_ops/generalize-small.h1725
-rw-r--r--src/atomic_ops/generalize-small.template575
-rw-r--r--src/atomic_ops/generalize.h1292
-rw-r--r--src/atomic_ops/sysdeps/Makefile.am45
-rw-r--r--src/atomic_ops/sysdeps/Makefile.in419
-rw-r--r--src/atomic_ops/sysdeps/README7
-rw-r--r--src/atomic_ops/sysdeps/acquire_release_volatile.h64
-rw-r--r--src/atomic_ops/sysdeps/aligned_atomic_load_store.h48
-rw-r--r--src/atomic_ops/sysdeps/all_acquire_release_volatile.h31
-rw-r--r--src/atomic_ops/sysdeps/all_aligned_atomic_load_store.h30
-rw-r--r--src/atomic_ops/sysdeps/all_atomic_load_store.h31
-rw-r--r--src/atomic_ops/sysdeps/ao_t_is_int.h126
-rw-r--r--src/atomic_ops/sysdeps/atomic_load_store.h46
-rw-r--r--src/atomic_ops/sysdeps/char_acquire_release_volatile.h55
-rw-r--r--src/atomic_ops/sysdeps/char_atomic_load_store.h46
-rw-r--r--src/atomic_ops/sysdeps/emul_cas.h76
-rw-r--r--src/atomic_ops/sysdeps/gcc/alpha.h68
-rw-r--r--src/atomic_ops/sysdeps/gcc/arm.h42
-rw-r--r--src/atomic_ops/sysdeps/gcc/cris.h71
-rw-r--r--src/atomic_ops/sysdeps/gcc/hppa.h97
-rw-r--r--src/atomic_ops/sysdeps/gcc/ia64.h297
-rw-r--r--src/atomic_ops/sysdeps/gcc/m68k.h45
-rw-r--r--src/atomic_ops/sysdeps/gcc/powerpc.h201
-rw-r--r--src/atomic_ops/sysdeps/gcc/s390.h63
-rw-r--r--src/atomic_ops/sysdeps/gcc/sparc.h46
-rw-r--r--src/atomic_ops/sysdeps/gcc/x86.h153
-rw-r--r--src/atomic_ops/sysdeps/gcc/x86_64.h147
-rw-r--r--src/atomic_ops/sysdeps/generic_pthread.h289
-rw-r--r--src/atomic_ops/sysdeps/hpc/hppa.h102
-rw-r--r--src/atomic_ops/sysdeps/hpc/ia64.h174
-rw-r--r--src/atomic_ops/sysdeps/ibmc/powerpc.h126
-rw-r--r--src/atomic_ops/sysdeps/icc/ia64.h225
-rw-r--r--src/atomic_ops/sysdeps/int_acquire_release_volatile.h55
-rw-r--r--src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h48
-rw-r--r--src/atomic_ops/sysdeps/int_atomic_load_store.h46
-rw-r--r--src/atomic_ops/sysdeps/msftc/x86.h94
-rw-r--r--src/atomic_ops/sysdeps/ordered.h38
-rw-r--r--src/atomic_ops/sysdeps/ordered_except_wr.h171
-rw-r--r--src/atomic_ops/sysdeps/short_acquire_release_volatile.h55
-rw-r--r--src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h48
-rw-r--r--src/atomic_ops/sysdeps/short_atomic_load_store.h46
-rw-r--r--src/atomic_ops/sysdeps/standard_ao_double_t.h8
-rw-r--r--src/atomic_ops/sysdeps/sunc/sparc.S5
-rw-r--r--src/atomic_ops/sysdeps/sunc/sparc.h38
-rw-r--r--src/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h36
-rw-r--r--src/atomic_ops/sysdeps/test_and_set_t_is_char.h38
-rw-r--r--src/atomic_ops_malloc.c288
-rw-r--r--src/atomic_ops_malloc.h44
-rw-r--r--src/atomic_ops_stack.c302
-rw-r--r--src/atomic_ops_stack.h188
-rw-r--r--src/atomic_ops_sysdeps.S9
-rw-r--r--src/config.h.in58
59 files changed, 10040 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..7ca41ff
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS=atomic_ops
+
+AM_CFLAGS=@PICFLAG@
+
+include_HEADERS=atomic_ops.h atomic_ops_stack.h atomic_ops_malloc.h
+lib_LIBRARIES = libatomic_ops.a libatomic_ops_gpl.a
+if NEED_ASM
+libatomic_ops_a_SOURCES = atomic_ops.c atomic_ops_sysdeps.S
+else
+libatomic_ops_a_SOURCES = atomic_ops.c
+endif
+
+libatomic_ops_gpl_a_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c
+
+EXTRA_DIST=Makefile.msft
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..81e8023
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,597 @@
+# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(libatomic_ops_a_SOURCES) $(libatomic_ops_gpl_a_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/config.h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
+libLIBRARIES_INSTALL = $(INSTALL_DATA)
+LIBRARIES = $(lib_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libatomic_ops_a_AR = $(AR) $(ARFLAGS)
+libatomic_ops_a_LIBADD =
+am__libatomic_ops_a_SOURCES_DIST = atomic_ops.c atomic_ops_sysdeps.S
+@NEED_ASM_FALSE@am_libatomic_ops_a_OBJECTS = atomic_ops.$(OBJEXT)
+@NEED_ASM_TRUE@am_libatomic_ops_a_OBJECTS = atomic_ops.$(OBJEXT) \
+@NEED_ASM_TRUE@ atomic_ops_sysdeps.$(OBJEXT)
+libatomic_ops_a_OBJECTS = $(am_libatomic_ops_a_OBJECTS)
+libatomic_ops_gpl_a_AR = $(AR) $(ARFLAGS)
+libatomic_ops_gpl_a_LIBADD =
+am_libatomic_ops_gpl_a_OBJECTS = atomic_ops_stack.$(OBJEXT) \
+ atomic_ops_malloc.$(OBJEXT)
+libatomic_ops_gpl_a_OBJECTS = $(am_libatomic_ops_gpl_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libatomic_ops_a_SOURCES) $(libatomic_ops_gpl_a_SOURCES)
+DIST_SOURCES = $(am__libatomic_ops_a_SOURCES_DIST) \
+ $(libatomic_ops_gpl_a_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+NEED_ASM_FALSE = @NEED_ASM_FALSE@
+NEED_ASM_TRUE = @NEED_ASM_TRUE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PICFLAG = @PICFLAG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+SUBDIRS = atomic_ops
+AM_CFLAGS = @PICFLAG@
+include_HEADERS = atomic_ops.h atomic_ops_stack.h atomic_ops_malloc.h
+lib_LIBRARIES = libatomic_ops.a libatomic_ops_gpl.a
+@NEED_ASM_FALSE@libatomic_ops_a_SOURCES = atomic_ops.c
+@NEED_ASM_TRUE@libatomic_ops_a_SOURCES = atomic_ops.c atomic_ops_sysdeps.S
+libatomic_ops_gpl_a_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c
+EXTRA_DIST = Makefile.msft
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(srcdir)/config.h.in: $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+install-libLIBRARIES: $(lib_LIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+ @$(POST_INSTALL)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ p=$(am__strip_dir) \
+ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \
+ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \
+ else :; fi; \
+ done
+
+uninstall-libLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLIBRARIES:
+ -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+libatomic_ops.a: $(libatomic_ops_a_OBJECTS) $(libatomic_ops_a_DEPENDENCIES)
+ -rm -f libatomic_ops.a
+ $(libatomic_ops_a_AR) libatomic_ops.a $(libatomic_ops_a_OBJECTS) $(libatomic_ops_a_LIBADD)
+ $(RANLIB) libatomic_ops.a
+libatomic_ops_gpl.a: $(libatomic_ops_gpl_a_OBJECTS) $(libatomic_ops_gpl_a_DEPENDENCIES)
+ -rm -f libatomic_ops_gpl.a
+ $(libatomic_ops_gpl_a_AR) libatomic_ops_gpl.a $(libatomic_ops_gpl_a_OBJECTS) $(libatomic_ops_gpl_a_LIBADD)
+ $(RANLIB) libatomic_ops_gpl.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic_ops.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic_ops_malloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic_ops_stack.Po@am__quote@
+
+.S.o:
+ $(CCASCOMPILE) -c $<
+
+.S.obj:
+ $(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LIBRARIES) $(HEADERS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-exec-am: install-libLIBRARIES
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS uninstall-info-am \
+ uninstall-libLIBRARIES
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
+ clean clean-generic clean-libLIBRARIES clean-recursive ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-recursive distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-includeHEADERS install-info install-info-am \
+ install-libLIBRARIES install-man install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-includeHEADERS \
+ uninstall-info-am uninstall-libLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/Makefile.msft b/src/Makefile.msft
new file mode 100644
index 0000000..5b93d27
--- /dev/null
+++ b/src/Makefile.msft
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2003-2005 Hewlett-Packard Developlment Company, L.P.
+#
+# The really trivial win32/VC++ Makefile. Note that atomic_ops.c isn't useful.
+# And we rely on a pre-built test_atomic_include.h and generalize-small.h,
+# since we can't rely on sed.
+# 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>
+
+LIB_OBJS=atomic_ops_stack.obj atomic_ops_malloc.obj
+
+all: check
+
+atomic_ops_stack.obj:
+ cl -O2 -c -DAO_ASSUME_WINDOWS98 atomic_ops_stack.c
+
+atomic_ops_malloc.obj:
+ cl -O2 -c -DAO_ASSUME_WINDOWS98 atomic_ops_malloc.c
+
+test_atomic: ..\tests\test_atomic.c ..\tests\test_atomic_include.h
+ cl -O2 -I. -DAO_ASSUME_WINDOWS98 ..\tests\test_atomic.c -o test_atomic
+
+test_atomic_w95: ..\tests\test_atomic.c ..\tests\test_atomic_include.h
+ cl -O2 -I. ..\tests\test_atomic.c -o test_atomic_w95
+
+test_malloc: ..\tests\test_malloc.c ..\tests\test_atomic_include.h \
+ libatomic_ops_gpl.lib
+ cl -O2 -DAO_ASSUME_WINDOWS98 -I. ..\tests\test_malloc.c -o test_malloc libatomic_ops_gpl.lib
+
+libatomic_ops_gpl.lib: $(LIB_OBJS)
+ lib /MACHINE:i386 /out:libatomic_ops_gpl.lib $(LIB_OBJS)
+
+check: test_atomic test_atomic_w95 test_malloc
+ echo The following will print lots of \"Missing ...\" messages.
+ test_atomic_w95
+ echo The following will print some \"Missing ...\" messages.
+ test_atomic
+ test_malloc
+
+
diff --git a/src/atomic_ops.c b/src/atomic_ops.c
new file mode 100644
index 0000000..f01b8d2
--- /dev/null
+++ b/src/atomic_ops.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2003 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(_MSC_VER) && !defined(__MINGW32__) && !defined(__BORLANDC__)
+
+#undef AO_REQUIRE_CAS
+
+#include <pthread.h>
+#include <signal.h>
+#ifdef _HPUX_SOURCE
+# include <sys/time.h>
+#else
+# include <sys/select.h>
+#endif
+#include "atomic_ops.h" /* Without cas emulation! */
+
+#ifndef AO_HAVE_double_t
+# include "atomic_ops/sysdeps/standard_ao_double_t.h"
+#endif
+
+/*
+ * Lock for pthreads-based implementation.
+ */
+
+pthread_mutex_t AO_pt_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * 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 grap 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.
+ *
+ * FIXME: We should probably also suppport 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,
+};
+
+static AO_T dummy = 1;
+
+/* Spin for 2**n units. */
+void AO_spin(int n)
+{
+ int i;
+ AO_T j = AO_load(&dummy);
+
+ for (i = 0; i < (2 << n); ++i)
+ {
+ j *= 5;
+ j -= 4;
+ }
+ AO_store(&dummy, j);
+}
+
+void AO_pause(int n)
+{
+ if (n < 12)
+ AO_spin(n);
+ 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);
+ }
+}
+
+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_test_and_set_acquire(l) == AO_TS_SET)
+ lock_ool(l);
+}
+
+AO_INLINE void unlock(volatile AO_TS_t *l)
+{
+ AO_CLEAR(l);
+}
+
+static sigset_t all_sigs;
+
+static volatile AO_t initialized = 0;
+
+static volatile AO_TS_t init_lock = AO_TS_INITIALIZER;
+
+int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old,
+ AO_t new_val)
+{
+ AO_TS_t *my_lock = AO_locks + AO_HASH(addr);
+ sigset_t old_sigs;
+ int result;
+
+ if (!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);
+ /* 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. */
+ lock(my_lock);
+ if (*addr == old)
+ {
+ *addr = new_val;
+ result = 1;
+ }
+ else
+ result = 0;
+ unlock(my_lock);
+ sigprocmask(SIG_SETMASK, &old_sigs, NULL);
+ return result;
+}
+
+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);
+ sigset_t old_sigs;
+ int result;
+
+ if (!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);
+ /* 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. */
+ 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);
+ sigprocmask(SIG_SETMASK, &old_sigs, NULL);
+ 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 */
+
+int AO_non_posix_implementation_is_entirely_in_headers;
+
+#endif
diff --git a/src/atomic_ops.h b/src/atomic_ops.h
new file mode 100755
index 0000000..a77bfd6
--- /dev/null
+++ b/src/atomic_ops.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2003 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 ATOMIC_OPS_H
+
+#define ATOMIC_OPS_H
+
+#include <assert.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 memops.*/
+/* _release_write: Ordered with respect to earlier writes. */
+/* _acquire_read: Ordered with repsect 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_or */
+/* AO_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. */
+/* */
+/* Compare_and_exchange takes an address and an expected old */
+/* value and a new value, and returns an int. Nonzero */
+/* indicates that it succeeded. */
+/* Test_and_set takes an address, atomically replaces it by */
+/* AO_TS_SET, and returns the prior value. */
+/* An AO_TS_t clear 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_or atomically ors an AO_t value into a */
+/* memory location, but does 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_release_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 uncluding 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 */
+/* relistic 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 unsigned long
+ /* Could conceivably be redefined below if/when we add */
+ /* win64 support. */
+
+/* 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)
+# define AO_INLINE static __inline
+#else
+# define AO_INLINE static
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+# define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory")
+#elif defined(_MSC_VER)
+# define AO_compiler_barrier() __asm { }
+#elif defined(__INTEL_COMPILER)
+# define AO_compiler_barrier() __memory_barrier() /* 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() 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(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS) \
+ && !defined(__INTEL_COMPILER)
+# if defined(__i386__)
+# include "atomic_ops/sysdeps/gcc/x86.h"
+# endif /* __i386__ */
+# if defined(__x86_64__)
+# include "atomic_ops/sysdeps/gcc/x86_64.h"
+# endif /* __i386__ */
+# 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__)
+# include "atomic_ops/sysdeps/gcc/powerpc.h"
+# endif /* __powerpc__ */
+# if defined(__arm__) && !defined(AO_USE_PTHREAD_DEFS)
+# include "atomic_ops/sysdeps/gcc/arm.h"
+# endif /* __arm__ */
+# if defined(__cris__) || defined(CRIS)
+# include "atomic_ops/sysdeps/gcc/cris.h"
+# endif
+#endif /* __GNUC__ && !AO_USE_PTHREAD_DEFS */
+
+#if defined(__INTEL_COMPILER) && !defined(AO_USE_PTHREAD_DEFS)
+# if defined(__ia64__)
+# include "atomic_ops/sysdeps/icc/ia64.h"
+# define AO_GENERALIZE_TWICE
+# 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(__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(_MSC_VER)
+# if _M_IX86 >= 400
+# include "atomic_ops/sysdeps/msftc/x86.h"
+# endif
+#endif
+
+#if defined(AO_REQUIRE_CAS) && !defined(AO_HAVE_compare_and_swap) \
+ && !defined(AO_HAVE_compare_and_swap_full) \
+ && !defined(AO_HAVE_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.
+ * Theoretically this 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"
+#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 /* ATOMIC_OPS_H */
diff --git a/src/atomic_ops/Makefile.am b/src/atomic_ops/Makefile.am
new file mode 100644
index 0000000..a710df0
--- /dev/null
+++ b/src/atomic_ops/Makefile.am
@@ -0,0 +1,12 @@
+SUBDIRS=sysdeps
+
+EXTRA_DIST=generalize-small.template
+
+#Private Headers
+private_HEADERS=generalize.h generalize-small.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:short:g -e s:XCTYPE:short:g $? >> $@
+ sed -e s:XSIZE:int:g -e s:XCTYPE:int:g $? >> $@
diff --git a/src/atomic_ops/Makefile.in b/src/atomic_ops/Makefile.in
new file mode 100644
index 0000000..d236333
--- /dev/null
+++ b/src/atomic_ops/Makefile.in
@@ -0,0 +1,480 @@
+# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/atomic_ops
+DIST_COMMON = $(private_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(privatedir)"
+privateHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(private_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+NEED_ASM_FALSE = @NEED_ASM_FALSE@
+NEED_ASM_TRUE = @NEED_ASM_TRUE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PICFLAG = @PICFLAG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+SUBDIRS = sysdeps
+EXTRA_DIST = generalize-small.template
+
+#Private Headers
+private_HEADERS = generalize.h generalize-small.h
+privatedir = ${includedir}/atomic_ops/
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/atomic_ops/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/atomic_ops/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+uninstall-info-am:
+install-privateHEADERS: $(private_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(privatedir)" || $(mkdir_p) "$(DESTDIR)$(privatedir)"
+ @list='$(private_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(privateHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(privatedir)/$$f'"; \
+ $(privateHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(privatedir)/$$f"; \
+ done
+
+uninstall-privateHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(private_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(privatedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(privatedir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(privatedir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-privateHEADERS
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-privateHEADERS
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
+ clean clean-generic clean-recursive ctags ctags-recursive \
+ distclean distclean-generic distclean-recursive distclean-tags \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-privateHEADERS install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-info-am uninstall-privateHEADERS
+
+
+generalize-small.h: generalize-small.template
+ sed -e s:XSIZE:byte: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.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/atomic_ops/generalize-small.h b/src/atomic_ops/generalize-small.h
new file mode 100644
index 0000000..4e45a0d
--- /dev/null
+++ b/src/atomic_ops/generalize-small.h
@@ -0,0 +1,1725 @@
+/* char_load */
+#if defined(AO_HAVE_char_load_acquire) && !defined(AO_HAVE_char_load)
+# define AO_char_load(addr) AO_char_load_acquire(addr)
+# define AO_HAVE_char_load
+#endif
+
+#if defined(AO_HAVE_char_load_full) && !defined(AO_HAVE_char_load_acquire)
+# define AO_char_load_acquire(addr) AO_char_load_full(addr)
+# define AO_HAVE_char_load_acquire
+#endif
+
+#if defined(AO_HAVE_char_load_full) && !defined(AO_HAVE_char_load_read)
+# define AO_char_load_read(addr) AO_char_load_full(addr)
+# define AO_HAVE_char_load_read
+#endif
+
+#if !defined(AO_HAVE_char_load_acquire_read) && defined(AO_HAVE_char_load_acquire)
+# define AO_char_load_acquire_read(addr) AO_char_load_acquire(addr)
+# define AO_HAVE_char_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_char_load) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_load_acquire)
+ AO_INLINE unsigned char
+ AO_char_load_acquire(volatile unsigned char *addr)
+ {
+ unsigned char result = AO_char_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_char_load_acquire
+#endif
+
+#if defined(AO_HAVE_char_load) && defined(AO_HAVE_nop_read) && \
+ !defined(AO_HAVE_char_load_read)
+ AO_INLINE unsigned char
+ AO_char_load_read(volatile unsigned char *addr)
+ {
+ unsigned char result = AO_char_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_read();
+ return result;
+ }
+# define AO_HAVE_char_load_read
+#endif
+
+#if defined(AO_HAVE_char_load_acquire) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_load_full)
+# define AO_char_load_full(addr) (AO_nop_full(), AO_char_load_acquire(addr))
+# define AO_HAVE_char_load_full
+#endif
+
+#if !defined(AO_HAVE_char_load_acquire_read) && defined(AO_HAVE_char_load_read)
+# define AO_char_load_acquire_read(addr) AO_char_load_read(addr)
+# define AO_HAVE_char_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_char_load_acquire_read) && !defined(AO_HAVE_char_load)
+# define AO_char_load(addr) AO_char_load_acquire_read(addr)
+# define AO_HAVE_char_load
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_char_load_acquire_read)
+# define AO_char_load_dd_acquire_read(addr) \
+ AO_char_load_acquire_read(addr)
+# define AO_HAVE_char_load_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_char_load)
+# define AO_char_load_dd_acquire_read(addr) \
+ AO_char_load(addr)
+# define AO_HAVE_char_load_dd_acquire_read
+# endif
+#endif
+
+
+/* char_store */
+
+#if defined(AO_HAVE_char_store_release) && !defined(AO_HAVE_char_store)
+# define AO_char_store(addr, val) AO_char_store_release(addr,val)
+# define AO_HAVE_char_store
+#endif
+
+#if defined(AO_HAVE_char_store_full) && !defined(AO_HAVE_char_store_release)
+# define AO_char_store_release(addr,val) AO_char_store_full(addr,val)
+# define AO_HAVE_char_store_release
+#endif
+
+#if defined(AO_HAVE_char_store_full) && !defined(AO_HAVE_char_store_write)
+# define AO_char_store_write(addr,val) AO_char_store_full(addr,val)
+# define AO_HAVE_char_store_write
+#endif
+
+#if defined(AO_HAVE_char_store_release) && \
+ !defined(AO_HAVE_char_store_release_write)
+# define AO_char_store_release_write(addr, val) \
+ AO_char_store_release(addr,val)
+# define AO_HAVE_char_store_release_write
+#endif
+
+#if defined(AO_HAVE_char_store_write) && !defined(AO_HAVE_char_store)
+# define AO_char_store(addr, val) AO_char_store_write(addr,val)
+# define AO_HAVE_char_store
+#endif
+
+#if defined(AO_HAVE_char_store) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_store_release)
+# define AO_char_store_release(addr,val) \
+ (AO_nop_full(), AO_char_store(addr,val))
+# define AO_HAVE_char_store_release
+#endif
+
+#if defined(AO_HAVE_nop_write) && defined(AO_HAVE_char_store) && \
+ !defined(AO_HAVE_char_store_write)
+# define AO_char_store_write(addr, val) \
+ (AO_nop_write(), AO_char_store(addr,val))
+# define AO_HAVE_char_store_write
+#endif
+
+#if defined(AO_HAVE_char_store_write) && \
+ !defined(AO_HAVE_char_store_release_write)
+# define AO_char_store_release_write(addr, val) AO_char_store_write(addr,val)
+# define AO_HAVE_char_store_release_write
+#endif
+
+#if defined(AO_HAVE_char_store_release) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_store_full)
+# define AO_char_store_full(addr, val) \
+ (AO_char_store_release(addr, val), AO_nop_full())
+# define AO_HAVE_char_store_full
+#endif
+
+
+/* char_fetch_and_add */
+#if defined(AO_HAVE_char_compare_and_swap_full) && \
+ !defined(AO_HAVE_char_fetch_and_add_full)
+ AO_INLINE AO_t
+ AO_char_fetch_and_add_full(volatile unsigned char *addr,
+ unsigned char incr)
+ {
+ unsigned char old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_char_compare_and_swap_full(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_char_fetch_and_add_full
+#endif
+
+#if defined(AO_HAVE_char_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_char_fetch_and_add_acquire)
+ AO_INLINE AO_t
+ AO_char_fetch_and_add_acquire(volatile unsigned char *addr,
+ unsigned char incr)
+ {
+ unsigned char old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_char_compare_and_swap_acquire(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_char_fetch_and_add_acquire
+#endif
+
+#if defined(AO_HAVE_char_compare_and_swap_release) && \
+ !defined(AO_HAVE_char_fetch_and_add_release)
+ AO_INLINE AO_t
+ AO_char_fetch_and_add_release(volatile unsigned char *addr,
+ unsigned char incr)
+ {
+ unsigned char old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_char_compare_and_swap_release(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_char_fetch_and_add_release
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_add_full)
+# if !defined(AO_HAVE_char_fetch_and_add_release)
+# define AO_char_fetch_and_add_release(addr, val) \
+ AO_char_fetch_and_add_full(addr, val)
+# define AO_HAVE_char_fetch_and_add_release
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add_acquire)
+# define AO_char_fetch_and_add_acquire(addr, val) \
+ AO_char_fetch_and_add_full(addr, val)
+# define AO_HAVE_char_fetch_and_add_acquire
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add_write)
+# define AO_char_fetch_and_add_write(addr, val) \
+ AO_char_fetch_and_add_full(addr, val)
+# define AO_HAVE_char_fetch_and_add_write
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add_read)
+# define AO_char_fetch_and_add_read(addr, val) \
+ AO_char_fetch_and_add_full(addr, val)
+# define AO_HAVE_char_fetch_and_add_read
+# endif
+#endif /* AO_HAVE_char_fetch_and_add_full */
+
+#if !defined(AO_HAVE_char_fetch_and_add) && \
+ defined(AO_HAVE_char_fetch_and_add_release)
+# define AO_char_fetch_and_add(addr, val) \
+ AO_char_fetch_and_add_release(addr, val)
+# define AO_HAVE_char_fetch_and_add
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add) && \
+ defined(AO_HAVE_char_fetch_and_add_acquire)
+# define AO_char_fetch_and_add(addr, val) \
+ AO_char_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_char_fetch_and_add
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add) && \
+ defined(AO_HAVE_char_fetch_and_add_write)
+# define AO_char_fetch_and_add(addr, val) \
+ AO_char_fetch_and_add_write(addr, val)
+# define AO_HAVE_char_fetch_and_add
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add) && \
+ defined(AO_HAVE_char_fetch_and_add_read)
+# define AO_char_fetch_and_add(addr, val) \
+ AO_char_fetch_and_add_read(addr, val)
+# define AO_HAVE_char_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_add_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_fetch_and_add_full)
+# define AO_char_fetch_and_add_full(addr, val) \
+ (AO_nop_full(), AO_char_fetch_and_add_acquire(addr, val))
+#endif
+
+#if !defined(AO_HAVE_char_fetch_and_add_release_write) && \
+ defined(AO_HAVE_char_fetch_and_add_write)
+# define AO_char_fetch_and_add_release_write(addr, val) \
+ AO_char_fetch_and_add_write(addr, val)
+# define AO_HAVE_char_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add_release_write) && \
+ defined(AO_HAVE_char_fetch_and_add_release)
+# define AO_char_fetch_and_add_release_write(addr, val) \
+ AO_char_fetch_and_add_release(addr, val)
+# define AO_HAVE_char_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_add_read)
+# define AO_char_fetch_and_add_acquire_read(addr, val) \
+ AO_char_fetch_and_add_read(addr, val)
+# define AO_HAVE_char_fetch_and_add_acquire_read
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_add_acquire)
+# define AO_char_fetch_and_add_acquire_read(addr, val) \
+ AO_char_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_char_fetch_and_add_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_char_fetch_and_add_acquire_read)
+# define AO_char_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_char_fetch_and_add_acquire_read(addr, val)
+# define AO_HAVE_char_fetch_and_add_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_char_fetch_and_add)
+# define AO_char_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_char_fetch_and_add(addr, val)
+# define AO_HAVE_char_fetch_and_add_dd_acquire_read
+# endif
+#endif
+
+/* char_fetch_and_add1 */
+
+#if defined(AO_HAVE_char_fetch_and_add_full) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_full)
+# define AO_char_fetch_and_add1_full(addr) \
+ AO_char_fetch_and_add_full(addr,1)
+# define AO_HAVE_char_fetch_and_add1_full
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_release) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_release)
+# define AO_char_fetch_and_add1_release(addr) \
+ AO_char_fetch_and_add_release(addr,1)
+# define AO_HAVE_char_fetch_and_add1_release
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_acquire)
+# define AO_char_fetch_and_add1_acquire(addr) \
+ AO_char_fetch_and_add_acquire(addr,1)
+# define AO_HAVE_char_fetch_and_add1_acquire
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_write) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_write)
+# define AO_char_fetch_and_add1_write(addr) \
+ AO_char_fetch_and_add_write(addr,1)
+# define AO_HAVE_char_fetch_and_add1_write
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_read) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_read)
+# define AO_char_fetch_and_add1_read(addr) \
+ AO_char_fetch_and_add_read(addr,1)
+# define AO_HAVE_char_fetch_and_add1_read
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_release_write)
+# define AO_char_fetch_and_add1_release_write(addr) \
+ AO_char_fetch_and_add_release_write(addr,1)
+# define AO_HAVE_char_fetch_and_add1_release_write
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_char_fetch_and_add1_acquire_read)
+# define AO_char_fetch_and_add1_acquire_read(addr) \
+ AO_char_fetch_and_add_acquire_read(addr,1)
+# define AO_HAVE_char_fetch_and_add1_acquire_read
+#endif
+#if defined(AO_HAVE_char_fetch_and_add) &&\
+ !defined(AO_HAVE_char_fetch_and_add1)
+# define AO_char_fetch_and_add1(addr) \
+ AO_char_fetch_and_add(addr,1)
+# define AO_HAVE_char_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_add1_full)
+# if !defined(AO_HAVE_char_fetch_and_add1_release)
+# define AO_char_fetch_and_add1_release(addr) \
+ AO_char_fetch_and_add1_full(addr)
+# define AO_HAVE_char_fetch_and_add1_release
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add1_acquire)
+# define AO_char_fetch_and_add1_acquire(addr) \
+ AO_char_fetch_and_add1_full(addr)
+# define AO_HAVE_char_fetch_and_add1_acquire
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add1_write)
+# define AO_char_fetch_and_add1_write(addr) \
+ AO_char_fetch_and_add1_full(addr)
+# define AO_HAVE_char_fetch_and_add1_write
+# endif
+# if !defined(AO_HAVE_char_fetch_and_add1_read)
+# define AO_char_fetch_and_add1_read(addr) \
+ AO_char_fetch_and_add1_full(addr)
+# define AO_HAVE_char_fetch_and_add1_read
+# endif
+#endif /* AO_HAVE_char_fetch_and_add1_full */
+
+#if !defined(AO_HAVE_char_fetch_and_add1) && \
+ defined(AO_HAVE_char_fetch_and_add1_release)
+# define AO_char_fetch_and_add1(addr) \
+ AO_char_fetch_and_add1_release(addr)
+# define AO_HAVE_char_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1) && \
+ defined(AO_HAVE_char_fetch_and_add1_acquire)
+# define AO_char_fetch_and_add1(addr) \
+ AO_char_fetch_and_add1_acquire(addr)
+# define AO_HAVE_char_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1) && \
+ defined(AO_HAVE_char_fetch_and_add1_write)
+# define AO_char_fetch_and_add1(addr) \
+ AO_char_fetch_and_add1_write(addr)
+# define AO_HAVE_char_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1) && \
+ defined(AO_HAVE_char_fetch_and_add1_read)
+# define AO_char_fetch_and_add1(addr) \
+ AO_char_fetch_and_add1_read(addr)
+# define AO_HAVE_char_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_add1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_fetch_and_add1_full)
+# define AO_char_fetch_and_add1_full(addr) \
+ (AO_nop_full(), AO_char_fetch_and_add1_acquire(addr))
+# define AO_HAVE_char_fetch_and_add1_full
+#endif
+
+#if !defined(AO_HAVE_char_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_char_fetch_and_add1_write)
+# define AO_char_fetch_and_add1_release_write(addr) \
+ AO_char_fetch_and_add1_write(addr)
+# define AO_HAVE_char_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_char_fetch_and_add1_release)
+# define AO_char_fetch_and_add1_release_write(addr) \
+ AO_char_fetch_and_add1_release(addr)
+# define AO_HAVE_char_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_add1_read)
+# define AO_char_fetch_and_add1_acquire_read(addr) \
+ AO_char_fetch_and_add1_read(addr)
+# define AO_HAVE_char_fetch_and_add1_acquire_read
+#endif
+#if !defined(AO_HAVE_char_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_add1_acquire)
+# define AO_char_fetch_and_add1_acquire_read(addr) \
+ AO_char_fetch_and_add1_acquire(addr)
+# define AO_HAVE_char_fetch_and_add1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_char_fetch_and_add1_acquire_read)
+# define AO_char_fetch_and_add1_dd_acquire_read(addr) \
+ AO_char_fetch_and_add1_acquire_read(addr)
+# define AO_HAVE_char_fetch_and_add1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_char_fetch_and_add1)
+# define AO_char_fetch_and_add1_dd_acquire_read(addr) \
+ AO_char_fetch_and_add1(addr)
+# define AO_HAVE_char_fetch_and_add1_dd_acquire_read
+# endif
+#endif
+
+/* char_fetch_and_sub1 */
+
+#if defined(AO_HAVE_char_fetch_and_add_full) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_full)
+# define AO_char_fetch_and_sub1_full(addr) \
+ AO_char_fetch_and_add_full(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_full
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_release) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_release)
+# define AO_char_fetch_and_sub1_release(addr) \
+ AO_char_fetch_and_add_release(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_release
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_acquire)
+# define AO_char_fetch_and_sub1_acquire(addr) \
+ AO_char_fetch_and_add_acquire(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_acquire
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_write) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_write)
+# define AO_char_fetch_and_sub1_write(addr) \
+ AO_char_fetch_and_add_write(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_write
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_read) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_read)
+# define AO_char_fetch_and_sub1_read(addr) \
+ AO_char_fetch_and_add_read(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_read
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_release_write)
+# define AO_char_fetch_and_sub1_release_write(addr) \
+ AO_char_fetch_and_add_release_write(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_release_write
+#endif
+#if defined(AO_HAVE_char_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1_acquire_read)
+# define AO_char_fetch_and_sub1_acquire_read(addr) \
+ AO_char_fetch_and_add_acquire_read(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1_acquire_read
+#endif
+#if defined(AO_HAVE_char_fetch_and_add) &&\
+ !defined(AO_HAVE_char_fetch_and_sub1)
+# define AO_char_fetch_and_sub1(addr) \
+ AO_char_fetch_and_add(addr,(unsigned char)(-1))
+# define AO_HAVE_char_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_sub1_full)
+# if !defined(AO_HAVE_char_fetch_and_sub1_release)
+# define AO_char_fetch_and_sub1_release(addr) \
+ AO_char_fetch_and_sub1_full(addr)
+# define AO_HAVE_char_fetch_and_sub1_release
+# endif
+# if !defined(AO_HAVE_char_fetch_and_sub1_acquire)
+# define AO_char_fetch_and_sub1_acquire(addr) \
+ AO_char_fetch_and_sub1_full(addr)
+# define AO_HAVE_char_fetch_and_sub1_acquire
+# endif
+# if !defined(AO_HAVE_char_fetch_and_sub1_write)
+# define AO_char_fetch_and_sub1_write(addr) \
+ AO_char_fetch_and_sub1_full(addr)
+# define AO_HAVE_char_fetch_and_sub1_write
+# endif
+# if !defined(AO_HAVE_char_fetch_and_sub1_read)
+# define AO_char_fetch_and_sub1_read(addr) \
+ AO_char_fetch_and_sub1_full(addr)
+# define AO_HAVE_char_fetch_and_sub1_read
+# endif
+#endif /* AO_HAVE_char_fetch_and_sub1_full */
+
+#if !defined(AO_HAVE_char_fetch_and_sub1) && \
+ defined(AO_HAVE_char_fetch_and_sub1_release)
+# define AO_char_fetch_and_sub1(addr) \
+ AO_char_fetch_and_sub1_release(addr)
+# define AO_HAVE_char_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1) && \
+ defined(AO_HAVE_char_fetch_and_sub1_acquire)
+# define AO_char_fetch_and_sub1(addr) \
+ AO_char_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_char_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1) && \
+ defined(AO_HAVE_char_fetch_and_sub1_write)
+# define AO_char_fetch_and_sub1(addr) \
+ AO_char_fetch_and_sub1_write(addr)
+# define AO_HAVE_char_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1) && \
+ defined(AO_HAVE_char_fetch_and_sub1_read)
+# define AO_char_fetch_and_sub1(addr) \
+ AO_char_fetch_and_sub1_read(addr)
+# define AO_HAVE_char_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_char_fetch_and_sub1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_char_fetch_and_sub1_full)
+# define AO_char_fetch_and_sub1_full(addr) \
+ (AO_nop_full(), AO_char_fetch_and_sub1_acquire(addr))
+# define AO_HAVE_char_fetch_and_sub1_full
+#endif
+
+#if !defined(AO_HAVE_char_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_char_fetch_and_sub1_write)
+# define AO_char_fetch_and_sub1_release_write(addr) \
+ AO_char_fetch_and_sub1_write(addr)
+# define AO_HAVE_char_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_char_fetch_and_sub1_release)
+# define AO_char_fetch_and_sub1_release_write(addr) \
+ AO_char_fetch_and_sub1_release(addr)
+# define AO_HAVE_char_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_sub1_read)
+# define AO_char_fetch_and_sub1_acquire_read(addr) \
+ AO_char_fetch_and_sub1_read(addr)
+# define AO_HAVE_char_fetch_and_sub1_acquire_read
+#endif
+#if !defined(AO_HAVE_char_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_char_fetch_and_sub1_acquire)
+# define AO_char_fetch_and_sub1_acquire_read(addr) \
+ AO_char_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_char_fetch_and_sub1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_char_fetch_and_sub1_acquire_read)
+# define AO_char_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_char_fetch_and_sub1_acquire_read(addr)
+# define AO_HAVE_char_fetch_and_sub1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_char_fetch_and_sub1)
+# define AO_char_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_char_fetch_and_sub1(addr)
+# define AO_HAVE_char_fetch_and_sub1_dd_acquire_read
+# endif
+#endif
+
+/* short_load */
+#if defined(AO_HAVE_short_load_acquire) && !defined(AO_HAVE_short_load)
+# define AO_short_load(addr) AO_short_load_acquire(addr)
+# define AO_HAVE_short_load
+#endif
+
+#if defined(AO_HAVE_short_load_full) && !defined(AO_HAVE_short_load_acquire)
+# define AO_short_load_acquire(addr) AO_short_load_full(addr)
+# define AO_HAVE_short_load_acquire
+#endif
+
+#if defined(AO_HAVE_short_load_full) && !defined(AO_HAVE_short_load_read)
+# define AO_short_load_read(addr) AO_short_load_full(addr)
+# define AO_HAVE_short_load_read
+#endif
+
+#if !defined(AO_HAVE_short_load_acquire_read) && defined(AO_HAVE_short_load_acquire)
+# define AO_short_load_acquire_read(addr) AO_short_load_acquire(addr)
+# define AO_HAVE_short_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_short_load) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_load_acquire)
+ AO_INLINE unsigned short
+ AO_short_load_acquire(volatile unsigned short *addr)
+ {
+ unsigned short result = AO_short_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_short_load_acquire
+#endif
+
+#if defined(AO_HAVE_short_load) && defined(AO_HAVE_nop_read) && \
+ !defined(AO_HAVE_short_load_read)
+ AO_INLINE unsigned short
+ AO_short_load_read(volatile unsigned short *addr)
+ {
+ unsigned short result = AO_short_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_read();
+ return result;
+ }
+# define AO_HAVE_short_load_read
+#endif
+
+#if defined(AO_HAVE_short_load_acquire) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_load_full)
+# define AO_short_load_full(addr) (AO_nop_full(), AO_short_load_acquire(addr))
+# define AO_HAVE_short_load_full
+#endif
+
+#if !defined(AO_HAVE_short_load_acquire_read) && defined(AO_HAVE_short_load_read)
+# define AO_short_load_acquire_read(addr) AO_short_load_read(addr)
+# define AO_HAVE_short_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_short_load_acquire_read) && !defined(AO_HAVE_short_load)
+# define AO_short_load(addr) AO_short_load_acquire_read(addr)
+# define AO_HAVE_short_load
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_short_load_acquire_read)
+# define AO_short_load_dd_acquire_read(addr) \
+ AO_short_load_acquire_read(addr)
+# define AO_HAVE_short_load_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_short_load)
+# define AO_short_load_dd_acquire_read(addr) \
+ AO_short_load(addr)
+# define AO_HAVE_short_load_dd_acquire_read
+# endif
+#endif
+
+
+/* short_store */
+
+#if defined(AO_HAVE_short_store_release) && !defined(AO_HAVE_short_store)
+# define AO_short_store(addr, val) AO_short_store_release(addr,val)
+# define AO_HAVE_short_store
+#endif
+
+#if defined(AO_HAVE_short_store_full) && !defined(AO_HAVE_short_store_release)
+# define AO_short_store_release(addr,val) AO_short_store_full(addr,val)
+# define AO_HAVE_short_store_release
+#endif
+
+#if defined(AO_HAVE_short_store_full) && !defined(AO_HAVE_short_store_write)
+# define AO_short_store_write(addr,val) AO_short_store_full(addr,val)
+# define AO_HAVE_short_store_write
+#endif
+
+#if defined(AO_HAVE_short_store_release) && \
+ !defined(AO_HAVE_short_store_release_write)
+# define AO_short_store_release_write(addr, val) \
+ AO_short_store_release(addr,val)
+# define AO_HAVE_short_store_release_write
+#endif
+
+#if defined(AO_HAVE_short_store_write) && !defined(AO_HAVE_short_store)
+# define AO_short_store(addr, val) AO_short_store_write(addr,val)
+# define AO_HAVE_short_store
+#endif
+
+#if defined(AO_HAVE_short_store) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_store_release)
+# define AO_short_store_release(addr,val) \
+ (AO_nop_full(), AO_short_store(addr,val))
+# define AO_HAVE_short_store_release
+#endif
+
+#if defined(AO_HAVE_nop_write) && defined(AO_HAVE_short_store) && \
+ !defined(AO_HAVE_short_store_write)
+# define AO_short_store_write(addr, val) \
+ (AO_nop_write(), AO_short_store(addr,val))
+# define AO_HAVE_short_store_write
+#endif
+
+#if defined(AO_HAVE_short_store_write) && \
+ !defined(AO_HAVE_short_store_release_write)
+# define AO_short_store_release_write(addr, val) AO_short_store_write(addr,val)
+# define AO_HAVE_short_store_release_write
+#endif
+
+#if defined(AO_HAVE_short_store_release) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_store_full)
+# define AO_short_store_full(addr, val) \
+ (AO_short_store_release(addr, val), AO_nop_full())
+# define AO_HAVE_short_store_full
+#endif
+
+
+/* short_fetch_and_add */
+#if defined(AO_HAVE_short_compare_and_swap_full) && \
+ !defined(AO_HAVE_short_fetch_and_add_full)
+ AO_INLINE AO_t
+ AO_short_fetch_and_add_full(volatile unsigned short *addr,
+ unsigned short incr)
+ {
+ unsigned short old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_short_compare_and_swap_full(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_short_fetch_and_add_full
+#endif
+
+#if defined(AO_HAVE_short_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_short_fetch_and_add_acquire)
+ AO_INLINE AO_t
+ AO_short_fetch_and_add_acquire(volatile unsigned short *addr,
+ unsigned short incr)
+ {
+ unsigned short old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_short_compare_and_swap_acquire(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_short_fetch_and_add_acquire
+#endif
+
+#if defined(AO_HAVE_short_compare_and_swap_release) && \
+ !defined(AO_HAVE_short_fetch_and_add_release)
+ AO_INLINE AO_t
+ AO_short_fetch_and_add_release(volatile unsigned short *addr,
+ unsigned short incr)
+ {
+ unsigned short old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_short_compare_and_swap_release(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_short_fetch_and_add_release
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_add_full)
+# if !defined(AO_HAVE_short_fetch_and_add_release)
+# define AO_short_fetch_and_add_release(addr, val) \
+ AO_short_fetch_and_add_full(addr, val)
+# define AO_HAVE_short_fetch_and_add_release
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add_acquire)
+# define AO_short_fetch_and_add_acquire(addr, val) \
+ AO_short_fetch_and_add_full(addr, val)
+# define AO_HAVE_short_fetch_and_add_acquire
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add_write)
+# define AO_short_fetch_and_add_write(addr, val) \
+ AO_short_fetch_and_add_full(addr, val)
+# define AO_HAVE_short_fetch_and_add_write
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add_read)
+# define AO_short_fetch_and_add_read(addr, val) \
+ AO_short_fetch_and_add_full(addr, val)
+# define AO_HAVE_short_fetch_and_add_read
+# endif
+#endif /* AO_HAVE_short_fetch_and_add_full */
+
+#if !defined(AO_HAVE_short_fetch_and_add) && \
+ defined(AO_HAVE_short_fetch_and_add_release)
+# define AO_short_fetch_and_add(addr, val) \
+ AO_short_fetch_and_add_release(addr, val)
+# define AO_HAVE_short_fetch_and_add
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add) && \
+ defined(AO_HAVE_short_fetch_and_add_acquire)
+# define AO_short_fetch_and_add(addr, val) \
+ AO_short_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_short_fetch_and_add
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add) && \
+ defined(AO_HAVE_short_fetch_and_add_write)
+# define AO_short_fetch_and_add(addr, val) \
+ AO_short_fetch_and_add_write(addr, val)
+# define AO_HAVE_short_fetch_and_add
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add) && \
+ defined(AO_HAVE_short_fetch_and_add_read)
+# define AO_short_fetch_and_add(addr, val) \
+ AO_short_fetch_and_add_read(addr, val)
+# define AO_HAVE_short_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_add_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_fetch_and_add_full)
+# define AO_short_fetch_and_add_full(addr, val) \
+ (AO_nop_full(), AO_short_fetch_and_add_acquire(addr, val))
+#endif
+
+#if !defined(AO_HAVE_short_fetch_and_add_release_write) && \
+ defined(AO_HAVE_short_fetch_and_add_write)
+# define AO_short_fetch_and_add_release_write(addr, val) \
+ AO_short_fetch_and_add_write(addr, val)
+# define AO_HAVE_short_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add_release_write) && \
+ defined(AO_HAVE_short_fetch_and_add_release)
+# define AO_short_fetch_and_add_release_write(addr, val) \
+ AO_short_fetch_and_add_release(addr, val)
+# define AO_HAVE_short_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_add_read)
+# define AO_short_fetch_and_add_acquire_read(addr, val) \
+ AO_short_fetch_and_add_read(addr, val)
+# define AO_HAVE_short_fetch_and_add_acquire_read
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_add_acquire)
+# define AO_short_fetch_and_add_acquire_read(addr, val) \
+ AO_short_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_short_fetch_and_add_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_short_fetch_and_add_acquire_read)
+# define AO_short_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_short_fetch_and_add_acquire_read(addr, val)
+# define AO_HAVE_short_fetch_and_add_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_short_fetch_and_add)
+# define AO_short_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_short_fetch_and_add(addr, val)
+# define AO_HAVE_short_fetch_and_add_dd_acquire_read
+# endif
+#endif
+
+/* short_fetch_and_add1 */
+
+#if defined(AO_HAVE_short_fetch_and_add_full) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_full)
+# define AO_short_fetch_and_add1_full(addr) \
+ AO_short_fetch_and_add_full(addr,1)
+# define AO_HAVE_short_fetch_and_add1_full
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_release) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_release)
+# define AO_short_fetch_and_add1_release(addr) \
+ AO_short_fetch_and_add_release(addr,1)
+# define AO_HAVE_short_fetch_and_add1_release
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_acquire)
+# define AO_short_fetch_and_add1_acquire(addr) \
+ AO_short_fetch_and_add_acquire(addr,1)
+# define AO_HAVE_short_fetch_and_add1_acquire
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_write) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_write)
+# define AO_short_fetch_and_add1_write(addr) \
+ AO_short_fetch_and_add_write(addr,1)
+# define AO_HAVE_short_fetch_and_add1_write
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_read) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_read)
+# define AO_short_fetch_and_add1_read(addr) \
+ AO_short_fetch_and_add_read(addr,1)
+# define AO_HAVE_short_fetch_and_add1_read
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_release_write)
+# define AO_short_fetch_and_add1_release_write(addr) \
+ AO_short_fetch_and_add_release_write(addr,1)
+# define AO_HAVE_short_fetch_and_add1_release_write
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_short_fetch_and_add1_acquire_read)
+# define AO_short_fetch_and_add1_acquire_read(addr) \
+ AO_short_fetch_and_add_acquire_read(addr,1)
+# define AO_HAVE_short_fetch_and_add1_acquire_read
+#endif
+#if defined(AO_HAVE_short_fetch_and_add) &&\
+ !defined(AO_HAVE_short_fetch_and_add1)
+# define AO_short_fetch_and_add1(addr) \
+ AO_short_fetch_and_add(addr,1)
+# define AO_HAVE_short_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_add1_full)
+# if !defined(AO_HAVE_short_fetch_and_add1_release)
+# define AO_short_fetch_and_add1_release(addr) \
+ AO_short_fetch_and_add1_full(addr)
+# define AO_HAVE_short_fetch_and_add1_release
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add1_acquire)
+# define AO_short_fetch_and_add1_acquire(addr) \
+ AO_short_fetch_and_add1_full(addr)
+# define AO_HAVE_short_fetch_and_add1_acquire
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add1_write)
+# define AO_short_fetch_and_add1_write(addr) \
+ AO_short_fetch_and_add1_full(addr)
+# define AO_HAVE_short_fetch_and_add1_write
+# endif
+# if !defined(AO_HAVE_short_fetch_and_add1_read)
+# define AO_short_fetch_and_add1_read(addr) \
+ AO_short_fetch_and_add1_full(addr)
+# define AO_HAVE_short_fetch_and_add1_read
+# endif
+#endif /* AO_HAVE_short_fetch_and_add1_full */
+
+#if !defined(AO_HAVE_short_fetch_and_add1) && \
+ defined(AO_HAVE_short_fetch_and_add1_release)
+# define AO_short_fetch_and_add1(addr) \
+ AO_short_fetch_and_add1_release(addr)
+# define AO_HAVE_short_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1) && \
+ defined(AO_HAVE_short_fetch_and_add1_acquire)
+# define AO_short_fetch_and_add1(addr) \
+ AO_short_fetch_and_add1_acquire(addr)
+# define AO_HAVE_short_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1) && \
+ defined(AO_HAVE_short_fetch_and_add1_write)
+# define AO_short_fetch_and_add1(addr) \
+ AO_short_fetch_and_add1_write(addr)
+# define AO_HAVE_short_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1) && \
+ defined(AO_HAVE_short_fetch_and_add1_read)
+# define AO_short_fetch_and_add1(addr) \
+ AO_short_fetch_and_add1_read(addr)
+# define AO_HAVE_short_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_add1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_fetch_and_add1_full)
+# define AO_short_fetch_and_add1_full(addr) \
+ (AO_nop_full(), AO_short_fetch_and_add1_acquire(addr))
+# define AO_HAVE_short_fetch_and_add1_full
+#endif
+
+#if !defined(AO_HAVE_short_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_short_fetch_and_add1_write)
+# define AO_short_fetch_and_add1_release_write(addr) \
+ AO_short_fetch_and_add1_write(addr)
+# define AO_HAVE_short_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_short_fetch_and_add1_release)
+# define AO_short_fetch_and_add1_release_write(addr) \
+ AO_short_fetch_and_add1_release(addr)
+# define AO_HAVE_short_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_add1_read)
+# define AO_short_fetch_and_add1_acquire_read(addr) \
+ AO_short_fetch_and_add1_read(addr)
+# define AO_HAVE_short_fetch_and_add1_acquire_read
+#endif
+#if !defined(AO_HAVE_short_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_add1_acquire)
+# define AO_short_fetch_and_add1_acquire_read(addr) \
+ AO_short_fetch_and_add1_acquire(addr)
+# define AO_HAVE_short_fetch_and_add1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_short_fetch_and_add1_acquire_read)
+# define AO_short_fetch_and_add1_dd_acquire_read(addr) \
+ AO_short_fetch_and_add1_acquire_read(addr)
+# define AO_HAVE_short_fetch_and_add1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_short_fetch_and_add1)
+# define AO_short_fetch_and_add1_dd_acquire_read(addr) \
+ AO_short_fetch_and_add1(addr)
+# define AO_HAVE_short_fetch_and_add1_dd_acquire_read
+# endif
+#endif
+
+/* short_fetch_and_sub1 */
+
+#if defined(AO_HAVE_short_fetch_and_add_full) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_full)
+# define AO_short_fetch_and_sub1_full(addr) \
+ AO_short_fetch_and_add_full(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_full
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_release) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_release)
+# define AO_short_fetch_and_sub1_release(addr) \
+ AO_short_fetch_and_add_release(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_release
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_acquire)
+# define AO_short_fetch_and_sub1_acquire(addr) \
+ AO_short_fetch_and_add_acquire(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_acquire
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_write) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_write)
+# define AO_short_fetch_and_sub1_write(addr) \
+ AO_short_fetch_and_add_write(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_write
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_read) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_read)
+# define AO_short_fetch_and_sub1_read(addr) \
+ AO_short_fetch_and_add_read(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_read
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_release_write)
+# define AO_short_fetch_and_sub1_release_write(addr) \
+ AO_short_fetch_and_add_release_write(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_release_write
+#endif
+#if defined(AO_HAVE_short_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1_acquire_read)
+# define AO_short_fetch_and_sub1_acquire_read(addr) \
+ AO_short_fetch_and_add_acquire_read(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1_acquire_read
+#endif
+#if defined(AO_HAVE_short_fetch_and_add) &&\
+ !defined(AO_HAVE_short_fetch_and_sub1)
+# define AO_short_fetch_and_sub1(addr) \
+ AO_short_fetch_and_add(addr,(unsigned short)(-1))
+# define AO_HAVE_short_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_sub1_full)
+# if !defined(AO_HAVE_short_fetch_and_sub1_release)
+# define AO_short_fetch_and_sub1_release(addr) \
+ AO_short_fetch_and_sub1_full(addr)
+# define AO_HAVE_short_fetch_and_sub1_release
+# endif
+# if !defined(AO_HAVE_short_fetch_and_sub1_acquire)
+# define AO_short_fetch_and_sub1_acquire(addr) \
+ AO_short_fetch_and_sub1_full(addr)
+# define AO_HAVE_short_fetch_and_sub1_acquire
+# endif
+# if !defined(AO_HAVE_short_fetch_and_sub1_write)
+# define AO_short_fetch_and_sub1_write(addr) \
+ AO_short_fetch_and_sub1_full(addr)
+# define AO_HAVE_short_fetch_and_sub1_write
+# endif
+# if !defined(AO_HAVE_short_fetch_and_sub1_read)
+# define AO_short_fetch_and_sub1_read(addr) \
+ AO_short_fetch_and_sub1_full(addr)
+# define AO_HAVE_short_fetch_and_sub1_read
+# endif
+#endif /* AO_HAVE_short_fetch_and_sub1_full */
+
+#if !defined(AO_HAVE_short_fetch_and_sub1) && \
+ defined(AO_HAVE_short_fetch_and_sub1_release)
+# define AO_short_fetch_and_sub1(addr) \
+ AO_short_fetch_and_sub1_release(addr)
+# define AO_HAVE_short_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1) && \
+ defined(AO_HAVE_short_fetch_and_sub1_acquire)
+# define AO_short_fetch_and_sub1(addr) \
+ AO_short_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_short_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1) && \
+ defined(AO_HAVE_short_fetch_and_sub1_write)
+# define AO_short_fetch_and_sub1(addr) \
+ AO_short_fetch_and_sub1_write(addr)
+# define AO_HAVE_short_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1) && \
+ defined(AO_HAVE_short_fetch_and_sub1_read)
+# define AO_short_fetch_and_sub1(addr) \
+ AO_short_fetch_and_sub1_read(addr)
+# define AO_HAVE_short_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_short_fetch_and_sub1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_short_fetch_and_sub1_full)
+# define AO_short_fetch_and_sub1_full(addr) \
+ (AO_nop_full(), AO_short_fetch_and_sub1_acquire(addr))
+# define AO_HAVE_short_fetch_and_sub1_full
+#endif
+
+#if !defined(AO_HAVE_short_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_short_fetch_and_sub1_write)
+# define AO_short_fetch_and_sub1_release_write(addr) \
+ AO_short_fetch_and_sub1_write(addr)
+# define AO_HAVE_short_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_short_fetch_and_sub1_release)
+# define AO_short_fetch_and_sub1_release_write(addr) \
+ AO_short_fetch_and_sub1_release(addr)
+# define AO_HAVE_short_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_sub1_read)
+# define AO_short_fetch_and_sub1_acquire_read(addr) \
+ AO_short_fetch_and_sub1_read(addr)
+# define AO_HAVE_short_fetch_and_sub1_acquire_read
+#endif
+#if !defined(AO_HAVE_short_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_short_fetch_and_sub1_acquire)
+# define AO_short_fetch_and_sub1_acquire_read(addr) \
+ AO_short_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_short_fetch_and_sub1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_short_fetch_and_sub1_acquire_read)
+# define AO_short_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_short_fetch_and_sub1_acquire_read(addr)
+# define AO_HAVE_short_fetch_and_sub1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_short_fetch_and_sub1)
+# define AO_short_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_short_fetch_and_sub1(addr)
+# define AO_HAVE_short_fetch_and_sub1_dd_acquire_read
+# endif
+#endif
+
+/* int_load */
+#if defined(AO_HAVE_int_load_acquire) && !defined(AO_HAVE_int_load)
+# define AO_int_load(addr) AO_int_load_acquire(addr)
+# define AO_HAVE_int_load
+#endif
+
+#if defined(AO_HAVE_int_load_full) && !defined(AO_HAVE_int_load_acquire)
+# define AO_int_load_acquire(addr) AO_int_load_full(addr)
+# define AO_HAVE_int_load_acquire
+#endif
+
+#if defined(AO_HAVE_int_load_full) && !defined(AO_HAVE_int_load_read)
+# define AO_int_load_read(addr) AO_int_load_full(addr)
+# define AO_HAVE_int_load_read
+#endif
+
+#if !defined(AO_HAVE_int_load_acquire_read) && defined(AO_HAVE_int_load_acquire)
+# define AO_int_load_acquire_read(addr) AO_int_load_acquire(addr)
+# define AO_HAVE_int_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_int_load) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_load_acquire)
+ AO_INLINE unsigned int
+ AO_int_load_acquire(volatile unsigned int *addr)
+ {
+ unsigned int result = AO_int_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_int_load_acquire
+#endif
+
+#if defined(AO_HAVE_int_load) && defined(AO_HAVE_nop_read) && \
+ !defined(AO_HAVE_int_load_read)
+ AO_INLINE unsigned int
+ AO_int_load_read(volatile unsigned int *addr)
+ {
+ unsigned int result = AO_int_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_read();
+ return result;
+ }
+# define AO_HAVE_int_load_read
+#endif
+
+#if defined(AO_HAVE_int_load_acquire) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_load_full)
+# define AO_int_load_full(addr) (AO_nop_full(), AO_int_load_acquire(addr))
+# define AO_HAVE_int_load_full
+#endif
+
+#if !defined(AO_HAVE_int_load_acquire_read) && defined(AO_HAVE_int_load_read)
+# define AO_int_load_acquire_read(addr) AO_int_load_read(addr)
+# define AO_HAVE_int_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_int_load_acquire_read) && !defined(AO_HAVE_int_load)
+# define AO_int_load(addr) AO_int_load_acquire_read(addr)
+# define AO_HAVE_int_load
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_int_load_acquire_read)
+# define AO_int_load_dd_acquire_read(addr) \
+ AO_int_load_acquire_read(addr)
+# define AO_HAVE_int_load_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_int_load)
+# define AO_int_load_dd_acquire_read(addr) \
+ AO_int_load(addr)
+# define AO_HAVE_int_load_dd_acquire_read
+# endif
+#endif
+
+
+/* int_store */
+
+#if defined(AO_HAVE_int_store_release) && !defined(AO_HAVE_int_store)
+# define AO_int_store(addr, val) AO_int_store_release(addr,val)
+# define AO_HAVE_int_store
+#endif
+
+#if defined(AO_HAVE_int_store_full) && !defined(AO_HAVE_int_store_release)
+# define AO_int_store_release(addr,val) AO_int_store_full(addr,val)
+# define AO_HAVE_int_store_release
+#endif
+
+#if defined(AO_HAVE_int_store_full) && !defined(AO_HAVE_int_store_write)
+# define AO_int_store_write(addr,val) AO_int_store_full(addr,val)
+# define AO_HAVE_int_store_write
+#endif
+
+#if defined(AO_HAVE_int_store_release) && \
+ !defined(AO_HAVE_int_store_release_write)
+# define AO_int_store_release_write(addr, val) \
+ AO_int_store_release(addr,val)
+# define AO_HAVE_int_store_release_write
+#endif
+
+#if defined(AO_HAVE_int_store_write) && !defined(AO_HAVE_int_store)
+# define AO_int_store(addr, val) AO_int_store_write(addr,val)
+# define AO_HAVE_int_store
+#endif
+
+#if defined(AO_HAVE_int_store) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_store_release)
+# define AO_int_store_release(addr,val) \
+ (AO_nop_full(), AO_int_store(addr,val))
+# define AO_HAVE_int_store_release
+#endif
+
+#if defined(AO_HAVE_nop_write) && defined(AO_HAVE_int_store) && \
+ !defined(AO_HAVE_int_store_write)
+# define AO_int_store_write(addr, val) \
+ (AO_nop_write(), AO_int_store(addr,val))
+# define AO_HAVE_int_store_write
+#endif
+
+#if defined(AO_HAVE_int_store_write) && \
+ !defined(AO_HAVE_int_store_release_write)
+# define AO_int_store_release_write(addr, val) AO_int_store_write(addr,val)
+# define AO_HAVE_int_store_release_write
+#endif
+
+#if defined(AO_HAVE_int_store_release) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_store_full)
+# define AO_int_store_full(addr, val) \
+ (AO_int_store_release(addr, val), AO_nop_full())
+# define AO_HAVE_int_store_full
+#endif
+
+
+/* int_fetch_and_add */
+#if defined(AO_HAVE_int_compare_and_swap_full) && \
+ !defined(AO_HAVE_int_fetch_and_add_full)
+ AO_INLINE AO_t
+ AO_int_fetch_and_add_full(volatile unsigned int *addr,
+ unsigned int incr)
+ {
+ unsigned int old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_int_compare_and_swap_full(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_int_fetch_and_add_full
+#endif
+
+#if defined(AO_HAVE_int_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_int_fetch_and_add_acquire)
+ AO_INLINE AO_t
+ AO_int_fetch_and_add_acquire(volatile unsigned int *addr,
+ unsigned int incr)
+ {
+ unsigned int old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_int_compare_and_swap_acquire(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_int_fetch_and_add_acquire
+#endif
+
+#if defined(AO_HAVE_int_compare_and_swap_release) && \
+ !defined(AO_HAVE_int_fetch_and_add_release)
+ AO_INLINE AO_t
+ AO_int_fetch_and_add_release(volatile unsigned int *addr,
+ unsigned int incr)
+ {
+ unsigned int old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_int_compare_and_swap_release(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_int_fetch_and_add_release
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_add_full)
+# if !defined(AO_HAVE_int_fetch_and_add_release)
+# define AO_int_fetch_and_add_release(addr, val) \
+ AO_int_fetch_and_add_full(addr, val)
+# define AO_HAVE_int_fetch_and_add_release
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add_acquire)
+# define AO_int_fetch_and_add_acquire(addr, val) \
+ AO_int_fetch_and_add_full(addr, val)
+# define AO_HAVE_int_fetch_and_add_acquire
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add_write)
+# define AO_int_fetch_and_add_write(addr, val) \
+ AO_int_fetch_and_add_full(addr, val)
+# define AO_HAVE_int_fetch_and_add_write
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add_read)
+# define AO_int_fetch_and_add_read(addr, val) \
+ AO_int_fetch_and_add_full(addr, val)
+# define AO_HAVE_int_fetch_and_add_read
+# endif
+#endif /* AO_HAVE_int_fetch_and_add_full */
+
+#if !defined(AO_HAVE_int_fetch_and_add) && \
+ defined(AO_HAVE_int_fetch_and_add_release)
+# define AO_int_fetch_and_add(addr, val) \
+ AO_int_fetch_and_add_release(addr, val)
+# define AO_HAVE_int_fetch_and_add
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add) && \
+ defined(AO_HAVE_int_fetch_and_add_acquire)
+# define AO_int_fetch_and_add(addr, val) \
+ AO_int_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_int_fetch_and_add
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add) && \
+ defined(AO_HAVE_int_fetch_and_add_write)
+# define AO_int_fetch_and_add(addr, val) \
+ AO_int_fetch_and_add_write(addr, val)
+# define AO_HAVE_int_fetch_and_add
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add) && \
+ defined(AO_HAVE_int_fetch_and_add_read)
+# define AO_int_fetch_and_add(addr, val) \
+ AO_int_fetch_and_add_read(addr, val)
+# define AO_HAVE_int_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_add_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_fetch_and_add_full)
+# define AO_int_fetch_and_add_full(addr, val) \
+ (AO_nop_full(), AO_int_fetch_and_add_acquire(addr, val))
+#endif
+
+#if !defined(AO_HAVE_int_fetch_and_add_release_write) && \
+ defined(AO_HAVE_int_fetch_and_add_write)
+# define AO_int_fetch_and_add_release_write(addr, val) \
+ AO_int_fetch_and_add_write(addr, val)
+# define AO_HAVE_int_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add_release_write) && \
+ defined(AO_HAVE_int_fetch_and_add_release)
+# define AO_int_fetch_and_add_release_write(addr, val) \
+ AO_int_fetch_and_add_release(addr, val)
+# define AO_HAVE_int_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_add_read)
+# define AO_int_fetch_and_add_acquire_read(addr, val) \
+ AO_int_fetch_and_add_read(addr, val)
+# define AO_HAVE_int_fetch_and_add_acquire_read
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_add_acquire)
+# define AO_int_fetch_and_add_acquire_read(addr, val) \
+ AO_int_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_int_fetch_and_add_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_int_fetch_and_add_acquire_read)
+# define AO_int_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_int_fetch_and_add_acquire_read(addr, val)
+# define AO_HAVE_int_fetch_and_add_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_int_fetch_and_add)
+# define AO_int_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_int_fetch_and_add(addr, val)
+# define AO_HAVE_int_fetch_and_add_dd_acquire_read
+# endif
+#endif
+
+/* int_fetch_and_add1 */
+
+#if defined(AO_HAVE_int_fetch_and_add_full) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_full)
+# define AO_int_fetch_and_add1_full(addr) \
+ AO_int_fetch_and_add_full(addr,1)
+# define AO_HAVE_int_fetch_and_add1_full
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_release) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_release)
+# define AO_int_fetch_and_add1_release(addr) \
+ AO_int_fetch_and_add_release(addr,1)
+# define AO_HAVE_int_fetch_and_add1_release
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_acquire)
+# define AO_int_fetch_and_add1_acquire(addr) \
+ AO_int_fetch_and_add_acquire(addr,1)
+# define AO_HAVE_int_fetch_and_add1_acquire
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_write) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_write)
+# define AO_int_fetch_and_add1_write(addr) \
+ AO_int_fetch_and_add_write(addr,1)
+# define AO_HAVE_int_fetch_and_add1_write
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_read) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_read)
+# define AO_int_fetch_and_add1_read(addr) \
+ AO_int_fetch_and_add_read(addr,1)
+# define AO_HAVE_int_fetch_and_add1_read
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_release_write)
+# define AO_int_fetch_and_add1_release_write(addr) \
+ AO_int_fetch_and_add_release_write(addr,1)
+# define AO_HAVE_int_fetch_and_add1_release_write
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_int_fetch_and_add1_acquire_read)
+# define AO_int_fetch_and_add1_acquire_read(addr) \
+ AO_int_fetch_and_add_acquire_read(addr,1)
+# define AO_HAVE_int_fetch_and_add1_acquire_read
+#endif
+#if defined(AO_HAVE_int_fetch_and_add) &&\
+ !defined(AO_HAVE_int_fetch_and_add1)
+# define AO_int_fetch_and_add1(addr) \
+ AO_int_fetch_and_add(addr,1)
+# define AO_HAVE_int_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_add1_full)
+# if !defined(AO_HAVE_int_fetch_and_add1_release)
+# define AO_int_fetch_and_add1_release(addr) \
+ AO_int_fetch_and_add1_full(addr)
+# define AO_HAVE_int_fetch_and_add1_release
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add1_acquire)
+# define AO_int_fetch_and_add1_acquire(addr) \
+ AO_int_fetch_and_add1_full(addr)
+# define AO_HAVE_int_fetch_and_add1_acquire
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add1_write)
+# define AO_int_fetch_and_add1_write(addr) \
+ AO_int_fetch_and_add1_full(addr)
+# define AO_HAVE_int_fetch_and_add1_write
+# endif
+# if !defined(AO_HAVE_int_fetch_and_add1_read)
+# define AO_int_fetch_and_add1_read(addr) \
+ AO_int_fetch_and_add1_full(addr)
+# define AO_HAVE_int_fetch_and_add1_read
+# endif
+#endif /* AO_HAVE_int_fetch_and_add1_full */
+
+#if !defined(AO_HAVE_int_fetch_and_add1) && \
+ defined(AO_HAVE_int_fetch_and_add1_release)
+# define AO_int_fetch_and_add1(addr) \
+ AO_int_fetch_and_add1_release(addr)
+# define AO_HAVE_int_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1) && \
+ defined(AO_HAVE_int_fetch_and_add1_acquire)
+# define AO_int_fetch_and_add1(addr) \
+ AO_int_fetch_and_add1_acquire(addr)
+# define AO_HAVE_int_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1) && \
+ defined(AO_HAVE_int_fetch_and_add1_write)
+# define AO_int_fetch_and_add1(addr) \
+ AO_int_fetch_and_add1_write(addr)
+# define AO_HAVE_int_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1) && \
+ defined(AO_HAVE_int_fetch_and_add1_read)
+# define AO_int_fetch_and_add1(addr) \
+ AO_int_fetch_and_add1_read(addr)
+# define AO_HAVE_int_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_add1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_fetch_and_add1_full)
+# define AO_int_fetch_and_add1_full(addr) \
+ (AO_nop_full(), AO_int_fetch_and_add1_acquire(addr))
+# define AO_HAVE_int_fetch_and_add1_full
+#endif
+
+#if !defined(AO_HAVE_int_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_int_fetch_and_add1_write)
+# define AO_int_fetch_and_add1_release_write(addr) \
+ AO_int_fetch_and_add1_write(addr)
+# define AO_HAVE_int_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_int_fetch_and_add1_release)
+# define AO_int_fetch_and_add1_release_write(addr) \
+ AO_int_fetch_and_add1_release(addr)
+# define AO_HAVE_int_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_add1_read)
+# define AO_int_fetch_and_add1_acquire_read(addr) \
+ AO_int_fetch_and_add1_read(addr)
+# define AO_HAVE_int_fetch_and_add1_acquire_read
+#endif
+#if !defined(AO_HAVE_int_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_add1_acquire)
+# define AO_int_fetch_and_add1_acquire_read(addr) \
+ AO_int_fetch_and_add1_acquire(addr)
+# define AO_HAVE_int_fetch_and_add1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_int_fetch_and_add1_acquire_read)
+# define AO_int_fetch_and_add1_dd_acquire_read(addr) \
+ AO_int_fetch_and_add1_acquire_read(addr)
+# define AO_HAVE_int_fetch_and_add1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_int_fetch_and_add1)
+# define AO_int_fetch_and_add1_dd_acquire_read(addr) \
+ AO_int_fetch_and_add1(addr)
+# define AO_HAVE_int_fetch_and_add1_dd_acquire_read
+# endif
+#endif
+
+/* int_fetch_and_sub1 */
+
+#if defined(AO_HAVE_int_fetch_and_add_full) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_full)
+# define AO_int_fetch_and_sub1_full(addr) \
+ AO_int_fetch_and_add_full(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_full
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_release) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_release)
+# define AO_int_fetch_and_sub1_release(addr) \
+ AO_int_fetch_and_add_release(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_release
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_acquire)
+# define AO_int_fetch_and_sub1_acquire(addr) \
+ AO_int_fetch_and_add_acquire(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_acquire
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_write) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_write)
+# define AO_int_fetch_and_sub1_write(addr) \
+ AO_int_fetch_and_add_write(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_write
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_read) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_read)
+# define AO_int_fetch_and_sub1_read(addr) \
+ AO_int_fetch_and_add_read(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_read
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_release_write)
+# define AO_int_fetch_and_sub1_release_write(addr) \
+ AO_int_fetch_and_add_release_write(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_release_write
+#endif
+#if defined(AO_HAVE_int_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1_acquire_read)
+# define AO_int_fetch_and_sub1_acquire_read(addr) \
+ AO_int_fetch_and_add_acquire_read(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1_acquire_read
+#endif
+#if defined(AO_HAVE_int_fetch_and_add) &&\
+ !defined(AO_HAVE_int_fetch_and_sub1)
+# define AO_int_fetch_and_sub1(addr) \
+ AO_int_fetch_and_add(addr,(unsigned int)(-1))
+# define AO_HAVE_int_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_sub1_full)
+# if !defined(AO_HAVE_int_fetch_and_sub1_release)
+# define AO_int_fetch_and_sub1_release(addr) \
+ AO_int_fetch_and_sub1_full(addr)
+# define AO_HAVE_int_fetch_and_sub1_release
+# endif
+# if !defined(AO_HAVE_int_fetch_and_sub1_acquire)
+# define AO_int_fetch_and_sub1_acquire(addr) \
+ AO_int_fetch_and_sub1_full(addr)
+# define AO_HAVE_int_fetch_and_sub1_acquire
+# endif
+# if !defined(AO_HAVE_int_fetch_and_sub1_write)
+# define AO_int_fetch_and_sub1_write(addr) \
+ AO_int_fetch_and_sub1_full(addr)
+# define AO_HAVE_int_fetch_and_sub1_write
+# endif
+# if !defined(AO_HAVE_int_fetch_and_sub1_read)
+# define AO_int_fetch_and_sub1_read(addr) \
+ AO_int_fetch_and_sub1_full(addr)
+# define AO_HAVE_int_fetch_and_sub1_read
+# endif
+#endif /* AO_HAVE_int_fetch_and_sub1_full */
+
+#if !defined(AO_HAVE_int_fetch_and_sub1) && \
+ defined(AO_HAVE_int_fetch_and_sub1_release)
+# define AO_int_fetch_and_sub1(addr) \
+ AO_int_fetch_and_sub1_release(addr)
+# define AO_HAVE_int_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1) && \
+ defined(AO_HAVE_int_fetch_and_sub1_acquire)
+# define AO_int_fetch_and_sub1(addr) \
+ AO_int_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_int_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1) && \
+ defined(AO_HAVE_int_fetch_and_sub1_write)
+# define AO_int_fetch_and_sub1(addr) \
+ AO_int_fetch_and_sub1_write(addr)
+# define AO_HAVE_int_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1) && \
+ defined(AO_HAVE_int_fetch_and_sub1_read)
+# define AO_int_fetch_and_sub1(addr) \
+ AO_int_fetch_and_sub1_read(addr)
+# define AO_HAVE_int_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_int_fetch_and_sub1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_int_fetch_and_sub1_full)
+# define AO_int_fetch_and_sub1_full(addr) \
+ (AO_nop_full(), AO_int_fetch_and_sub1_acquire(addr))
+# define AO_HAVE_int_fetch_and_sub1_full
+#endif
+
+#if !defined(AO_HAVE_int_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_int_fetch_and_sub1_write)
+# define AO_int_fetch_and_sub1_release_write(addr) \
+ AO_int_fetch_and_sub1_write(addr)
+# define AO_HAVE_int_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_int_fetch_and_sub1_release)
+# define AO_int_fetch_and_sub1_release_write(addr) \
+ AO_int_fetch_and_sub1_release(addr)
+# define AO_HAVE_int_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_sub1_read)
+# define AO_int_fetch_and_sub1_acquire_read(addr) \
+ AO_int_fetch_and_sub1_read(addr)
+# define AO_HAVE_int_fetch_and_sub1_acquire_read
+#endif
+#if !defined(AO_HAVE_int_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_int_fetch_and_sub1_acquire)
+# define AO_int_fetch_and_sub1_acquire_read(addr) \
+ AO_int_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_int_fetch_and_sub1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_int_fetch_and_sub1_acquire_read)
+# define AO_int_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_int_fetch_and_sub1_acquire_read(addr)
+# define AO_HAVE_int_fetch_and_sub1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_int_fetch_and_sub1)
+# define AO_int_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_int_fetch_and_sub1(addr)
+# define AO_HAVE_int_fetch_and_sub1_dd_acquire_read
+# endif
+#endif
+
diff --git a/src/atomic_ops/generalize-small.template b/src/atomic_ops/generalize-small.template
new file mode 100644
index 0000000..b7e02b0
--- /dev/null
+++ b/src/atomic_ops/generalize-small.template
@@ -0,0 +1,575 @@
+/* XSIZE_load */
+#if defined(AO_HAVE_XSIZE_load_acquire) && !defined(AO_HAVE_XSIZE_load)
+# define AO_XSIZE_load(addr) AO_XSIZE_load_acquire(addr)
+# define AO_HAVE_XSIZE_load
+#endif
+
+#if defined(AO_HAVE_XSIZE_load_full) && !defined(AO_HAVE_XSIZE_load_acquire)
+# define AO_XSIZE_load_acquire(addr) AO_XSIZE_load_full(addr)
+# define AO_HAVE_XSIZE_load_acquire
+#endif
+
+#if defined(AO_HAVE_XSIZE_load_full) && !defined(AO_HAVE_XSIZE_load_read)
+# define AO_XSIZE_load_read(addr) AO_XSIZE_load_full(addr)
+# define AO_HAVE_XSIZE_load_read
+#endif
+
+#if !defined(AO_HAVE_XSIZE_load_acquire_read) && defined(AO_HAVE_XSIZE_load_acquire)
+# define AO_XSIZE_load_acquire_read(addr) AO_XSIZE_load_acquire(addr)
+# define AO_HAVE_XSIZE_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_XSIZE_load) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_load_acquire)
+ AO_INLINE unsigned XCTYPE
+ AO_XSIZE_load_acquire(volatile unsigned XCTYPE *addr)
+ {
+ unsigned XCTYPE result = AO_XSIZE_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_XSIZE_load_acquire
+#endif
+
+#if defined(AO_HAVE_XSIZE_load) && defined(AO_HAVE_nop_read) && \
+ !defined(AO_HAVE_XSIZE_load_read)
+ AO_INLINE unsigned XCTYPE
+ AO_XSIZE_load_read(volatile unsigned XCTYPE *addr)
+ {
+ unsigned XCTYPE result = AO_XSIZE_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_read();
+ return result;
+ }
+# define AO_HAVE_XSIZE_load_read
+#endif
+
+#if defined(AO_HAVE_XSIZE_load_acquire) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_load_full)
+# define AO_XSIZE_load_full(addr) (AO_nop_full(), AO_XSIZE_load_acquire(addr))
+# define AO_HAVE_XSIZE_load_full
+#endif
+
+#if !defined(AO_HAVE_XSIZE_load_acquire_read) && defined(AO_HAVE_XSIZE_load_read)
+# define AO_XSIZE_load_acquire_read(addr) AO_XSIZE_load_read(addr)
+# define AO_HAVE_XSIZE_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_XSIZE_load_acquire_read) && !defined(AO_HAVE_XSIZE_load)
+# define AO_XSIZE_load(addr) AO_XSIZE_load_acquire_read(addr)
+# define AO_HAVE_XSIZE_load
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_XSIZE_load_acquire_read)
+# define AO_XSIZE_load_dd_acquire_read(addr) \
+ AO_XSIZE_load_acquire_read(addr)
+# define AO_HAVE_XSIZE_load_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_XSIZE_load)
+# define AO_XSIZE_load_dd_acquire_read(addr) \
+ AO_XSIZE_load(addr)
+# define AO_HAVE_XSIZE_load_dd_acquire_read
+# endif
+#endif
+
+
+/* XSIZE_store */
+
+#if defined(AO_HAVE_XSIZE_store_release) && !defined(AO_HAVE_XSIZE_store)
+# define AO_XSIZE_store(addr, val) AO_XSIZE_store_release(addr,val)
+# define AO_HAVE_XSIZE_store
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_full) && !defined(AO_HAVE_XSIZE_store_release)
+# define AO_XSIZE_store_release(addr,val) AO_XSIZE_store_full(addr,val)
+# define AO_HAVE_XSIZE_store_release
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_full) && !defined(AO_HAVE_XSIZE_store_write)
+# define AO_XSIZE_store_write(addr,val) AO_XSIZE_store_full(addr,val)
+# define AO_HAVE_XSIZE_store_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_release) && \
+ !defined(AO_HAVE_XSIZE_store_release_write)
+# define AO_XSIZE_store_release_write(addr, val) \
+ AO_XSIZE_store_release(addr,val)
+# define AO_HAVE_XSIZE_store_release_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_write) && !defined(AO_HAVE_XSIZE_store)
+# define AO_XSIZE_store(addr, val) AO_XSIZE_store_write(addr,val)
+# define AO_HAVE_XSIZE_store
+#endif
+
+#if defined(AO_HAVE_XSIZE_store) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_store_release)
+# define AO_XSIZE_store_release(addr,val) \
+ (AO_nop_full(), AO_XSIZE_store(addr,val))
+# define AO_HAVE_XSIZE_store_release
+#endif
+
+#if defined(AO_HAVE_nop_write) && defined(AO_HAVE_XSIZE_store) && \
+ !defined(AO_HAVE_XSIZE_store_write)
+# define AO_XSIZE_store_write(addr, val) \
+ (AO_nop_write(), AO_XSIZE_store(addr,val))
+# define AO_HAVE_XSIZE_store_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_write) && \
+ !defined(AO_HAVE_XSIZE_store_release_write)
+# define AO_XSIZE_store_release_write(addr, val) AO_XSIZE_store_write(addr,val)
+# define AO_HAVE_XSIZE_store_release_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_store_release) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_store_full)
+# define AO_XSIZE_store_full(addr, val) \
+ (AO_XSIZE_store_release(addr, val), AO_nop_full())
+# define AO_HAVE_XSIZE_store_full
+#endif
+
+
+/* XSIZE_fetch_and_add */
+#if defined(AO_HAVE_XSIZE_compare_and_swap_full) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_add_full)
+ AO_INLINE AO_t
+ AO_XSIZE_fetch_and_add_full(volatile unsigned XCTYPE *addr,
+ unsigned XCTYPE incr)
+ {
+ unsigned XCTYPE old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_XSIZE_compare_and_swap_full(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_XSIZE_fetch_and_add_full
+#endif
+
+#if defined(AO_HAVE_XSIZE_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_add_acquire)
+ AO_INLINE AO_t
+ AO_XSIZE_fetch_and_add_acquire(volatile unsigned XCTYPE *addr,
+ unsigned XCTYPE incr)
+ {
+ unsigned XCTYPE old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_XSIZE_compare_and_swap_acquire(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_XSIZE_fetch_and_add_acquire
+#endif
+
+#if defined(AO_HAVE_XSIZE_compare_and_swap_release) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_add_release)
+ AO_INLINE AO_t
+ AO_XSIZE_fetch_and_add_release(volatile unsigned XCTYPE *addr,
+ unsigned XCTYPE incr)
+ {
+ unsigned XCTYPE old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_XSIZE_compare_and_swap_release(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_XSIZE_fetch_and_add_release
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add_full)
+# if !defined(AO_HAVE_XSIZE_fetch_and_add_release)
+# define AO_XSIZE_fetch_and_add_release(addr, val) \
+ AO_XSIZE_fetch_and_add_full(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_release
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add_acquire)
+# define AO_XSIZE_fetch_and_add_acquire(addr, val) \
+ AO_XSIZE_fetch_and_add_full(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_acquire
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add_write)
+# define AO_XSIZE_fetch_and_add_write(addr, val) \
+ AO_XSIZE_fetch_and_add_full(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_write
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add_read)
+# define AO_XSIZE_fetch_and_add_read(addr, val) \
+ AO_XSIZE_fetch_and_add_full(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_read
+# endif
+#endif /* AO_HAVE_XSIZE_fetch_and_add_full */
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_add) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_release)
+# define AO_XSIZE_fetch_and_add(addr, val) \
+ AO_XSIZE_fetch_and_add_release(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_acquire)
+# define AO_XSIZE_fetch_and_add(addr, val) \
+ AO_XSIZE_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_write)
+# define AO_XSIZE_fetch_and_add(addr, val) \
+ AO_XSIZE_fetch_and_add_write(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_read)
+# define AO_XSIZE_fetch_and_add(addr, val) \
+ AO_XSIZE_fetch_and_add_read(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_add_full)
+# define AO_XSIZE_fetch_and_add_full(addr, val) \
+ (AO_nop_full(), AO_XSIZE_fetch_and_add_acquire(addr, val))
+#endif
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_add_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_write)
+# define AO_XSIZE_fetch_and_add_release_write(addr, val) \
+ AO_XSIZE_fetch_and_add_write(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_release)
+# define AO_XSIZE_fetch_and_add_release_write(addr, val) \
+ AO_XSIZE_fetch_and_add_release(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_read)
+# define AO_XSIZE_fetch_and_add_acquire_read(addr, val) \
+ AO_XSIZE_fetch_and_add_read(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_acquire_read
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add_acquire)
+# define AO_XSIZE_fetch_and_add_acquire_read(addr, val) \
+ AO_XSIZE_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_XSIZE_fetch_and_add_acquire_read)
+# define AO_XSIZE_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_XSIZE_fetch_and_add_acquire_read(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_XSIZE_fetch_and_add)
+# define AO_XSIZE_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_XSIZE_fetch_and_add(addr, val)
+# define AO_HAVE_XSIZE_fetch_and_add_dd_acquire_read
+# endif
+#endif
+
+/* XSIZE_fetch_and_add1 */
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add_full) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_full)
+# define AO_XSIZE_fetch_and_add1_full(addr) \
+ AO_XSIZE_fetch_and_add_full(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_full
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_release) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_release)
+# define AO_XSIZE_fetch_and_add1_release(addr) \
+ AO_XSIZE_fetch_and_add_release(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_release
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_acquire)
+# define AO_XSIZE_fetch_and_add1_acquire(addr) \
+ AO_XSIZE_fetch_and_add_acquire(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_acquire
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_write) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_write)
+# define AO_XSIZE_fetch_and_add1_write(addr) \
+ AO_XSIZE_fetch_and_add_write(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_write
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_read) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_read)
+# define AO_XSIZE_fetch_and_add1_read(addr) \
+ AO_XSIZE_fetch_and_add_read(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_read
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_release_write)
+# define AO_XSIZE_fetch_and_add1_release_write(addr) \
+ AO_XSIZE_fetch_and_add_release_write(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_release_write
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_acquire_read)
+# define AO_XSIZE_fetch_and_add1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add_acquire_read(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1_acquire_read
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_add1)
+# define AO_XSIZE_fetch_and_add1(addr) \
+ AO_XSIZE_fetch_and_add(addr,1)
+# define AO_HAVE_XSIZE_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add1_full)
+# if !defined(AO_HAVE_XSIZE_fetch_and_add1_release)
+# define AO_XSIZE_fetch_and_add1_release(addr) \
+ AO_XSIZE_fetch_and_add1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_release
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add1_acquire)
+# define AO_XSIZE_fetch_and_add1_acquire(addr) \
+ AO_XSIZE_fetch_and_add1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_acquire
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add1_write)
+# define AO_XSIZE_fetch_and_add1_write(addr) \
+ AO_XSIZE_fetch_and_add1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_write
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_add1_read)
+# define AO_XSIZE_fetch_and_add1_read(addr) \
+ AO_XSIZE_fetch_and_add1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_read
+# endif
+#endif /* AO_HAVE_XSIZE_fetch_and_add1_full */
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_release)
+# define AO_XSIZE_fetch_and_add1(addr) \
+ AO_XSIZE_fetch_and_add1_release(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_acquire)
+# define AO_XSIZE_fetch_and_add1(addr) \
+ AO_XSIZE_fetch_and_add1_acquire(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_write)
+# define AO_XSIZE_fetch_and_add1(addr) \
+ AO_XSIZE_fetch_and_add1_write(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_read)
+# define AO_XSIZE_fetch_and_add1(addr) \
+ AO_XSIZE_fetch_and_add1_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_add1_full)
+# define AO_XSIZE_fetch_and_add1_full(addr) \
+ (AO_nop_full(), AO_XSIZE_fetch_and_add1_acquire(addr))
+# define AO_HAVE_XSIZE_fetch_and_add1_full
+#endif
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_write)
+# define AO_XSIZE_fetch_and_add1_release_write(addr) \
+ AO_XSIZE_fetch_and_add1_write(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_release)
+# define AO_XSIZE_fetch_and_add1_release_write(addr) \
+ AO_XSIZE_fetch_and_add1_release(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_read)
+# define AO_XSIZE_fetch_and_add1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add1_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_acquire_read
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_add1_acquire)
+# define AO_XSIZE_fetch_and_add1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add1_acquire(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_XSIZE_fetch_and_add1_acquire_read)
+# define AO_XSIZE_fetch_and_add1_dd_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add1_acquire_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_XSIZE_fetch_and_add1)
+# define AO_XSIZE_fetch_and_add1_dd_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add1(addr)
+# define AO_HAVE_XSIZE_fetch_and_add1_dd_acquire_read
+# endif
+#endif
+
+/* XSIZE_fetch_and_sub1 */
+
+#if defined(AO_HAVE_XSIZE_fetch_and_add_full) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_full)
+# define AO_XSIZE_fetch_and_sub1_full(addr) \
+ AO_XSIZE_fetch_and_add_full(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_full
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_release) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_release)
+# define AO_XSIZE_fetch_and_sub1_release(addr) \
+ AO_XSIZE_fetch_and_add_release(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_release
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire)
+# define AO_XSIZE_fetch_and_sub1_acquire(addr) \
+ AO_XSIZE_fetch_and_add_acquire(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_acquire
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_write) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_write)
+# define AO_XSIZE_fetch_and_sub1_write(addr) \
+ AO_XSIZE_fetch_and_add_write(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_write
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_read) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_read)
+# define AO_XSIZE_fetch_and_sub1_read(addr) \
+ AO_XSIZE_fetch_and_add_read(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_read
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_release_write)
+# define AO_XSIZE_fetch_and_sub1_release_write(addr) \
+ AO_XSIZE_fetch_and_add_release_write(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_release_write
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire_read)
+# define AO_XSIZE_fetch_and_sub1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_add_acquire_read(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1_acquire_read
+#endif
+#if defined(AO_HAVE_XSIZE_fetch_and_add) &&\
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1)
+# define AO_XSIZE_fetch_and_sub1(addr) \
+ AO_XSIZE_fetch_and_add(addr,(unsigned XCTYPE)(-1))
+# define AO_HAVE_XSIZE_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_sub1_full)
+# if !defined(AO_HAVE_XSIZE_fetch_and_sub1_release)
+# define AO_XSIZE_fetch_and_sub1_release(addr) \
+ AO_XSIZE_fetch_and_sub1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_release
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire)
+# define AO_XSIZE_fetch_and_sub1_acquire(addr) \
+ AO_XSIZE_fetch_and_sub1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_acquire
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_sub1_write)
+# define AO_XSIZE_fetch_and_sub1_write(addr) \
+ AO_XSIZE_fetch_and_sub1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_write
+# endif
+# if !defined(AO_HAVE_XSIZE_fetch_and_sub1_read)
+# define AO_XSIZE_fetch_and_sub1_read(addr) \
+ AO_XSIZE_fetch_and_sub1_full(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_read
+# endif
+#endif /* AO_HAVE_XSIZE_fetch_and_sub1_full */
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_release)
+# define AO_XSIZE_fetch_and_sub1(addr) \
+ AO_XSIZE_fetch_and_sub1_release(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire)
+# define AO_XSIZE_fetch_and_sub1(addr) \
+ AO_XSIZE_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_write)
+# define AO_XSIZE_fetch_and_sub1(addr) \
+ AO_XSIZE_fetch_and_sub1_write(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_read)
+# define AO_XSIZE_fetch_and_sub1(addr) \
+ AO_XSIZE_fetch_and_sub1_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_XSIZE_fetch_and_sub1_full)
+# define AO_XSIZE_fetch_and_sub1_full(addr) \
+ (AO_nop_full(), AO_XSIZE_fetch_and_sub1_acquire(addr))
+# define AO_HAVE_XSIZE_fetch_and_sub1_full
+#endif
+
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_write)
+# define AO_XSIZE_fetch_and_sub1_release_write(addr) \
+ AO_XSIZE_fetch_and_sub1_write(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_release)
+# define AO_XSIZE_fetch_and_sub1_release_write(addr) \
+ AO_XSIZE_fetch_and_sub1_release(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_read)
+# define AO_XSIZE_fetch_and_sub1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_sub1_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_acquire_read
+#endif
+#if !defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire)
+# define AO_XSIZE_fetch_and_sub1_acquire_read(addr) \
+ AO_XSIZE_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_XSIZE_fetch_and_sub1_acquire_read)
+# define AO_XSIZE_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_XSIZE_fetch_and_sub1_acquire_read(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_XSIZE_fetch_and_sub1)
+# define AO_XSIZE_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_XSIZE_fetch_and_sub1(addr)
+# define AO_HAVE_XSIZE_fetch_and_sub1_dd_acquire_read
+# endif
+#endif
+
diff --git a/src/atomic_ops/generalize.h b/src/atomic_ops/generalize.h
new file mode 100644
index 0000000..0f42b32
--- /dev/null
+++ b/src/atomic_ops/generalize.h
@@ -0,0 +1,1292 @@
+/*
+ * 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.
+ */
+
+/*
+ * Generalize atomic operations for atomic_ops.h.
+ * Should not be included directly.
+ *
+ * We make no attempt to define useless operations, such as
+ * AO_nop_acquire
+ * AO_nop_release
+ *
+ * We have also so far neglected to define some others, which
+ * do not appear likely to be useful, e.g. stores with acquire
+ * or read barriers.
+ *
+ * This file is sometimes included twice by atomic_ops.h.
+ * All definitions include explicit checks that we are not replacing
+ * an earlier definition. In general, more desirable expansions
+ * appear earlier so that we are more likely to use them.
+ *
+ * We only make safe generalizations, except that by default we define
+ * the ...dd_acquire_read operations to be equivalent to those without
+ * a barrier. On platforms for which this is unsafe, the platform-specific
+ * file must define AO_NO_DD_ORDERING.
+ */
+
+#ifndef ATOMIC_OPS_H
+# error Atomic_ops_generalize.h should not be included directly.
+#endif
+
+#if AO_CHAR_TS_T
+# define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
+ AO_char_compare_and_swap_full(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
+ AO_char_compare_and_swap_acquire(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
+ AO_char_compare_and_swap_release(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP(a,o,n) \
+ AO_char_compare_and_swap(a,o,n)
+#endif
+
+#if AO_AO_TS_T
+# define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
+ AO_compare_and_swap_full(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
+ AO_compare_and_swap_acquire(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
+ AO_compare_and_swap_release(a,o,n)
+# define AO_TS_COMPARE_AND_SWAP(a,o,n) \
+ AO_compare_and_swap(a,o,n)
+#endif
+
+/* Generate test_and_set_full, if necessary and possible. */
+#if !defined(AO_HAVE_test_and_set) && \
+ !defined(AO_HAVE_test_and_set_release) && \
+ !defined(AO_HAVE_test_and_set_acquire) && \
+ !defined(AO_HAVE_test_and_set_read) && \
+ !defined(AO_HAVE_test_and_set_full)
+# if AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_full) || \
+ AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_full)
+ AO_INLINE AO_TS_VAL_t
+ AO_test_and_set_full(volatile AO_TS_t *addr)
+ {
+ if (AO_TS_COMPARE_AND_SWAP_FULL(addr, AO_TS_CLEAR, AO_TS_SET))
+ return AO_TS_CLEAR;
+ else
+ return AO_TS_SET;
+ }
+# define AO_HAVE_test_and_set_full
+# endif /* AO_HAVE_compare_and_swap_full */
+
+# if AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_acquire) || \
+ AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_acquire)
+ AO_INLINE AO_TS_VAL_t
+ AO_test_and_set_acquire(volatile AO_TS_t *addr)
+ {
+ if (AO_TS_COMPARE_AND_SWAP_ACQUIRE(addr, AO_TS_CLEAR, AO_TS_SET))
+ return AO_TS_CLEAR;
+ else
+ return AO_TS_SET;
+ }
+# define AO_HAVE_test_and_set_acquire
+# endif /* AO_HAVE_compare_and_swap_acquire */
+
+# if AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_release) || \
+ AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_release)
+ AO_INLINE AO_TS_VAL_t
+ AO_test_and_set_release(volatile AO_TS_t *addr)
+ {
+ if (AO_TS_COMPARE_AND_SWAP_RELEASE(addr, AO_TS_CLEAR, AO_TS_SET))
+ return AO_TS_CLEAR;
+ else
+ return AO_TS_SET;
+ }
+# define AO_HAVE_test_and_set_release
+# endif /* AO_HAVE_compare_and_swap_release */
+
+# if AO_AO_TS_T && defined(AO_HAVE_compare_and_swap) || \
+ AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap)
+ AO_INLINE AO_TS_VAL_t
+ AO_test_and_set(volatile AO_TS_t *addr)
+ {
+ if (AO_TS_COMPARE_AND_SWAP(addr, AO_TS_CLEAR, AO_TS_SET))
+ return AO_TS_CLEAR;
+ else
+ return AO_TS_SET;
+ }
+# define AO_HAVE_test_and_set
+# endif /* AO_HAVE_compare_and_swap */
+
+# if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
+ && !defined(AO_HAVE_test_and_set_acquire)
+ AO_INLINE AO_TS_VAL_t
+ AO_test_and_set_acquire(volatile AO_TS_t *addr)
+ {
+ AO_TS_VAL_t result = AO_test_and_set(addr);
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_test_and_set_acquire
+# endif
+
+#endif /* No prior test and set */
+
+/* Nop */
+#if !defined(AO_HAVE_nop)
+ AO_INLINE void AO_nop(void) {}
+# define AO_HAVE_nop
+#endif
+
+#if defined(AO_HAVE_test_and_set_full) && !defined(AO_HAVE_nop_full)
+ AO_INLINE void
+ AO_nop_full()
+ {
+ AO_TS_t dummy = AO_TS_INITIALIZER;
+ AO_test_and_set_full(&dummy);
+ }
+# define AO_HAVE_nop_full
+#endif
+
+#if defined(AO_HAVE_nop_acquire)
+# error AO_nop_acquire is useless: dont define.
+#endif
+#if defined(AO_HAVE_nop_release)
+# error AO_nop_release is useless: dont define.
+#endif
+
+#if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_read)
+# define AO_nop_read() AO_nop_full()
+# define AO_HAVE_nop_read
+#endif
+
+#if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_write)
+# define AO_nop_write() AO_nop_full()
+# define AO_HAVE_nop_write
+#endif
+
+/* Load */
+#if defined(AO_HAVE_load_full) && !defined(AO_HAVE_load_acquire)
+# define AO_load_acquire(addr) AO_load_full(addr)
+# define AO_HAVE_load_acquire
+#endif
+
+#if defined(AO_HAVE_load_acquire) && !defined(AO_HAVE_load)
+# define AO_load(addr) AO_load_acquire(addr)
+# define AO_HAVE_load
+#endif
+
+#if defined(AO_HAVE_load_full) && !defined(AO_HAVE_load_read)
+# define AO_load_read(addr) AO_load_full(addr)
+# define AO_HAVE_load_read
+#endif
+
+#if !defined(AO_HAVE_load_acquire_read) && defined(AO_HAVE_load_acquire)
+# define AO_load_acquire_read(addr) AO_load_acquire(addr)
+# define AO_HAVE_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_load) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_load_acquire)
+ AO_INLINE AO_t
+ AO_load_acquire(volatile AO_t *addr)
+ {
+ AO_t result = AO_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_load_acquire
+#endif
+
+#if defined(AO_HAVE_load) && defined(AO_HAVE_nop_read) && \
+ !defined(AO_HAVE_load_read)
+ AO_INLINE AO_t
+ AO_load_read(volatile AO_t *addr)
+ {
+ AO_t result = AO_load(addr);
+ /* Acquire barrier would be useless, since the load could be delayed */
+ /* beyond it. */
+ AO_nop_read();
+ return result;
+ }
+# define AO_HAVE_load_read
+#endif
+
+#if defined(AO_HAVE_load_acquire) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_load_full)
+# define AO_load_full(addr) (AO_nop_full(), AO_load_acquire(addr))
+# define AO_HAVE_load_full
+#endif
+
+#if !defined(AO_HAVE_load_acquire_read) && defined(AO_HAVE_load_read)
+# define AO_load_acquire_read(addr) AO_load_read(addr)
+# define AO_HAVE_load_acquire_read
+#endif
+
+#if defined(AO_HAVE_load_acquire_read) && !defined(AO_HAVE_load)
+# define AO_load(addr) AO_load_acquire_read(addr)
+# define AO_HAVE_load
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_load_acquire_read)
+# define AO_load_dd_acquire_read(addr) AO_load_acquire_read(addr)
+# define AO_HAVE_load_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_load)
+# define AO_load_dd_acquire_read(addr) AO_load(addr)
+# define AO_HAVE_load_dd_acquire_read
+# endif
+#endif
+
+
+/* Store */
+
+#if defined(AO_HAVE_store_full) && !defined(AO_HAVE_store_release)
+# define AO_store_release(addr,val) AO_store_full(addr,val)
+# define AO_HAVE_store_release
+#endif
+
+#if defined(AO_HAVE_store_release) && !defined(AO_HAVE_store)
+# define AO_store(addr, val) AO_store_release(addr,val)
+# define AO_HAVE_store
+#endif
+
+#if defined(AO_HAVE_store_full) && !defined(AO_HAVE_store_write)
+# define AO_store_write(addr,val) AO_store_full(addr,val)
+# define AO_HAVE_store_write
+#endif
+
+#if defined(AO_HAVE_store_release) && !defined(AO_HAVE_store_release_write)
+# define AO_store_release_write(addr, val) AO_store_release(addr,val)
+# define AO_HAVE_store_release_write
+#endif
+
+#if defined(AO_HAVE_store_write) && !defined(AO_HAVE_store)
+# define AO_store(addr, val) AO_store_write(addr,val)
+# define AO_HAVE_store
+#endif
+
+#if defined(AO_HAVE_store) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_store_release)
+# define AO_store_release(addr,val) (AO_nop_full(), AO_store(addr,val))
+# define AO_HAVE_store_release
+#endif
+
+#if defined(AO_HAVE_nop_write) && defined(AO_HAVE_store) && \
+ !defined(AO_HAVE_store_write)
+# define AO_store_write(addr, val) (AO_nop_write(), AO_store(addr,val))
+# define AO_HAVE_store_write
+#endif
+
+#if defined(AO_HAVE_store_write) && !defined(AO_HAVE_store_release_write)
+# define AO_store_release_write(addr, val) AO_store_write(addr,val)
+# define AO_HAVE_store_release_write
+#endif
+
+#if defined(AO_HAVE_store_release) && defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_store_full)
+# define AO_store_full(addr, val) (AO_store_release(addr, val), AO_nop_full())
+# define AO_HAVE_store_full
+#endif
+
+
+/* Fetch_and_add */
+/* We first try to implement fetch_and_add variants in terms */
+/* of the corresponding compare_and_swap variants to minimize */
+/* adding barriers. */
+#if defined(AO_HAVE_compare_and_swap_full) && \
+ !defined(AO_HAVE_fetch_and_add_full)
+ AO_INLINE AO_t
+ AO_fetch_and_add_full(volatile AO_t *addr, AO_t incr)
+ {
+ AO_t old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_compare_and_swap_full(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_fetch_and_add_full
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_fetch_and_add_acquire)
+ AO_INLINE AO_t
+ AO_fetch_and_add_acquire(volatile AO_t *addr, AO_t incr)
+ {
+ AO_t old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_compare_and_swap_acquire(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_fetch_and_add_acquire
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_release) && \
+ !defined(AO_HAVE_fetch_and_add_release)
+ AO_INLINE AO_t
+ AO_fetch_and_add_release(volatile AO_t *addr, AO_t incr)
+ {
+ AO_t old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_compare_and_swap_release(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_fetch_and_add_release
+#endif
+
+#if defined(AO_HAVE_compare_and_swap) && \
+ !defined(AO_HAVE_fetch_and_add)
+ AO_INLINE AO_t
+ AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
+ {
+ AO_t old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_compare_and_swap(addr, old, old+incr));
+ return old;
+ }
+# define AO_HAVE_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_fetch_and_add_full)
+# if !defined(AO_HAVE_fetch_and_add_release)
+# define AO_fetch_and_add_release(addr, val) \
+ AO_fetch_and_add_full(addr, val)
+# define AO_HAVE_fetch_and_add_release
+# endif
+# if !defined(AO_HAVE_fetch_and_add_acquire)
+# define AO_fetch_and_add_acquire(addr, val) \
+ AO_fetch_and_add_full(addr, val)
+# define AO_HAVE_fetch_and_add_acquire
+# endif
+# if !defined(AO_HAVE_fetch_and_add_write)
+# define AO_fetch_and_add_write(addr, val) \
+ AO_fetch_and_add_full(addr, val)
+# define AO_HAVE_fetch_and_add_write
+# endif
+# if !defined(AO_HAVE_fetch_and_add_read)
+# define AO_fetch_and_add_read(addr, val) \
+ AO_fetch_and_add_full(addr, val)
+# define AO_HAVE_fetch_and_add_read
+# endif
+#endif /* AO_HAVE_fetch_and_add_full */
+
+#if !defined(AO_HAVE_fetch_and_add) && \
+ defined(AO_HAVE_fetch_and_add_release)
+# define AO_fetch_and_add(addr, val) \
+ AO_fetch_and_add_release(addr, val)
+# define AO_HAVE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_fetch_and_add) && \
+ defined(AO_HAVE_fetch_and_add_acquire)
+# define AO_fetch_and_add(addr, val) \
+ AO_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_fetch_and_add) && \
+ defined(AO_HAVE_fetch_and_add_write)
+# define AO_fetch_and_add(addr, val) \
+ AO_fetch_and_add_write(addr, val)
+# define AO_HAVE_fetch_and_add
+#endif
+#if !defined(AO_HAVE_fetch_and_add) && \
+ defined(AO_HAVE_fetch_and_add_read)
+# define AO_fetch_and_add(addr, val) \
+ AO_fetch_and_add_read(addr, val)
+# define AO_HAVE_fetch_and_add
+#endif
+
+#if defined(AO_HAVE_fetch_and_add_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_fetch_and_add_full)
+# define AO_fetch_and_add_full(addr, val) \
+ (AO_nop_full(), AO_fetch_and_add_acquire(addr, val))
+# define AO_HAVE_fetch_and_add_full
+#endif
+
+#if !defined(AO_HAVE_fetch_and_add_release_write) && \
+ defined(AO_HAVE_fetch_and_add_write)
+# define AO_fetch_and_add_release_write(addr, val) \
+ AO_fetch_and_add_write(addr, val)
+# define AO_HAVE_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_add_release_write) && \
+ defined(AO_HAVE_fetch_and_add_release)
+# define AO_fetch_and_add_release_write(addr, val) \
+ AO_fetch_and_add_release(addr, val)
+# define AO_HAVE_fetch_and_add_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_fetch_and_add_read)
+# define AO_fetch_and_add_acquire_read(addr, val) \
+ AO_fetch_and_add_read(addr, val)
+# define AO_HAVE_fetch_and_add_acquire_read
+#endif
+#if !defined(AO_HAVE_fetch_and_add_acquire_read) && \
+ defined(AO_HAVE_fetch_and_add_acquire)
+# define AO_fetch_and_add_acquire_read(addr, val) \
+ AO_fetch_and_add_acquire(addr, val)
+# define AO_HAVE_fetch_and_add_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_fetch_and_add_acquire_read)
+# define AO_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_fetch_and_add_acquire_read(addr, val)
+# define AO_HAVE_fetch_and_add_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_fetch_and_add)
+# define AO_fetch_and_add_dd_acquire_read(addr, val) \
+ AO_fetch_and_add(addr, val)
+# define AO_HAVE_fetch_and_add_dd_acquire_read
+# endif
+#endif
+
+/* Fetch_and_add1 */
+
+#if defined(AO_HAVE_fetch_and_add_full) &&\
+ !defined(AO_HAVE_fetch_and_add1_full)
+# define AO_fetch_and_add1_full(addr) AO_fetch_and_add_full(addr,1)
+# define AO_HAVE_fetch_and_add1_full
+#endif
+#if defined(AO_HAVE_fetch_and_add_release) &&\
+ !defined(AO_HAVE_fetch_and_add1_release)
+# define AO_fetch_and_add1_release(addr) AO_fetch_and_add_release(addr,1)
+# define AO_HAVE_fetch_and_add1_release
+#endif
+#if defined(AO_HAVE_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_fetch_and_add1_acquire)
+# define AO_fetch_and_add1_acquire(addr) AO_fetch_and_add_acquire(addr,1)
+# define AO_HAVE_fetch_and_add1_acquire
+#endif
+#if defined(AO_HAVE_fetch_and_add_write) &&\
+ !defined(AO_HAVE_fetch_and_add1_write)
+# define AO_fetch_and_add1_write(addr) AO_fetch_and_add_write(addr,1)
+# define AO_HAVE_fetch_and_add1_write
+#endif
+#if defined(AO_HAVE_fetch_and_add_read) &&\
+ !defined(AO_HAVE_fetch_and_add1_read)
+# define AO_fetch_and_add1_read(addr) AO_fetch_and_add_read(addr,1)
+# define AO_HAVE_fetch_and_add1_read
+#endif
+#if defined(AO_HAVE_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_fetch_and_add1_release_write)
+# define AO_fetch_and_add1_release_write(addr) \
+ AO_fetch_and_add_release_write(addr,1)
+# define AO_HAVE_fetch_and_add1_release_write
+#endif
+#if defined(AO_HAVE_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_fetch_and_add1_acquire_read)
+# define AO_fetch_and_add1_acquire_read(addr) \
+ AO_fetch_and_add_acquire_read(addr,1)
+# define AO_HAVE_fetch_and_add1_acquire_read
+#endif
+#if defined(AO_HAVE_fetch_and_add) &&\
+ !defined(AO_HAVE_fetch_and_add1)
+# define AO_fetch_and_add1(addr) \
+ AO_fetch_and_add(addr,1)
+# define AO_HAVE_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_fetch_and_add1_full)
+# if !defined(AO_HAVE_fetch_and_add1_release)
+# define AO_fetch_and_add1_release(addr) \
+ AO_fetch_and_add1_full(addr)
+# define AO_HAVE_fetch_and_add1_release
+# endif
+# if !defined(AO_HAVE_fetch_and_add1_acquire)
+# define AO_fetch_and_add1_acquire(addr) \
+ AO_fetch_and_add1_full(addr)
+# define AO_HAVE_fetch_and_add1_acquire
+# endif
+# if !defined(AO_HAVE_fetch_and_add1_write)
+# define AO_fetch_and_add1_write(addr) \
+ AO_fetch_and_add1_full(addr)
+# define AO_HAVE_fetch_and_add1_write
+# endif
+# if !defined(AO_HAVE_fetch_and_add1_read)
+# define AO_fetch_and_add1_read(addr) \
+ AO_fetch_and_add1_full(addr)
+# define AO_HAVE_fetch_and_add1_read
+# endif
+#endif /* AO_HAVE_fetch_and_add1_full */
+
+#if !defined(AO_HAVE_fetch_and_add1) && \
+ defined(AO_HAVE_fetch_and_add1_release)
+# define AO_fetch_and_add1(addr) \
+ AO_fetch_and_add1_release(addr)
+# define AO_HAVE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_fetch_and_add1) && \
+ defined(AO_HAVE_fetch_and_add1_acquire)
+# define AO_fetch_and_add1(addr) \
+ AO_fetch_and_add1_acquire(addr)
+# define AO_HAVE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_fetch_and_add1) && \
+ defined(AO_HAVE_fetch_and_add1_write)
+# define AO_fetch_and_add1(addr) \
+ AO_fetch_and_add1_write(addr)
+# define AO_HAVE_fetch_and_add1
+#endif
+#if !defined(AO_HAVE_fetch_and_add1) && \
+ defined(AO_HAVE_fetch_and_add1_read)
+# define AO_fetch_and_add1(addr) \
+ AO_fetch_and_add1_read(addr)
+# define AO_HAVE_fetch_and_add1
+#endif
+
+#if defined(AO_HAVE_fetch_and_add1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_fetch_and_add1_full)
+# define AO_fetch_and_add1_full(addr) \
+ (AO_nop_full(), AO_fetch_and_add1_acquire(addr))
+# define AO_HAVE_fetch_and_add1_full
+#endif
+
+#if !defined(AO_HAVE_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_fetch_and_add1_write)
+# define AO_fetch_and_add1_release_write(addr) \
+ AO_fetch_and_add1_write(addr)
+# define AO_HAVE_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_add1_release_write) && \
+ defined(AO_HAVE_fetch_and_add1_release)
+# define AO_fetch_and_add1_release_write(addr) \
+ AO_fetch_and_add1_release(addr)
+# define AO_HAVE_fetch_and_add1_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_fetch_and_add1_read)
+# define AO_fetch_and_add1_acquire_read(addr) \
+ AO_fetch_and_add1_read(addr)
+# define AO_HAVE_fetch_and_add1_acquire_read
+#endif
+#if !defined(AO_HAVE_fetch_and_add1_acquire_read) && \
+ defined(AO_HAVE_fetch_and_add1_acquire)
+# define AO_fetch_and_add1_acquire_read(addr) \
+ AO_fetch_and_add1_acquire(addr)
+# define AO_HAVE_fetch_and_add1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_fetch_and_add1_acquire_read)
+# define AO_fetch_and_add1_dd_acquire_read(addr) \
+ AO_fetch_and_add1_acquire_read(addr)
+# define AO_HAVE_fetch_and_add1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_fetch_and_add1)
+# define AO_fetch_and_add1_dd_acquire_read(addr) AO_fetch_and_add1(addr)
+# define AO_HAVE_fetch_and_add1_dd_acquire_read
+# endif
+#endif
+
+/* Fetch_and_sub1 */
+
+#if defined(AO_HAVE_fetch_and_add_full) &&\
+ !defined(AO_HAVE_fetch_and_sub1_full)
+# define AO_fetch_and_sub1_full(addr) AO_fetch_and_add_full(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_full
+#endif
+#if defined(AO_HAVE_fetch_and_add_release) &&\
+ !defined(AO_HAVE_fetch_and_sub1_release)
+# define AO_fetch_and_sub1_release(addr) \
+ AO_fetch_and_add_release(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_release
+#endif
+#if defined(AO_HAVE_fetch_and_add_acquire) &&\
+ !defined(AO_HAVE_fetch_and_sub1_acquire)
+# define AO_fetch_and_sub1_acquire(addr) \
+ AO_fetch_and_add_acquire(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_acquire
+#endif
+#if defined(AO_HAVE_fetch_and_add_write) &&\
+ !defined(AO_HAVE_fetch_and_sub1_write)
+# define AO_fetch_and_sub1_write(addr) \
+ AO_fetch_and_add_write(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_write
+#endif
+#if defined(AO_HAVE_fetch_and_add_read) &&\
+ !defined(AO_HAVE_fetch_and_sub1_read)
+# define AO_fetch_and_sub1_read(addr) \
+ AO_fetch_and_add_read(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_read
+#endif
+#if defined(AO_HAVE_fetch_and_add_release_write) &&\
+ !defined(AO_HAVE_fetch_and_sub1_release_write)
+# define AO_fetch_and_sub1_release_write(addr) \
+ AO_fetch_and_add_release_write(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_release_write
+#endif
+#if defined(AO_HAVE_fetch_and_add_acquire_read) &&\
+ !defined(AO_HAVE_fetch_and_sub1_acquire_read)
+# define AO_fetch_and_sub1_acquire_read(addr) \
+ AO_fetch_and_add_acquire_read(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1_acquire_read
+#endif
+#if defined(AO_HAVE_fetch_and_add) &&\
+ !defined(AO_HAVE_fetch_and_sub1)
+# define AO_fetch_and_sub1(addr) \
+ AO_fetch_and_add(addr,(AO_t)(-1))
+# define AO_HAVE_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_fetch_and_sub1_full)
+# if !defined(AO_HAVE_fetch_and_sub1_release)
+# define AO_fetch_and_sub1_release(addr) \
+ AO_fetch_and_sub1_full(addr)
+# define AO_HAVE_fetch_and_sub1_release
+# endif
+# if !defined(AO_HAVE_fetch_and_sub1_acquire)
+# define AO_fetch_and_sub1_acquire(addr) \
+ AO_fetch_and_sub1_full(addr)
+# define AO_HAVE_fetch_and_sub1_acquire
+# endif
+# if !defined(AO_HAVE_fetch_and_sub1_write)
+# define AO_fetch_and_sub1_write(addr) \
+ AO_fetch_and_sub1_full(addr)
+# define AO_HAVE_fetch_and_sub1_write
+# endif
+# if !defined(AO_HAVE_fetch_and_sub1_read)
+# define AO_fetch_and_sub1_read(addr) \
+ AO_fetch_and_sub1_full(addr)
+# define AO_HAVE_fetch_and_sub1_read
+# endif
+#endif /* AO_HAVE_fetch_and_sub1_full */
+
+#if !defined(AO_HAVE_fetch_and_sub1) && \
+ defined(AO_HAVE_fetch_and_sub1_release)
+# define AO_fetch_and_sub1(addr) \
+ AO_fetch_and_sub1_release(addr)
+# define AO_HAVE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1) && \
+ defined(AO_HAVE_fetch_and_sub1_acquire)
+# define AO_fetch_and_sub1(addr) \
+ AO_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1) && \
+ defined(AO_HAVE_fetch_and_sub1_write)
+# define AO_fetch_and_sub1(addr) \
+ AO_fetch_and_sub1_write(addr)
+# define AO_HAVE_fetch_and_sub1
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1) && \
+ defined(AO_HAVE_fetch_and_sub1_read)
+# define AO_fetch_and_sub1(addr) \
+ AO_fetch_and_sub1_read(addr)
+# define AO_HAVE_fetch_and_sub1
+#endif
+
+#if defined(AO_HAVE_fetch_and_sub1_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_fetch_and_sub1_full)
+# define AO_fetch_and_sub1_full(addr) \
+ (AO_nop_full(), AO_fetch_and_sub1_acquire(addr))
+# define AO_HAVE_fetch_and_sub1_full
+#endif
+
+#if !defined(AO_HAVE_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_fetch_and_sub1_write)
+# define AO_fetch_and_sub1_release_write(addr) \
+ AO_fetch_and_sub1_write(addr)
+# define AO_HAVE_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1_release_write) && \
+ defined(AO_HAVE_fetch_and_sub1_release)
+# define AO_fetch_and_sub1_release_write(addr) \
+ AO_fetch_and_sub1_release(addr)
+# define AO_HAVE_fetch_and_sub1_release_write
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_fetch_and_sub1_read)
+# define AO_fetch_and_sub1_acquire_read(addr) \
+ AO_fetch_and_sub1_read(addr)
+# define AO_HAVE_fetch_and_sub1_acquire_read
+#endif
+#if !defined(AO_HAVE_fetch_and_sub1_acquire_read) && \
+ defined(AO_HAVE_fetch_and_sub1_acquire)
+# define AO_fetch_and_sub1_acquire_read(addr) \
+ AO_fetch_and_sub1_acquire(addr)
+# define AO_HAVE_fetch_and_sub1_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_fetch_and_sub1_acquire_read)
+# define AO_fetch_and_sub1_dd_acquire_read(addr) \
+ AO_fetch_and_sub1_acquire_read(addr)
+# define AO_HAVE_fetch_and_sub1_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_fetch_and_sub1)
+# define AO_fetch_and_sub1_dd_acquire_read(addr) AO_fetch_and_sub1(addr)
+# define AO_HAVE_fetch_and_sub1_dd_acquire_read
+# endif
+#endif
+
+/* Atomic or */
+#if defined(AO_HAVE_compare_and_swap_full) && \
+ !defined(AO_HAVE_or_full)
+ AO_INLINE void
+ AO_or_full(volatile AO_t *addr, AO_t incr)
+ {
+ AO_t old;
+ do
+ {
+ old = *addr;
+ }
+ while (!AO_compare_and_swap_full(addr, old, (old | incr)));
+ }
+# define AO_HAVE_or_full
+#endif
+
+#if defined(AO_HAVE_or_full)
+# if !defined(AO_HAVE_or_release)
+# define AO_or_release(addr, val) \
+ AO_or_full(addr, val)
+# define AO_HAVE_or_release
+# endif
+# if !defined(AO_HAVE_or_acquire)
+# define AO_or_acquire(addr, val) \
+ AO_or_full(addr, val)
+# define AO_HAVE_or_acquire
+# endif
+# if !defined(AO_HAVE_or_write)
+# define AO_or_write(addr, val) \
+ AO_or_full(addr, val)
+# define AO_HAVE_or_write
+# endif
+# if !defined(AO_HAVE_or_read)
+# define AO_or_read(addr, val) \
+ AO_or_full(addr, val)
+# define AO_HAVE_or_read
+# endif
+#endif /* AO_HAVE_or_full */
+
+#if !defined(AO_HAVE_or) && \
+ defined(AO_HAVE_or_release)
+# define AO_or(addr, val) \
+ AO_or_release(addr, val)
+# define AO_HAVE_or
+#endif
+#if !defined(AO_HAVE_or) && \
+ defined(AO_HAVE_or_acquire)
+# define AO_or(addr, val) \
+ AO_or_acquire(addr, val)
+# define AO_HAVE_or
+#endif
+#if !defined(AO_HAVE_or) && \
+ defined(AO_HAVE_or_write)
+# define AO_or(addr, val) \
+ AO_or_write(addr, val)
+# define AO_HAVE_or
+#endif
+#if !defined(AO_HAVE_or) && \
+ defined(AO_HAVE_or_read)
+# define AO_or(addr, val) \
+ AO_or_read(addr, val)
+# define AO_HAVE_or
+#endif
+
+#if defined(AO_HAVE_or_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_or_full)
+# define AO_or_full(addr, val) \
+ (AO_nop_full(), AO_or_acquire(addr, val))
+#endif
+
+#if !defined(AO_HAVE_or_release_write) && \
+ defined(AO_HAVE_or_write)
+# define AO_or_release_write(addr, val) \
+ AO_or_write(addr, val)
+# define AO_HAVE_or_release_write
+#endif
+#if !defined(AO_HAVE_or_release_write) && \
+ defined(AO_HAVE_or_release)
+# define AO_or_release_write(addr, val) \
+ AO_or_release(addr, val)
+# define AO_HAVE_or_release_write
+#endif
+#if !defined(AO_HAVE_or_acquire_read) && \
+ defined(AO_HAVE_or_read)
+# define AO_or_acquire_read(addr, val) \
+ AO_or_read(addr, val)
+# define AO_HAVE_or_acquire_read
+#endif
+#if !defined(AO_HAVE_or_acquire_read) && \
+ defined(AO_HAVE_or_acquire)
+# define AO_or_acquire_read(addr, val) \
+ AO_or_acquire(addr, val)
+# define AO_HAVE_or_acquire_read
+#endif
+
+/* dd_aquire_read is meaningless. */
+
+/* Test_and_set */
+
+#if defined(AO_HAVE_test_and_set_full)
+# if !defined(AO_HAVE_test_and_set_release)
+# define AO_test_and_set_release(addr) \
+ AO_test_and_set_full(addr)
+# define AO_HAVE_test_and_set_release
+# endif
+# if !defined(AO_HAVE_test_and_set_acquire)
+# define AO_test_and_set_acquire(addr) \
+ AO_test_and_set_full(addr)
+# define AO_HAVE_test_and_set_acquire
+# endif
+# if !defined(AO_HAVE_test_and_set_write)
+# define AO_test_and_set_write(addr) \
+ AO_test_and_set_full(addr)
+# define AO_HAVE_test_and_set_write
+# endif
+# if !defined(AO_HAVE_test_and_set_read)
+# define AO_test_and_set_read(addr) \
+ AO_test_and_set_full(addr)
+# define AO_HAVE_test_and_set_read
+# endif
+#endif /* AO_HAVE_test_and_set_full */
+
+#if !defined(AO_HAVE_test_and_set) && \
+ defined(AO_HAVE_test_and_set_release)
+# define AO_test_and_set(addr) \
+ AO_test_and_set_release(addr)
+# define AO_HAVE_test_and_set
+#endif
+#if !defined(AO_HAVE_test_and_set) && \
+ defined(AO_HAVE_test_and_set_acquire)
+# define AO_test_and_set(addr) \
+ AO_test_and_set_acquire(addr)
+# define AO_HAVE_test_and_set
+#endif
+#if !defined(AO_HAVE_test_and_set) && \
+ defined(AO_HAVE_test_and_set_write)
+# define AO_test_and_set(addr) \
+ AO_test_and_set_write(addr)
+# define AO_HAVE_test_and_set
+#endif
+#if !defined(AO_HAVE_test_and_set) && \
+ defined(AO_HAVE_test_and_set_read)
+# define AO_test_and_set(addr) \
+ AO_test_and_set_read(addr)
+# define AO_HAVE_test_and_set
+#endif
+
+#if defined(AO_HAVE_test_and_set_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_test_and_set_full)
+# define AO_test_and_set_full(addr) \
+ (AO_nop_full(), AO_test_and_set_acquire(addr))
+# define AO_HAVE_test_and_set_full
+#endif
+
+#if !defined(AO_HAVE_test_and_set_release_write) && \
+ defined(AO_HAVE_test_and_set_write)
+# define AO_test_and_set_release_write(addr) \
+ AO_test_and_set_write(addr)
+# define AO_HAVE_test_and_set_release_write
+#endif
+#if !defined(AO_HAVE_test_and_set_release_write) && \
+ defined(AO_HAVE_test_and_set_release)
+# define AO_test_and_set_release_write(addr) \
+ AO_test_and_set_release(addr)
+# define AO_HAVE_test_and_set_release_write
+#endif
+#if !defined(AO_HAVE_test_and_set_acquire_read) && \
+ defined(AO_HAVE_test_and_set_read)
+# define AO_test_and_set_acquire_read(addr) \
+ AO_test_and_set_read(addr)
+# define AO_HAVE_test_and_set_acquire_read
+#endif
+#if !defined(AO_HAVE_test_and_set_acquire_read) && \
+ defined(AO_HAVE_test_and_set_acquire)
+# define AO_test_and_set_acquire_read(addr) \
+ AO_test_and_set_acquire(addr)
+# define AO_HAVE_test_and_set_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_test_and_set_acquire_read)
+# define AO_test_and_set_dd_acquire_read(addr) \
+ AO_test_and_set_acquire_read(addr)
+# define AO_HAVE_test_and_set_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_test_and_set)
+# define AO_test_and_set_dd_acquire_read(addr) AO_test_and_set(addr)
+# define AO_HAVE_test_and_set_dd_acquire_read
+# endif
+#endif
+
+/* Compare_and_swap */
+#if defined(AO_HAVE_compare_and_swap) && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_and_swap_acquire)
+ AO_INLINE int
+ AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val)
+ {
+ int result = AO_compare_and_swap(addr, old, new_val);
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_compare_and_swap_acquire
+#endif
+#if defined(AO_HAVE_compare_and_swap) && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_and_swap_release)
+# define AO_compare_and_swap_release(addr, old, new_val) \
+ (AO_nop_full(), AO_compare_and_swap(addr, old, new_val))
+# define AO_HAVE_compare_and_swap_release
+#endif
+#if defined(AO_HAVE_compare_and_swap_full)
+# if !defined(AO_HAVE_compare_and_swap_release)
+# define AO_compare_and_swap_release(addr, old, new_val) \
+ AO_compare_and_swap_full(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_release
+# endif
+# if !defined(AO_HAVE_compare_and_swap_acquire)
+# define AO_compare_and_swap_acquire(addr, old, new_val) \
+ AO_compare_and_swap_full(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_acquire
+# endif
+# if !defined(AO_HAVE_compare_and_swap_write)
+# define AO_compare_and_swap_write(addr, old, new_val) \
+ AO_compare_and_swap_full(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_write
+# endif
+# if !defined(AO_HAVE_compare_and_swap_read)
+# define AO_compare_and_swap_read(addr, old, new_val) \
+ AO_compare_and_swap_full(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_read
+# endif
+#endif /* AO_HAVE_compare_and_swap_full */
+
+#if !defined(AO_HAVE_compare_and_swap) && \
+ defined(AO_HAVE_compare_and_swap_release)
+# define AO_compare_and_swap(addr, old, new_val) \
+ AO_compare_and_swap_release(addr, old, new_val)
+# define AO_HAVE_compare_and_swap
+#endif
+#if !defined(AO_HAVE_compare_and_swap) && \
+ defined(AO_HAVE_compare_and_swap_acquire)
+# define AO_compare_and_swap(addr, old, new_val) \
+ AO_compare_and_swap_acquire(addr, old, new_val)
+# define AO_HAVE_compare_and_swap
+#endif
+#if !defined(AO_HAVE_compare_and_swap) && \
+ defined(AO_HAVE_compare_and_swap_write)
+# define AO_compare_and_swap(addr, old, new_val) \
+ AO_compare_and_swap_write(addr, old, new_val)
+# define AO_HAVE_compare_and_swap
+#endif
+#if !defined(AO_HAVE_compare_and_swap) && \
+ defined(AO_HAVE_compare_and_swap_read)
+# define AO_compare_and_swap(addr, old, new_val) \
+ AO_compare_and_swap_read(addr, old, new_val)
+# define AO_HAVE_compare_and_swap
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_compare_and_swap_full)
+# define AO_compare_and_swap_full(addr, old, new_val) \
+ (AO_nop_full(), AO_compare_and_swap_acquire(addr, old, new_val))
+# define AO_HAVE_compare_and_swap_full
+#endif
+
+#if !defined(AO_HAVE_compare_and_swap_release_write) && \
+ defined(AO_HAVE_compare_and_swap_write)
+# define AO_compare_and_swap_release_write(addr, old, new_val) \
+ AO_compare_and_swap_write(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_release_write
+#endif
+#if !defined(AO_HAVE_compare_and_swap_release_write) && \
+ defined(AO_HAVE_compare_and_swap_release)
+# define AO_compare_and_swap_release_write(addr, old, new_val) \
+ AO_compare_and_swap_release(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_release_write
+#endif
+#if !defined(AO_HAVE_compare_and_swap_acquire_read) && \
+ defined(AO_HAVE_compare_and_swap_read)
+# define AO_compare_and_swap_acquire_read(addr, old, new_val) \
+ AO_compare_and_swap_read(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_acquire_read
+#endif
+#if !defined(AO_HAVE_compare_and_swap_acquire_read) && \
+ defined(AO_HAVE_compare_and_swap_acquire)
+# define AO_compare_and_swap_acquire_read(addr, old, new_val) \
+ AO_compare_and_swap_acquire(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_compare_and_swap_acquire_read)
+# define AO_compare_and_swap_dd_acquire_read(addr, old, new_val) \
+ AO_compare_and_swap_acquire_read(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_compare_and_swap)
+# define AO_compare_and_swap_dd_acquire_read(addr, old, new_val) \
+ AO_compare_and_swap(addr, old, new_val)
+# define AO_HAVE_compare_and_swap_dd_acquire_read
+# endif
+#endif
+
+#include "generalize-small.h"
+
+/* Compare_double_and_swap_double */
+#if defined(AO_HAVE_compare_double_and_swap_double) && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_double_and_swap_double_acquire)
+ AO_INLINE int
+ AO_compare_double_and_swap_double_acquire(volatile AO_double_t *addr,
+ AO_t o1, AO_t o2,
+ AO_t n1, AO_t n2)
+ {
+ int result = AO_compare_double_and_swap_double(addr, o1, o2, n1, n2);
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_compare_double_and_swap_double_acquire
+#endif
+#if defined(AO_HAVE_compare_double_and_swap_double) \
+ && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_double_and_swap_double_release)
+# define AO_compare_double_and_swap_double_release(addr, o1, o2, n1, n2) \
+ (AO_nop_full(), AO_compare_double_and_swap_double(addr, o1, o2, n1, n2))
+# define AO_HAVE_compare_double_and_swap_double_release
+#endif
+#if defined(AO_HAVE_compare_double_and_swap_double_full)
+# if !defined(AO_HAVE_compare_double_and_swap_double_release)
+# define AO_compare_double_and_swap_double_release(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_full(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_release
+# endif
+# if !defined(AO_HAVE_compare_double_and_swap_double_acquire)
+# define AO_compare_double_and_swap_double_acquire(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_full(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_acquire
+# endif
+# if !defined(AO_HAVE_compare_double_and_swap_double_write)
+# define AO_compare_double_and_swap_double_write(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_full(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_write
+# endif
+# if !defined(AO_HAVE_compare_double_and_swap_double_read)
+# define AO_compare_double_and_swap_double_read(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_full(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_read
+# endif
+#endif /* AO_HAVE_compare_double_and_swap_double_full */
+
+#if !defined(AO_HAVE_compare_double_and_swap_double) && \
+ defined(AO_HAVE_compare_double_and_swap_double_release)
+# define AO_compare_double_and_swap_double(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_release(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double) && \
+ defined(AO_HAVE_compare_double_and_swap_double_acquire)
+# define AO_compare_double_and_swap_double(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_acquire(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double) && \
+ defined(AO_HAVE_compare_double_and_swap_double_write)
+# define AO_compare_double_and_swap_double(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_write(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double) && \
+ defined(AO_HAVE_compare_double_and_swap_double_read)
+# define AO_compare_double_and_swap_double(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_read(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double
+#endif
+
+#if defined(AO_HAVE_compare_double_and_swap_double_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_compare_double_and_swap_double_full)
+# define AO_compare_double_and_swap_double_full(addr, o1, o2, n1, n2) \
+ (AO_nop_full(), AO_compare_double_and_swap_double_acquire(addr, o1, o2, n1, n2))
+# define AO_HAVE_compare_double_and_swap_double_full
+#endif
+
+#if !defined(AO_HAVE_compare_double_and_swap_double_release_write) && \
+ defined(AO_HAVE_compare_double_and_swap_double_write)
+# define AO_compare_double_and_swap_double_release_write(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_write(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_release_write
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double_release_write) && \
+ defined(AO_HAVE_compare_double_and_swap_double_release)
+# define AO_compare_double_and_swap_double_release_write(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_release(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_release_write
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) && \
+ defined(AO_HAVE_compare_double_and_swap_double_read)
+# define AO_compare_double_and_swap_double_acquire_read(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_read(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_acquire_read
+#endif
+#if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) && \
+ defined(AO_HAVE_compare_double_and_swap_double_acquire)
+# define AO_compare_double_and_swap_double_acquire_read(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_acquire(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_compare_double_and_swap_double_acquire_read)
+# define AO_compare_double_and_swap_double_dd_acquire_read(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double_acquire_read(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_compare_double_and_swap_double)
+# define AO_compare_double_and_swap_double_dd_acquire_read(addr, o1, o2, n1, n2) \
+ AO_compare_double_and_swap_double(addr, o1, o2, n1, n2)
+# define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
+# endif
+#endif
+
+/* Compare_and_swap_double */
+#if defined(AO_HAVE_compare_and_swap_double) && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_and_swap_double_acquire)
+ AO_INLINE int
+ AO_compare_and_swap_double_acquire(volatile AO_double_t *addr,
+ AO_t o1, AO_t o2,
+ AO_t n1, AO_t n2)
+ {
+ int result = AO_compare_and_swap_double(addr, o1, n1, n2);
+ AO_nop_full();
+ return result;
+ }
+# define AO_HAVE_compare_and_swap_double_acquire
+#endif
+#if defined(AO_HAVE_compare_and_swap_double) \
+ && defined(AO_HAVE_nop_full)\
+ && !defined(AO_HAVE_compare_and_swap_double_release)
+# define AO_compare_and_swap_double_release(addr, o1, n1, n2) \
+ (AO_nop_full(), AO_compare_and_swap_double(addr, o1, n1, n2))
+# define AO_HAVE_compare_and_swap_double_release
+#endif
+#if defined(AO_HAVE_compare_and_swap_double_full)
+# if !defined(AO_HAVE_compare_and_swap_double_release)
+# define AO_compare_and_swap_double_release(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_full(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_release
+# endif
+# if !defined(AO_HAVE_compare_and_swap_double_acquire)
+# define AO_compare_and_swap_double_acquire(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_full(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_acquire
+# endif
+# if !defined(AO_HAVE_compare_and_swap_double_write)
+# define AO_compare_and_swap_double_write(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_full(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_write
+# endif
+# if !defined(AO_HAVE_compare_and_swap_double_read)
+# define AO_compare_and_swap_double_read(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_full(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_read
+# endif
+#endif /* AO_HAVE_compare_and_swap_double_full */
+
+#if !defined(AO_HAVE_compare_and_swap_double) && \
+ defined(AO_HAVE_compare_and_swap_double_release)
+# define AO_compare_and_swap_double(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_release(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double) && \
+ defined(AO_HAVE_compare_and_swap_double_acquire)
+# define AO_compare_and_swap_double(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_acquire(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double) && \
+ defined(AO_HAVE_compare_and_swap_double_write)
+# define AO_compare_and_swap_double(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_write(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double) && \
+ defined(AO_HAVE_compare_and_swap_double_read)
+# define AO_compare_and_swap_double(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_read(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_double_acquire) &&\
+ defined(AO_HAVE_nop_full) && \
+ !defined(AO_HAVE_compare_and_swap_double_full)
+# define AO_compare_and_swap_double_full(addr, o1, n1, n2) \
+ (AO_nop_full(), AO_compare_and_swap_double_acquire(addr, o1, n1, n2))
+# define AO_HAVE_compare_and_swap_double_full
+#endif
+
+#if !defined(AO_HAVE_compare_and_swap_double_release_write) && \
+ defined(AO_HAVE_compare_and_swap_double_write)
+# define AO_compare_and_swap_double_release_write(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_write(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_release_write
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double_release_write) && \
+ defined(AO_HAVE_compare_and_swap_double_release)
+# define AO_compare_and_swap_double_release_write(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_release(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_release_write
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double_acquire_read) && \
+ defined(AO_HAVE_compare_and_swap_double_read)
+# define AO_compare_and_swap_double_acquire_read(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_read(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_acquire_read
+#endif
+#if !defined(AO_HAVE_compare_and_swap_double_acquire_read) && \
+ defined(AO_HAVE_compare_and_swap_double_acquire)
+# define AO_compare_and_swap_double_acquire_read(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_acquire(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_acquire_read
+#endif
+
+#ifdef AO_NO_DD_ORDERING
+# if defined(AO_HAVE_compare_and_swap_double_acquire_read)
+# define AO_compare_and_swap_double_dd_acquire_read(addr, o1, n1, n2) \
+ AO_compare_and_swap_double_acquire_read(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_dd_acquire_read
+# endif
+#else
+# if defined(AO_HAVE_compare_and_swap_double)
+# define AO_compare_and_swap_double_dd_acquire_read(addr, o1, n1, n2) \
+ AO_compare_and_swap_double(addr, o1, n1, n2)
+# define AO_HAVE_compare_and_swap_double_dd_acquire_read
+# endif
+#endif
diff --git a/src/atomic_ops/sysdeps/Makefile.am b/src/atomic_ops/sysdeps/Makefile.am
new file mode 100644
index 0000000..5234381
--- /dev/null
+++ b/src/atomic_ops/sysdeps/Makefile.am
@@ -0,0 +1,45 @@
+#General sysdep utility headers, followed by the arch-specific ones
+nobase_sysdep_HEADERS= generic_pthread.h \
+ atomic_load_store.h \
+ aligned_atomic_load_store.h \
+ acquire_release_volatile.h \
+ char_acquire_release_volatile.h \
+ char_atomic_load_store.h \
+ short_acquire_release_volatile.h \
+ short_aligned_atomic_load_store.h \
+ short_atomic_load_store.h \
+ int_acquire_release_volatile.h \
+ int_aligned_atomic_load_store.h \
+ int_atomic_load_store.h \
+ all_acquire_release_volatile.h \
+ all_aligned_atomic_load_store.h \
+ all_atomic_load_store.h \
+ ordered_except_wr.h \
+ ordered.h \
+ ao_t_is_int.h \
+ test_and_set_t_is_ao_t.h \
+ test_and_set_t_is_char.h \
+ emul_cas.h \
+ standard_ao_double_t.h \
+ README \
+ \
+ gcc/alpha.h gcc/arm.h gcc/x86.h \
+ gcc/hppa.h gcc/ia64.h \
+ gcc/powerpc.h gcc/sparc.h \
+ gcc/hppa.h gcc/m68k.h gcc/s390.h \
+ gcc/ia64.h gcc/x86_64.h gcc/cris.h \
+ \
+ icc/ia64.h \
+ \
+ msftc/x86.h \
+ \
+ hpc/ia64.h hpc/hppa.h \
+ \
+ sunc/sparc.h \
+ \
+ ibmc/powerpc.h
+
+sysdepdir= ${includedir}/atomic_ops/sysdeps
+
+# A few architectures require special .S files
+EXTRA_DIST = sunc/sparc.S
diff --git a/src/atomic_ops/sysdeps/Makefile.in b/src/atomic_ops/sysdeps/Makefile.in
new file mode 100644
index 0000000..91d0789
--- /dev/null
+++ b/src/atomic_ops/sysdeps/Makefile.in
@@ -0,0 +1,419 @@
+# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/atomic_ops/sysdeps
+DIST_COMMON = README $(nobase_sysdep_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(sysdepdir)"
+nobase_sysdepHEADERS_INSTALL = $(install_sh_DATA)
+HEADERS = $(nobase_sysdep_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+NEED_ASM_FALSE = @NEED_ASM_FALSE@
+NEED_ASM_TRUE = @NEED_ASM_TRUE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PICFLAG = @PICFLAG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+#General sysdep utility headers, followed by the arch-specific ones
+nobase_sysdep_HEADERS = generic_pthread.h \
+ atomic_load_store.h \
+ aligned_atomic_load_store.h \
+ acquire_release_volatile.h \
+ char_acquire_release_volatile.h \
+ char_atomic_load_store.h \
+ short_acquire_release_volatile.h \
+ short_aligned_atomic_load_store.h \
+ short_atomic_load_store.h \
+ int_acquire_release_volatile.h \
+ int_aligned_atomic_load_store.h \
+ int_atomic_load_store.h \
+ all_acquire_release_volatile.h \
+ all_aligned_atomic_load_store.h \
+ all_atomic_load_store.h \
+ ordered_except_wr.h \
+ ordered.h \
+ ao_t_is_int.h \
+ test_and_set_t_is_ao_t.h \
+ test_and_set_t_is_char.h \
+ emul_cas.h \
+ standard_ao_double_t.h \
+ README \
+ \
+ gcc/alpha.h gcc/arm.h gcc/x86.h \
+ gcc/hppa.h gcc/ia64.h \
+ gcc/powerpc.h gcc/sparc.h \
+ gcc/hppa.h gcc/m68k.h gcc/s390.h \
+ gcc/ia64.h gcc/x86_64.h gcc/cris.h \
+ \
+ icc/ia64.h \
+ \
+ msftc/x86.h \
+ \
+ hpc/ia64.h hpc/hppa.h \
+ \
+ sunc/sparc.h \
+ \
+ ibmc/powerpc.h
+
+sysdepdir = ${includedir}/atomic_ops/sysdeps
+
+# A few architectures require special .S files
+EXTRA_DIST = sunc/sparc.S
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/atomic_ops/sysdeps/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/atomic_ops/sysdeps/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+uninstall-info-am:
+install-nobase_sysdepHEADERS: $(nobase_sysdep_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sysdepdir)" || $(mkdir_p) "$(DESTDIR)$(sysdepdir)"
+ @$(am__vpath_adj_setup) \
+ list='$(nobase_sysdep_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__vpath_adj) \
+ echo " $(nobase_sysdepHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(sysdepdir)/$$f'"; \
+ $(nobase_sysdepHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(sysdepdir)/$$f"; \
+ done
+
+uninstall-nobase_sysdepHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @$(am__vpath_adj_setup) \
+ list='$(nobase_sysdep_HEADERS)'; for p in $$list; do \
+ $(am__vpath_adj) \
+ echo " rm -f '$(DESTDIR)$(sysdepdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sysdepdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(mkdir_p) $(distdir)/gcc $(distdir)/hpc $(distdir)/ibmc $(distdir)/icc $(distdir)/msftc $(distdir)/sunc
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sysdepdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_sysdepHEADERS
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-nobase_sysdepHEADERS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ ctags distclean distclean-generic distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man \
+ install-nobase_sysdepHEADERS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \
+ uninstall-nobase_sysdepHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/atomic_ops/sysdeps/README b/src/atomic_ops/sysdeps/README
new file mode 100644
index 0000000..605699f
--- /dev/null
+++ b/src/atomic_ops/sysdeps/README
@@ -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.
diff --git a/src/atomic_ops/sysdeps/acquire_release_volatile.h b/src/atomic_ops/sysdeps/acquire_release_volatile.h
new file mode 100644
index 0000000..1a387d3
--- /dev/null
+++ b/src/atomic_ops/sysdeps/acquire_release_volatile.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/*
+ * This file adds definitions appropriate for environments in which an AO_t
+ * volatile load has acquire semantics, and an AO_t volatile store has release
+ * semantics. This is arguably supposed to be true with the standard Itanium
+ * software conventions.
+ */
+
+/*
+ * Empirically gcc/ia64 does some reordering of ordinary operations around volatiles
+ * even when we think it shouldn't. Gcc 3.3 and earlier could reorder a volatile store
+ * with another store. As of March 2005, gcc pre-4 reused previously computed
+ * common subexpressions across a volatile load.
+ * Hence we now add compiler barriers for gcc.
+ */
+#if !defined(AO_GCC_BARRIER)
+# if defined(__GNUC__)
+# define AO_GCC_BARRIER() AO_compiler_barrier()
+# else
+# define AO_GCC_BARRIER()
+# endif
+#endif
+
+AO_INLINE AO_t
+AO_load_acquire(volatile AO_t *p)
+{
+ AO_t result = *p;
+ /* A normal volatile load generates an ld.acq */
+ AO_GCC_BARRIER();
+ return result;
+}
+#define AO_HAVE_load_acquire
+
+AO_INLINE void
+AO_store_release(volatile AO_t *p, AO_t val)
+{
+ AO_GCC_BARRIER();
+ /* A normal volatile store generates an st.rel */
+ *p = val;
+}
+#define AO_HAVE_store_release
+
+
diff --git a/src/atomic_ops/sysdeps/aligned_atomic_load_store.h b/src/atomic_ops/sysdeps/aligned_atomic_load_store.h
new file mode 100644
index 0000000..e69c0dd
--- /dev/null
+++ b/src/atomic_ops/sysdeps/aligned_atomic_load_store.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of AO_t are
+ * atomic fo all legal alignments.
+ */
+
+AO_INLINE AO_t
+AO_load(volatile AO_t *addr)
+{
+ assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+ /* Cast away the volatile for architectures where */
+ /* volatile adds barrier semantics. */
+ return *(AO_t *)addr;
+}
+
+#define AO_HAVE_load
+
+AO_INLINE void
+AO_store(volatile AO_t *addr, AO_t new_val)
+{
+ assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+ (*(AO_t *)addr) = new_val;
+}
+
+#define AO_HAVE_store
+
+
diff --git a/src/atomic_ops/sysdeps/all_acquire_release_volatile.h b/src/atomic_ops/sysdeps/all_acquire_release_volatile.h
new file mode 100644
index 0000000..6787387
--- /dev/null
+++ b/src/atomic_ops/sysdeps/all_acquire_release_volatile.h
@@ -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 volatile AO_t, unsigned char, unsigned
+ * short, and unsigned int loads and stores have acquire/release semantics for
+ * all normally legal alignments.
+ */
+#include "acquire_release_volatile.h"
+#include "char_acquire_release_volatile.h"
+#include "short_acquire_release_volatile.h"
+#include "int_acquire_release_volatile.h"
diff --git a/src/atomic_ops/sysdeps/all_aligned_atomic_load_store.h b/src/atomic_ops/sysdeps/all_aligned_atomic_load_store.h
new file mode 100644
index 0000000..b9f7247
--- /dev/null
+++ b/src/atomic_ops/sysdeps/all_aligned_atomic_load_store.h
@@ -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 and strores are atomic for all normally legal alignments.
+ */
+#include "aligned_atomic_load_store.h"
+#include "char_atomic_load_store.h"
+#include "short_aligned_atomic_load_store.h"
+#include "int_aligned_atomic_load_store.h"
diff --git a/src/atomic_ops/sysdeps/all_atomic_load_store.h b/src/atomic_ops/sysdeps/all_atomic_load_store.h
new file mode 100644
index 0000000..d0ebe08
--- /dev/null
+++ b/src/atomic_ops/sysdeps/all_atomic_load_store.h
@@ -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 strores are atomic for all normally legal
+ * alignments.
+ */
+#include "atomic_load_store.h"
+#include "char_atomic_load_store.h"
+#include "short_atomic_load_store.h"
+#include "int_atomic_load_store.h"
diff --git a/src/atomic_ops/sysdeps/ao_t_is_int.h b/src/atomic_ops/sysdeps/ao_t_is_int.h
new file mode 100644
index 0000000..18156c8
--- /dev/null
+++ b/src/atomic_ops/sysdeps/ao_t_is_int.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+/*
+ * Inclusion of this file signifies that AO_t is in fact int. Hence
+ * any AO_... operations can also server as AO_int_... operations.
+ * We currently define only the more important ones here, and allow for
+ * the normal generalization process to define the others.
+ * We should probably add others in the future.
+ */
+
+#if defined(AO_HAVE_compare_and_swap_full) && \
+ !defined(AO_HAVE_int_compare_and_swap_full)
+# define AO_int_compare_and_swap_full(addr, old, new_val) \
+ AO_compare_and_swap_full((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap_full
+# endif
+
+#if defined(AO_HAVE_compare_and_swap_acquire) && \
+ !defined(AO_HAVE_int_compare_and_swap_acquire)
+# define AO_int_compare_and_swap_acquire(addr, old, new_val) \
+ AO_compare_and_swap_acquire((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap_acquire
+# endif
+
+#if defined(AO_HAVE_compare_and_swap_release) && \
+ !defined(AO_HAVE_int_compare_and_swap_release)
+# define AO_int_compare_and_swap_release(addr, old, new_val) \
+ AO_compare_and_swap_release((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap_release
+# endif
+
+#if defined(AO_HAVE_compare_and_swap_write) && \
+ !defined(AO_HAVE_int_compare_and_swap_write)
+# define AO_int_compare_and_swap_write(addr, old, new_val) \
+ AO_compare_and_swap_write((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap_write
+# endif
+
+#if defined(AO_HAVE_compare_and_swap_read) && \
+ !defined(AO_HAVE_int_compare_and_swap_read)
+# define AO_int_compare_and_swap_read(addr, old, new_val) \
+ AO_compare_and_swap_read((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap_read
+# endif
+
+#if defined(AO_HAVE_compare_and_swap) && \
+ !defined(AO_HAVE_int_compare_and_swap)
+# define AO_int_compare_and_swap(addr, old, new_val) \
+ AO_compare_and_swap((volatile AO_t *)addr, \
+ (AO_t) old, (AO_t)new_val)
+# define AO_HAVE_int_compare_and_swap
+# endif
+
+#if defined(AO_HAVE_load_acquire) && \
+ !defined(AO_HAVE_int_load_acquire)
+# define AO_int_load_acquire(addr) (int)AO_load_acquire((volatile AO_t *)addr)
+# define AO_HAVE_int_load_acquire
+# endif
+
+#if defined(AO_HAVE_store_release) && \
+ !defined(AO_HAVE_int_store_release)
+# define AO_int_store_release(addr, val) \
+ AO_store_release((volatile AO_t *)addr, (AO_t)val)
+# define AO_HAVE_int_store_release
+# endif
+
+#if defined(AO_HAVE_fetch_and_add_full) && \
+ !defined(AO_HAVE_int_fetch_and_add_full)
+# define AO_int_fetch_and_add_full(addr, incr) \
+ (int)AO_fetch_and_add_full((volatile AO_t *)addr, (AO_t)incr)
+# define AO_HAVE_int_fetch_and_add_full
+# endif
+
+#if defined(AO_HAVE_fetch_and_add1_acquire) && \
+ !defined(AO_HAVE_int_fetch_and_add1_acquire)
+# define AO_int_fetch_and_add1_acquire(addr) \
+ (int)AO_fetch_and_add1_acquire((volatile AO_t *)addr)
+# define AO_HAVE_int_fetch_and_add1_acquire
+# endif
+
+#if defined(AO_HAVE_fetch_and_add1_release) && \
+ !defined(AO_HAVE_int_fetch_and_add1_release)
+# define AO_int_fetch_and_add1_release(addr) \
+ (int)AO_fetch_and_add1_release((volatile AO_t *)addr)
+# define AO_HAVE_int_fetch_and_add1_release
+# endif
+
+#if defined(AO_HAVE_fetch_and_sub1_acquire) && \
+ !defined(AO_HAVE_int_fetch_and_sub1_acquire)
+# define AO_int_fetch_and_sub1_acquire(addr) \
+ (int)AO_fetch_and_sub1_acquire((volatile AO_t *)addr)
+# define AO_HAVE_int_fetch_and_sub1_acquire
+# endif
+
+#if defined(AO_HAVE_fetch_and_sub1_release) && \
+ !defined(AO_HAVE_int_fetch_and_sub1_release)
+# define AO_int_fetch_and_sub1_release(addr) \
+ (int)AO_fetch_and_sub1_release((volatile AO_t *)addr)
+# define AO_HAVE_int_fetch_and_sub1_release
+# endif
+
diff --git a/src/atomic_ops/sysdeps/atomic_load_store.h b/src/atomic_ops/sysdeps/atomic_load_store.h
new file mode 100644
index 0000000..68c5179
--- /dev/null
+++ b/src/atomic_ops/sysdeps/atomic_load_store.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of AO_t are
+ * atomic fo all legal alignments.
+ */
+
+AO_INLINE AO_t
+AO_load(volatile AO_t *addr)
+{
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(AO_t *)addr);
+}
+
+#define AO_HAVE_load
+
+AO_INLINE void
+AO_store(volatile AO_t *addr, AO_t new_val)
+{
+ (*(AO_t *)addr) = new_val;
+}
+
+#define AO_HAVE_store
+
+
diff --git a/src/atomic_ops/sysdeps/char_acquire_release_volatile.h b/src/atomic_ops/sysdeps/char_acquire_release_volatile.h
new file mode 100644
index 0000000..37aa021
--- /dev/null
+++ b/src/atomic_ops/sysdeps/char_acquire_release_volatile.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file adds definitions appropriate for environments in which an unsigned char
+ * volatile load has acquire semantics, and an unsigned char volatile store has release
+ * semantics. This is true with the standard Itanium ABI.
+ */
+#if !defined(AO_GCC_BARRIER)
+# if defined(__GNUC__)
+# define AO_GCC_BARRIER() AO_compiler_barrier()
+# else
+# define AO_GCC_BARRIER()
+# endif
+#endif
+
+AO_INLINE unsigned char
+AO_char_load_acquire(volatile unsigned char *p)
+{
+ unsigned char result = *p;
+ /* A normal volatile load generates an ld.acq */
+ AO_GCC_BARRIER();
+ return result;
+}
+#define AO_HAVE_char_load_acquire
+
+AO_INLINE void
+AO_char_store_release(volatile unsigned char *p, unsigned char val)
+{
+ AO_GCC_BARRIER();
+ /* A normal volatile store generates an st.rel */
+ *p = val;
+}
+#define AO_HAVE_char_store_release
+
+
diff --git a/src/atomic_ops/sysdeps/char_atomic_load_store.h b/src/atomic_ops/sysdeps/char_atomic_load_store.h
new file mode 100644
index 0000000..6eb0978
--- /dev/null
+++ b/src/atomic_ops/sysdeps/char_atomic_load_store.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of unsigned char are
+ * atomic for all legal alignments.
+ */
+
+AO_INLINE unsigned char
+AO_char_load(volatile unsigned char *addr)
+{
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(unsigned char *)addr);
+}
+
+#define AO_HAVE_char_load
+
+AO_INLINE void
+AO_char_store(volatile unsigned char *addr, unsigned char new_val)
+{
+ (*(unsigned char *)addr) = new_val;
+}
+
+#define AO_HAVE_char_store
+
+
diff --git a/src/atomic_ops/sysdeps/emul_cas.h b/src/atomic_ops/sysdeps/emul_cas.h
new file mode 100644
index 0000000..4187f9f
--- /dev/null
+++ b/src/atomic_ops/sysdeps/emul_cas.h
@@ -0,0 +1,76 @@
+/*
+ * 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
+ * id appropriate, and if AO_FORCE_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.
+ */
+
+#if !defined(ATOMIC_OPS_H)
+# error This file should not be included directly.
+#endif
+
+#ifndef AO_HAVE_double_t
+# include "standard_ao_double_t.h"
+#endif
+
+int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old,
+ 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);
+
+#define AO_compare_and_swap_full(addr, old, newval) \
+ AO_compare_and_swap_emulation(addr, old, newval)
+#define AO_HAVE_compare_and_swap_full
+
+#ifndef AO_HAVE_compare_double_and_swap_double
+# 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
diff --git a/src/atomic_ops/sysdeps/gcc/alpha.h b/src/atomic_ops/sysdeps/gcc/alpha.h
new file mode 100644
index 0000000..90c060c
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/alpha.h
@@ -0,0 +1,68 @@
+/*
+ * 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 "../atomic_load_store.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+
+#define AO_NO_DD_ORDERING
+ /* Data dependence does not imply read ordering. */
+
+AO_INLINE void
+AO_nop_full()
+{
+ __asm__ __volatile__("mb" : : : "memory");
+}
+
+#define AO_HAVE_nop_full
+
+AO_INLINE void
+AO_nop_write()
+{
+ __asm__ __volatile__("wmb" : : : "memory");
+}
+
+#define AO_HAVE_nop_write
+
+/* mb should be used for AO_nop_read(). That's the default. */
+
+/* We believe that ldq_l ... stq_c does not imply any memory barrier. */
+/* We should add an explicit fetch_and_add definition. */
+AO_INLINE int
+AO_compare_and_swap(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ unsigned long was_equal;
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " cmpeq %0,%4,%2\n"
+ " mov %3,%0\n"
+ " beq %2,2f\n"
+ " stq_c %0,%1\n"
+ " beq %0,1b\n"
+ "2:\n"
+ :"=&r" (temp), "=m" (*addr), "=&r" (was_equal)
+ : "r" (new_val), "Ir" (old)
+ :"memory");
+ return was_equal;
+}
+
+#define AO_HAVE_compare_and_swap
+
+
diff --git a/src/atomic_ops/sysdeps/gcc/arm.h b/src/atomic_ops/sysdeps/gcc/arm.h
new file mode 100644
index 0000000..e10ffa0
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/arm.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ */
+
+/* FIXME. Very incomplete. No support for 64 bits. */
+
+#include "../all_atomic_load_store.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");
+ return oldval;
+}
+
+#define AO_HAVE_test_and_set_full
+
+
+
diff --git a/src/atomic_ops/sysdeps/gcc/cris.h b/src/atomic_ops/sysdeps/gcc/cris.h
new file mode 100644
index 0000000..3864905
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/cris.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ * Most of this code originally comes from Hans-Peter Nilsson. It is included
+ * here with his permission.
+ *
+ * This version has not been tested. It was coped here from a GC
+ * patch so that we wouldn't lose the code in the upgrade to gc7.
+ */
+
+#include "../all_atomic_load_store.h"
+
+#include "../ordered.h" /* There are no multiprocessor implementations. */
+
+#include "../test_and_set_t_is_ao_t.h"
+
+/*
+ * The architecture apparently supports an "f" flag which is
+ * set on preemption. This essentially gives us load-locked,
+ * store-conditional primitives, though I'm not quite sure how
+ * this would work on a hypothetical multiprocessor. -HB
+ *
+ * For details, see
+ * http://developer.axis.com/doc/hardware/etrax100lx/prog_man/
+ * 1_architectural_description.pdf
+ *
+ * Presumably many other primitives (notably CAS, including the double-
+ * width versions) could be implemented in this manner, if someone got
+ * around to it.
+ */
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr) {
+ /* Ripped from linuxthreads/sysdeps/cris/pt-machine.h */
+ register unsigned long int ret;
+
+ /* Note the use of a dummy output of *addr to expose the write. The
+ memory barrier is to stop *other* writes being moved past this code. */
+ __asm__ __volatile__("clearf\n"
+ "0:\n\t"
+ "movu.b [%2],%0\n\t"
+ "ax\n\t"
+ "move.b %3,[%2]\n\t"
+ "bwf 0b\n\t"
+ "clearf"
+ : "=&r" (ret), "=m" (*addr)
+ : "r" (addr), "r" ((int) 1), "m" (*addr)
+ : "memory");
+ return ret;
+}
+
+#define AO_HAVE_test_and_set_full
+
diff --git a/src/atomic_ops/sysdeps/gcc/hppa.h b/src/atomic_ops/sysdeps/gcc/hppa.h
new file mode 100644
index 0000000..3349a38
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/hppa.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003 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.
+ *
+ * Modified by Carlos O'Donell <carlos@baldric.uwo.ca>, 2003
+ * - Added self-aligning lock.
+ *
+ */
+
+#include "../all_atomic_load_store.h"
+
+/* Some architecture set descriptions include special "ordered" memory */
+/* operations. As far as we can tell, no existing processors actually */
+/* require those. Nor does it appear likely that future processors */
+/* will. */
+#include "../ordered.h"
+
+/* GCC will not guarantee the alignment we need, use four lock words */
+/* and select the correctly aligned datum. See the glibc 2.3.2 */
+/* linuxthread port for the original implementation. */
+struct AO_pa_clearable_loc {
+ int data[4];
+};
+
+#undef AO_TS_INITIALIZER
+#define AO_TS_t struct AO_pa_clearable_loc
+#define AO_TS_INITIALIZER {1,1,1,1}
+/* Switch meaning of set and clear, since we only have an atomic clear */
+/* instruction. */
+typedef enum {AO_PA_TS_set = 0, AO_PA_TS_clear = 1} AO_PA_TS_val;
+#define AO_TS_VAL_t AO_PA_TS_val
+#define AO_TS_CLEAR AO_PA_TS_clear
+#define AO_TS_SET AO_PA_TS_set
+
+/* The hppa only has one atomic read and modify memory operation, */
+/* load and clear, so hppa spinlocks must use zero to signify that */
+/* someone is holding the lock. The address used for the ldcw */
+/* semaphore must be 16-byte aligned. */
+
+#define __ldcw(a) ({ \
+ volatile unsigned int __ret; \
+ __asm__ __volatile__("ldcw 0(%2),%0" \
+ : "=r" (__ret), "=m" (*(a)) : "r" (a)); \
+ __ret; \
+})
+
+/* Because malloc only guarantees 8-byte alignment for malloc'd data, */
+/* and GCC only guarantees 8-byte alignment for stack locals, we can't */
+/* be assured of 16-byte alignment for atomic lock data even if we */
+/* specify "__attribute ((aligned(16)))" in the type declaration. So, */
+/* we use a struct containing an array of four ints for the atomic lock */
+/* type and dynamically select the 16-byte aligned int from the array */
+/* for the semaphore. */
+#define __PA_LDCW_ALIGNMENT 16
+#define __ldcw_align(a) ({ \
+ unsigned long __ret = (unsigned long) a; \
+ __ret += __PA_LDCW_ALIGNMENT - 1; \
+ __ret &= ~(__PA_LDCW_ALIGNMENT - 1); \
+ (volatile unsigned int *) __ret; \
+})
+
+/* Works on PA 1.1 and PA 2.0 systems */
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t * addr)
+{
+ volatile unsigned int *a = __ldcw_align (addr);
+ return __ldcw (a);
+}
+
+AO_INLINE void
+AO_pa_clear(volatile AO_TS_t * addr)
+{
+ volatile unsigned int *a = __ldcw_align (addr);
+ AO_compiler_barrier();
+ *a = 1;
+}
+#define AO_CLEAR(addr) AO_pa_clear(addr)
+
+#define AO_HAVE_test_and_set_full
+
diff --git a/src/atomic_ops/sysdeps/gcc/ia64.h b/src/atomic_ops/sysdeps/gcc/ia64.h
new file mode 100644
index 0000000..522eaee
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/ia64.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+#include "../all_atomic_load_store.h"
+
+#include "../acquire_release_volatile.h"
+
+#include "../test_and_set_t_is_char.h"
+
+#ifdef _ILP32
+ /* 32-bit HP/UX code. */
+ /* This requires pointer "swizzling". Pointers need to be expanded */
+ /* to 64 bits using the addp4 instruction before use. This makes it */
+ /* hard to share code, but we try anyway. */
+# define AO_LEN "4"
+ /* We assume that addr always appears in argument position 1 in asm */
+ /* code. If it is clobbered due to swizzling, we also need it in */
+ /* second position. Any later arguments are referenced symbolically, */
+ /* so that we don't have to worry about their position. This requires*/
+ /* gcc 3.1, but you shouldn't be using anything older than that on */
+ /* IA64 anyway. */
+ /* The AO_MASK macro is a workaround for the fact that HP/UX gcc */
+ /* appears to otherwise store 64-bit pointers in ar.ccv, i.e. it */
+ /* doesn't appear to clear high bits in a pointer value we pass into */
+ /* assembly code, even if it is supposedly of type AO_t. */
+# define AO_IN_ADDR "1"(addr)
+# define AO_OUT_ADDR , "=r"(addr)
+# define AO_SWIZZLE "addp4 %1=0,%1;;\n"
+# define AO_MASK(ptr) __asm__("zxt4 %1=%1": "=r"(ptr) : "0"(ptr));
+#else
+# define AO_LEN "8"
+# define AO_IN_ADDR "r"(addr)
+# define AO_OUT_ADDR
+# define AO_SWIZZLE
+# define AO_MASK(ptr)
+#endif
+
+AO_INLINE void
+AO_nop_full()
+{
+ __asm__ __volatile__("mf" : : : "memory");
+}
+#define AO_HAVE_nop_full
+
+AO_INLINE AO_t
+AO_fetch_and_add1_acquire (volatile AO_t *addr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ (AO_SWIZZLE
+ "fetchadd" AO_LEN ".acq %0=[%1],1":
+ "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
+ return result;
+}
+#define AO_HAVE_fetch_and_add1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_add1_release (volatile AO_t *addr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ (AO_SWIZZLE
+ "fetchadd" AO_LEN ".rel %0=[%1],1":
+ "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_fetch_and_add1_release
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_acquire (volatile AO_t *addr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ (AO_SWIZZLE
+ "fetchadd" AO_LEN ".acq %0=[%1],-1":
+ "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_fetch_and_sub1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_release (volatile AO_t *addr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ (AO_SWIZZLE
+ "fetchadd" AO_LEN ".rel %0=[%1],-1":
+ "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_fetch_and_sub1_release
+
+#ifndef _ILP32
+
+AO_INLINE unsigned int
+AO_int_fetch_and_add1_acquire (volatile unsigned int *addr)
+{
+ unsigned int result;
+
+ __asm__ __volatile__ ("fetchadd4.acq %0=[%1],1":
+ "=r" (result): AO_IN_ADDR :"memory");
+ return result;
+}
+#define AO_HAVE_int_fetch_and_add1_acquire
+
+AO_INLINE unsigned int
+AO_int_fetch_and_add1_release (volatile unsigned int *addr)
+{
+ unsigned int result;
+
+ __asm__ __volatile__ ("fetchadd4.rel %0=[%1],1":
+ "=r" (result): AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_int_fetch_and_add1_release
+
+AO_INLINE unsigned int
+AO_int_fetch_and_sub1_acquire (volatile unsigned int *addr)
+{
+ unsigned int result;
+
+ __asm__ __volatile__ ("fetchadd4.acq %0=[%1],-1":
+ "=r" (result): AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_int_fetch_and_sub1_acquire
+
+AO_INLINE unsigned int
+AO_int_fetch_and_sub1_release (volatile unsigned int *addr)
+{
+ unsigned int result;
+
+ __asm__ __volatile__ ("fetchadd4.rel %0=[%1],-1":
+ "=r" (result): AO_IN_ADDR :"memory");
+ return result;
+}
+
+#define AO_HAVE_int_fetch_and_sub1_release
+
+#endif /* !_ILP32 */
+
+AO_INLINE int
+AO_compare_and_swap_acquire(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+ AO_MASK(old);
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
+ ".acq %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_acquire
+
+AO_INLINE int
+AO_compare_and_swap_release(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+ AO_MASK(old);
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
+ ".rel %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_release
+
+AO_INLINE int
+AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ unsigned char oldval;
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg1.acq %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_acquire
+
+AO_INLINE int
+AO_char_compare_and_swap_release(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ unsigned char oldval;
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg1.rel %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_release
+
+AO_INLINE int
+AO_short_compare_and_swap_acquire(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ unsigned short oldval;
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg2.acq %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_acquire
+
+AO_INLINE int
+AO_short_compare_and_swap_release(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ unsigned short oldval;
+ __asm__ __volatile__(AO_SWIZZLE
+ "mov ar.ccv=%[old] ;; cmpxchg2.rel %0=[%1],%[new_val],ar.ccv"
+ : "=r"(oldval) AO_OUT_ADDR
+ : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
+ : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_release
+
+#ifndef _ILP32
+
+AO_INLINE int
+AO_int_compare_and_swap_acquire(volatile unsigned int *addr,
+ unsigned int old, unsigned int new_val)
+{
+ unsigned int oldval;
+ __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.acq %0=[%1],%2,ar.ccv"
+ : "=r"(oldval)
+ : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old) : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_int_compare_and_swap_acquire
+
+AO_INLINE int
+AO_int_compare_and_swap_release(volatile unsigned int *addr,
+ unsigned int old, unsigned int new_val)
+{
+ unsigned int oldval;
+ __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.rel %0=[%1],%2,ar.ccv"
+ : "=r"(oldval)
+ : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old) : "memory");
+ return (oldval == old);
+}
+
+#define AO_HAVE_int_compare_and_swap_release
+
+#endif /* !_ILP32 */
+
+/* FIXME: Add compare_and_swap_double as soon as there is widely */
+/* available hardware that implements it. */
+
+/* FIXME: Add compare_double_and_swap_double for the _ILP32 case. */
+
+#ifdef _ILP32
+# include "../ao_t_is_int.h"
+#endif
diff --git a/src/atomic_ops/sysdeps/gcc/m68k.h b/src/atomic_ops/sysdeps/gcc/m68k.h
new file mode 100644
index 0000000..9e7f70a
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/m68k.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ */
+
+/* FIXME. Very incomplete. */
+#include "../all_aligned_atomic_load_store.h"
+
+/* Are there any m68k multiprocessors still around? */
+/* AFAIK, Alliants were sequentially consistent. */
+#include "../ordered.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+
+/* Contributed by Tony Mantler or new. Should be changed to MIT license? */
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr) {
+ int oldval;
+
+ /* The return value is semi-phony. */
+ /* 'tas' sets bit 7 while the return */
+ /* value pretends bit 0 was set */
+ __asm__ __volatile__(
+ "tas %1@; sne %0; negb %0"
+ : "=d" (oldval)
+ : "a" (addr) : "memory");
+ return oldval;
+}
+
+#define AO_HAVE_test_and_set_full
+
+
+
diff --git a/src/atomic_ops/sysdeps/gcc/powerpc.h b/src/atomic_ops/sysdeps/gcc/powerpc.h
new file mode 100644
index 0000000..5f33e71
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/powerpc.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+ * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
+ * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P.
+ *
+ *
+ * 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.
+ *
+ */
+
+/* FIXME. Incomplete. No support for 64 bits. */
+/* Memory model documented at http://www-106.ibm.com/developerworks/ */
+/* eserver/articles/archguide.html and (clearer) */
+/* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
+/* There appears to be no implicit ordering between any kind of */
+/* independent memory references. */
+/* Architecture enforces some ordering based on control dependence. */
+/* I don't know if that could help. */
+/* Data-dependent loads are always ordered. */
+/* Based on the above references, eieio is intended for use on */
+/* uncached memory, which we don't support. It does not order loads */
+/* from cached memory. */
+/* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to */
+/* track some of this down and correcting my misunderstandings. -HB */
+
+#include "../all_aligned_atomic_load_store.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+ /* There seems to be no byte equivalent of lwarx, so this */
+ /* may really be what we want, at least in the 32-bit case. */
+
+AO_INLINE void
+AO_nop_full()
+{
+ __asm__ __volatile__("sync" : : : "memory");
+}
+
+#define AO_HAVE_nop_full
+
+/* lwsync apparently works for everything but a StoreLoad barrier. */
+AO_INLINE void
+AO_lwsync()
+{
+ __asm__ __volatile__("lwsync" : : : "memory");
+}
+
+#define AO_nop_write() AO_lwsync()
+#define AO_HAVE_nop_write
+
+#define AO_nop_read() AO_lwsync()
+#define AO_HAVE_nop_read
+
+/* We explicitly specify load_acquire, since it is important, and can */
+/* be implemented relatively cheaply. It could be implemented */
+/* with an ordinary load followed by a lwsync. But the general wisdom */
+/* seems to be that a data dependent branch followed by an isync is */
+/* cheaper. And the documentation is fairly explicit that this also */
+/* has acquire semantics. */
+AO_INLINE AO_t
+AO_load_acquire(volatile AO_t *addr)
+{
+ int cr;
+ AO_t result;
+
+ /* FIXME: We should get gcc to allocate one of the condition */
+ /* registers. I always got "impossible constraint" when I */
+ /* tried the "y" constraint. */
+ __asm__ __volatile__ (
+ "lwz %0,%1\n"
+ "cmpw cr7,%0,%0\n"
+ "bne- cr7,1f\n"
+ "1: isync\n"
+ : "=r" (result)
+ : "m"(*addr) : "memory", "cc");
+ return result;
+}
+
+#define AO_HAVE_load_acquire
+
+/* We explicitly specify store_release, since it relies */
+/* on the fact that lwsync is also a LoadStore barrier. */
+AO_INLINE void
+AO_store_release(volatile AO_t *addr, AO_t value)
+{
+ AO_lwsync();
+ *addr = value;
+}
+
+#define AO_HAVE_load_acquire
+
+/* This is similar to the code in the garbage collector. Deleting */
+/* this and having it synthesized from compare_and_swap would probably */
+/* only cost us a load immediate instruction. */
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set(volatile AO_TS_t *addr) {
+ int oldval;
+ int temp = 1; /* locked value */
+
+ __asm__ __volatile__(
+ "1:lwarx %0,0,%1\n" /* load and reserve */
+ "cmpwi %0, 0\n" /* if load is */
+ "bne 2f\n" /* non-zero, return already set */
+ "stwcx. %2,0,%1\n" /* else store conditional */
+ "bne- 1b\n" /* retry if lost reservation */
+ "2:\n" /* oldval is zero if we set */
+ : "=&r"(oldval)
+ : "r"(addr), "r"(temp)
+ : "memory", "cc");
+
+ return oldval;
+}
+
+#define AO_have_test_and_set
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_acquire(volatile AO_TS_t *addr) {
+ AO_TS_VAL_t result = AO_test_and_set(addr);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_test_and_set_acquire
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_release(volatile AO_TS_t *addr) {
+ AO_lwsync();
+ return AO_test_and_set(addr);
+}
+
+#define AO_HAVE_test_and_set_release
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr) {
+ AO_TS_VAL_t result;
+ AO_lwsync();
+ result = AO_test_and_set(addr);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_test_and_set_full
+
+AO_INLINE int
+AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_t oldval;
+ int result = 0;
+
+ __asm__ __volatile__(
+ "1:lwarx %0,0,%2\n" /* load and reserve */
+ "cmpw %0, %4\n" /* if load is not equal to */
+ "bne 2f\n" /* old, fail */
+ "stwcx. %3,0,%2\n" /* else store conditional */
+ "bne- 1b\n" /* retry if lost reservation */
+ "li %1,1\n" /* result = 1; */
+ "2:\n"
+ : "=&r"(oldval), "=&r"(result)
+ : "r"(addr), "r"(new_val), "r"(old), "1"(result)
+ : "memory", "cc");
+
+ return result;
+}
+
+#define AO_HAVE_compare_and_swap
+
+AO_INLINE int
+AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ int result = AO_compare_and_swap(addr, old, new_val);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_compare_and_swap_acquire
+
+AO_INLINE int
+AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_lwsync();
+ return AO_compare_and_swap(addr, old, new_val);
+}
+
+#define AO_HAVE_compare_and_swap_release
+
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_t result;
+ AO_lwsync();
+ result = AO_compare_and_swap(addr, old, new_val);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* FIXME: We should also implement fetch_and_add and or primitives */
+/* directly. */
diff --git a/src/atomic_ops/sysdeps/gcc/s390.h b/src/atomic_ops/sysdeps/gcc/s390.h
new file mode 100644
index 0000000..7cb9986
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/s390.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ *
+ */
+
+/* FIXME: untested. */
+/* The relevant documentation appears to be at */
+/* http://publibz.boulder.ibm.com/epubs/pdf/dz9zr003.pdf */
+/* around page 5-96. Apparently: */
+/* - Memory references in general are atomic only for a single */
+/* byte. But it appears that the most common load/store */
+/* instructions also guarantee atomicity for aligned */
+/* operands of standard types. WE FOOLISHLY ASSUME that */
+/* compilers only generate those. If that turns out to be */
+/* wrong, we need inline assembly code for AO_load and */
+/* AO_store. */
+/* - A store followed by a load is unordered since the store */
+/* may be delayed. Otherwise everything is ordered. */
+/* - There is a hardware compare-and-swap (CS) instruction. */
+
+#include "ordered_except_wr.h"
+#include "all_aligned_atomic_load_store.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+/* FIXME: Is there a way to do byte-sized test-and-set? */
+
+/* FIXME: AO_nop_full should probably be implemented directly. */
+/* It appears that certain BCR instructions have that effect. */
+/* Presumably they're cheaper than CS? */
+
+AO_INLINE AO_t AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ int retval;
+ __asm__ __volatile__ (
+# ifndef __s390x__
+ " cs %1,%2,0(%3)\n"
+# else
+ " csg %1,%2,0(%3)\n"
+# endif
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=&d" (retval), "+d" (old)
+ : "d" (new_val), "a" (addr)
+ : "cc", "memory");
+ return retval == 0;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* FIXME: Add double-wide compare-and-swap for 32-bit executables. */
diff --git a/src/atomic_ops/sysdeps/gcc/sparc.h b/src/atomic_ops/sysdeps/gcc/sparc.h
new file mode 100644
index 0000000..4850855
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/sparc.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ *
+ */
+
+/* FIXME. Very incomplete. No support for sparc64. */
+/* Non-ancient SPARCs provide compare-and-swap (casa). */
+/* We should make that available. */
+
+#include "../all_atomic_load_store.h"
+
+/* Real SPARC code uses TSO: */
+#include "../ordered_except_wr.h"
+
+/* Test_and_set location is just a byte. */
+#include "../test_and_set_t_is_char.h"
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr) {
+ int oldval;
+
+ __asm__ __volatile__("ldstub %1,%0"
+ : "=r"(oldval), "=m"(*addr)
+ : "m"(*addr) : "memory");
+ return oldval;
+}
+
+#define AO_HAVE_test_and_set_full
+
+/* FIXME: This needs to be extended for SPARC v8 and v9. */
+/* SPARC V8 also has swap. V9 has CAS. */
+/* There are barriers like membar #LoadStore. */
+/* CASA (32-bit) and CASXA(64-bit) instructions were */
+/* added in V9. */
diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h
new file mode 100644
index 0000000..19d2274
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/x86.h
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ *
+ * Some of the machine specific code was borrowed from our GC distribution.
+ */
+
+/* The following really assume we have a 486 or better. Unfortunately */
+/* gcc doesn't define a suitable feature test macro based on command */
+/* line options. */
+/* We should perhaps test dynamically. */
+
+#include "../all_aligned_atomic_load_store.h"
+
+/* Real X86 implementations, except for some old WinChips, appear */
+/* to enforce ordering between memory operations, EXCEPT that a later */
+/* read can pass earlier writes, presumably due to the visible */
+/* presence of store buffers. */
+/* We ignore both the WinChips, and the fact that the official specs */
+/* seem to be much weaker (and arguably too weak to be usable). */
+
+#include "../ordered_except_wr.h"
+
+#include "../test_and_set_t_is_char.h"
+
+#include "../standard_ao_double_t.h"
+
+#if defined(AO_USE_PENTIUM4_INSTRS)
+AO_INLINE void
+AO_nop_full()
+{
+ __asm__ __volatile__("mfence" : : : "memory");
+}
+
+#define AO_HAVE_nop_full
+
+#else
+
+/* We could use the cpuid instruction. But that seems to be slower */
+/* than the default implementation based on test_and_set_full. Thus */
+/* we omit that bit of misinformation here. */
+
+#endif
+
+/* As far as we can tell, the lfence and sfence instructions are not */
+/* currently needed or useful for cached memory accesses. */
+
+/* Really only works for 486 and later */
+AO_INLINE AO_t
+AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ ("lock; xaddl %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_fetch_and_add_full
+
+AO_INLINE unsigned char
+AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
+{
+ unsigned char result;
+
+ __asm__ __volatile__ ("lock; xaddb %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_char_fetch_and_add_full
+
+AO_INLINE unsigned short
+AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
+{
+ unsigned short result;
+
+ __asm__ __volatile__ ("lock; xaddw %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_short_fetch_and_add_full
+
+/* Really only works for 486 and later */
+AO_INLINE void
+AO_or_full (volatile AO_t *p, AO_t incr)
+{
+ __asm__ __volatile__ ("lock; orl %1, %0" :
+ "=m" (*p) : "r" (incr), "m" (*p) : "memory");
+}
+
+#define AO_HAVE_or_full
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+ unsigned char oldval;
+ /* Note: the "xchg" instruction does not need a "lock" prefix */
+ __asm__ __volatile__("xchgb %0, %1"
+ : "=r"(oldval), "=m"(*addr)
+ : "0"(0xff), "m"(*addr) : "memory");
+ return (AO_TS_VAL_t)oldval;
+}
+
+#define AO_HAVE_test_and_set_full
+
+/* Returns nonzero if the comparison succeeded. */
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ char result;
+ __asm__ __volatile__("lock; cmpxchgl %3, %0; setz %1"
+ : "=m"(*addr), "=q"(result)
+ : "m"(*addr), "r" (new_val), "a"(old) : "memory");
+ return (int) result;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* Returns nonzero if the comparison succeeded. */
+/* Really requires at least a Pentium. */
+AO_INLINE int
+AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
+ AO_t old_val1, AO_t old_val2,
+ AO_t new_val1, AO_t new_val2)
+{
+ char result;
+ __asm__ __volatile__("lock; cmpxchg8b %0; setz %1"
+ : "=m"(*addr), "=q"(result)
+ : "m"(*addr), "d" (old_val1), "a" (old_val2),
+ "c" (new_val1), "b" (new_val2) : "memory");
+ return (int) result;
+}
+
+#define AO_HAVE_double_compare_and_swap_full
+
+#include "../ao_t_is_int.h"
diff --git a/src/atomic_ops/sysdeps/gcc/x86_64.h b/src/atomic_ops/sysdeps/gcc/x86_64.h
new file mode 100644
index 0000000..356476f
--- /dev/null
+++ b/src/atomic_ops/sysdeps/gcc/x86_64.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ *
+ * Some of the machine specific code was borrowed from our GC distribution.
+ */
+
+/* The following really assume we have a 486 or better. Unfortunately */
+/* gcc doesn't define a suitable feature test macro based on command */
+/* line options. */
+/* We should perhaps test dynamically. */
+
+#include "../all_aligned_atomic_load_store.h"
+
+/* Real X86 implementations, except for some old WinChips, appear */
+/* to enforce ordering between memory operations, EXCEPT that a later */
+/* read can pass earlier writes, presumably due to the visible */
+/* presence of store buffers. */
+/* We ignore both the WinChips, and the fact that the official specs */
+/* seem to be much weaker (and arguably too weak to be usable). */
+
+#include "../ordered_except_wr.h"
+
+#include "../test_and_set_t_is_char.h"
+
+#if defined(AO_USE_PENTIUM4_INSTRS)
+AO_INLINE void
+AO_nop_full()
+{
+ __asm__ __volatile__("mfence" : : : "memory");
+}
+
+#define AO_HAVE_nop_full
+
+#else
+
+/* We could use the cpuid instruction. But that seems to be slower */
+/* than the default implementation based on test_and_set_full. Thus */
+/* we omit that bit of misinformation here. */
+
+#endif
+
+/* As far as we can tell, the lfence and sfence instructions are not */
+/* currently needed or useful for cached memory accesses. */
+
+/* Really only works for 486 and later */
+AO_INLINE AO_t
+AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
+{
+ AO_t result;
+
+ __asm__ __volatile__ ("lock; xaddq %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_fetch_and_add_full
+
+AO_INLINE unsigned char
+AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
+{
+ unsigned char result;
+
+ __asm__ __volatile__ ("lock; xaddb %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_char_fetch_and_add_full
+
+AO_INLINE unsigned short
+AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
+{
+ unsigned short result;
+
+ __asm__ __volatile__ ("lock; xaddw %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_short_fetch_and_add_full
+
+AO_INLINE unsigned short
+AO_int_fetch_and_add_full (volatile unsigned int *p, unsigned int incr)
+{
+ unsigned int result;
+
+ __asm__ __volatile__ ("lock; xaddl %0, %1" :
+ "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
+ : "memory");
+ return result;
+}
+
+#define AO_HAVE_int_fetch_and_add_full
+
+/* Really only works for 486 and later */
+AO_INLINE void
+AO_or_full (volatile AO_t *p, AO_t incr)
+{
+ __asm__ __volatile__ ("lock; orq %1, %0" :
+ "=m" (*p) : "r" (incr), "m" (*p) : "memory");
+}
+
+#define AO_HAVE_or_full
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+ unsigned char oldval;
+ /* Note: the "xchg" instruction does not need a "lock" prefix */
+ __asm__ __volatile__("xchgb %0, %1"
+ : "=r"(oldval), "=m"(*addr)
+ : "0"(0xff), "m"(*addr) : "memory");
+ return (AO_TS_VAL_t)oldval;
+}
+
+#define AO_HAVE_test_and_set_full
+
+/* Returns nonzero if the comparison succeeded. */
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ char result;
+ __asm__ __volatile__("lock; cmpxchgq %3, %0; setz %1"
+ : "=m"(*addr), "=q"(result)
+ : "m"(*addr), "r" (new_val), "a"(old) : "memory");
+ return (int) result;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* FIXME: The Intel version has a 16byte CAS instruction. */
diff --git a/src/atomic_ops/sysdeps/generic_pthread.h b/src/atomic_ops/sysdeps/generic_pthread.h
new file mode 100644
index 0000000..8d17c0a
--- /dev/null
+++ b/src/atomic_ops/sysdeps/generic_pthread.h
@@ -0,0 +1,289 @@
+/*
+ * 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.
+ */
+
+/* The following is useful primarily for debugging and documentation. */
+/* We define various atomic operations by acquiring a global pthread */
+/* lock. The resulting implementation will perform poorly, but should */
+/* be correct unless it is used from signal handlers. */
+/* We assume that all pthread operations act like full memory barriers. */
+/* (We believe that is the intent of the specification.) */
+
+#include <pthread.h>
+
+#include "test_and_set_t_is_ao_t.h"
+ /* This is not necessarily compatible with the native */
+ /* implementation. But those can't be safely mixed anyway. */
+
+/* We define only the full barrier variants, and count on the */
+/* generalization section below to fill in the rest. */
+extern pthread_mutex_t AO_pt_lock;
+
+AO_INLINE void
+AO_nop_full()
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_nop_full
+
+AO_INLINE AO_t
+AO_load_full(volatile AO_t *addr)
+{
+ AO_t result;
+ pthread_mutex_lock(&AO_pt_lock);
+ result = *addr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return result;
+}
+
+#define AO_HAVE_load_full
+
+AO_INLINE void
+AO_store_full(volatile AO_t *addr, AO_t val)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ *addr = val;
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_store_full
+
+AO_INLINE unsigned char
+AO_char_load_full(volatile unsigned char *addr)
+{
+ unsigned char result;
+ pthread_mutex_lock(&AO_pt_lock);
+ result = *addr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return result;
+}
+
+#define AO_HAVE_char_load_full
+
+AO_INLINE void
+AO_char_store_full(volatile unsigned char *addr, unsigned char val)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ *addr = val;
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_char_store_full
+
+AO_INLINE unsigned short
+AO_short_load_full(volatile unsigned short *addr)
+{
+ unsigned short result;
+ pthread_mutex_lock(&AO_pt_lock);
+ result = *addr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return result;
+}
+
+#define AO_HAVE_short_load_full
+
+AO_INLINE void
+AO_short_store_full(volatile unsigned short *addr, unsigned short val)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ *addr = val;
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_short_store_full
+
+AO_INLINE unsigned int
+AO_int_load_full(volatile unsigned int *addr)
+{
+ unsigned int result;
+ pthread_mutex_lock(&AO_pt_lock);
+ result = *addr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return result;
+}
+
+#define AO_HAVE_int_load_full
+
+AO_INLINE void
+AO_int_store_full(volatile unsigned int *addr, unsigned int val)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ *addr = val;
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_int_store_full
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+ AO_TS_VAL_t result;
+ pthread_mutex_lock(&AO_pt_lock);
+ result = (AO_TS_VAL_t)(*addr);
+ *addr = AO_TS_SET;
+ pthread_mutex_unlock(&AO_pt_lock);
+ assert(result == AO_TS_SET || result == AO_TS_CLEAR);
+ return result;
+}
+
+#define AO_HAVE_test_and_set_full
+
+AO_INLINE AO_t
+AO_fetch_and_add_full(volatile AO_t *p, AO_t incr)
+{
+ AO_t tmp;
+
+ pthread_mutex_lock(&AO_pt_lock);
+ tmp = *p;
+ *p = tmp + incr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return tmp;
+}
+
+#define AO_HAVE_fetch_and_add_full
+
+AO_INLINE unsigned char
+AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr)
+{
+ unsigned char tmp;
+
+ pthread_mutex_lock(&AO_pt_lock);
+ tmp = *p;
+ *p = tmp + incr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return tmp;
+}
+
+#define AO_HAVE_char_fetch_and_add_full
+
+AO_INLINE unsigned short
+AO_short_fetch_and_add_full(volatile unsigned short *p, unsigned short incr)
+{
+ unsigned short tmp;
+
+ pthread_mutex_lock(&AO_pt_lock);
+ tmp = *p;
+ *p = tmp + incr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return tmp;
+}
+
+#define AO_HAVE_short_fetch_and_add_full
+
+AO_INLINE unsigned int
+AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr)
+{
+ unsigned int tmp;
+
+ pthread_mutex_lock(&AO_pt_lock);
+ tmp = *p;
+ *p = tmp + incr;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return tmp;
+}
+
+#define AO_HAVE_int_fetch_and_add_full
+
+AO_INLINE void
+AO_or_full(volatile AO_t *p, AO_t incr)
+{
+ AO_t tmp;
+
+ pthread_mutex_lock(&AO_pt_lock);
+ tmp = *p;
+ *p = (tmp | incr);
+ pthread_mutex_unlock(&AO_pt_lock);
+}
+
+#define AO_HAVE_or_full
+
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ if (*addr == old)
+ {
+ *addr = new_val;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 1;
+ }
+ else
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 0;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* Unlike real architectures, we define both double-width CAS variants. */
+
+typedef struct {
+ AO_t AO_val1;
+ AO_t AO_val2;
+} AO_double_t;
+
+#define AO_HAVE_double_t
+
+AO_INLINE int
+AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
+ AO_t old1, AO_t old2,
+ AO_t new1, AO_t new2)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ if (addr -> AO_val1 == old1 && addr -> AO_val2 == old2)
+ {
+ addr -> AO_val1 = new1;
+ addr -> AO_val2 = new2;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 1;
+ }
+ else
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 0;
+}
+
+#define AO_HAVE_compare_double_and_swap_double_full
+
+AO_INLINE int
+AO_compare_and_swap_double_full(volatile AO_double_t *addr,
+ AO_t old1,
+ AO_t new1, AO_t new2)
+{
+ pthread_mutex_lock(&AO_pt_lock);
+ if (addr -> AO_val1 == old1)
+ {
+ addr -> AO_val1 = new1;
+ addr -> AO_val2 = new2;
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 1;
+ }
+ else
+ pthread_mutex_unlock(&AO_pt_lock);
+ return 0;
+}
+
+#define AO_HAVE_compare_and_swap_double_full
+
+/* We can't use hardware loads and stores, since they don't */
+/* interact correctly with atomic updates. */
+
diff --git a/src/atomic_ops/sysdeps/hpc/hppa.h b/src/atomic_ops/sysdeps/hpc/hppa.h
new file mode 100644
index 0000000..80bd94c
--- /dev/null
+++ b/src/atomic_ops/sysdeps/hpc/hppa.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2003 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.
+ *
+ * Derived from the corresponsing header file for gcc.
+ *
+ */
+
+#include "../atomic_load_store.h"
+
+/* Some architecture set descriptions include special "ordered" memory */
+/* operations. As far as we can tell, no existing processors actually */
+/* require those. Nor does it appear likely that future processors */
+/* will. */
+/* FIXME: */
+/* The PA emulator on Itanium may obey weaker restrictions. */
+/* There should be a mode in which we don't assume sequential */
+/* consistency here. */
+#include "../ordered.h"
+
+#include <machine/inline.h>
+
+/* GCC will not guarantee the alignment we need, use four lock words */
+/* and select the correctly aligned datum. See the glibc 2.3.2 */
+/* linuxthread port for the original implementation. */
+struct AO_pa_clearable_loc {
+ int data[4];
+};
+
+#undef AO_TS_INITIALIZER
+#define AO_TS_t struct AO_pa_clearable_loc
+#define AO_TS_INITIALIZER {1,1,1,1}
+/* Switch meaning of set and clear, since we only have an atomic clear */
+/* instruction. */
+typedef enum {AO_PA_TS_set = 0, AO_PA_TS_clear = 1} AO_PA_TS_val;
+#define AO_TS_VAL_t AO_PA_TS_val
+#define AO_TS_CLEAR AO_PA_TS_clear
+#define AO_TS_SET AO_PA_TS_set
+
+/* The hppa only has one atomic read and modify memory operation, */
+/* load and clear, so hppa spinlocks must use zero to signify that */
+/* someone is holding the lock. The address used for the ldcw */
+/* semaphore must be 16-byte aligned. */
+
+#define __ldcw(a, ret) \
+ _LDCWX(0 /* index */, 0 /* s */, a /* base */, ret);
+
+/* Because malloc only guarantees 8-byte alignment for malloc'd data, */
+/* and GCC only guarantees 8-byte alignment for stack locals, we can't */
+/* be assured of 16-byte alignment for atomic lock data even if we */
+/* specify "__attribute ((aligned(16)))" in the type declaration. So, */
+/* we use a struct containing an array of four ints for the atomic lock */
+/* type and dynamically select the 16-byte aligned int from the array */
+/* for the semaphore. */
+#define __PA_LDCW_ALIGNMENT 16
+
+#define __ldcw_align(a, ret) { \
+ ret = (unsigned long) a; \
+ ret += __PA_LDCW_ALIGNMENT - 1; \
+ ret &= ~(__PA_LDCW_ALIGNMENT - 1); \
+}
+
+/* Works on PA 1.1 and PA 2.0 systems */
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t * addr)
+{
+ register unsigned int ret;
+ register unsigned long a;
+ __ldcw_align (addr, a);
+ __ldcw (a, ret);
+ return ret;
+}
+
+AO_INLINE void
+AO_pa_clear(volatile AO_TS_t * addr)
+{
+ unsigned long a;
+ __ldcw_align (addr,a);
+ AO_compiler_barrier();
+ *(volatile unsigned int *)a = 1;
+}
+#define AO_CLEAR(addr) AO_pa_clear(addr)
+
+#define AO_HAVE_test_and_set_full
+
diff --git a/src/atomic_ops/sysdeps/hpc/ia64.h b/src/atomic_ops/sysdeps/hpc/ia64.h
new file mode 100644
index 0000000..72552d5
--- /dev/null
+++ b/src/atomic_ops/sysdeps/hpc/ia64.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/*
+ * This file specifies Itanimum primitives for use with the HP compiler
+ * unde HP/UX. We use intrinsics instead of the inline assembly code in the
+ * gcc file.
+ */
+
+#include "../atomic_load_store.h"
+
+#include "../acquire_release_volatile.h"
+
+#include "../test_and_set_t_is_char.h"
+
+#include <machine/sys/inline.h>
+
+#ifdef __LP64__
+# define AO_T_FASIZE _FASZ_D
+# define AO_T_SIZE _SZ_D
+#else
+# define AO_T_FASIZE _FASZ_W
+# define AO_T_SIZE _SZ_W
+#endif
+
+AO_INLINE void
+AO_nop_full()
+{
+ _Asm_mf();
+}
+#define AO_HAVE_nop_full
+
+AO_INLINE AO_t
+AO_fetch_and_add1_acquire (volatile AO_t *p)
+{
+ return _Asm_fetchadd(AO_T_FASIZE, _SEM_ACQ, p, 1,
+ _LDHINT_NONE, _DOWN_MEM_FENCE);
+}
+#define AO_HAVE_fetch_and_add1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_add1_release (volatile AO_t *p)
+{
+ return _Asm_fetchadd(AO_T_FASIZE, _SEM_REL, p, 1,
+ _LDHINT_NONE, _UP_MEM_FENCE);
+}
+
+#define AO_HAVE_fetch_and_add1_release
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_acquire (volatile AO_t *p)
+{
+ return _Asm_fetchadd(AO_T_FASIZE, _SEM_ACQ, p, -1,
+ _LDHINT_NONE, _DOWN_MEM_FENCE);
+}
+
+#define AO_HAVE_fetch_and_sub1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_release (volatile AO_t *p)
+{
+ return _Asm_fetchadd(AO_T_FASIZE, _SEM_REL, p, -1,
+ _LDHINT_NONE, _UP_MEM_FENCE);
+}
+
+#define AO_HAVE_fetch_and_sub1_release
+
+AO_INLINE int
+AO_compare_and_swap_acquire(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+
+ _Asm_mov_to_ar(_AREG_CCV, old, _DOWN_MEM_FENCE);
+ oldval = _Asm_cmpxchg(AO_T_SIZE, _SEM_ACQ, addr,
+ new_val, _LDHINT_NONE, _DOWN_MEM_FENCE);
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_acquire
+
+AO_INLINE int
+AO_compare_and_swap_release(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+ _Asm_mov_to_ar(_AREG_CCV, old, _UP_MEM_FENCE);
+ oldval = _Asm_cmpxchg(AO_T_SIZE, _SEM_REL, addr,
+ new_val, _LDHINT_NONE, _UP_MEM_FENCE);
+ /* Hopefully the compiler knows not to reorder the above two? */
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_release
+
+AO_INLINE int
+AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ unsigned char oldval;
+
+ _Asm_mov_to_ar(_AREG_CCV, old, _DOWN_MEM_FENCE);
+ oldval = _Asm_cmpxchg(_SZ_B, _SEM_ACQ, addr,
+ new_val, _LDHINT_NONE, _DOWN_MEM_FENCE);
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_acquire
+
+AO_INLINE int
+AO_char_compare_and_swap_release(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ insigned char oldval;
+ _Asm_mov_to_ar(_AREG_CCV, old, _UP_MEM_FENCE);
+ oldval = _Asm_cmpxchg(_SZ_B, _SEM_REL, addr,
+ new_val, _LDHINT_NONE, _UP_MEM_FENCE);
+ /* Hopefully the compiler knows not to reorder the above two? */
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_release
+
+AO_INLINE int
+AO_short_compare_and_swap_acquire(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ unsigned short oldval;
+
+ _Asm_mov_to_ar(_AREG_CCV, old, _DOWN_MEM_FENCE);
+ oldval = _Asm_cmpxchg(_SZ_B, _SEM_ACQ, addr,
+ new_val, _LDHINT_NONE, _DOWN_MEM_FENCE);
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_acquire
+
+AO_INLINE int
+AO_short_compare_and_swap_release(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ insigned short oldval;
+ _Asm_mov_to_ar(_AREG_CCV, old, _UP_MEM_FENCE);
+ oldval = _Asm_cmpxchg(_SZ_B, _SEM_REL, addr,
+ new_val, _LDHINT_NONE, _UP_MEM_FENCE);
+ /* Hopefully the compiler knows not to reorder the above two? */
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_release
+
+#ifndef __LP64__
+# include "ao_t_is_int.h"
+#endif
+
diff --git a/src/atomic_ops/sysdeps/ibmc/powerpc.h b/src/atomic_ops/sysdeps/ibmc/powerpc.h
new file mode 100644
index 0000000..d1f9c50
--- /dev/null
+++ b/src/atomic_ops/sysdeps/ibmc/powerpc.h
@@ -0,0 +1,126 @@
+/* FIXME. This is only a placeholder for the AIX compiler. */
+/* It doesn't work. Please send a patch. */
+/* Memory model documented at http://www-106.ibm.com/developerworks/ */
+/* eserver/articles/archguide.html and (clearer) */
+/* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
+/* There appears to be no implicit ordering between any kind of */
+/* independent memory references. */
+/* Architecture enforces some ordering based on control dependence. */
+/* I don't know if that could help. */
+/* Data-dependent loads are always ordered. */
+/* Based on the above references, eieio is intended for use on */
+/* uncached memory, which we don't support. It does not order loads */
+/* from cached memory. */
+/* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to */
+/* track some of this down and correcting my misunderstandings. -HB */
+
+#include "../all_aligned_atomic_load_store.h"
+
+void AO_sync(void);
+#pragma mc_func AO_sync { "7c0004ac" }
+
+void AO_lwsync(void);
+#pragma mc_func AO_lwsync { "7c2004ac" }
+
+#define AO_nop_write() AO_lwsync()
+#define AO_HAVE_nop_write
+
+#define AO_nop_read() AO_lwsync()
+#define AO_HAVE_nop_read
+
+/* We explicitly specify load_acquire and store_release, since these */
+/* rely on the fact that lwsync is also a LoadStore barrier. */
+AO_INLINE AO_t
+AO_load_acquire(volatile AO_t *addr)
+{
+ AO_t result = *addr;
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_load_acquire
+
+AO_INLINE void
+AO_store_release(volatile AO_t *addr, AO_t value)
+{
+ AO_lwsync();
+ *addr = value;
+}
+
+#define AO_HAVE_load_acquire
+
+/* This is similar to the code in the garbage collector. Deleting */
+/* this and having it synthesized from compare_and_swap would probably */
+/* only cost us a load immediate instruction. */
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set(volatile AO_TS_t *addr) {
+# error Implement me
+}
+
+#define AO_have_test_and_set
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_acquire(volatile AO_TS_t *addr) {
+ AO_TS_VAL_t result = AO_test_and_set(addr);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_test_and_set_acquire
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_release(volatile AO_TS_t *addr) {
+ AO_lwsync();
+ return AO_test_and_set(addr);
+}
+
+#define AO_HAVE_test_and_set_release
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr) {
+ AO_TS_VAL_t result;
+ AO_lwsync();
+ result = AO_test_and_set(addr);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_test_and_set_full
+
+AO_INLINE AO_t
+AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) {
+# error Implement me
+}
+
+#define AO_HAVE_compare_and_swap
+
+AO_INLINE AO_t
+AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_t result = AO_compare_and_swap(addr, old, new_val);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_compare_and_swap_acquire
+
+AO_INLINE AO_t
+AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_lwsync();
+ return AO_compare_and_swap(addr, old, new_val);
+}
+
+#define AO_HAVE_compare_and_swap_release
+
+AO_INLINE AO_t
+AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ AO_t result;
+ AO_lwsync();
+ result = AO_compare_and_swap(addr, old, new_val);
+ AO_lwsync();
+ return result;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+/* FIXME: We should also implement fetch_and_add and or primitives */
+/* directly. */
diff --git a/src/atomic_ops/sysdeps/icc/ia64.h b/src/atomic_ops/sysdeps/icc/ia64.h
new file mode 100644
index 0000000..358ddda
--- /dev/null
+++ b/src/atomic_ops/sysdeps/icc/ia64.h
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file specifies Itanimum primitives for use with the Intel (ecc)
+ * compiler. We use intrinsics instead of the inline assembly code in the
+ * gcc file.
+ */
+
+#include "../all_atomic_load_store.h"
+
+#include "../test_and_set_t_is_char.h"
+
+#include <ia64intrin.h>
+
+/* The acquire release semantics of volatile can be turned off. And volatile */
+/* operations in icc9 don't imply ordering with respect to other nonvolatile */
+/* operations. */
+
+#define AO_INTEL_PTR_t void *
+
+AO_INLINE AO_t
+AO_load_acquire(volatile AO_t *p)
+{
+ return (AO_t)(__ld8_acq((AO_INTEL_PTR_t)p));
+}
+#define AO_HAVE_load_acquire
+
+AO_INLINE void
+AO_store_release(volatile AO_t *p, AO_t val)
+{
+ __st8_rel((AO_INTEL_PTR_t)p, (__int64)val);
+}
+#define AO_HAVE_store_release
+
+AO_INLINE unsigned char
+AO_char_load_acquire(volatile unsigned char *p)
+{
+ /* A normal volatile load generates an ld.acq */
+ return (__ld1_acq((AO_INTEL_PTR_t)p));
+}
+#define AO_HAVE_char_load_acquire
+
+AO_INLINE void
+AO_char_store_release(volatile unsigned char *p, unsigned char val)
+{
+ __st1_rel((AO_INTEL_PTR_t)p, val);
+}
+#define AO_HAVE_char_store_release
+
+AO_INLINE unsigned short
+AO_short_load_acquire(volatile unsigned short *p)
+{
+ /* A normal volatile load generates an ld.acq */
+ return (__ld2_acq((AO_INTEL_PTR_t)p));
+}
+#define AO_HAVE_short_load_acquire
+
+AO_INLINE void
+AO_short_store_release(volatile unsigned short *p, unsigned short val)
+{
+ __st2_rel((AO_INTEL_PTR_t)p, val);
+}
+#define AO_HAVE_short_store_release
+
+AO_INLINE unsigned int
+AO_int_load_acquire(volatile unsigned int *p)
+{
+ /* A normal volatile load generates an ld.acq */
+ return (__ld4_acq((AO_INTEL_PTR_t)p));
+}
+#define AO_HAVE_int_load_acquire
+
+AO_INLINE void
+AO_int_store_release(volatile unsigned int *p, unsigned int val)
+{
+ __st4_rel((AO_INTEL_PTR_t)p, val);
+}
+#define AO_HAVE_int_store_release
+
+AO_INLINE void
+AO_nop_full()
+{
+ __mf();
+}
+#define AO_HAVE_nop_full
+
+AO_INLINE AO_t
+AO_fetch_and_add1_acquire (volatile AO_t *p)
+{
+ return __fetchadd8_acq((unsigned __int64 *)p, 1);
+}
+#define AO_HAVE_fetch_and_add1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_add1_release (volatile AO_t *p)
+{
+ return __fetchadd8_rel((unsigned __int64 *)p, 1);
+}
+
+#define AO_HAVE_fetch_and_add1_release
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_acquire (volatile AO_t *p)
+{
+ return __fetchadd8_acq((unsigned __int64 *)p, -1);
+}
+
+#define AO_HAVE_fetch_and_sub1_acquire
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_release (volatile AO_t *p)
+{
+ return __fetchadd8_rel((unsigned __int64 *)p, -1);
+}
+
+#define AO_HAVE_fetch_and_sub1_release
+
+AO_INLINE int
+AO_compare_and_swap_acquire(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+ oldval = _InterlockedCompareExchange64_acq(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_acquire
+
+AO_INLINE int
+AO_compare_and_swap_release(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ AO_t oldval;
+ oldval = _InterlockedCompareExchange64_rel(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_compare_and_swap_release
+
+AO_INLINE int
+AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ unsigned char oldval;
+ oldval = _InterlockedCompareExchange8_acq(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_acquire
+
+AO_INLINE int
+AO_char_compare_and_swap_release(volatile unsigned char *addr,
+ unsigned char old, unsigned char new_val)
+{
+ unsigned char oldval;
+ oldval = _InterlockedCompareExchange8_rel(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_char_compare_and_swap_release
+
+AO_INLINE int
+AO_short_compare_and_swap_acquire(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ unsigned short oldval;
+ oldval = _InterlockedCompareExchange16_acq(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_acquire
+
+AO_INLINE int
+AO_short_compare_and_swap_release(volatile unsigned short *addr,
+ unsigned short old, unsigned short new_val)
+{
+ unsigned short oldval;
+ oldval = _InterlockedCompareExchange16_rel(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_short_compare_and_swap_release
+
+AO_INLINE int
+AO_int_compare_and_swap_acquire(volatile unsigned int *addr,
+ unsigned int old, unsigned int new_val)
+{
+ unsigned int oldval;
+ oldval = _InterlockedCompareExchange_acq(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_int_compare_and_swap_acquire
+
+AO_INLINE int
+AO_int_compare_and_swap_release(volatile unsigned int *addr,
+ unsigned int old, unsigned int new_val)
+{
+ unsigned int oldval;
+ oldval = _InterlockedCompareExchange_rel(addr, new_val, old);
+ return (oldval == old);
+}
+
+#define AO_HAVE_int_compare_and_swap_release
+
diff --git a/src/atomic_ops/sysdeps/int_acquire_release_volatile.h b/src/atomic_ops/sysdeps/int_acquire_release_volatile.h
new file mode 100644
index 0000000..e0a6ed0
--- /dev/null
+++ b/src/atomic_ops/sysdeps/int_acquire_release_volatile.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file adds definitions appropriate for environments in which an unsigned
+ * int volatile load has acquire semantics, and an unsigned short volatile
+ * store has release semantics. This is true with the standard Itanium ABI.
+ */
+#if !defined(AO_GCC_BARRIER)
+# if defined(__GNUC__)
+# define AO_GCC_BARRIER() AO_compiler_barrier()
+# else
+# define AO_GCC_BARRIER()
+# endif
+#endif
+
+AO_INLINE unsigned int
+AO_int_load_acquire(volatile unsigned int *p)
+{
+ unsigned int result = *p;
+ /* A normal volatile load generates an ld.acq */
+ AO_GCC_BARRIER();
+ return result;
+}
+#define AO_HAVE_int_load_acquire
+
+AO_INLINE void
+AO_int_store_release(volatile unsigned int *p, unsigned int val)
+{
+ AO_GCC_BARRIER();
+ /* A normal volatile store generates an st.rel */
+ *p = val;
+}
+#define AO_HAVE_int_store_release
+
+
diff --git a/src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h b/src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h
new file mode 100644
index 0000000..fa59656
--- /dev/null
+++ b/src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of unsigned int are
+ * atomic fo all legal alignments.
+ */
+
+AO_INLINE unsigned int
+AO_int_load(volatile unsigned int *addr)
+{
+ assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(unsigned int *)addr);
+}
+
+#define AO_HAVE_int_load
+
+AO_INLINE void
+AO_int_store(volatile unsigned int *addr, unsigned int new_val)
+{
+ assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+ (*(unsigned int *)addr) = new_val;
+}
+
+#define AO_HAVE_int_store
+
+
diff --git a/src/atomic_ops/sysdeps/int_atomic_load_store.h b/src/atomic_ops/sysdeps/int_atomic_load_store.h
new file mode 100644
index 0000000..b2a4813
--- /dev/null
+++ b/src/atomic_ops/sysdeps/int_atomic_load_store.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of unsigned int are
+ * atomic for all legal alignments.
+ */
+
+AO_INLINE unsigned int
+AO_int_load(volatile unsigned int *addr)
+{
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(unsigned int *)addr);
+}
+
+#define AO_HAVE_int_load
+
+AO_INLINE void
+AO_int_store(volatile unsigned int *addr, unsigned int new_val)
+{
+ (*(unsigned int *)addr) = new_val;
+}
+
+#define AO_HAVE_int_store
+
+
diff --git a/src/atomic_ops/sysdeps/msftc/x86.h b/src/atomic_ops/sysdeps/msftc/x86.h
new file mode 100644
index 0000000..eac112c
--- /dev/null
+++ b/src/atomic_ops/sysdeps/msftc/x86.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/* The following really assume we have a 486 or better. */
+/* If ASSUME_WINDOWS98 is defined, we assume Windows 98 or newer. */
+
+#include "../aligned_atomic_load_store.h"
+
+/* Real X86 implementations, except for some old WinChips, appear */
+/* to enforce ordering between memory operations, EXCEPT that a later */
+/* read can pass earlier writes, presumably due to the visible */
+/* presence of store buffers. */
+/* We ignore both the WinChips, and the fact that the official specs */
+/* seem to be much weaker (and arguably too weak to be usable). */
+
+#include "../ordered_except_wr.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+ /* We should use byte-sized test-and-set locations, as with */
+ /* gcc. But I couldn't find the appropriate compiler */
+ /* intrinsic. - HB */
+
+#include <windows.h>
+
+/* As far as we can tell, the lfence and sfence instructions are not */
+/* currently needed or useful for cached memory accesses. */
+
+AO_INLINE AO_t
+AO_fetch_and_add1_full (volatile AO_t *p)
+{
+ return InterlockedIncrement((LONG volatile *)p) - 1;
+}
+
+#define AO_HAVE_fetch_and_add1_full
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_full (volatile AO_t *p)
+{
+ return InterlockedDecrement((LONG volatile *)p) + 1;
+}
+
+#define AO_HAVE_fetch_and_sub1_full
+
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+ return (AO_TS_VAL_t) InterlockedExchange((LONG volatile *)addr,
+ (LONG)AO_TS_SET);
+}
+
+#define AO_HAVE_test_and_set_full
+
+#ifdef AO_ASSUME_WINDOWS98
+/* Returns nonzero if the comparison succeeded. */
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+# if 0
+ /* Use the pointer variant, since that should always have the right size. */
+ /* This seems to fail with VC++ 6 on Win2000 because the routine isn't */
+ /* actually there. */
+ return InterlockedCompareExchangePointer((PVOID volatile *)addr,
+ (PVOID)new_val, (PVOID) old)
+ == (PVOID)old;
+# endif
+ /* FIXME - This is nearly useless on win64. */
+ /* Use InterlockedCompareExchange64 for win64? */
+ return InterlockedCompareExchange((DWORD volatile *)addr,
+ (DWORD)new_val, (DWORD) old)
+ == (DWORD)old;
+}
+
+#define AO_HAVE_compare_and_swap_full
+#endif /* ASSUME_WINDOWS98 */
diff --git a/src/atomic_ops/sysdeps/ordered.h b/src/atomic_ops/sysdeps/ordered.h
new file mode 100644
index 0000000..2bcd8d8
--- /dev/null
+++ b/src/atomic_ops/sysdeps/ordered.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/*
+ * These are common definitions for architectures that provide processor
+ * ordered memory operations.
+ */
+
+#include "ordered_except_wr.h"
+
+AO_INLINE void
+AO_nop_full()
+{
+ AO_compiler_barrier();
+}
+
+#define AO_HAVE_nop_full
+
+
diff --git a/src/atomic_ops/sysdeps/ordered_except_wr.h b/src/atomic_ops/sysdeps/ordered_except_wr.h
new file mode 100644
index 0000000..b984f0d
--- /dev/null
+++ b/src/atomic_ops/sysdeps/ordered_except_wr.h
@@ -0,0 +1,171 @@
+/*
+ * 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_write()
+{
+ AO_compiler_barrier();
+ /* sfence according to Intel docs. Pentium 3 and up. */
+ /* Unnecessary for cached accesses? */
+}
+
+#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
+AO_store_write(volatile AO_t *addr, AO_t val)
+{
+ AO_compiler_barrier();
+ AO_store(addr, val);
+}
+# define AO_HAVE_store_write
+
+# define AO_store_release(addr, val) AO_store_write(addr, val)
+# define AO_HAVE_store_release
+
+#endif /* AO_HAVE_store */
+
+#if defined(AO_HAVE_char_store)
+
+AO_INLINE void
+AO_char_store_write(volatile unsigned char *addr, unsigned char val)
+{
+ AO_compiler_barrier();
+ AO_char_store(addr, val);
+}
+# define AO_HAVE_char_store_write
+
+# define AO_char_store_release(addr, val) AO_char_store_write(addr, val)
+# define AO_HAVE_char_store_release
+
+#endif /* AO_HAVE_char_store */
+
+#if defined(AO_HAVE_short_store)
+
+AO_INLINE void
+AO_short_store_write(volatile unsigned short *addr, unsigned short val)
+{
+ AO_compiler_barrier();
+ AO_short_store(addr, val);
+}
+# define AO_HAVE_short_store_write
+
+# define AO_short_store_release(addr, val) AO_short_store_write(addr, val)
+# define AO_HAVE_short_store_release
+
+#endif /* AO_HAVE_short_store */
+
+#if defined(AO_HAVE_int_store)
+
+AO_INLINE void
+AO_int_store_write(volatile unsigned int *addr, unsigned int val)
+{
+ AO_compiler_barrier();
+ AO_int_store(addr, val);
+}
+# define AO_HAVE_int_store_write
+
+# define AO_int_store_release(addr, val) AO_int_store_write(addr, val)
+# define AO_HAVE_int_store_release
+
+#endif /* AO_HAVE_int_store */
+
diff --git a/src/atomic_ops/sysdeps/short_acquire_release_volatile.h b/src/atomic_ops/sysdeps/short_acquire_release_volatile.h
new file mode 100644
index 0000000..035ada7
--- /dev/null
+++ b/src/atomic_ops/sysdeps/short_acquire_release_volatile.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file adds definitions appropriate for environments in which an unsigned short
+ * volatile load has acquire semantics, and an unsigned short volatile store has release
+ * semantics. This is true with the standard Itanium ABI.
+ */
+#if !defined(AO_GCC_BARRIER)
+# if defined(__GNUC__)
+# define AO_GCC_BARRIER() AO_compiler_barrier()
+# else
+# define AO_GCC_BARRIER()
+# endif
+#endif
+
+AO_INLINE unsigned short
+AO_short_load_acquire(volatile unsigned short *p)
+{
+ unsigned short result = *p;
+ /* A normal volatile load generates an ld.acq */
+ AO_GCC_BARRIER();
+ return result;
+}
+#define AO_HAVE_short_load_acquire
+
+AO_INLINE void
+AO_short_store_release(volatile unsigned short *p, unsigned short val)
+{
+ AO_GCC_BARRIER();
+ /* A normal volatile store generates an st.rel */
+ *p = val;
+}
+#define AO_HAVE_short_store_release
+
+
diff --git a/src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h b/src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h
new file mode 100644
index 0000000..54ed757
--- /dev/null
+++ b/src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of unsigned short are
+ * atomic fo all legal alignments.
+ */
+
+AO_INLINE unsigned short
+AO_short_load(volatile unsigned short *addr)
+{
+ assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(unsigned short *)addr);
+}
+
+#define AO_HAVE_short_load
+
+AO_INLINE void
+AO_short_store(volatile unsigned short *addr, unsigned short new_val)
+{
+ assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+ (*(unsigned short *)addr) = new_val;
+}
+
+#define AO_HAVE_short_store
+
+
diff --git a/src/atomic_ops/sysdeps/short_atomic_load_store.h b/src/atomic_ops/sysdeps/short_atomic_load_store.h
new file mode 100644
index 0000000..f1b5281
--- /dev/null
+++ b/src/atomic_ops/sysdeps/short_atomic_load_store.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/*
+ * Definitions for architecturs on which loads and stores of unsigned short are
+ * atomic for all legal alignments.
+ */
+
+AO_INLINE unsigned short
+AO_short_load(volatile unsigned short *addr)
+{
+ /* Cast away the volatile for architectures like IA64 where */
+ /* volatile adds barrier semantics. */
+ return (*(unsigned short *)addr);
+}
+
+#define AO_HAVE_short_load
+
+AO_INLINE void
+AO_short_store(volatile unsigned short *addr, unsigned short new_val)
+{
+ (*(unsigned short *)addr) = new_val;
+}
+
+#define AO_HAVE_short_store
+
+
diff --git a/src/atomic_ops/sysdeps/standard_ao_double_t.h b/src/atomic_ops/sysdeps/standard_ao_double_t.h
new file mode 100644
index 0000000..1d08fc7
--- /dev/null
+++ b/src/atomic_ops/sysdeps/standard_ao_double_t.h
@@ -0,0 +1,8 @@
+typedef union {
+ unsigned long long AO_whole;
+ struct {AO_t AO_v1; AO_t AO_v2;} AO_parts;
+} AO_double_t;
+#define AO_HAVE_double_t
+#define AO_val1 AO_parts.AO_v1
+#define AO_val2 AO_parts.AO_v2
+
diff --git a/src/atomic_ops/sysdeps/sunc/sparc.S b/src/atomic_ops/sysdeps/sunc/sparc.S
new file mode 100644
index 0000000..81f0ef0
--- /dev/null
+++ b/src/atomic_ops/sysdeps/sunc/sparc.S
@@ -0,0 +1,5 @@
+ .seg "text"
+ .globl AO_test_and_set_full
+AO_test_and_set_full:
+ retl
+ ldstub [%o0],%o0
diff --git a/src/atomic_ops/sysdeps/sunc/sparc.h b/src/atomic_ops/sysdeps/sunc/sparc.h
new file mode 100644
index 0000000..3578722
--- /dev/null
+++ b/src/atomic_ops/sysdeps/sunc/sparc.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#include "../all_atomic_load_store.h"
+
+/* Real SPARC code uses TSO: */
+#include "../ordered_except_wr.h"
+
+/* Test_and_set location is just a byte. */
+#include "../test_and_set_t_is_char.h"
+
+extern AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr);
+/* Implemented in separate .S file, for now. */
+
+#define AO_HAVE_test_and_set_full
+
+/* FIXME: Like the gcc version, this needs to be extended for V8 */
+/* and V9. */
diff --git a/src/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h b/src/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h
new file mode 100644
index 0000000..663bccf
--- /dev/null
+++ b/src/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * These are common definitions for architectures on which test_and_set
+ * operates on pointer-sized quantities, the "clear" value contains
+ * all zeroes, and the "set" value contains all ones.
+ * This can be used if test_and_set is synthesized from compare_and_swap.
+ */
+typedef enum {AO_TS_clear = 0, AO_TS_set = 1} AO_TS_val;
+#define AO_TS_VAL_t AO_TS_val
+#define AO_TS_CLEAR AO_TS_clear
+#define AO_TS_SET AO_TS_set
+
+#define AO_TS_t AO_t
+
+#define AO_AO_TS_T 1
diff --git a/src/atomic_ops/sysdeps/test_and_set_t_is_char.h b/src/atomic_ops/sysdeps/test_and_set_t_is_char.h
new file mode 100644
index 0000000..bde0f21
--- /dev/null
+++ b/src/atomic_ops/sysdeps/test_and_set_t_is_char.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * These are common definitions for architectures on which test_and_set
+ * operates on byte sized quantities, the "clear" value contains
+ * all zeroes, and the "set" value contains all ones.
+ */
+
+#define AO_TS_t unsigned char
+typedef enum {AO_BYTE_TS_clear = 0, AO_BYTE_TS_set = 0xff} AO_BYTE_TS_val;
+#define AO_TS_VAL_t AO_BYTE_TS_val
+#define AO_TS_CLEAR AO_BYTE_TS_clear
+#define AO_TS_SET AO_BYTE_TS_set
+
+#define AO_CHAR_TS_T 1
+
+
+
diff --git a/src/atomic_ops_malloc.c b/src/atomic_ops_malloc.c
new file mode 100644
index 0000000..dff4908
--- /dev/null
+++ b/src/atomic_ops_malloc.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+ * Original Author: Hans Boehm
+ *
+ * This file may be redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * It is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License in the
+ * file doc/COPYING for more details.
+ */
+
+#if defined(HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#define AO_REQUIRE_CAS
+#include "atomic_ops_stack.h"
+#include <string.h> /* for ffs, which is assumed reentrant. */
+#include <stdlib.h>
+#ifdef AO_TRACE_MALLOC
+# include <stdio.h>
+# include <pthread.h>
+#endif
+
+/*
+ * We round up each allocation request to the next power of two
+ * minus one word.
+ * We keep one stack of free objects for each size. Each object
+ * has an initial word (offset -sizeof(AO_t) from the visible pointer)
+ * which contains either
+ * The binary log of the object size in bytes (small objects)
+ * The object size (a multiple of CHUNK_SIZE) for large objects.
+ * The second case only arises if mmap-based allocation is supported.
+ * We align the user-visible part of each object on a GRANULARITY
+ * byte boundary. That means that the actual (hidden) start of
+ * the object starts a word before this boundary.
+ */
+
+#ifndef LOG_MAX_SIZE
+# define LOG_MAX_SIZE 16
+ /* We assume that 2**LOG_MAX_SIZE is a multiple of page size. */
+#endif
+
+#ifndef ALIGNMENT
+# define ALIGNMENT 16
+ /* Assumed to be at least sizeof(AO_t). */
+#endif
+
+#define CHUNK_SIZE (1 << LOG_MAX_SIZE)
+
+#ifndef AO_INITIAL_HEAP_SIZE
+# define AO_INITIAL_HEAP_SIZE (2*(LOG_MAX_SIZE+1)*CHUNK_SIZE)
+#endif
+
+char AO_initial_heap[AO_INITIAL_HEAP_SIZE];
+
+static volatile AO_t initial_heap_ptr = (AO_t)AO_initial_heap;
+static volatile char *initial_heap_lim = AO_initial_heap + AO_INITIAL_HEAP_SIZE;
+
+#if defined(HAVE_MMAP)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+static volatile AO_t mmap_enabled = 0;
+
+void
+AO_malloc_enable_mmap(void)
+{
+ AO_store(&mmap_enabled, 1);
+}
+
+static char *get_mmaped(size_t sz)
+{
+ char * result;
+
+ assert(!(sz & (CHUNK_SIZE - 1)));
+ if (!mmap_enabled) return 0;
+# if defined(MAP_ANONYMOUS)
+ result = mmap(0, sz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+# elif defined(MAP_ANON)
+ result = mmap(0, sz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+# else
+ {
+ int zero_fd = open("/dev/zero", O_RDONLY);
+ result = mmap(0, sz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, zero_fd, 0);
+ close(zero_fd);
+ }
+# endif
+ if (result == MAP_FAILED) result = 0;
+ return result;
+}
+
+/* Allocate an object of size (incl. header) of size > CHUNK_SIZE. */
+/* sz includes space for an AO_t-sized header. */
+static char *
+AO_malloc_large(size_t sz)
+{
+ char * result;
+ /* The header will force us to waste ALIGNMENT bytes, incl. header. */
+ sz += ALIGNMENT;
+ /* Round to multiple of CHUNK_SIZE. */
+ sz = (sz + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
+ result = get_mmaped(sz);
+ if (result == 0) return 0;
+ result += ALIGNMENT;
+ ((AO_t *)result)[-1] = (AO_t)sz;
+ return result;
+}
+
+static void
+AO_free_large(char * p)
+{
+ AO_t sz = ((AO_t *)p)[-1];
+ if (munmap(p - ALIGNMENT, (size_t)sz) != 0)
+ abort(); /* Programmer error. Not really async-signal-safe, but ... */
+}
+
+
+#else /* No MMAP */
+
+void
+AO_malloc_enable_mmap(void)
+{
+}
+
+static char *get_mmaped(size_t sz)
+{
+ return 0;
+}
+
+static char *
+AO_malloc_large(size_t sz)
+{
+ return 0;
+}
+
+static void
+AO_free_large(char * p)
+{
+ abort(); /* Programmer error. Not really async-signal-safe, but ... */
+}
+
+#endif /* No MMAP */
+
+static char *
+get_chunk(void)
+{
+ char *initial_ptr;
+ char *my_chunk_ptr;
+ char * my_lim;
+
+retry:
+ initial_ptr = (char *)AO_load(&initial_heap_ptr);
+ my_chunk_ptr = (char *)(((AO_t)initial_ptr + (ALIGNMENT - 1))
+ & ~(ALIGNMENT - 1));
+ if (initial_ptr != my_chunk_ptr)
+ {
+ /* Align correctly. If this fails, someone else did it for us. */
+ AO_compare_and_swap_acquire(&initial_heap_ptr, (AO_t)initial_ptr,
+ (AO_t)my_chunk_ptr);
+ }
+ my_lim = my_chunk_ptr + CHUNK_SIZE;
+ if (my_lim <= initial_heap_lim)
+ {
+ if (!AO_compare_and_swap(&initial_heap_ptr, (AO_t)my_chunk_ptr,
+ (AO_t)my_lim))
+ goto retry;
+ return my_chunk_ptr;
+ }
+ /* We failed. The initial heap is used up. */
+ my_chunk_ptr = get_mmaped(CHUNK_SIZE);
+ assert (!((AO_t)my_chunk_ptr & (ALIGNMENT-1)));
+ return my_chunk_ptr;
+}
+
+/* Object free lists. Ith entry corresponds to objects */
+/* of total size 2**i bytes. */
+AO_stack_t AO_free_list[LOG_MAX_SIZE+1];
+
+/* Chunk free list, linked through first word in chunks. */
+/* All entries of size CHUNK_SIZE. */
+AO_stack_t AO_chunk_free_list;
+
+/* Break up the chunk, and add it to the object free list for */
+/* the given size. Sz must be a power of two. */
+/* We have exclusive access to chunk. */
+static void
+add_chunk_as(void * chunk, size_t sz, unsigned log_sz)
+{
+ char *first = (char *)chunk + ALIGNMENT - sizeof(AO_t);
+ char *limit = (char *)chunk + CHUNK_SIZE - sz;
+ char *next, *p;
+
+ for (p = first; p <= limit; p = next) {
+ next = p + sz;
+ AO_stack_push(AO_free_list+log_sz, (AO_t *)p);
+ }
+}
+
+static int msbs[16] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
+
+/* Return the position of the most significant set bit in the */
+/* argument. */
+/* We follow the conventions of ffs(), i.e. the least */
+/* significant bit is number one. */
+int msb(size_t s)
+{
+ int result = 0;
+ if ((s & 0xff) != s) {
+ /* The following shift often generates warnings on 32-bit arch's */
+ /* That's OK, because it will never be executed there. */
+ if (sizeof(size_t) > 4 && (s >> 32) != 0)
+ {
+ s >>= 32;
+ result += 32;
+ }
+ if ((s >> 16) != 0)
+ {
+ s >>= 16;
+ result += 16;
+ }
+ if ((s >> 8) != 0)
+ {
+ s >>= 8;
+ result += 8;
+ }
+ }
+ if (s > 15)
+ {
+ s >>= 4;
+ result += 4;
+ }
+ result += msbs[s];
+ return result;
+}
+
+void *
+AO_malloc(size_t sz)
+{
+ AO_t *result;
+ size_t adj_sz = sz + sizeof(AO_t);
+ int log_sz;
+ if (sz > CHUNK_SIZE)
+ return AO_malloc_large(sz);
+ log_sz = msb(adj_sz-1);
+ result = AO_stack_pop(AO_free_list+log_sz);
+ while (0 == result) {
+ void * chunk = get_chunk();
+ if (0 == chunk) return 0;
+ adj_sz = 1 << log_sz;
+ add_chunk_as(chunk, adj_sz, log_sz);
+ result = AO_stack_pop(AO_free_list+log_sz);
+ }
+ *result = log_sz;
+# ifdef AO_TRACE_MALLOC
+ fprintf(stderr, "%x: AO_malloc(%lu) = %p\n",
+ (int)pthread_self(), (unsigned long)sz, result+1);
+# endif
+ return result + 1;
+}
+
+void
+AO_free(void *p)
+{
+ char *base = (char *)p - sizeof(AO_t);
+ int log_sz;
+
+ if (0 == p) return;
+ log_sz = *(AO_t *)base;
+# ifdef AO_TRACE_MALLOC
+ fprintf(stderr, "%x: AO_free(%p sz:%lu)\n", (int)pthread_self(), p,
+ (unsigned long)
+ (log_sz > LOG_MAX_SIZE? log_sz : (1 << log_sz)));
+# endif
+ if (log_sz > LOG_MAX_SIZE)
+ AO_free_large(p);
+ else
+ AO_stack_push(AO_free_list+log_sz, (AO_t *)base);
+}
diff --git a/src/atomic_ops_malloc.h b/src/atomic_ops_malloc.h
new file mode 100644
index 0000000..c55d27c
--- /dev/null
+++ b/src/atomic_ops_malloc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+/* Almost lock-free malloc implementation based on stack implementation. */
+/* See README.malloc file for detailed usage rules. */
+
+#ifndef AO_ATOMIC_H
+#define AO_ATOMIC_H
+
+#include <stdlib.h> /* For size_t */
+
+#include "atomic_ops_stack.h"
+
+#ifdef AO_STACK_IS_LOCK_FREE
+# define AO_MALLOC_IS_LOCK_FREE
+#endif
+
+void AO_free(void *);
+
+void * AO_malloc(size_t);
+
+/* Allow use of mmpa to grow the heap. No-op on some platforms. */
+void AO_malloc_enable_mmap(void);
+
+#endif /* !AO_ATOMIC_H */
diff --git a/src/atomic_ops_stack.c b/src/atomic_ops_stack.c
new file mode 100644
index 0000000..c3df101
--- /dev/null
+++ b/src/atomic_ops_stack.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+ * Original Author: Hans Boehm
+ *
+ * This file may be redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * It is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License in the
+ * file doc/COPYING for more details.
+ */
+
+#if defined(HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#define AO_REQUIRE_CAS
+#include "atomic_ops_stack.h"
+
+#if defined(_MSC_VER) \
+ || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
+ /* AO_pause not defined elsewhere */
+ /* FIXME: At least AO_spin should be factored out. */
+#include <windows.h>
+
+AO_t dummy;
+
+/* Spin for 2**n units. */
+static void AO_spin(int n)
+{
+ int i;
+ AO_T j = AO_load(&dummy);
+
+ for (i = 0; i < (2 << n); ++i)
+ {
+ j *= 5;
+ j -= 4;
+ }
+ AO_store(&dummy, j);
+}
+
+void AO_pause(int n)
+{
+ if (n < 12)
+ AO_spin(n);
+ else
+ {
+ DWORD msecs;
+
+ /* Short async-signal-safe sleep. */
+ msecs = (n > 18? 100 : (1 << (n - 12)));
+ Sleep(msecs);
+ }
+}
+
+#else
+
+/* AO_pause is available elsewhere */
+
+extern void AO_pause(int);
+
+#endif
+
+#ifdef AO_USE_ALMOST_LOCK_FREE
+
+/* LIFO linked lists based on compare-and-swap. We need to avoid */
+/* the case of a node deleton and reinsertion while I'm deleting */
+/* it, since that may cause my CAS to succeed eventhough the next */
+/* pointer is now wrong. Our solution is not fully lock-free, but it */
+/* is good enough for signal handlers, provided we have a suitably low */
+/* bound on the number of recursive signal handler reentries. */
+/* A list consists of a first pointer and a blacklist */
+/* of pointer values that are currently being removed. No list element */
+/* on the blacklist may be inserted. If we would otherwise do so, we */
+/* are allowed to insert a variant that differs only in the least */
+/* significant, ignored, bits. If the list is full, we wait. */
+
+/* Crucial observation: A particular padded pointer x (i.e. pointer */
+/* plus arbitrary low order bits) can never be newly inserted into */
+/* a list while it's in the corresponding auxiliary data structure. */
+
+/* The second argument is a pointer to the link field of the element */
+/* to be inserted. */
+/* Both list headers and link fields contain "perturbed" pointers, i.e. */
+/* pointers with extra bits "or"ed into the low order bits. */
+void
+AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
+ AO_stack_aux *a)
+{
+ int i;
+ AO_t x_bits = (AO_t)x;
+ AO_t next;
+
+ /* No deletions of x can start here, since x is not currently in the */
+ /* list. */
+ retry:
+# if AO_BL_SIZE == 2
+ {
+ /* Start all loads as close to concurrently as possible. */
+ AO_t entry1 = AO_load(a -> AO_stack_bl);
+ AO_t entry2 = AO_load(a -> AO_stack_bl + 1);
+ if (entry1 == x_bits || entry2 == x_bits)
+ {
+ /* Entry is currently being removed. Change it a little. */
+ ++x_bits;
+ if ((x_bits & AO_BIT_MASK) == 0)
+ /* Version count overflowed; */
+ /* EXTREMELY unlikely, but possible. */
+ x_bits = (AO_t)x;
+ goto retry;
+ }
+ }
+# else
+ for (i = 0; i < AO_BL_SIZE; ++i)
+ {
+ if (AO_load(a -> AO_stack_bl + i) == x_bits)
+ {
+ /* Entry is currently being removed. Change it a little. */
+ ++x_bits;
+ if ((x_bits & AO_BIT_MASK) == 0)
+ /* Version count overflowed; */
+ /* EXTREMELY unlikely, but possible. */
+ x_bits = (AO_t)x;
+ goto retry;
+ }
+ }
+# endif
+ /* x_bits is not currently being deleted */
+ do
+ {
+ next = AO_load(list);
+ *x = next;
+ }
+ while(!AO_compare_and_swap_release(list, next, x_bits));
+}
+
+/*
+ * I concluded experimentally that checking a value first before
+ * performing a compare-and-swap is usually beneficial on X86, but
+ * slows things down appreciably with contention on Itanium.
+ * ince the Itanium behavior makes more sense to me (more cache line
+ * movement unless we're mostly reading, but back-off should guard
+ * against that), we take Itanium as the default. Measurements on
+ * other multiprocessor architectures would be useful. (On a uniprocessor,
+ * the initial check is almost certainly a very small loss.) - HB
+ */
+#ifdef __i386__
+# define PRECHECK(a) (a) == 0 &&
+#else
+# define PRECHECK(a)
+#endif
+
+AO_t *
+AO_stack_pop_explicit_aux_acquire(volatile AO_t *list, AO_stack_aux * a)
+{
+ unsigned i;
+ int j = 0;
+ AO_t first;
+ AO_t * first_ptr;
+ AO_t next;
+
+ retry:
+ first = AO_load(list);
+ if (0 == first) return 0;
+ /* Insert first into aux black list. */
+ /* This may spin if more than AO_BL_SIZE removals using auxiliary */
+ /* structure a are currently in progress. */
+ for (i = 0; ; )
+ {
+ if (PRECHECK(a -> AO_stack_bl[i])
+ AO_compare_and_swap_acquire(a->AO_stack_bl+i, 0, first))
+ break;
+ ++i;
+ if ( i >= AO_BL_SIZE )
+ {
+ i = 0;
+ AO_pause(++j);
+ }
+ }
+ assert(i >= 0 && i < AO_BL_SIZE);
+ assert(a -> AO_stack_bl[i] == first);
+ /* First is on the auxiliary black list. It may be removed by */
+ /* another thread before we get to it, but a new insertion of x */
+ /* cannot be started here. */
+ /* Only we can remove it from the black list. */
+ /* We need to make sure that first is still the first entry on the */
+ /* list. Otherwise it's possible that a reinsertion of it was */
+ /* already started before we added the black list entry. */
+ if (first != AO_load(list)) {
+ AO_store_release(a->AO_stack_bl+i, 0);
+ goto retry;
+ }
+ first_ptr = AO_REAL_NEXT_PTR(first);
+ next = AO_load(first_ptr);
+ if (!AO_compare_and_swap_release(list, first, next)) {
+ AO_store_release(a->AO_stack_bl+i, 0);
+ goto retry;
+ }
+ assert(*list != first);
+ /* Since we never insert an entry on the black list, this cannot have */
+ /* succeeded unless first remained on the list while we were running. */
+ /* Thus its next link cannot have changed out from under us, and we */
+ /* removed exactly one entry and preserved the rest of the list. */
+ /* Note that it is quite possible that an additional entry was */
+ /* inserted and removed while we were running; this is OK since the */
+ /* part of the list following first must have remained unchanged, and */
+ /* first must again have been at the head of the list when the */
+ /* compare_and_swap succeeded. */
+ AO_store_release(a->AO_stack_bl+i, 0);
+ return first_ptr;
+}
+
+#else /* ! USE_ALMOST_LOCK_FREE */
+
+/* Better names for fields in AO_stack_t */
+#define ptr AO_val2
+#define version AO_val1
+
+#if defined(AO_HAVE_compare_double_and_swap_double)
+
+void AO_stack_push_release(AO_stack_t *list, AO_t *element)
+{
+ AO_t next;
+
+ do {
+ next = AO_load(&(list -> ptr));
+ *element = next;
+ } while (!AO_compare_and_swap_release
+ ( &(list -> ptr), next, (AO_t) element));
+ /* This uses a narrow CAS here, an old optimization suggested */
+ /* by Treiber. Pop is still safe, since we run into the ABA */
+ /* problem only if there were both interveining "pop"s and "push"es.*/
+ /* Inthat case we still see a change inthe version number. */
+}
+
+AO_t *AO_stack_pop_acquire(AO_stack_t *list)
+{
+ AO_t *cptr;
+ AO_t next;
+ AO_t cversion;
+
+ do {
+ /* Version must be loaded first. */
+ cversion = AO_load_acquire(&(list -> version));
+ cptr = (AO_t *)AO_load(&(list -> ptr));
+ if (cptr == 0) return 0;
+ next = *cptr;
+ } while (!AO_compare_double_and_swap_double_release
+ (list, cversion, (AO_t) cptr, cversion+1, (AO_t) next));
+ return cptr;
+}
+
+
+#elif defined(AO_HAVE_compare_and_swap_double)
+
+/* Needed for future IA64 processors. No current clients? */
+
+#error Untested! Probably doesnt work.
+
+/* We have a wide CAS, but only does an AO_t-wide comparison. */
+/* We can't use the Treiber optimization, since we only check */
+/* for an unchanged version number, not an unchanged pointer. */
+void AO_stack_push_release(AO_stack_t *list, AO_t *element)
+{
+ AO_t version;
+ AO_t next_ptr;
+
+ do {
+ /* Again version must be loaded first, for different reason. */
+ version = AO_load_acquire(&(list -> version));
+ next_ptr = AO_load(&(list -> ptr));
+ *element = next_ptr;
+ } while (!AO_compare_and_swap_double_release(
+ list, version,
+ version+1, (AO_t) element));
+}
+
+AO_t *AO_stack_pop_acquire(AO_stack_t *list)
+{
+ AO_t *cptr;
+ AO_t next;
+ AO_t cversion;
+
+ do {
+ cversion = AO_load_acquire(&(list -> version));
+ cptr = (AO_t *)AO_load(&(list -> ptr));
+ if (cptr == 0) return 0;
+ next = *cptr;
+ } while (!AO_compare_double_and_swap_double_release
+ (list, cversion, (AO_t) cptr, cversion+1, next));
+ return cptr;
+}
+
+
+#endif /* AO_HAVE_compare_and_swap_double */
+
+#endif /* ! USE_ALMOST_LOCK_FREE */
diff --git a/src/atomic_ops_stack.h b/src/atomic_ops_stack.h
new file mode 100644
index 0000000..f0c789b
--- /dev/null
+++ b/src/atomic_ops_stack.h
@@ -0,0 +1,188 @@
+/*
+ * The implementation of the routines described here is covered by the GPL.
+ * This header file is covered by the following license:
+ */
+
+/*
+ * Copyright (c) 2005 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.
+ */
+
+/* Almost lock-free LIFO linked lists (linked stacks). */
+#ifndef AO_STACK_H
+#define AO_STACK_H
+
+#include "atomic_ops.h"
+
+#if !defined(AO_HAVE_compare_double_and_swap_double) \
+ && !defined(AO_HAVE_compare_double_and_swap) \
+ && defined(AO_HAVE_compare_and_swap)
+# define AO_USE_ALMOST_LOCK_FREE
+#else
+ /* If we have no compare-and-swap operation defined, we assume */
+ /* that we will actually be using CAS emulation. If we do that, */
+ /* it's cheaper to use the version-based implementation. */
+# define AO_STACK_IS_LOCK_FREE
+#endif
+
+/*
+ * These are not guaranteed to be completely lock-free.
+ * List insertion may spin under extremely unlikely conditions.
+ * It cannot deadlock due to recursive reentry unless AO_list_remove
+ * is called while at least AO_BL_SIZE activations of
+ * AO_list_remove are currently active in the same thread, i.e.
+ * we must have at least AO_BL_SIZE recursive signal handler
+ * invocations.
+ *
+ * All operations take an AO_list_aux argument. It is safe to
+ * share a single AO_list_aux structure among all lists, but that
+ * may increase contention. Any given list must always be accessed
+ * with the same AO_list_aux structure.
+ *
+ * We make some machine-dependent assumptions:
+ * - We have a compare-and-swap operation.
+ * - At least _AO_N_BITS low order bits in pointers are
+ * zero and normally unused.
+ * - size_t and pointers have the same size.
+ *
+ * We do use a fully lock-free implementation if double-width
+ * compare-and-swap operations are available.
+ */
+
+#ifdef AO_USE_ALMOST_LOCK_FREE
+/* The number of low order pointer bits we can use for a small */
+/* version number. */
+# if defined(__LP64__) || defined(_LP64) || defined(_WIN64)
+ /* WIN64 isn't really supported yet. */
+# define AO_N_BITS 3
+# else
+# define AO_N_BITS 2
+# endif
+
+# define AO_BIT_MASK ((1 << AO_N_BITS) - 1)
+/*
+ * AO_stack_aux should be treated as opaque.
+ * It is fully defined here, so it can be allocated, and to facilitate
+ * debugging.
+ */
+#ifndef AO_BL_SIZE
+# define AO_BL_SIZE 2
+#endif
+
+#if AO_BL_SIZE > (1 << AO_N_BITS)
+# error AO_BL_SIZE too big
+#endif
+
+typedef struct AO__stack_aux {
+ volatile AO_t AO_stack_bl[AO_BL_SIZE];
+} AO_stack_aux;
+
+/* The stack implementation knows only about the lecation of */
+/* link fields in nodes, and nothing about the rest of the */
+/* stack elements. Link fields hold an AO_t, which is not */
+/* necessarily a real pointer. This converts the AO_t to a */
+/* real (AO_t *) which is either o, or points at the link */
+/* field in the next node. */
+#define AO_REAL_NEXT_PTR(x) (AO_t *)((x) & ~AO_BIT_MASK)
+
+/* The following two routines should not normally be used directly. */
+/* We make them visible here for the rare cases in which it makes sense */
+/* to share the an AO_stack_aux between stacks. */
+void
+AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
+ AO_stack_aux *);
+
+AO_t *
+AO_stack_pop_explicit_aux_acquire(volatile AO_t *list, AO_stack_aux *);
+
+/* And now AO_stack_t for the real interface: */
+
+typedef struct AO__stack {
+ volatile AO_t AO_ptr;
+ AO_stack_aux AO_aux;
+} AO_stack_t;
+
+#define AO_STACK_INITIALIZER {0}
+
+AO_INLINE void AO_stack_init(AO_stack_t *list)
+{
+# if AO_BL_SIZE == 2
+ list -> AO_aux.AO_stack_bl[0] = 0;
+ list -> AO_aux.AO_stack_bl[1] = 0;
+# else
+ int i;
+ for (i = 0; i < AO_BL_SIZE; ++i)
+ list -> AO_aux.AO_stack_bl[i] = 0;
+# endif
+ list -> AO_ptr = 0;
+}
+
+/* Convert an AO_stack_t to a pointer to the link field in */
+/* the first element. */
+#define AO_REAL_HEAD_PTR(x) AO_REAL_NEXT_PTR((x).AO_ptr)
+
+#define AO_stack_push_release(l, e) \
+ AO_stack_push_explicit_aux_release(&((l)->AO_ptr), e, &((l)->AO_aux))
+#define AO_HAVE_stack_push_release
+
+#define AO_stack_pop_acquire(l) \
+ AO_stack_pop_explicit_aux_acquire(&((l)->AO_ptr), &((l)->AO_aux))
+#define AO_HAVE_stack_pop_acquire
+
+# else /* Use fully non-blocking data structure, wide CAS */
+
+#ifndef AO_HAVE_double_t
+ /* Can happen if we're using CAS emulation, since we don't want to */
+ /* force that here, in case other atomic_ops clients don't want it. */
+# include "atomic_ops/sysdeps/standard_ao_double_t.h"
+#endif
+
+typedef volatile AO_double_t AO_stack_t;
+/* AO_val1 is version, AO_val2 is pointer. */
+
+#define AO_STACK_INITIALIZER {0}
+
+AO_INLINE void AO_stack_init(AO_stack_t *list)
+{
+ list -> AO_val1 = 0;
+ list -> AO_val2 = 0;
+}
+
+#define AO_REAL_HEAD_PTR(x) (AO_t *)((x).AO_val2)
+#define AO_REAL_NEXT_PTR(x) (AO_t *)(x)
+
+void AO_stack_push_release(AO_stack_t *list, AO_t *new_element);
+#define AO_HAVE_stack_push_release
+AO_t * AO_stack_pop_acquire(AO_stack_t *list);
+#define AO_HAVE_stack_pop_acquire
+
+#endif /* Wide CAS case */
+
+#if defined(AO_HAVE_stack_push_release) && !defined(AO_HAVE_stack_push)
+# define AO_stack_push(l, e) AO_stack_push_release(l, e)
+# define AO_HAVE_stack_push
+#endif
+
+#if defined(AO_HAVE_stack_pop_acquire) && !defined(AO_HAVE_stack_pop)
+# define AO_stack_pop(l) AO_stack_pop_acquire(l)
+# define AO_HAVE_stack_pop
+#endif
+
+#endif /* !AO_STACK_H */
diff --git a/src/atomic_ops_sysdeps.S b/src/atomic_ops_sysdeps.S
new file mode 100644
index 0000000..f586f23
--- /dev/null
+++ b/src/atomic_ops_sysdeps.S
@@ -0,0 +1,9 @@
+/*
+ * Include the appropriate system-dependent assembly file, if any.
+ * This is used only if the platform supports neither inline assembly
+ * code, nor appropriate compiler intrinsics.
+ */
+
+#if !defined(__GNUC__) && (defined(sparc) || defined(__sparc))
+# include "atomic_ops/sysdeps/sunc/sparc.S"
+#endif
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..5b61fbd
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,58 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION