Large diffs are not rendered by default.

@@ -0,0 +1,365 @@
Installation Instructions
*************************

Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.

Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.

Basic Installation
==================

Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.

The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').

It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.

If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.

The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.

The simplest way to compile this package is:

1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.

Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.

2. Type `make' to compile the package.

3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.

4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.

5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.

6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.

7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.

8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.

Compilers and Options
=====================

Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.

You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:

./configure CC=c99 CFLAGS=-g LIBS=-lposix

*Note Defining Variables::, for more details.

Compiling For Multiple Architectures
====================================

You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.

With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.

On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:

./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"

This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.

Installation Names
==================

By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.

You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.

In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.

The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.

The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.

The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.

Optional Features
=================

If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.

Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.

For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.

Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.

Particular systems
==================

On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:

./configure CC="cc -Ae -D_XOPEN_SOURCE=500"

and if that doesn't work, install pre-built binaries of GCC for HP-UX.

On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try

./configure CC="cc"

and if that doesn't work, try

./configure CC="cc -nodtk"

On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.

On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:

./configure --prefix=/boot/common

Specifying the System Type
==========================

There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:

CPU-COMPANY-SYSTEM

where SYSTEM can have one of these forms:

OS
KERNEL-OS

See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.

If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.

If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.

Sharing Defaults
================

If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.

Defining Variables
==================

Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:

./configure CC=/usr/local2/bin/gcc

causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).

Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:

CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash

`configure' Invocation
======================

`configure' recognizes the following options to control how it
operates.

`--help'
`-h'
Print a summary of all of the options to `configure', and exit.

`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.

`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.

`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.

`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.

`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).

`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.

`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.

`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.

`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

@@ -0,0 +1,3 @@
SUBDIRS = src doc tests

#distclean-local:

Large diffs are not rendered by default.

@@ -0,0 +1 @@

@@ -0,0 +1,56 @@
Synopsis
========

This package provides semi-portable access to hardware provided
atomic memory operations. These might allow you to write code:

- That does more interesting things in signal handlers.
- Makes more effective use of multiprocessors by allowing you to write
clever lock-free code. Note that such code is very difficult to get
right, and will unavoidably be less portable than lock-based code. It
is also not always faster than lock-based code. But it may occasionally
be a large performance win.
- To experiment with new and much better thread programming paradigms, etc.

For details and licensing restrictions see the files in the doc
subdirectory.

This is version 7.2alpha6 of libatomic_ops.

You might find a more recent version of this at

http://www.hpl.hp.com/personal/Hans_Boehm/gc

or

http://www.hpl.hp.com/research/linux/atomic_ops/


Installation and Usage
======================

The configuration and build scripts for this package were generated by
Automake/Autoconf. "./configure --prefix=<install dir>; make; make install"
in this directory should work. For a more customized build, see "INSTALL"
and the output of "./configure --help".

Note that much of the content of this library is in the header files.
However, two small libraries are built and installed:

- libatomic_ops.a is a support library, which is not needed on some platforms.
This is intended to be usable, under some mild restrictions, in free or
proprietary code, as are all the header files. See doc/LICENSING.txt.
- libatomic_ops_gpl.a contains some higher level facilities. This code is
currently covered by the GPL. The contents currently correspond to
the headers atomic_ops_stack.h and atomic_ops_malloc.h.


Platform Specific Notes
=======================

Win32/64: src/Makefile.msft contains a very simple Makefile for building
and running tests and building the gpl library. The core atomic_ops
implementation is entirely in header files.

HP-UX/PA-RISC: aCC -Ae won't work as a C compiler, since it doesn't support
inline assembly code. Use cc.

Large diffs are not rendered by default.

@@ -0,0 +1,143 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.

scriptversion=2009-10-06.20; # UTC

# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
# Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it 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.
#
# This program 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 for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.

case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac

ofile=
cfile=
eat=

for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done

if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi

# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`

# Create the lock directory.
# Note: use `[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15

# Run the compile.
"$@"
ret=$?

if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi

rmdir "$lockdir"
exit $ret

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,89 @@
# Process this file with autoconf to produce a configure script.
AC_INIT([libatomic_ops],[7.2alpha6])
AC_CANONICAL_TARGET([])
AC_CONFIG_SRCDIR(src/atomic_ops.c)
AM_INIT_AUTOMAKE
AC_PROG_RANLIB

