Moved all the threading code to one place. Added explicit support for
Darwin, Linux, Pthreads, C11 threads and Win32 threads, including new
implementations of Once for Linux, Pthreads, C11 and Win32.
rdar://90776105
Moved all the threading code to one place. Added explicit support for
Darwin, Linux, Pthreads, C11 threads and Win32 threads, including new
implementations of Once for Linux, Pthreads, C11 and Win32.
rdar://90776105
Not all targets have a 16-byte type alignment guarantee. For the types
which are not naturally aligned, provide a type specific `operator new`
overload to ensure that we are properly aligning the type on allocation
as we run the risk of under-aligned allocations otherwise.
This should no longer be needed with C++17 and newer which do a two
phase `operator new` lookup preferring
`operator new(std::size, std::align_val_t)` if needed. The base type
would be fully pre-processed away. The empty base class optimization
should help ensure that we do not pay any extra size costs for the
alignment fixes.
As we are a C++14 codebase, we must locally implement some of the
standard type_traits utilities, namely `void_t`. We take the minimal
definition here, assuming that the compiler is up-to-date with C++14 DR
reports which fixed an issue in SFINAE. We use the SFINAE for detecting
the presence of the `operator new` overload to guide the over-alignment,
which is inherited through the new `swift::overaligned_type<>` base
type.
Annotate the known classes which request explicit alignment which is
non-pointer alignment. This list was identified by
`git grep ' alignas(.*) '`.
`operator new` up until C++17 was alignment unaware. We use C++ types
decorated with `alignas` to enforce 16-byte alignment. This is fine on
the current platforms that we support as they are all enforcing 16-byte
alignment on allocations. However, this is not a guarantee that C++
makes. It only provides the guarantee that `operator new` will align
the memory to `__STDCPP_DEFAULT_NEW_ALIGNMENT__`. On 32-bit platforms
such as Windows i686, this value is actually 8. However, due to the
class(es) being attributed as `alignas(16)`, the default constructor
which is emitted by the compiler assumes the proper alignment will be
provided for externally and will zero the memory using the following
sequence:
~~~
xorps xmm0, xmm0
movaps xmm0, [eax]
movaps xmm0, [eax+16]
~~~
This assumes that the returned pointer is suitably aligned for XMM
operations - 16-bytes - as the attribution indicates as such. This
misalignment would cause a bus error on Linux, and more confusingly
triggers an invalid access (the equivalent of a segmentation fault)
on Windows.
Add a static assertion to identify this unintended misalignment on
allocation. This check will be meaningless post C++17 as that will use
a two-phase overload resolution for `operator new`, preferring the newly
introduced `operator new(std::size_t, std::align_val_t)` which would
suitably align the type and as such is guarded by the feature macro
`__cpp_aligned_new`.
Add a tryReloadAndWait method to Worker (which can only be used
when not the worker thread). Revise the docs to describe this
sort of pattern as the more standard pattern, which I think is
likely to better reflect common use.
The existing uses of AWQ don't need arguments during construction,
but uses that do almost certainly need to update existing instances
if createQueue happens to re-use one. Users probably aren't going
to think about this proactively by doing something wild like reading
the documentation. We can point this mistake out to them by making
their code not compile if they call createQueue with arguments
without providing a special method. This pattern also makes the
actual update code much easier to write, since callers don't need
to specially detect this case.