Commit Graph

361 Commits

Author SHA1 Message Date
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
b990132e85 Added casts to silence MSVC warnings about lost FP precision of constants. 2018-02-18 13:57:32 +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
e081674ce9 Use FP numbers in FP tests. 2018-02-14 03:19:09 +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
2a6b6ca8a7 Removed unnecessary includes to reduce dependencies. 2018-02-13 19:36:00 +03:00
Andrey Semashev
6dad4f3d21 Removed unused memset intrinsic macro. 2018-02-13 04:45:40 +03:00
Andrey Semashev
b575159f8e Improved the wording of the note re. padding bits in FP types. 2018-02-13 04:09:24 +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
Andrey Semashev
92c57ac1e4 Added atomic operations that return the result of the operation.
These operations are useful for two reasons. First, they are needed by
atomic<> interface as the pre-increment/decrement and add/subtract operators
need to perform the corresponding arithmetics and return the actual result while
not exhibiting UB in case of overflow. This means that the operation must be
performed on the unsigned storage type in the backend. Second, the (op)_and_test
operations on ARM and PowerPC can be implemented in a more generic way on top of
the operations that return the result. And since we have those operations
internally, why not expose them to users.

Added tests and docs for the new operations. Also, added docs for the recently
added scoped names of the memory_order enum values.

Also, added a specialized "emulated" backend for the extra operations. This
backend makes better use of the fact that the operations are lock-protected
by avoiding any CAS-based loops.
2018-02-11 00:56:23 +03:00
Andrey Semashev
35497819a6 Microoptimization to reduce the number of branches in 128-bit operator==. 2018-02-10 17:19:03 +03:00
Andrey Semashev
8e7ea418ba Fixed a typo in the comment. 2018-02-04 23:50:10 +03:00
Andrey Semashev
233a2f72ba Switched integer storage type to be always an unsigned integer type.
The standard says that arithmetic operations on atomic types must always produce
a well-defined result in terms of two's complement arithmetic
([atomics.types.int]/7), which means integer owerflows are allowed and no trap
representations are allowed. This requires that all internal arithmetics be done
on unsigned integer types, even when the value type is a signed integer.

The implementation now casts between signed and unsigned integers internally,
performing zero or sign extension if the internal storage size is larger than
the stored value. This should have roughly the same performance as before,
although it mostly depends on the optimizer. The casting implementation
currently relies on that the signed integer representation is two's complement
on all supported platforms; other representations are not supported.
2018-02-04 23:42:50 +03:00
Andrey Semashev
64668130e9 Moved string op macros to a separate header. 2018-02-04 17:55:37 +03:00
Andrey Semashev
2a422ef2a9 Another attempt to work around MinGW gcc < 4.6 compilation failure.
The compiler complains:

error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'

Try to work around it by explicitly specifying all registers to use.
2018-02-04 17:40:02 +03:00
Andrey Semashev
ff1e9747e6 Save/restore ebx for PIE code, just as well as for PIC. 2018-02-04 16:29:17 +03:00
Andrey Semashev
08486a7165 Reverted the previous change that gcc up to 4.6 don't support ax:dx pairs.
That change did not fix the compilers. The issue seems to be a bug specific to
MinGW gcc compilers up to 4.6, inclusively, and the cause of the problem is
yet unknown.
2018-02-04 15:39:05 +03:00
Andrey Semashev
acec1a7668 Simplified asm constraints to avoid comma-separated alternatives.
Alternatives are not supported by all compilers, and for the purpose we're using
them we can use constraint-local alternatives (i.e. "qm" instead of "q,m").
Additionally, this reduces duplication of other constraints in the asm block.
2018-02-04 15:24:31 +03:00
Andrey Semashev
fe57fa0375 Added specialized negate_and_test and complement_and_test for MSVC 32-bit x86 target. 2018-02-04 03:11:10 +03:00
Andrey Semashev
d1ea283a6b Only include hwcaps headers for the target architecture. 2018-02-04 02:56:27 +03:00
Andrey Semashev
9fd085c59f Added negate_and_test and complement_and_test ops.
As the names suggest, the methods perform the corresponding operation and test
if the result is not zero.

Also, for the emulated fetch_complement, take care of integral promotion, which
could mess up the storage bits that were not part of the value on backends
where the storage is larger than the value. This could in turn break CAS on
the atomic value as it compares the whole storage.
2018-02-04 00:13:27 +03:00
Andrey Semashev
ceadfbcea2 Use may_alias attribute to silence gcc warnings about breaking strict aliasing.
We need to mark the uint32_t and uint64_t that are used to load parts of the
double-width values into registers.
2018-02-03 23:20:39 +03:00
Andrey Semashev
9768684841 Added specialized implementation of (op)_and_test operations on PowerPC. 2018-02-03 22:31:50 +03:00
Andrey Semashev
5a04508961 Added specialized implementation of (op)_and_test operations on ARM. 2018-02-03 22:01:13 +03:00
Andrey Semashev
701b5c863b Updated copyright. 2018-02-03 21:49:00 +03:00
Andrey Semashev
5f80667cd3 Minor optimization. 2018-02-03 21:21:19 +03:00
Andrey Semashev
90e4a3ebc0 Updated formatting. 2018-02-03 01:10:24 +03:00
Andrey Semashev
c91cb67396 Fixed incorrect code generated by clang for 32-bit x86 PIC.
The compiler, surprisingly, uses ebx for memory operands, which messed up the
save/restore logic in asm blocks, resulting the memory operand (which was
supposed to be the pointer to the atomic storage) being incorrect.