AM_CONFIG_HEADER(src/config.h)

# Checks for programs.
AM_PROG_CC_C_O
AM_PROG_AS

# Checks for functions.
AC_FUNC_MMAP

# Checks for header files.
AC_HEADER_STDC
# AC_CHECK_HEADERS([ ])

# Determine PIC flag, adjust default CFLAGS
need_asm=false
PICFLAG=
AC_MSG_CHECKING(Determining PIC compiler flag)
if test "$GCC" = yes; then
AC_MSG_RESULT(-fPIC)
PICFLAG=-fPIC
case "$host" in
*-*-solaris*)
# Workaround: at least GCC 3.4.6 does not define this macro.
CFLAGS="$CFLAGS -D__PIC__=1"
;;
esac
else
case "$host" in
*-*-hpux*)
AC_MSG_RESULT("+Z")
PICFLAG="+Z"
CFLAGS="$CFLAGS +O2 -mt"
;;
*-*-solaris*)
AC_MSG_RESULT(-Kpic)
PICFLAG=-Kpic
CFLAGS="$CFLAGS -O"
need_asm=true
;;
*-*-linux*)
AC_MSG_RESULT(-fPIC)
PICFLAG=-fPIC
# Any Linux compiler had better be gcc compatible.
;;
*)
AC_MSG_RESULT("<none>")
;;
esac
fi
CFLAGS="$CFLAGS -DNDEBUG"
AC_SUBST(PICFLAG)
AC_SUBST(DEFS)

AH_TEMPLATE([_PTHREADS], [Indicates the use of pthreads (NetBSD).])

THREADDLLIBS=
## Libraries needed to support threads.
AC_CHECK_LIB(pthread, pthread_self, THREADDLLIBS="-lpthread",,)
AC_DEFINE(_REENTRANT, 1, [Required define if using POSIX threads.])
case "$host" in
*-*-netbsd*)
AC_DEFINE(_PTHREADS)
;;
*-*-openbsd* | *-*-kfreebsd*-gnu | *-*-dgux*)
THREADDLLIBS=-pthread
;;
*-*-cygwin* | *-*-darwin*)
THREADDLLIBS=
;;
esac
AC_SUBST(THREADDLLIBS)

AM_CONDITIONAL(NEED_ASM, test x$need_asm = xtrue)

AC_CONFIG_FILES([Makefile src/Makefile src/atomic_ops/Makefile \
src/atomic_ops/sysdeps/Makefile doc/Makefile tests/Makefile])
AC_CONFIG_COMMANDS([default],[[]],[[
PICFLAG="${PICFLAG}"
CC="${CC}"
DEFS="${DEFS}"
]])
AC_OUTPUT

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,64 @@
Our intent is to make it easy to use libatomic_ops, in
both free and proprietary software. Hence most code that we expect to be
linked into a client application is covered by an MIT-style license.

A few library routines are covered by the GNU General Public License.
These are put into a separate library, libatomic_ops_gpl.a .

The low-level part of the library is mostly covered by the following
license:

----------------------------------------

Copyright (c) ...

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.

--------------------------------

A few files in the sysdeps directory were inherited in part from the
Boehm-Demers-Weiser conservative garbage collector, and are covered by
its license, which is similar in spirit:

--------------------------------

Copyright (c) ...

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.

----------------------------------

A few files are covered by the GNU General Public License. (See file
"COPYING".) This applies only to test code, sample applications,
and the libatomic_ops_gpl portion of the library.
Thus libatomic_ops_gpl should generally not be linked into proprietary code.
(This distinction was motivated by patent considerations.)

It is possible that the license of the GPL pieces may be changed for
future versions to make them more consistent with the rest of the package.
If you submit patches, and have strong preferences about licensing, please
express them.

@@ -0,0 +1,3 @@
# installed documentation
#
dist_pkgdata_DATA=COPYING LICENSING.txt README.txt README_stack.txt README_malloc.txt README_win32.txt
@@ -0,0 +1,388 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@

VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
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 = doc
DIST_COMMON = $(dist_pkgdata_DATA) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in COPYING
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 =
CONFIG_CLEAN_VPATH_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 = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(pkgdatadir)"
DATA = $(dist_pkgdata_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
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@
GREP = @GREP@
INSTALL = @INSTALL@
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@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAG = @PICFLAG@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
THREADDLLIBS = @THREADDLLIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
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@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@

# installed documentation
#
dist_pkgdata_DATA = COPYING LICENSING.txt README.txt README_stack.txt README_malloc.txt README_win32.txt
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 ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/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
$(am__aclocal_m4_deps):
install-dist_pkgdataDATA: $(dist_pkgdata_DATA)
@$(NORMAL_INSTALL)
test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)"
@list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \
done

uninstall-dist_pkgdataDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files
tags: TAGS
TAGS:

ctags: CTAGS
CTAGS:


distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$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 $(DATA)
installdirs:
for dir in "$(DESTDIR)$(pkgdatadir)"; 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)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am: install-dist_pkgdataDATA

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

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-dist_pkgdataDATA

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-dist_pkgdataDATA install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am uninstall uninstall-am \
uninstall-dist_pkgdataDATA


# 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:
@@ -0,0 +1,241 @@
Usage:

0) If possible, do this on a multiprocessor, especially if you are planning
on modifying or enhancing the package. It will work on a uniprocessor,
but the tests are much more likely to pass in the presence of serious problems.

1) Type ./configure --prefix=<install dir>; make; make check
in the directory containing unpacked source. The usual GNU build machinery
is used, except that only static, but position-independent, libraries
are normally built. On Windows, read README_win32.txt instead.

2) Applications should include atomic_ops.h. Nearly all operations
are implemented by header files included from it. It is sometimes
necessary, and always recommended to also link against libatomic_ops.a.
To use the almost non-blocking stack or malloc implementations,
see the corresponding README files, and also link against libatomic_gpl.a
before linking against libatomic_ops.a.

OVERVIEW:
Atomic_ops.h defines a large collection of operations, each one of which is
a combination of an (optional) atomic memory operation, and a memory barrier.
Also defines associated feature-test macros to determine whether a particular
operation is available on the current target hardware (either directly or
by synthesis). This is an attempt to replace various existing files with
similar goals, since they usually do not handle differences in memory
barrier styles with sufficient generality.

If this is included after defining AO_REQUIRE_CAS, then the package
will make an attempt to emulate compare-and-swap in a way that (at least
on Linux) should still be async-signal-safe. As a result, most other
atomic operations will then be defined using the compare-and-swap
emulation. This emulation is slow, since it needs to disable signals.
And it needs to block in case of contention. If you care about performance
on a platform that can't directly provide compare-and-swap, there are
probably better alternatives. But this allows easy ports to some such
platforms (e.g. PA_RISC). The option is ignored if compare-and-swap
can be implemented directly.

If atomic_ops.h is included after defining AO_USE_PTHREAD_DEFS, then all
atomic operations will be emulated with pthread locking. This is NOT
async-signal-safe. And it is slow. It is intended primarily for debugging
of the atomic_ops package itself.

Note that the implementation reflects our understanding of real processor
behavior. This occasionally diverges from the documented behavior. (E.g.
the documented X86 behavior seems to be weak enough that it is impractical
to use. Current real implementations appear to be much better behaved.)
We of course are in no position to guarantee that future processors
(even HPs) will continue to behave this way, though we hope they will.

This is a work in progress. Corrections/additions for other platforms are
greatly appreciated. It passes rudimentary tests on X86, Itanium, and
Alpha.

OPERATIONS:

Most operations operate on values of type AO_t, which are unsigned integers
whose size matches that of pointers on the given architecture. Exceptions
are:

- AO_test_and_set operates on AO_TS_t, which is whatever size the hardware
supports with good performance. In some cases this is the length of a cache
line. In some cases it is a byte. In many cases it is equivalent to AO_t.

- A few operations are implemented on smaller or larger size integers.
Such operations are indicated by the appropriate prefix:

AO_char_... Operates on unsigned char values.
AO_short_... Operates on unsigned short values.
AO_int_... Operates on unsigned int values.

