This removes dependencies on Boost.Thread and Boost.Chrono, as well as
their dependencies and potentially allows to test more compilers. In particular,
this removes the dependency on Boost.Lexical cast, which no longer compiles
with gcc 4.6 and 4.7.
This works around spurious test failures on Mac OS as the notifying operation
sometimes fails with ENOENT. Presumably, the OS sometimes invalidates the
internal identification of the stack memory region, which makes __ulock_wake
fail to find the ulock object that other threads are blocked on.
By using dynamic memory we (hopefully) are using a location in a normal mapped
memory region that should not be mangled by the OS. Ideally, we would use
process-shared memory for this test, but that makes it more difficult to make
it portable and runnable in parallel. Dynamic local memory should do for now.
The previous change to increase the delay didn't help, so we're instead
changing the expectation - the first woken thread is allowed to receive
value3 on wake up.
Occasionally, IPC notify_one test fails on Windows because the first
of the woken threads receives value3 from wait(). This is possible if
the thread lingers in wait() for some reason. Increase the delay
before the second notification slightly to reduce the likelihood
of this happening.
The implementation uses GetTickCount/GetTickCount64 internally,
which is a steady and sufficiently low precision time source.
We need the clock to have relatively low precision so that wait
tests don't fail spuriously because the blocked threads wake up
too soon, according to more precise clocks.
boost::chrono::system_clock currently has an acceptably low precision,
but it is not a steady clock.
Checking for the capability macros is not good enough because ipc_atomic_ref
can be not lock-free even when the macro (and ipc_atomic) indicates lock-free.
We now check the is_always_lockfree property to decide whether to run or skip
tests for a given IPC atomic type.
Also, made struct_3_bytes output more informative.
The inter-process atomics have ipc_ prefixes: ipc_atomic, ipc_atomic_ref
and ipc_atomic_flag. These types are similar to their unprefixed counterparts
with the following distinctions:
- The operations are provided with an added precondition that is_lock_free()
returns true.
- All operations, including waiting/notifying operations, are address-free,
so the types are suitable for inter-process communication.
- The new has_native_wait_notify() operation and always_has_native_wait_notify
static constant allow to test if the target platform has native support for
address-free waiting/notifying operations. If it does not, a generic
implementation is used based on a busy wait.
- The new set of capability macros added. The macros are named
BOOST_ATOMIC_HAS_NATIVE_<T>_IPC_WAIT_NOTIFY and indicate whether address-free
waiting/notifying operations are supported natively for a given type.
Additionally, to unify interface and implementation of different components,
the has_native_wait_notify() operation and always_has_native_wait_notify
static constant were added to non-IPC atomic types as well. Added
BOOST_ATOMIC_HAS_NATIVE_<T>_WAIT_NOTIFY capability macros to indicate
native support for inter-thread waiting/notifying operations.
Also, added is_lock_free() and is_always_lock_free to atomic_flag.
This commit adds implementation, docs and tests.