2
0
mirror of https://github.com/boostorg/atomic.git synced 2026-02-02 20:32:09 +00:00
Commit Graph

246 Commits

Author SHA1 Message Date
Andrey Semashev
0e5e52efad Improve lock pool implementation.
Increased lock pool size to 64 entries and improve pool efficiency:

- Shift off lower pointer bits that are zero due to object alignment.
- Mix higher pointer bits to account for alignment typically imposed by
  malloc/new implementations.
- Use bit masking to select a lock from pool, given that the pool size
  is a power of 2 now.

Also, extracted (u)intptr_t definition to a common header to avoid code
duplication.
2020-03-09 20:01:49 +03:00
Andrey Semashev
c4e60c3a65 Added static asserts verifying that the user's type is acceptable for atomics.
Require that user's type is complete and trivially copyable.
2020-03-04 00:11:39 +03:00
Andrey Semashev
f32165562d Apply missing max_align_t workaround to gcc 4.8 as well. 2020-03-01 22:15:16 +03:00
Andrey Semashev
f91557eeef Added a workaround for missing max_align_t in gcc 4.7. 2020-03-01 20:29:54 +03:00
Andrey Semashev
5e88a03da1 Fixed compilation due to missing type_with_alignment definition. 2020-03-01 20:20:55 +03:00
Andrey Semashev
28c79c0147 Updated copyright years. 2020-03-01 19:23:32 +03:00
Andrey Semashev
6d82535d88 Renamed integral_extend.hpp to integral_conversions.hpp. 2020-03-01 19:21:56 +03:00
Andrey Semashev
e65d952cdf Use static_casts to convert value_type to storage_type for integral atomics.
This simplifies the code slightly without changing semantics. static_cast was
already used in atomic constructor in order to make it constexpr, and this
commit makes the rest of the code consistent.
2020-03-01 19:14:38 +03:00
Andrey Semashev
e96f56aed1 Added a workaround for MSVC 14.0 alignas issues in 32-bit mode.
The compiler allows to apply alignas but later fails to pass arguments
of the aligned types to functions with error C2719. At the same time,
std::max_align_t has alignment of 8 and the error doesn't show up when
the type is aligned using the union trick. Thus we disable alignas
for MSVC 14.0 in 32-bit mode.

Also, use std::max_align_t on MSVC, when possible.
2020-03-01 18:41:14 +03:00
Andrey Semashev
c22fc7d416 Added a workaround for gcc 4.7 not supporting constexpr ctors with unions.
gcc 4.7 does not support constexpr constructors that initialize one member
of an anonymous union data member of the class. atomic and atomic_flag
no longer have constexpr constructors on this compiler.
2020-03-01 18:05:01 +03:00
Andrey Semashev
91b7d325e0 Added a workaround for older gcc and clang with broken std::alignment_of.
gcc older than 8.1 and clang older than 8.0 produce incorrect results of
std::alignment_of for 64-bit types on 32-bit x86. Use boost::alignment_of,
which contains workarounds for these compilers.
2020-03-01 16:53:36 +03:00
Andrey Semashev
ce80ca0ce8 Added a workaround for gcc 4.8 not supporting alignas with a constant expression
gcc 4.8 requires that the argument of alignas is a literal constant and does not
accept a constant expression.

This workaround is temporary, until Boost.Config updates BOOST_NO_CXX11_ALIGNAS:

https://github.com/boostorg/config/pull/324
2020-03-01 13:43:10 +03:00
Andrey Semashev
f450738d7b Use max_align_t to determine alignment of the 16-byte storage_type.
This should fix MSVC errors, which complains that function arguments cannot
be aligned to 16 bytes.
2020-03-01 03:59:53 +03:00
Andrey Semashev
be98ffef76 Removed unnecessary typename to fix MSVC build. 2020-03-01 03:19:22 +03:00
Andrey Semashev
34a2bc134c Fixed compilation on 32-bit x86, reduced code duplication.
On 32-bit x86, 64-bit integers have 4-byte alignment, which resulted in
a non-integral type being selected for storage type in case of lock-based
atomic_ref. This broke arithmetic and bitwise operations on atomic_ref.

We now select an integral type based on its native alignment, not the storage
alignment we require for atomic operations. This is fine in case of lock-based
backend.

Also, extended buffer_storage with support for specifying alignment and removed
aligned_buffer_storage and storage128_t.
2020-03-01 03:11:33 +03:00
Andrey Semashev
a1a31e14e2 Reduce alignment requirements of lock-based backend of atomic_ref.
Lock-based operations have no reason to require object alignment higher
than alignof(T). This commit implements a special storage type for
lock-based operations, which has the same alignment as value_type.