(Currently a very limited selection of these is implemented. We're
working on it.)

The defined operations are all of the form AO_[<size>_]<op><barrier>(<args>).

The <op> component specifies an atomic memory operation. It may be
one of the following, where the corresponding argument and result types
are also specified:

void nop()
No atomic operation. The barrier may still be useful.
AO_t load(const volatile AO_t * addr)
Atomic load of *addr.
void store(volatile AO_t * addr, AO_t new_val)
Atomically store new_val to *addr.
AO_t fetch_and_add(volatile AO_t *addr, AO_t incr)
Atomically add incr to *addr, and return the original value of *addr.
AO_t fetch_and_add1(volatile AO_t *addr)
Equivalent to AO_fetch_and_add(addr, 1).
AO_t fetch_and_sub1(volatile AO_t *addr)
Equivalent to AO_fetch_and_add(addr, (AO_t)(-1)).
void or(volatile AO_t *addr, AO_t incr)
Atomically or incr into *addr.
int compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
Atomically compare *addr to old_val, and replace *addr by new_val
if the first comparison succeeds. Returns nonzero if the comparison
succeeded and *addr was updated.
AO_TS_VAL_t test_and_set(volatile AO_TS_t * addr)
Atomically read the binary value at *addr, and set it. AO_TS_VAL_t
is an enumeration type which includes two values AO_TS_SET and
AO_TS_CLEAR. An AO_TS_t location is capable of holding an
AO_TS_VAL_t, but may be much larger, as dictated by hardware
constraints. Test_and_set logically sets the value to AO_TS_SET.
It may be reset to AO_TS_CLEAR with the AO_CLEAR(AO_TS_t *) macro.
AO_TS_t locations should be initialized to AO_TS_INITIALIZER.
The values of AO_TS_SET and AO_TS_CLEAR are hardware dependent.
(On PA-RISC, AO_TS_SET is zero!)

Test_and_set is a more limited version of compare_and_swap. Its only
advantage is that it is more easily implementable on some hardware. It
should thus be used if only binary test-and-set functionality is needed.

If available, we also provide compare_and_swap operations that operate
on wider values. Since standard data types for double width values
may not be available, these explicitly take pairs of arguments for the
new and/or old value. Unfortunately, there are two common variants,
neither of which can easily and efficiently emulate the other.
The first performs a comparison against the entire value being replaced,
where the second replaces a double-width replacement, but performs
a single-width comparison:

int compare_double_and_swap_double(volatile AO_double_t * addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2);

int compare_and_swap_double(volatile AO_double_t * addr,
AO_t old_val1,
AO_t new_val1, AO_t new_val2);

where AO_double_t is a structure containing AO_val1 and AO_val2 fields,
both of type AO_t. For compare_and_swap_double, we compare against
the val1 field. AO_double_t exists only if AO_HAVE_double_t
is defined.

ORDERING CONSTRAINTS:

Each operation name also includes a suffix that specifies the associated
ordering semantics. The ordering constraint limits reordering of this
operation with repsect to other atomic operations and ordinary memory
references. The current implementation assumes that all memory references
are to ordinary cacheable memory; the ordering guarantee is with respect
to other threads or processes, not I/O devices. (Whether or not this
distinction is important is platform-dependent.)

Ordering suffixes are one of the following:

<none>: No memory barrier. A plain AO_nop() really does nothing.
_release: Earlier operations must become visible to other threads
before the atomic operation.
_acquire: Later operations must become visible after this operation.
_read: Subsequent reads must become visible after reads included in
the atomic operation or preceding it. Rarely useful for clients?
_write: Earlier writes become visible before writes during or after
the atomic operation. Rarely useful for clients?
_full: Ordered with respect to both earlier and later memops.
AO_store_full or AO_nop_full are the normal ways to force a store
to be ordered with respect to a later load.
_release_write: Ordered with respect to earlier writes. This is
normally implemented as either a _write or _release
barrier.
_dd_acquire_read: Ordered with respect to later reads that are data
dependent on this one. This is needed on
a pointer read, which is later dereferenced to read a
second value, with the expectation that the second
read is ordered after the first one. On most architectures,
this is equivalent to no barrier. (This is very
hard to define precisely. It should probably be avoided.
A major problem is that optimizers tend to try to
eliminate dependencies from the generated code, since
dependencies force the hardware to execute the code
serially.)
_release_read: Ordered with respect to earlier reads. Useful for
implementing read locks. Can be implemented as _release,
but not as _read, since _read groups the current operation
with the earlier ones.

