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

261 Commits

Author SHA1 Message Date
Andrey Semashev
c849b6d877 Use 32-bit storage to implement atomic_flag.
Most platforms that support futexes or similar mechanisms support it
for 32-bit integers, which makes it more preferred to implement
atomic_flag efficiently. Most architectures also support 32-bit atomic
operations natively as well.

Also, reduced code duplication in instantiating operation backends.
2020-06-03 01:48:48 +03:00
Andrey Semashev
b9fadc852a Added Windows backend for waiting/notifying operations.
The backend uses runtime detection of availability of Windows API
for futex-like operations (only available since Windows 8).
2020-06-03 01:48:48 +03:00
Andrey Semashev
e72ccb02e4 Added support for NetBSD futex variant. 2020-06-03 01:48:48 +03:00
Andrey Semashev
214169b86e Added DragonFly BSD umtx backend for waiting/notifying operations. 2020-06-03 01:48:48 +03:00
Andrey Semashev
b5988af279 Added FreeBSD _umtx_op backend for waiting/notifying operations. 2020-06-03 01:48:48 +03:00
Andrey Semashev
bf182818f4 Added futex-based implementation for waiting/notifying operations. 2020-06-03 01:48:37 +03:00
Andrey Semashev
76e25f36a3 Added generic implementation of C++20 waiting/notifying operations.
The generic implementation is based on the lock pool. A list of condition
variables (or waiting futexes) is added per lock. Basically, the lock
pool serves as a global hash table, where each lock represents
a bucket and each wait state is an element. Every wait operation
allocates a wait state keyed on the pointer to the atomic object. Notify
operations look up the wait state by the atomic pointer and notify
the condition variable/futex. The corresponding lock needs to be acquired
to protect the wait state list during all wait/notify operations.

Backends not involving the lock pool are going to be added later.

The implementation of wait operation extends the C++20 definition in that
it returns the newly loaded value instead of void. This allows the caller
to avoid loading the value himself.

The waiting/notifying operations are not address-free. Address-free variants
will be added later.

Added tests for the new operations and refactored existing tests for atomic
operations. Added docs for the new operations.
2020-06-03 01:39:20 +03:00
Andrey Semashev
8472012d9f Cast pointers to uintptr_t.
This silences bogus MSVC-8 warnings about possible pointer truncation.
2020-05-31 23:33:33 +03:00
Andrey Semashev
7497d41fa7 Added support for yield ARMv8-A instruction.
Also, added "memory" clobber for pause instruction to prevent the compiler
to reorder memory loads and stores across pause().
2020-05-28 20:26:51 +03:00
Andrey Semashev
8e387475a5 Replaced integral_truncate with bitwise_cast in atomic_ref<integral>.
bitwise_cast is more lightweight in terms of compile times and is equivalent
to integral_truncate in case of atomic_ref as its storage type is always
of the same size as the value type.
2020-05-23 23:44:05 +03:00
Andrey Semashev
90568e8e1c Ensure that the atomic_ref storage size matches the value size.
Also, removed the unnecessary uintptr_storage_type from atomic_ref
specialization for pointers.
2020-05-23 23:32:38 +03:00
Andrey Semashev
e3dce0e226 Added missing const qualifiers in atomic_ref ops and updated tests to verify this. 2020-05-23 23:19:14 +03:00
Andrey Semashev
0b94a7d655 Fixed incorrect size of buffer_storage on C++03 compilers.
Due to BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL macro expansion, the aligner
data member was made an array, which increased the size of the resulting
buffer_storage. This caused memory corruption with atomic_ref, which
requires the storage type to be of the same size as the value.

To protect against such mistakes in the future, changed
BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL and BOOST_ATOMIC_DETAIL_ALIGNED_VAR
definitions to prohibit their direct use with arrays.
2020-05-23 23:05:43 +03:00
Andrey Semashev
75a6423a37 Fixed name clash between macro param and type_with_alignment::type member. 2020-05-22 22:46:19 +03:00
Andrey Semashev
5cfa550311 Moved aligned variable declaration workaround to a separate header. 2020-05-22 18:29:08 +03:00
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