xref: /aosp_15_r20/external/libcxx/src/experimental/memory_resource.cpp (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker //===------------------------ memory_resource.cpp -------------------------===//
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*58b9f456SAndroid Build Coastguard Worker 
10*58b9f456SAndroid Build Coastguard Worker #include "experimental/memory_resource"
11*58b9f456SAndroid Build Coastguard Worker 
12*58b9f456SAndroid Build Coastguard Worker #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
13*58b9f456SAndroid Build Coastguard Worker #include "atomic"
14*58b9f456SAndroid Build Coastguard Worker #elif !defined(_LIBCPP_HAS_NO_THREADS)
15*58b9f456SAndroid Build Coastguard Worker #include "mutex"
16*58b9f456SAndroid Build Coastguard Worker #endif
17*58b9f456SAndroid Build Coastguard Worker 
18*58b9f456SAndroid Build Coastguard Worker _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
19*58b9f456SAndroid Build Coastguard Worker 
20*58b9f456SAndroid Build Coastguard Worker // memory_resource
21*58b9f456SAndroid Build Coastguard Worker 
22*58b9f456SAndroid Build Coastguard Worker //memory_resource::~memory_resource() {}
23*58b9f456SAndroid Build Coastguard Worker 
24*58b9f456SAndroid Build Coastguard Worker // new_delete_resource()
25*58b9f456SAndroid Build Coastguard Worker 
26*58b9f456SAndroid Build Coastguard Worker class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
27*58b9f456SAndroid Build Coastguard Worker     : public memory_resource
28*58b9f456SAndroid Build Coastguard Worker {
29*58b9f456SAndroid Build Coastguard Worker public:
30*58b9f456SAndroid Build Coastguard Worker     ~__new_delete_memory_resource_imp() = default;
31*58b9f456SAndroid Build Coastguard Worker 
32*58b9f456SAndroid Build Coastguard Worker protected:
do_allocate(size_t __size,size_t __align)33*58b9f456SAndroid Build Coastguard Worker     virtual void* do_allocate(size_t __size, size_t __align)
34*58b9f456SAndroid Build Coastguard Worker         { return _VSTD::__libcpp_allocate(__size, __align); /* FIXME */}
35*58b9f456SAndroid Build Coastguard Worker 
do_deallocate(void * __p,size_t __n,size_t __align)36*58b9f456SAndroid Build Coastguard Worker     virtual void do_deallocate(void* __p, size_t __n, size_t __align) {
37*58b9f456SAndroid Build Coastguard Worker       _VSTD::__libcpp_deallocate(__p, __n, __align); /* FIXME */
38*58b9f456SAndroid Build Coastguard Worker     }
39*58b9f456SAndroid Build Coastguard Worker 
do_is_equal(memory_resource const & __other) const40*58b9f456SAndroid Build Coastguard Worker     virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
41*58b9f456SAndroid Build Coastguard Worker         { return &__other == this; }
42*58b9f456SAndroid Build Coastguard Worker };
43*58b9f456SAndroid Build Coastguard Worker 
44*58b9f456SAndroid Build Coastguard Worker // null_memory_resource()
45*58b9f456SAndroid Build Coastguard Worker 
46*58b9f456SAndroid Build Coastguard Worker class _LIBCPP_TYPE_VIS __null_memory_resource_imp
47*58b9f456SAndroid Build Coastguard Worker     : public memory_resource
48*58b9f456SAndroid Build Coastguard Worker {
49*58b9f456SAndroid Build Coastguard Worker public:
50*58b9f456SAndroid Build Coastguard Worker     ~__null_memory_resource_imp() = default;
51*58b9f456SAndroid Build Coastguard Worker 
52*58b9f456SAndroid Build Coastguard Worker protected:
do_allocate(size_t,size_t)53*58b9f456SAndroid Build Coastguard Worker     virtual void* do_allocate(size_t, size_t) {
54*58b9f456SAndroid Build Coastguard Worker         __throw_bad_alloc();
55*58b9f456SAndroid Build Coastguard Worker     }
do_deallocate(void *,size_t,size_t)56*58b9f456SAndroid Build Coastguard Worker     virtual void do_deallocate(void *, size_t, size_t) {}
do_is_equal(memory_resource const & __other) const57*58b9f456SAndroid Build Coastguard Worker     virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
58*58b9f456SAndroid Build Coastguard Worker     { return &__other == this; }
59*58b9f456SAndroid Build Coastguard Worker };
60*58b9f456SAndroid Build Coastguard Worker 
61*58b9f456SAndroid Build Coastguard Worker namespace {
62*58b9f456SAndroid Build Coastguard Worker 
63*58b9f456SAndroid Build Coastguard Worker union ResourceInitHelper {
64*58b9f456SAndroid Build Coastguard Worker   struct {
65*58b9f456SAndroid Build Coastguard Worker     __new_delete_memory_resource_imp new_delete_res;
66*58b9f456SAndroid Build Coastguard Worker     __null_memory_resource_imp       null_res;
67*58b9f456SAndroid Build Coastguard Worker   } resources;
68*58b9f456SAndroid Build Coastguard Worker   char dummy;
ResourceInitHelper()69*58b9f456SAndroid Build Coastguard Worker   _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {}
~ResourceInitHelper()70*58b9f456SAndroid Build Coastguard Worker   ~ResourceInitHelper() {}
71*58b9f456SAndroid Build Coastguard Worker };
72*58b9f456SAndroid Build Coastguard Worker 
73*58b9f456SAndroid Build Coastguard Worker // Detect if the init_priority attribute is supported.
74*58b9f456SAndroid Build Coastguard Worker #if (defined(_LIBCPP_COMPILER_GCC) && defined(__APPLE__)) \
75*58b9f456SAndroid Build Coastguard Worker   || defined(_LIBCPP_COMPILER_MSVC)
76*58b9f456SAndroid Build Coastguard Worker // GCC on Apple doesn't support the init priority attribute,
77*58b9f456SAndroid Build Coastguard Worker // and MSVC doesn't support any GCC attributes.
78*58b9f456SAndroid Build Coastguard Worker # define _LIBCPP_INIT_PRIORITY_MAX
79*58b9f456SAndroid Build Coastguard Worker #else
80*58b9f456SAndroid Build Coastguard Worker # define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101)))
81*58b9f456SAndroid Build Coastguard Worker #endif
82*58b9f456SAndroid Build Coastguard Worker 
83*58b9f456SAndroid Build Coastguard Worker // When compiled in C++14 this initialization should be a constant expression.
84*58b9f456SAndroid Build Coastguard Worker // Only in C++11 is "init_priority" needed to ensure initialization order.
85*58b9f456SAndroid Build Coastguard Worker #if _LIBCPP_STD_VER > 11
86*58b9f456SAndroid Build Coastguard Worker _LIBCPP_SAFE_STATIC
87*58b9f456SAndroid Build Coastguard Worker #endif
88*58b9f456SAndroid Build Coastguard Worker ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX;
89*58b9f456SAndroid Build Coastguard Worker 
90*58b9f456SAndroid Build Coastguard Worker } // end namespace
91*58b9f456SAndroid Build Coastguard Worker 
92*58b9f456SAndroid Build Coastguard Worker 
new_delete_resource()93*58b9f456SAndroid Build Coastguard Worker memory_resource * new_delete_resource() _NOEXCEPT {
94*58b9f456SAndroid Build Coastguard Worker     return &res_init.resources.new_delete_res;
95*58b9f456SAndroid Build Coastguard Worker }
96*58b9f456SAndroid Build Coastguard Worker 
null_memory_resource()97*58b9f456SAndroid Build Coastguard Worker memory_resource * null_memory_resource() _NOEXCEPT {
98*58b9f456SAndroid Build Coastguard Worker     return &res_init.resources.null_res;
99*58b9f456SAndroid Build Coastguard Worker }
100*58b9f456SAndroid Build Coastguard Worker 
101*58b9f456SAndroid Build Coastguard Worker // default_memory_resource()
102*58b9f456SAndroid Build Coastguard Worker 
103*58b9f456SAndroid Build Coastguard Worker static memory_resource *
__default_memory_resource(bool set=false,memory_resource * new_res=nullptr)104*58b9f456SAndroid Build Coastguard Worker __default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
105*58b9f456SAndroid Build Coastguard Worker {
106*58b9f456SAndroid Build Coastguard Worker #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
107*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_SAFE_STATIC static atomic<memory_resource*> __res =
108*58b9f456SAndroid Build Coastguard Worker         ATOMIC_VAR_INIT(&res_init.resources.new_delete_res);
109*58b9f456SAndroid Build Coastguard Worker     if (set) {
110*58b9f456SAndroid Build Coastguard Worker         new_res = new_res ? new_res : new_delete_resource();
111*58b9f456SAndroid Build Coastguard Worker         // TODO: Can a weaker ordering be used?
112*58b9f456SAndroid Build Coastguard Worker         return _VSTD::atomic_exchange_explicit(
113*58b9f456SAndroid Build Coastguard Worker             &__res, new_res, memory_order::memory_order_acq_rel);
114*58b9f456SAndroid Build Coastguard Worker     }
115*58b9f456SAndroid Build Coastguard Worker     else {
116*58b9f456SAndroid Build Coastguard Worker         return _VSTD::atomic_load_explicit(
117*58b9f456SAndroid Build Coastguard Worker             &__res, memory_order::memory_order_acquire);
118*58b9f456SAndroid Build Coastguard Worker     }
119*58b9f456SAndroid Build Coastguard Worker #elif !defined(_LIBCPP_HAS_NO_THREADS)
120*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_SAFE_STATIC static memory_resource * res = &res_init.resources.new_delete_res;
121*58b9f456SAndroid Build Coastguard Worker     static mutex res_lock;
122*58b9f456SAndroid Build Coastguard Worker     if (set) {
123*58b9f456SAndroid Build Coastguard Worker         new_res = new_res ? new_res : new_delete_resource();
124*58b9f456SAndroid Build Coastguard Worker         lock_guard<mutex> guard(res_lock);
125*58b9f456SAndroid Build Coastguard Worker         memory_resource * old_res = res;
126*58b9f456SAndroid Build Coastguard Worker         res = new_res;
127*58b9f456SAndroid Build Coastguard Worker         return old_res;
128*58b9f456SAndroid Build Coastguard Worker     } else {
129*58b9f456SAndroid Build Coastguard Worker         lock_guard<mutex> guard(res_lock);
130*58b9f456SAndroid Build Coastguard Worker         return res;
131*58b9f456SAndroid Build Coastguard Worker     }
132*58b9f456SAndroid Build Coastguard Worker #else
133*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_SAFE_STATIC static memory_resource* res = &res_init.resources.new_delete_res;
134*58b9f456SAndroid Build Coastguard Worker     if (set) {
135*58b9f456SAndroid Build Coastguard Worker         new_res = new_res ? new_res : new_delete_resource();
136*58b9f456SAndroid Build Coastguard Worker         memory_resource * old_res = res;
137*58b9f456SAndroid Build Coastguard Worker         res = new_res;
138*58b9f456SAndroid Build Coastguard Worker         return old_res;
139*58b9f456SAndroid Build Coastguard Worker     } else {
140*58b9f456SAndroid Build Coastguard Worker         return res;
141*58b9f456SAndroid Build Coastguard Worker     }
142*58b9f456SAndroid Build Coastguard Worker #endif
143*58b9f456SAndroid Build Coastguard Worker }
144*58b9f456SAndroid Build Coastguard Worker 
get_default_resource()145*58b9f456SAndroid Build Coastguard Worker memory_resource * get_default_resource() _NOEXCEPT
146*58b9f456SAndroid Build Coastguard Worker {
147*58b9f456SAndroid Build Coastguard Worker     return __default_memory_resource();
148*58b9f456SAndroid Build Coastguard Worker }
149*58b9f456SAndroid Build Coastguard Worker 
set_default_resource(memory_resource * __new_res)150*58b9f456SAndroid Build Coastguard Worker memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
151*58b9f456SAndroid Build Coastguard Worker {
152*58b9f456SAndroid Build Coastguard Worker     return __default_memory_resource(true, __new_res);
153*58b9f456SAndroid Build Coastguard Worker }
154*58b9f456SAndroid Build Coastguard Worker 
155*58b9f456SAndroid Build Coastguard Worker _LIBCPP_END_NAMESPACE_LFTS_PMR
156