| .. _module-pw_alignment: |
| |
| ============ |
| pw_alignment |
| ============ |
| .. pigweed-module:: |
| :name: pw_alignment |
| |
| - **Transparent**: Enforce natural alignment without any changes to how your |
| objects are used. |
| - **Efficient**: Prevent your compiler from emitting libcalls to builtin |
| atomic functions and ensure it uses native atomic instructions instead. |
| |
| .. code-block:: c++ |
| |
| #include "pw_alignment/alignment.h" |
| |
| // Passing a `std::optional<bool>` to `__atomic_exchange` might not replace |
| // the call with native instructions if the compiler cannot determine all |
| // instances of this object will happen to be aligned. |
| std::atomic<std::optional<bool>> maybe_nat_aligned_obj; |
| |
| // `pw::NaturallyAligned<...>` forces the object to be aligned to its size, |
| // so passing it to `__atomic_exchange` will result in a replacement with |
| // native instructions. |
| std::atomic<pw::NaturallyAligned<std::optional<bool>>> nat_aligned_obj; |
| |
| // Shorter spelling for the same as above. |
| pw::AlignedAtomic<std::optional<bool>> also_nat_aligned_obj; |
| |
| ``pw_alignment`` portably ensures that your compiler uses native atomic |
| instructions rather than libcalls to builtin atomic functions. Take for example |
| ``std::atomic<std::optional<bool>>``. Accessing the underlying object normally |
| involves a call to a builtin ``__atomic_*`` function. The problem is that the |
| compiler sometimes can't determine that the size of the object is the same |
| as the size of its alignment. ``pw_alignment`` ensures that an object aligns to |
| its size so that compilers can always make this optimization. |
| |
| .. warning:: |
| Using ``std::optional<bool>`` is only a workaround that may not work with all |
| compilers. This specifically does not work when targetting ARM cortex M0. |
| Additionally, ``std::optional<bool>`` is not the recommended way to represent |
| a ternary variable. |
| |
| .. grid:: 2 |
| |
| .. grid-item-card:: :octicon:`rocket` Get Started |
| :link: module-pw_alignment-getstarted |
| :link-type: ref |
| :class-item: sales-pitch-cta-primary |
| |
| How to set up ``pw_alignment`` in your build system. |
| |
| .. grid-item-card:: :octicon:`code-square` API Reference |
| :link: module-pw_alignment-reference |
| :link-type: ref |
| :class-item: sales-pitch-cta-secondary |
| |
| Reference information about the ``pw_alignment`` API. |
| |
| .. _module-pw_alignment-getstarted: |
| |
| ----------- |
| Get started |
| ----------- |
| .. repository: https://bazel.build/concepts/build-ref#repositories |
| |
| .. tab-set:: |
| |
| .. tab-item:: Bazel |
| |
| Add ``@pigweed//pw_alignment`` to the ``deps`` list in your Bazel target: |
| |
| .. code-block:: |
| |
| cc_library("...") { |
| # ... |
| deps = [ |
| # ... |
| "@pigweed//pw_alignment", |
| # ... |
| ] |
| } |
| |
| This assumes that your Bazel ``WORKSPACE`` has a `repository |
| <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed`` |
| that points to the upstream Pigweed repository. |
| |
| .. tab-item:: GN |
| |
| Add ``$dir_pw_alignment`` to the ``deps`` list in your ``pw_executable()`` |
| build target: |
| |
| .. code-block:: |
| |
| pw_executable("...") { |
| # ... |
| deps = [ |
| # ... |
| "$dir_pw_alignment", |
| # ... |
| ] |
| } |
| |
| .. tab-item:: CMake |
| |
| Add ``pw_alignment`` to your ``pw_add_library`` or similar CMake target: |
| |
| .. code-block:: |
| |
| pw_add_library(my_library STATIC |
| HEADERS |
| ... |
| PRIVATE_DEPS |
| # ... |
| pw_alignment |
| # ... |
| ) |
| |
| .. _module-pw_alignment-reference: |
| |
| ------------- |
| API reference |
| ------------- |
| .. doxygengroup:: pw_alignment |
| :members: |