Also, added tests to verify required_alignment correctness both
in lock-free and lock-based cases.
2020-03-01 00:22:35 +03:00
Andrey Semashev
0d8dd8eb6c Use std::alignment_of, when possible. 2020-02-29 23:52:19 +03:00
Andrey Semashev
8ed0729abb Renamed make_storage_type to storage_traits. 2020-02-29 23:52:19 +03:00
Andrey Semashev
59ee7c9e9e Removed support for BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST.
The macro was used to highlight the (op)_and_test methods of atomic<>
that changed the returned value to the opposite in Boost 1.67. The old
behavior was only released in 1.66 and the macro was a means to help
1.66 users to transition to the new releases.

1.67 will have been released 2 years before the upcoming 1.73 release,
in which this macro will be removed.
2020-02-29 23:52:19 +03:00
Andrey Semashev
c22d7f5bda Added value() accessor to atomic template, deprecated storage().
This commit changes how storage alignment is enforced and ensures
that the storage is sufficiently aligned for both atomic operations
and direct access to the stored value. This allowed to implement
the new value() accessor, which returns a reference to the stored
value. This is unlike the previously available storage() accessor,
which returns a reference to storage_type and requires users to cast
the reference to value_type, which is potentially unsafe.

The public storage() accessor is now deprecated in favor of value()
and storage_type - in favor of value_type. The deprecation warnings
can be disabled by defining BOOST_ATOMIC_SILENCE_STORAGE_DEPRECATION.
2020-02-29 23:51:39 +03:00
Andrey Semashev
7822509ce9 Use storage alignment specified by operations in generic atomic_ref.
When emulated operations backend is used, the storage type still has
high alignment requirement, possibly higher than that of the user's type.
This means that code generated for operations may be incorrect for the
underaligned user's objects, which can cause alignment violation crashes.
This was causing Cygwin and MinGW test failures.

For now, use the alignment requirement from the operations, even in
the lock-based mode. This increases alignment requirement unnecessarily,
because lock-based implementation could work with reduced alignment
storage. A better fix requires a different approach to storage type
generation. It will be done in a later commit.
2020-02-28 01:19:28 +03:00
Andrey Semashev
7966b114de Fixed possible unaligned access to expected value in compare_exchange.
Casting reference to value_type to reference to storage_type is not legal
if storage_type has a higher alignment requirements than value_type.
2020-02-27 00:10:27 +03:00
Andrey Semashev
2087c837ae Removed mismatched #pragma warning(pop).
Closes https://github.com/boostorg/atomic/issues/29.
2020-02-26 15:33:14 +03:00
Andrey Semashev
4336ac66bd Added support for C++20 atomic_flag::test operation.
The operation allows to test whether the flag is in the set state.
Also added tests and docs.
2020-02-26 01:24:54 +03:00
Andrey Semashev
87ee6b1c48 Rearranged includes of operations headers.
Atomic and atomic_ref implementation requires operations algorithms
to be fully defined, therefore include the full headers in the *_template
headers.
2020-02-26 01:10:32 +03:00
Andrey Semashev
1ea83f3ccc Removed includes of atomic_flag and fences from atomic/atomic.hpp.
Users are advised to either include the necessary headers explicitly
or include boost/atomic.hpp, which includes all library headers.
2020-02-26 01:02:37 +03:00
Andrey Semashev
502208b6c5 Removed checks for padding bits in generic atomic_ref specialization.
We currently don't support structs with padding bits, so the checks
are useless. Also, updated docs so that users are not given the idea
that structs with padding bits are supported.
2020-02-26 00:42:15 +03:00
Andrey Semashev
2ed311af18 Fixed wrong x86 code generated for bit_test_and_op for 8 and 16-bit atomics.
The implementation used to generate 32-bit bts/btr/btc for 8 and 16-bit
atomics, which could result in alignment and access violation and possibly
data corruption. 32 and 64-bit atomics are unaffected.

This commit fixes operaend width for 16-bit atomics. For 8-bit atomics the
generic implementation is used based on or/and/xor instructions since there
are no 8-bit bts/btr/btc.
2020-02-25 23:59:02 +03:00
Andrey Semashev
8b70628d91 Added compilation fixes for MSVC. 2020-02-25 17:09:22 +03:00
Andrey Semashev
b95c39d5e1 Removed clearing padding for class types on atomic_ref construction.
We currently don't support clearing internal padding in structures,
and we cannot detect tail padding in structures either. So for now there
is no point in the CAS loop during atomic_ref construction.
2020-02-25 02:24:49 +03:00
Andrey Semashev
904871c37d Implemented atomic_ref.
This commit adds C++20 atomic_ref implementation, documentation and tests.
2020-02-25 02:00:05 +03:00
Andrey Semashev
a2209fc2aa Ported to BOOST_INLINE_VARIABLE. 2019-10-29 21:26:12 +03:00
Andrey Semashev
d491c662a1 Removed redundant semicolon. 2019-10-14 00:00:13 +03:00
Andrey Semashev
282b4c2ca6 Added cmpxchg16b detection for clang-win. 2019-10-13 10:57:52 +03:00
Andrey Semashev
56bd60673a Added a workaround for __float128 not being considered a FP type by libstdc++-7. 2019-10-13 01:19:57 +03:00
Andrey Semashev
00455afcd1 Added compiler barrier macro for clang-win.
This should silence compiler warnings about _ReadWriteBarrier being
deprecated.
2019-10-12 16:51:28 +03:00
Andrey Semashev
19eecf893c Removed unused argument to silence compiler warnings.
Fixes https://github.com/boostorg/atomic/issues/16.
2018-07-30 12:10:48 +03:00
Andrey Semashev
6e14ca24da Removed clang-specific branch for x86 DCAS-based loads.
The storage to load from is const-qualified and DCAS via compiler intrinsics
require an unqualified pointer. Use asm implementation instead, which should be
as efficient as intrinsics, if not better, in this case.

