LCOV - code coverage report
Current view: top level - capy/ex - frame_allocator.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 7 7
Test Date: 2026-02-13 23:13:33 Functions: 100.0 % 3 3

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/capy
       8              : //
       9              : 
      10              : #ifndef BOOST_CAPY_FRAME_ALLOCATOR_HPP
      11              : #define BOOST_CAPY_FRAME_ALLOCATOR_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : 
      15              : #include <memory_resource>
      16              : 
      17              : /*  Design rationale (pdimov):
      18              : 
      19              :     This accessor is a thin wrapper over a thread-local pointer.
      20              :     It returns exactly what was stored, including nullptr. No
      21              :     dynamic initializer on the thread-local; a dynamic TLS
      22              :     initializer moves you into a costlier implementation bucket
      23              :     on some platforms - avoid it.
      24              : 
      25              :     Null handling is the caller's responsibility (e.g. in
      26              :     promise_type::operator new). The accessor must not substitute
      27              :     a default, because there are multiple valid choices
      28              :     (new_delete_resource, the default pmr resource, etc.). If
      29              :     the allocator is not set, it reports "not set" and the
      30              :     caller interprets that however it wants.
      31              : */
      32              : 
      33              : namespace boost {
      34              : namespace capy {
      35              : 
      36              : namespace detail {
      37              : 
      38              : inline std::pmr::memory_resource*&
      39        20850 : current_frame_allocator_ref() noexcept
      40              : {
      41              :     static thread_local std::pmr::memory_resource* mr = nullptr;
      42        20850 :     return mr;
      43              : }
      44              : 
      45              : } // namespace detail
      46              : 
      47              : /** Return the current frame allocator for this thread.
      48              : 
      49              :     These accessors exist to implement the allocator
      50              :     propagation portion of the @ref IoAwaitable protocol.
      51              :     Launch functions (`run_async`, `run`) set the
      52              :     thread-local value before invoking a child coroutine;
      53              :     the child's `promise_type::operator new` reads it to
      54              :     allocate the coroutine frame from the correct resource.
      55              : 
      56              :     The value is only valid during a narrow execution
      57              :     window. Between a coroutine's resumption
      58              :     and the next suspension point, the protocol guarantees
      59              :     that TLS contains the allocator associated with the
      60              :     currently running chain. Outside that window the value
      61              :     is indeterminate. Only code that implements an
      62              :     @ref IoAwaitable should call these functions.
      63              : 
      64              :     A return value of `nullptr` means "not specified" -
      65              :     no allocator has been established for this chain.
      66              :     The awaitable is free to use whatever allocation
      67              :     strategy makes best sense (e.g.
      68              :     `std::pmr::new_delete_resource()`).
      69              : 
      70              :     Use of the frame allocator is optional. An awaitable
      71              :     that does not consult this value to allocate its
      72              :     coroutine frame is never wrong. However, a conforming
      73              :     awaitable must still propagate the allocator faithfully
      74              :     so that downstream coroutines can use it.
      75              : 
      76              :     @return The thread-local memory_resource pointer,
      77              :     or `nullptr` if none has been set.
      78              : 
      79              :     @see set_current_frame_allocator, IoAwaitable
      80              : */
      81              : inline
      82              : std::pmr::memory_resource*
      83         5780 : get_current_frame_allocator() noexcept
      84              : {
      85         5780 :     return detail::current_frame_allocator_ref();
      86              : }
      87              : 
      88              : /** Set the current frame allocator for this thread.
      89              : 
      90              :     Installs @p mr as the frame allocator that will be
      91              :     read by the next coroutine's `promise_type::operator
      92              :     new` on this thread. Only launch functions and
      93              :     @ref IoAwaitable machinery should call this; see
      94              :     @ref get_current_frame_allocator for the full protocol
      95              :     description.
      96              : 
      97              :     Passing `nullptr` means "not specified" - no
      98              :     particular allocator is established for the chain.
      99              : 
     100              :     @param mr The memory_resource to install, or
     101              :     `nullptr` to clear.
     102              : 
     103              :     @see get_current_frame_allocator, IoAwaitable
     104              : */
     105              : inline void
     106        15070 : set_current_frame_allocator(
     107              :     std::pmr::memory_resource* mr) noexcept
     108              : {
     109        15070 :     detail::current_frame_allocator_ref() = mr;
     110        15070 : }
     111              : 
     112              : } // namespace capy
     113              : } // namespace boost
     114              : 
     115              : #endif
        

Generated by: LCOV version 2.3