First, clang (and, apparently, recent gcc as well) are able to deal with ebx
around the asm blocks by themselves, which makes it unnecessary to save/restore
the register in the asm blocks. Therefore, for those compilers we now use the
non-PIC branch in PIC mode as well. This sidesteps the original problem with
clang.

Second, since we can't be sure if other compilers are able to pull the same
trick, the PIC branches of code have been updated to avoid any memory operand
constraints and use the explicitly calculated pointer in a register instead. We
also no longer use a scratch slot on the stack to save ebx but instead use esi
for that, which is also conveniently used for one of the inputs. This should
be slightly faster as well. The downside is that we're possibly wasting one
register for storing the pointer to the storage, but there seem to be no way
around it.
2018-02-03 00:46:07 +03:00
Andrey Semashev
13845129c4 Extended the workaround for missing support for ax:dx pairs in asm statements.
Apparently, gcc versions up to 4.6, inclusively, have problems allocating
eax:edx register pairs in asm statements for 32-bit x86 targets. Included those
compilers in the existing workaround.

Also, for clang removed the use of __sync-based workarounds for exchange()
implementation and use the asm branch with the workaround. It should produce
a more efficient code.
2018-02-02 16:19:37 +03:00
Andrey Semashev
2631ef968e Removed the code that relied on implied zero displacements in x86 asm.
Clang failed to compile such code. Given that gcc 7 also complained about
missing displacements in memory operands, this trick is no longer effective
with newer compilers.

Instead, the assembler code have been refactored to avoid having to specify
any displacements at all, offloading this work to the compiler. We hope that
the compiler will be smart enough to not overallocate registers for every
memory operand used in the inline assembler. At least, recent gcc and clang are
able to do this and generate code comparable to what was achieved previously.

Additionally, it was possible to reduce assembler code in several places by
removing mov instructions setting up input registers or handling the results.
Instead, we now rely on the compiler doing this work to satisfy assembler block
constraints.

In 32-bit load and store, improved support for targets with SSE but not SSE2.
It is possible to use SSE to do the loads/stores. Also, the scratch xmm register
is now picked by the compiler.
2018-01-30 02:55:40 +03:00
Andrey Semashev
1ec5090b33 Fixed DCAS not being lock-free on 32-bit x86 target with clang.
Clang has a bug of not advertising support for atomics implemented via
cmpxchg8b, even if the instruction is enabled in the command line. We have
to workaround the same problem with cmpxchg16b on 64-bit x86 as well, so
we apply the same approach here - we implement all atomic ops through DCAS
ourselves.

This fix adds a check for cmpxchg8b to capabilities definition.
2018-01-29 20:03:40 +03:00
Andrey Semashev
10c61bb25d Converted memory_order to scoped enum on C++11 and later.
This follows the change expected in C++2a, which has been accepted into
N4713 (proposal P0439). The old memory order constants are still
available for backward compatibility.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0439r0.html
2018-01-29 00:38:44 +03:00
Andrey Semashev
9c8bca1d01 Added a missing assert that consume is prohibited in atomic_flag::clear. 2018-01-28 23:23:08 +03:00
Andrey Semashev
04064a4427 Marked pointer (op)_and_test operations with BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST. 2018-01-28 23:15:06 +03:00
Andrey Semashev
b24cea0af1 Changed the result of (op)_and_test operations to the opposite.
This makes the result of (op)_and_test more consistent with other
methods such as test_and_set and bit_test_and_set, as well as the
methods used in the C++ standard library.

This is a breaking change. The users are able to define
BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST macro to generate warnings on each
use of the changed functions. This will help users to port from Boost
1.66 to newer Boost releases.

More info at:

https://github.com/boostorg/atomic/issues/11
http://boost.2283326.n4.nabble.com/atomic-op-and-test-naming-
tc4701445.html
2018-01-28 20:50:12 +03:00
Andrey Semashev
271337025b Disabled OS X tests because Travis CI capacity is insufficient. 2017-10-26 21:04:55 +03:00
Andrey Semashev
42bdded224 Added dev-package with i386 linux headers for 32-bit jobs. 2017-10-11 01:30:27 +03:00
Andrey Semashev
84652d8ab0 Added multilib packages to 32-bit jobs. 2017-10-10 22:53:02 +03:00
Andrey Semashev
682fd3fd4d Use older clang versions for Ubuntu Precise instead of Trusty since Travis whitelist does not contein entries for Trusty. 2017-10-10 22:37:52 +03:00
Andrey Semashev
535fe9d184 Fixing Travis CI testing script. 2017-10-10 21:14:27 +03:00
Andrey Semashev
0cddb32c85 Added CI badges to README.md. 2017-10-10 20:26:34 +03:00
Andrey Semashev
29748d98ef Disabled 32-bit MinGW-w64 jobs as there seems to be no such comiler installed in AppVeyor. 2017-09-25 15:31:58 +03:00
Andrey Semashev
bd8c040205 Another attempt to find MinGW 32-bit compiler. 2017-09-25 14:00:13 +03:00