1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_FRAME_ALLOCATOR_HPP
10  
#ifndef BOOST_CAPY_FRAME_ALLOCATOR_HPP
11  
#define BOOST_CAPY_FRAME_ALLOCATOR_HPP
11  
#define BOOST_CAPY_FRAME_ALLOCATOR_HPP
12  

12  

13  
#include <boost/capy/detail/config.hpp>
13  
#include <boost/capy/detail/config.hpp>
14  
#include <boost/capy/detail/frame_memory_resource.hpp>
14  
#include <boost/capy/detail/frame_memory_resource.hpp>
15  

15  

16  
#include <memory_resource>
16  
#include <memory_resource>
17  

17  

 
18 +
/*  Design rationale (pdimov):
 
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 +

18  
namespace boost {
32  
namespace boost {
19  
namespace capy {
33  
namespace capy {
20  

34  

21  
/** Thread-local storage for the current frame allocator.
35  
/** Thread-local storage for the current frame allocator.
22  

36  

23  
    This function returns a reference to the thread-local pointer
37  
    This function returns a reference to the thread-local pointer
24  
    that holds the current memory_resource for frame allocation.
38  
    that holds the current memory_resource for frame allocation.
25  
    The pointer is set by run_async before creating any tasks.
39  
    The pointer is set by run_async before creating any tasks.
26  

40  

27  
    @return Reference to the thread-local memory_resource pointer.
41  
    @return Reference to the thread-local memory_resource pointer.
28  
*/
42  
*/
29  
inline std::pmr::memory_resource*&
43  
inline std::pmr::memory_resource*&
30  
current_frame_allocator() noexcept
44  
current_frame_allocator() noexcept
31  
{
45  
{
32  
    static thread_local std::pmr::memory_resource* mr = nullptr;
46  
    static thread_local std::pmr::memory_resource* mr = nullptr;
33  
    return mr;
47  
    return mr;
34  
}
48  
}
35  

49  

36  
// For backward compatibility
50  
// For backward compatibility
37  
using detail::frame_memory_resource;
51  
using detail::frame_memory_resource;
38  

52  

39  
} // namespace capy
53  
} // namespace capy
40  
} // namespace boost
54  
} // namespace boost
41  

55  

42  
#endif
56  
#endif