diff options
author | Petter Urkedal <paurkedal@gmail.com> | 2011-08-18 11:03:25 +0400 |
---|---|---|
committer | Petter Urkedal <paurkedal@gmail.com> | 2011-08-18 11:07:44 +0400 |
commit | 26e4e93e7e43a7d013749615fb53f7839c7361e6 (patch) | |
tree | d61042bb79287bf574a0ee449aaaa8cd15d5f202 | |
parent | 9d9e6356307089167c2cbce23a134592ffb63b4e (diff) |
WiP on stdatomic.h.add-stdatomic-h
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | pkgconfig/atomic_ops_as_stdatomic-uninstalled.pc.in | 10 | ||||
-rw-r--r-- | pkgconfig/atomic_ops_as_stdatomic.pc.in | 10 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/atomic_ops/as_stdatomic/stdatomic.h | 161 |
6 files changed, 187 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index a52cd7f..c14e70a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS = src doc tests ACLOCAL_AMFLAGS = -I m4 pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = pkgconfig/atomic_ops.pc +pkgconfig_DATA = pkgconfig/atomic_ops.pc pkgconfig/atomic_ops_as_stdatomic.pc noinst_DATA = pkgconfig/atomic_ops-uninstalled.pc dist_pkgdata_DATA = COPYING diff --git a/configure.ac b/configure.ac index 2a16a41..b0abd12 100644 --- a/configure.ac +++ b/configure.ac @@ -87,7 +87,9 @@ AC_CONFIG_FILES([ src/Makefile tests/Makefile pkgconfig/atomic_ops.pc - pkgconfig/atomic_ops-uninstalled.pc ]) + pkgconfig/atomic_ops-uninstalled.pc + pkgconfig/atomic_ops_as_stdatomic.pc + pkgconfig/atomic_ops_as_stdatomic-uninstalled.pc ]) AC_CONFIG_COMMANDS([default],[[]],[[ PICFLAG="${PICFLAG}" diff --git a/pkgconfig/atomic_ops_as_stdatomic-uninstalled.pc.in b/pkgconfig/atomic_ops_as_stdatomic-uninstalled.pc.in new file mode 100644 index 0000000..dd63801 --- /dev/null +++ b/pkgconfig/atomic_ops_as_stdatomic-uninstalled.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +top_builddir=@abs_top_builddir@ +top_srcdir=@abs_top_srcdir@ + +Name: The atomic_ops library (uninstalled) +Description: Atomic memory update operations +Version: @PACKAGE_VERSION@ +Libs: ${top_builddir}/src/libatomic_ops.la +Cflags: -I${top_builddir}/src -I${top_srcdir}/src -I${top_srcdir}/src/atomic_ops/as_stdatomic diff --git a/pkgconfig/atomic_ops_as_stdatomic.pc.in b/pkgconfig/atomic_ops_as_stdatomic.pc.in new file mode 100644 index 0000000..8ffccc3 --- /dev/null +++ b/pkgconfig/atomic_ops_as_stdatomic.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: The atomic_ops library, stdatomic.h +Description: Partial implementation of stdatomic.h based on libatomic_ops +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -latomic_ops +Cflags: -I${includedir} -I${includedir}/atomic_ops/as_stdatomic diff --git a/src/Makefile.am b/src/Makefile.am index b439521..e423aa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,8 @@ libatomic_ops_gpl_la_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c EXTRA_DIST=Makefile.msft atomic_ops/sysdeps/README \ atomic_ops/generalize-small.template atomic_ops/sysdeps/sunc/sparc.S +nobase_include_HEADERS = atomic_ops/as_stdatomic/stdatomic.h + #Private Headers privatedir=${includedir}/ nobase_private_HEADERS=atomic_ops/generalize.h atomic_ops/generalize-small.h \ diff --git a/src/atomic_ops/as_stdatomic/stdatomic.h b/src/atomic_ops/as_stdatomic/stdatomic.h new file mode 100644 index 0000000..a63a665 --- /dev/null +++ b/src/atomic_ops/as_stdatomic/stdatomic.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2011 Hewlett-Packard Development Company, L.P. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <atomic_ops.h> +#include <limits.h> + +#ifndef AO_BIT +# define AO_BIT LONG_BIT /* CHECKME */ +#endif + +/* TODO */ +/* #define ATOMIC_INTEGRAL_LOCK_FREE 1 */ +/* #define ATOMIC_ADDRESS_LOCK_FREE 1 */ + + +/* Memory Order and Fences + * ======================= */ + +typedef enum { + memory_order_relaxed, + memory_order_acquire, + memory_order_release, + memory_order_acq_rel, + memory_order_seq_cst +} memory_order; + +#define atomic_thread_fence(order) \ + do { switch (order) { \ + case memory_order_relaxed: break; \ + case memory_order_acquire: AO_nop_acquire(); break; \ + case memory_order_release: AO_nop_release(); break; \ + case memory_order_acq_rel: \ + case memory_order_seq_cst: AO_nop_full(); break; \ + } } while (0) + +#define atomic_signal_fence atomic_thread_fence + + +/* Atomic Integers, Bool, and Address + * ================================== + * + * CHECKME: Is it appropriate to use AO_t if it is smaller than some of the + * corresponding non-atomic types? */ + +typedef struct { AO_t __ao_val; } atomic_bool; +typedef struct { AO_t __ao_val; } atomic_address; + +typedef struct { AO_t __ao_val; } atomic_char; +typedef struct { AO_t __ao_val; } atomic_schar; +typedef struct { AO_t __ao_val; } atomic_uchar; +typedef struct { AO_t __ao_val; } atomic_short; +typedef struct { AO_t __ao_val; } atomic_ushort; +typedef struct { AO_t __ao_val; } atomic_int; +typedef struct { AO_t __ao_val; } atomic_uint; +typedef struct { AO_t __ao_val; } atomic_long; +typedef struct { AO_t __ao_val; } atomic_ulong; +#if defined LLONG_BIT && AO_BIT >= LLONG_BIT +typedef struct { AO_t __ao_val; } atomic_llong; +typedef struct { AO_t __ao_val; } atomic_ullong; +#endif + +typedef struct { AO_t __ao_val; } atomic_char16_t; +typedef struct { AO_t __ao_val; } atomic_char32_t; +typedef struct { AO_t __ao_val; } atomic_wchar_t; +typedef struct { AO_t __ao_val; } atomic_int_least8_t; +typedef struct { AO_t __ao_val; } atomic_uint_least8_t; +typedef struct { AO_t __ao_val; } atomic_int_fast8_t; +typedef struct { AO_t __ao_val; } atomic_uint_fast8_t; +typedef struct { AO_t __ao_val; } atomic_int_least16_t; +typedef struct { AO_t __ao_val; } atomic_uint_least16_t; +typedef struct { AO_t __ao_val; } atomic_int_fast16_t; +typedef struct { AO_t __ao_val; } atomic_uint_fast16_t; +typedef struct { AO_t __ao_val; } atomic_int_least32_t; +typedef struct { AO_t __ao_val; } atomic_uint_least32_t; +typedef struct { AO_t __ao_val; } atomic_int_fast32_t; +typedef struct { AO_t __ao_val; } atomic_uint_fast32_t; +#if AO_BIT >= 64 +typedef struct { AO_t __ao_val; } atomic_int_least64_t; +typedef struct { AO_t __ao_val; } atomic_uint_least64_t; +typedef struct { AO_t __ao_val; } atomic_int_fast64_t; +typedef struct { AO_t __ao_val; } atomic_uint_fast64_t; +#endif +typedef struct { AO_t __ao_val; } atomic_intptr_t; +typedef struct { AO_t __ao_val; } atomic_uintptr_t; +typedef struct { AO_t __ao_val; } atomic_size_t; +typedef struct { AO_t __ao_val; } atomic_ptrdiff_t; +#if 0 /* FIXME */ +typedef struct { AO_t __ao_val; } atomic_ssize_t; +typedef struct { AO_t __ao_val; } atomic_intmax_t; +typedef struct { AO_t __ao_val; } atomic_uintmax_t; +#endif + +#define _AO_of(a) (&(a)->__ao_val) + +#if defined(ATOMIC_INTEGRAL_IS_LOCK_FREE) && \ + defined(ATOMIC_ADDRESS_IS_LOCK_FREE) +# define atomic_is_lock_free(a) 1 +#else +# define atomic_is_lock_free(a) 0 +#endif + +#define atomic_store(a, x) AO_store_full(_AO_of(a), (AO_t)(x)) + +#define atomic_store_explicit(a, x, order) \ + do { switch (order) { \ + case memory_order_relaxed: AO_store(_AO_of(a), (AO_t)(x)); break; \ + case memory_order_acquire: AO_store_acquire(_AO_of(a), (AO_t)(x)); break; \ + case memory_order_release: AO_store_release(_AO_of(a), (AO_t)(x)); break; \ + case memory_order_acq_rel: \ + case memory_order_seq_cst: AO_store_full(_AO_of(a), (AO_t)(x)); break; \ + } } while (0) + +/* FIXME: The return type of the atomic load macros is unsuitable for + * atomic_address. */ + +#define atomic_load(a) AO_load_full(_AO_of(a)) + +#define atomic_load_explicit(a, order) \ + (((order) == memory_order_relaxed)? AO_load(_AO_of(a)) : \ + ((order) == memory_order_acquire)? AO_load_acquire(_AO_of(a)) : \ + ((order) == memory_order_release)? AO_load_release(_AO_of(a)) : \ + AO_load_full(_AO_of(a))) + +/* TODO: atomic_exchange, atomic_compare_exchange_<strength>, + * atomic_fetch_<op> */ + + +/* Atomic Flag + * =========== */ + +typedef struct { AO_TS_t __ao_flag; } atomic_flag; + +#define _AO_TS_of(af) (&(af)->__ao_flag) + +#define ATOMIC_FLAG_INIT {AO_TS_INITIALIZER} + +#define atomic_flag_test_and_set(af) AO_test_and_set(_AO_TS_of(af)) + +/* CHECKME: AO_CLEAR has release-semantic whereas N1349 seems to permit + * memory_order_seq_cst. */ +#define atomic_flag_clear(af) AO_CLEAR(_AO_TS_of(af)) +#define atomic_flag_clear_explicit(af, order) AO_CLEAR(_AO_TS_of(af)) |