We assume that if a store is data-dependent on an a previous load, then
the two are always implicitly ordered.

It is possible to test whether AO_<op><barrier> is available on the
current platform by checking whether AO_HAVE_<op>_<barrier> is defined
as a macro.

Note that we generally don't implement operations that are either
meaningless (e.g. AO_nop_acquire, AO_nop_release) or which appear to
have no clear use (e.g. AO_load_release, AO_store_acquire, AO_load_write,
AO_store_read). On some platforms (e.g. PA-RISC) many operations
will remain undefined unless AO_REQUIRE_CAS is defined before including
the package.

When typed in the package build directory, the following command
will print operations that are unimplemented on the platform:

make test_atomic; ./test_atomic

The following command generates a file "list_atomic.i" containing the
macro expansions of all implemented operations on the platform:

make list_atomic.i

Future directions:

It currently appears that something roughly analogous to this is very likely
to become part of the C++0x standard. That effort has pointed out a number
of issues that we expect to address there. Since some of the solutions
really require compiler support, they may not be completely addressed here.

Known issues include:

We should be more precise in defining the semantics of the ordering
constraints, and if and how we can guarantee sequential consistency.

Dd_acquire_read is very hard or impossible to define in a way that cannot
be invalidated by reasonably standard compiler transformations.

There is probably no good reason to provide operations on standard
integer types, since those may have the wrong alignment constraints.


Example:

If you want to initialize an object, and then "publish" a pointer to it
in a global location p, such that other threads reading the new value of
p are guaranteed to see an initialized object, it suffices to use
AO_release_write(p, ...) to write the pointer to the object, and to
retrieve it in other threads with AO_acquire_read(p).

Platform notes:

All X86: We quietly assume 486 or better.

Microsoft compilers:
Define AO_ASSUME_WINDOWS98 to get access to hardware compare-and-swap
functionality. This relies on the InterlockedCompareExchange() function
which was apparently not supported in Windows95. (There may be a better
way to get access to this.)

Gcc on x86:
Define AO_USE_PENTIUM4_INSTRS to use the Pentium 4 mfence instruction.
Currently this is appears to be of marginal benefit.
@@ -0,0 +1,57 @@
The libatomic_ops_gpl includes a simple almost-lock-free malloc implementation.

This is intended as a safe way to allocate memory from a signal handler,
or to allocate memory in the context of a library that does not know what
thread library it will be used with. In either case locking is impossible.

Note that the operations are only guaranteed to be 1-lock-free, i.e. a
single blocked thread will not prevent progress, but multiple blocked
threads may. To safely use these operations in a signal handler,
the handler should be non-reentrant, i.e. it should not be interruptable
by another handler using these operations. Furthermore use outside
of signal handlers in a multithreaded application should be protected
by a lock, so that at most one invocation may be interrupted by a signal.
The header will define the macro "AO_MALLOC_IS_LOCK_FREE" on platforms
on which malloc is completely lock-free, and hence these restrictions
do not apply.

In the presence of threads, but absence of contention, the time performance
of this package should be as good, or slightly better than, most system
malloc implementations. Its space performance
is theoretically optimal (to within a constant factor), but probably
quite poor in practice. In particular, no attempt is made to
coalesce free small memory blocks. Something like Doug Lea's malloc is
likely to use significantly less memory for complex applications.

Performance on platforms without an efficient compare-and-swap implementation
will be poor.

This package was not designed for processor-scalability in the face of
high allocation rates. If all threads happen to allocate different-sized
objects, you might get lucky. Otherwise expect contention and false-sharing
problems. If this is an issue, something like Maged Michael's algorithm
(PLDI 2004) would be technically a far better choice. If you are concerned
only with scalability, and not signal-safety, you might also consider
using Hoard instead. We have seen a factor of 3 to 4 slowdown from the
standard glibc malloc implementation with contention, even when the
performance without contention was faster. (To make the implementation
more scalable, one would need to replicate at least the free list headers,
so that concurrent access is possible without cache conflicts.)

