1.. _module-pw_alignment: 2 3============ 4pw_alignment 5============ 6.. pigweed-module:: 7 :name: pw_alignment 8 9- **Transparent**: Enforce natural alignment without any changes to how your 10 objects are used. 11- **Efficient**: Prevent your compiler from emitting libcalls to builtin 12 atomic functions and ensure it uses native atomic instructions instead. 13 14.. code-block:: c++ 15 16 #include "pw_alignment/alignment.h" 17 18 // Passing a `std::optional<bool>` to `__atomic_exchange` might not replace 19 // the call with native instructions if the compiler cannot determine all 20 // instances of this object will happen to be aligned. 21 std::atomic<std::optional<bool>> maybe_nat_aligned_obj; 22 23 // `pw::NaturallyAligned<...>` forces the object to be aligned to its size, 24 // so passing it to `__atomic_exchange` will result in a replacement with 25 // native instructions. 26 std::atomic<pw::NaturallyAligned<std::optional<bool>>> nat_aligned_obj; 27 28 // Shorter spelling for the same as above. 29 pw::AlignedAtomic<std::optional<bool>> also_nat_aligned_obj; 30 31``pw_alignment`` portably ensures that your compiler uses native atomic 32instructions rather than libcalls to builtin atomic functions. Take for example 33``std::atomic<std::optional<bool>>``. Accessing the underlying object normally 34involves a call to a builtin ``__atomic_*`` function. The problem is that the 35compiler sometimes can't determine that the size of the object is the same 36as the size of its alignment. ``pw_alignment`` ensures that an object aligns to 37its size so that compilers can always make this optimization. 38 39.. warning:: 40 Using ``std::optional<bool>`` is only a workaround that may not work with all 41 compilers. This specifically does not work when targetting ARM cortex M0. 42 Additionally, ``std::optional<bool>`` is not the recommended way to represent 43 a ternary variable. 44 45.. grid:: 2 46 47 .. grid-item-card:: :octicon:`rocket` Get Started 48 :link: module-pw_alignment-getstarted 49 :link-type: ref 50 :class-item: sales-pitch-cta-primary 51 52 How to set up ``pw_alignment`` in your build system. 53 54 .. grid-item-card:: :octicon:`code-square` API Reference 55 :link: module-pw_alignment-reference 56 :link-type: ref 57 :class-item: sales-pitch-cta-secondary 58 59 Reference information about the ``pw_alignment`` API. 60 61.. _module-pw_alignment-getstarted: 62 63----------- 64Get started 65----------- 66.. repository: https://bazel.build/concepts/build-ref#repositories 67 68.. tab-set:: 69 70 .. tab-item:: Bazel 71 72 Add ``@pigweed//pw_alignment`` to the ``deps`` list in your Bazel target: 73 74 .. code-block:: 75 76 cc_library("...") { 77 # ... 78 deps = [ 79 # ... 80 "@pigweed//pw_alignment", 81 # ... 82 ] 83 } 84 85 This assumes that your Bazel ``WORKSPACE`` has a `repository 86 <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed`` 87 that points to the upstream Pigweed repository. 88 89 .. tab-item:: GN 90 91 Add ``$dir_pw_alignment`` to the ``deps`` list in your ``pw_executable()`` 92 build target: 93 94 .. code-block:: 95 96 pw_executable("...") { 97 # ... 98 deps = [ 99 # ... 100 "$dir_pw_alignment", 101 # ... 102 ] 103 } 104 105 .. tab-item:: CMake 106 107 Add ``pw_alignment`` to your ``pw_add_library`` or similar CMake target: 108 109 .. code-block:: 110 111 pw_add_library(my_library STATIC 112 HEADERS 113 ... 114 PRIVATE_DEPS 115 # ... 116 pw_alignment 117 # ... 118 ) 119 120.. _module-pw_alignment-reference: 121 122------------- 123API reference 124------------- 125.. doxygengroup:: pw_alignment 126 :members: 127