Fixes https://github.com/boostorg/atomic/issues/15.
2018-07-17 12:37:29 +03:00
Andrey Semashev
406228d493 Made initializing constructor of atomic<> implicit.
This is an attempt to make boost::atomic<> interface closer to the standard. It
makes a difference in C++17 as it mandates copy elision, which makes this code
possible:

  boost::atomic<int> a = 10;

It also makes is_convertible<T, boost::atomic<T>> return true, which has
implications on the standard library components, such as std::pair.

This removes the workaround for gcc 4.7, which complains that
operator=(value_arg_type) is considered ambiguous with operator=(atomic const&)
in assignment expressions, even though conversion to atomic<> is less preferred
than conversion to value_arg_type. We try to work around the problem from the
operator= side.

Added a new compile test to check that the initializing constructor is implicit.
2018-02-20 01:39:52 +03:00
Andrey Semashev
9fd86de20b Silenced gcc warnings about unused parameter. 2018-02-18 14:00:16 +03:00
Andrey Semashev
7ce05c8ff0 Extended the workaround for noexcept in defaulted constructors to clang 3.1. 2018-02-15 15:46:31 +03:00
Andrey Semashev
35c87f5f6e Extended the workaround for noexcept in defaulted constructors to gcc 4.6. 2018-02-14 16:50:57 +03:00
Andrey Semashev
095812d84f Make the default constructor trivial if the user's type default constructor is.
This requires the is_trivially_default_constructible type trait, which is not
available in the older libstdc++ versions up to gcc 5.1. Thus the config macro
is updated to reflect the fact that Boost.Atomic now has more advanced needs.

Also, attempt to work around Intel compiler problem, which seems to break
(allegedly) because of the noexcept specifiers in the defaulted default
constructors. This may not be the cause, so this change will need to be tested.

Also, use value_arg_type consistently across different specializations of
basic_atomic.
2018-02-14 15:26:57 +03:00
Andrey Semashev
e7347a7d87 Use __builtin_addressof intrinsic where possible. 2018-02-14 03:34:56 +03:00
Andrey Semashev
92248dd5b8 Unified implementation of bitwise_fp_cast and bitwise_cast.
Also use memset to clear the tail padding of the storage as gcc generates
slightly better code for that.
2018-02-14 02:36:11 +03:00
Andrey Semashev
72309f41f9 Fixed CAS test failures for 80-bit long double.
The CAS implementation did not zero-fill the padding bits for the `expected`
argument, which caused CAS to fail sometimes.
2018-02-13 23:58:44 +03:00
Andrey Semashev
6dad4f3d21 Removed unused memset intrinsic macro. 2018-02-13 04:45:40 +03:00
Andrey Semashev
edef50f042 Added support for atomic floating point operations.
The support includes:

- The standard fetch_add/fetch_sub operations.
- Extra operations: (fetch_/opaque_)negate, (opaque_)add/sub.
- Extra capability macros: BOOST_ATOMIC_FLOAT/DOUBLE/LONG_DOUBLE_LOCK_FREE.

The atomic operations are currently implemented on top of the integer-based
backends and thus are mostly CAS-based. The CAS operations perform binary
comparisons, and as such have different behavior wrt. special FP values like
NaN and signed zero than normal C++.

The support for floating point types is optional and can be disabled by
defining BOOST_ATOMIC_NO_FLOATING_POINT. This can be useful if on a certain
platform parameters of the floating point types cannot be deduced from the
compiler-defined or system macros (in which case the compilation fails).

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0020r6.html
2018-02-13 03:36:35 +03:00
Andrey Semashev
e751e235bc Silenced "unused parameter" warnings. 2018-02-12 17:53:57 +03:00
Andrey Semashev
8d7556f913 Added a specialized implementation of generic extra ops for CAS-based platforms.
This specialized implementation is able to save the result of the operations as
it is calculated in the CAS loop.
2018-02-11 01:57:16 +03:00