Unfortunately there is no portable async-signal-safe way to obtain large
chunks of memory from the OS. Based on reading of the source code,
mmap-based allocation appears safe under Linux, and probably BSD variants.
It is probably unsafe for operating systems built on Mach, such as
Apple's Darwin. Without use of mmap, the allocator is
limited to a fixed size, statically preallocated heap (2MB by default),
and will fail to allocate objects above a certain size (just under 64K
by default). Use of mmap to circumvent these limitations requires an
explicit call.

The entire interface to the AO_malloc package currently consists of:

#include <atomic_ops_malloc.h> /* includes atomic_ops.h */

void *AO_malloc(size_t sz);
void AO_free(void *p);
void AO_malloc_enable_mmap(void);
@@ -0,0 +1,78 @@
Note that the AO_stack implementation is licensed under the GPL,
unlike the lower level routines.

The header file atomic_ops_stack.h defines a linked stack abstraction.
Stacks may be accessed by multiple concurrent threads. The implementation
is 1-lock-free, i.e. it will continue to make progress if at most one
thread becomes inactive while operating on the data structure.

(The implementation can be built to be N-lock-free for any given N. But that
seems to rarely be useful, especially since larger N involve some slowdown.)

This makes it safe to access these data structures from non-reentrant
signal handlers, provided at most one non-signal-handler thread is
accessing the data structure at once. This latter condition can be
ensured by acquiring an ordinary lock around the non-handler accesses
to the data structure.

For details see:

Hans-J. Boehm, "An Almost Non-Blocking Stack", PODC 2004,
http://portal.acm.org/citation.cfm?doid=1011767.1011774, or
http://www.hpl.hp.com/techreports/2004/HPL-2004-105.html
(This is not exactly the implementation described there, since the
interface was cleaned up in the interim. But it should perform
very similarly.)

We use a fully lock-free implementation when the underlying hardware
makes that less expensive, i.e. when we have a double-wide compare-and-swap
operation available. (The fully lock-free implementation uses an AO_t-
sized version count, and assumes it does not wrap during the time any
given operation is active. This seems reasonably safe on 32-bit hardware,
and very safe on 64-bit hardware.) If a fully lock-free implementation
is used, the macro AO_STACK_IS_LOCK_FREE will be defined.

The implementation is interesting only because it allows reuse of
existing nodes. This is necessary, for example, to implement a memory
allocator.

Since we want to leave the precise stack node type up to the client,
we insist only that each stack node contains a link field of type AO_t.
When a new node is pushed on the stack, the push operation expects to be
passed the pointer to this link field, which will then be overwritten by
this link field. Similarly, the pop operation returns a pointer to the
link field of the object that previously was on the top of the stack.

The cleanest way to use these routines is probably to define the stack node
type with an initial AO_t link field, so that the conversion between the
link-field pointer and the stack element pointer is just a compile-time
cast. But other possibilities exist. (This would be cleaner in C++ with
templates.)

A stack is represented by an AO_stack_t structure. (This is normally
2 or 3 times the size of a pointer.) It may be statically initialized
by setting it to AO_STACK_INITIALIZER, or dynamically initialized to
an empty stack with AO_stack_init. There are only three operations for
accessing stacks:

void AO_stack_init(AO_stack_t *list);
void AO_stack_push_release(AO_stack_t *list, AO_t *new_element);
AO_t * AO_stack_pop_acquire(volatile AO_stack_t *list);

We require that the objects pushed as list elements remain addressable
as long as any push or pop operation are in progress. (It is OK for an object
to be "pop"ped off a stack and "deallocated" with a concurrent "pop" on
the same stack still in progress, but only if "deallocation" leaves the
object addressable. The second "pop" may still read the object, but
the value it reads will not matter.)

We require that the headers (AO_stack objects) remain allocated and
valid as long as any operations on them are still in-flight.

We also provide macros AO_REAL_HEAD_PTR that converts an AO_stack_t
to a pointer to the link field in the next element, and AO_REAL_NEXT_PTR
that converts a link field to a real, dereferencable, pointer to the link field
in the next element. This is intended only for debugging, or to traverse
the list after modification has ceased. There is otherwise no guarantee that
walking a stack using this macro will produce any kind of consistent
picture of the data structure.
@@ -0,0 +1,28 @@
Most of the atomic_ops functionality is available under Win32 with
the Microsoft tools, but the build process currently is considerably more
primitive than on Linux/Unix platforms.

To build:

1) Go to the src directory in the distribution.
2) Make sure the Microsoft command-line tools (e.g. nmake) are available.
3) Run "nmake -f Makefile.msft". This should run some tests, which
may print warnings about the types of the "Interlocked" functions.
I haven't been able to make all versions of VC++ happy. If you know
how to, please send a patch.
4) To compile applications, you will need to retain or copy the following
pieces from the resulting src directory contents:
"atomic_ops.h" - Header file defining low-level primitives. This
includes files from:
"atomic_ops"- Subdirectory containing implementation header files.
"atomic_ops_stack.h" - Header file describing almost lock-free stack.
"atomic_ops_malloc.h" - Header file describing almost lock-free malloc.
"libatomic_ops_gpl.lib" - Library containing implementation of the
above two. The atomic_ops.h implementation
is entirely in the header files in Win32.

Most clients of atomic_ops.h will need to define AO_ASSUME_WINDOWS98 before
including it. Compare_and_swap is otherwise not available.

Note that the library is covered by the GNU General Public License, while
the top 2 of these pieces allow use in proprietary code.

Large diffs are not rendered by default.

@@ -0,0 +1,376 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.

scriptversion=2009-04-28.21; # UTC

# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.

# This program is free software; you can redistribute it and/or modify
# it 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.

# This program 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 for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi

run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'

# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi

msg="missing on your system"

case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;

-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;

-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;

-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;

esac

# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`

# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;

tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;

*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac

# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;

autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;

autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;

automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;

autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."

file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;

bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;

lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;

help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."

file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;

makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;

tar*)
shift

# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi

echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;

*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac

exit 0

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
@@ -0,0 +1,162 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy

scriptversion=2009-04-28.21; # UTC

# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.

nl='
'
IFS=" "" $nl"
errstatus=0
dirmode=

usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."

# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done

for file
do
if test -d "$file"; then
shift
else
break
fi
done

case $# in
0) exit 0 ;;
esac

# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac

for file
do
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS

for d
do
test "x$d" = x && continue

pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac

if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"

mkdir "$pathcomp" || lasterr=$?

if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?

if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi

pathcomp=$pathcomp/
done
done

exit $errstatus

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
@@ -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

Large diffs are not rendered by default.

@@ -0,0 +1,45 @@
#
# Copyright (c) 2003-2005 Hewlett-Packard Development 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


@@ -0,0 +1,261 @@
/*
* 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(__native_client__) && !defined(AO_USE_NO_SIGNALS) \
&& !defined(AO_USE_NANOSLEEP)
/* Since NaCl is not recognized by configure yet, we do it here. */
# define AO_USE_NO_SIGNALS
# define AO_USE_NANOSLEEP
#endif

#if defined(AO_USE_WIN32_PTHREADS) && !defined(AO_USE_NO_SIGNALS)
# define AO_USE_NO_SIGNALS
#endif

#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__BORLANDC__) \
|| defined(AO_USE_NO_SIGNALS)

#undef AO_REQUIRE_CAS

#include <pthread.h>

#ifndef AO_USE_NO_SIGNALS
# include <signal.h>
#endif

#ifdef AO_USE_NANOSLEEP
/* This requires _POSIX_TIMERS feature. */
# include <sys/time.h>
# include <time.h>
#elif defined(AO_USE_WIN32_PTHREADS)
# include <windows.h> /* for Sleep() */
#elif defined(_HPUX_SOURCE)
# include <sys/time.h>
#else
# include <sys/select.h>
#endif

#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 grab the corresponding
* lock. Different locations may hash to the same lock, but since we
* never acquire more than one lock at a time, this can't deadlock.
* We explicitly disable signals while we perform this operation.
*
* FIXME: We should probably also support emulation based on Lamport
* locks, since we may not have test_and_set either.
*/
#define AO_HASH_SIZE 16

#define AO_HASH(x) (((unsigned long)(x) >> 12) & (AO_HASH_SIZE-1))

AO_TS_t AO_locks[AO_HASH_SIZE] = {
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER, AO_TS_INITIALIZER,
};

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
{
# ifdef AO_USE_NANOSLEEP
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = (n > 28 ? 100000 * 1000 : 1 << (n - 2));
nanosleep(&ts, 0);
# elif defined(AO_USE_WIN32_PTHREADS)
Sleep(n > 28 ? 100 : 1 << (n - 22)); /* in millis */
# else
struct timeval tv;
/* Short async-signal-safe sleep. */
tv.tv_sec = 0;
tv.tv_usec = n > 28 ? 100000 : 1 << (n - 12);
select(0, 0, 0, 0, &tv);
# endif
}
}

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);
}

#ifndef AO_USE_NO_SIGNALS
static sigset_t all_sigs;
static volatile AO_t initialized = 0;
#endif

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);
int result;

# ifndef AO_USE_NO_SIGNALS
sigset_t old_sigs;
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. */
# endif
lock(my_lock);
if (*addr == old)
{
*addr = new_val;
result = 1;
}
else
result = 0;
unlock(my_lock);
# ifndef AO_USE_NO_SIGNALS
sigprocmask(SIG_SETMASK, &old_sigs, NULL);
# endif
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);
int result;

# ifndef AO_USE_NO_SIGNALS
sigset_t old_sigs;
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. */
# endif
lock(my_lock);
if (addr -> AO_val1 == old_val1 && addr -> AO_val2 == old_val2)
{
addr -> AO_val1 = new_val1;
addr -> AO_val2 = new_val2;
result = 1;
}
else
result = 0;
unlock(my_lock);
# ifndef AO_USE_NO_SIGNALS
sigprocmask(SIG_SETMASK, &old_sigs, NULL);
# endif
return result;
}

void AO_store_full_emulation(volatile AO_t *addr, AO_t val)
{
AO_TS_t *my_lock = AO_locks + AO_HASH(addr);
lock(my_lock);
*addr = val;
unlock(my_lock);
}

#else /* Non-posix platform */

int AO_non_posix_implementation_is_entirely_in_headers;

#endif

Large diffs are not rendered by default.

@@ -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:char:g -e s:XCTYPE:char:g $? > $@
sed -e s:XSIZE:short:g -e s:XCTYPE:short:g $? >> $@
sed -e s:XSIZE:int:g -e s:XCTYPE:int:g $? >> $@

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,48 @@
#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 \
read_ordered.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 \
\
armcc/arm_v6.h \
\
gcc/alpha.h gcc/arm.h gcc/avr32.h gcc/cris.h \
gcc/hppa.h gcc/ia64.h gcc/m68k.h \
gcc/mips.h gcc/powerpc.h gcc/s390.h \
gcc/sh.h gcc/sparc.h gcc/x86.h gcc/x86_64.h \
\
hpc/hppa.h hpc/ia64.h \
\
ibmc/powerpc.h \
\
icc/ia64.h \
\
msftc/arm.h msftc/common32_defs.h msftc/x86.h \
msftc/x86_64.h \
\
sunc/sparc.h sunc/x86.h sunc/x86_64.h

sysdepdir= ${includedir}/atomic_ops/sysdeps

# A few architectures require special .S files
EXTRA_DIST = sunc/sparc.S

Large diffs are not rendered by default.

@@ -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.
@@ -0,0 +1,62 @@
/*
* 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(const 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
@@ -0,0 +1,42 @@
/*
* 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 architectures on which loads and stores of AO_t are */
/* atomic fo all legal alignments. */

AO_INLINE AO_t
AO_load(const volatile AO_t *addr)
{
assert(((size_t)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(((size_t)addr & (sizeof(AO_t) - 1)) == 0);
(*(AO_t *)addr) = new_val;
}
#define AO_HAVE_store
@@ -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"
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

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

/*
* Describes architectures on which AO_t, unsigned char, unsigned short,
* and unsigned int loads and stores are atomic 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"
@@ -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((const 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