1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include <experimental/memory_resource>
11 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
13 #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
15 #elif !defined(_LIBCPP_HAS_NO_THREADS)
17 # if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
18 # pragma comment(lib, "pthread")
22 _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
26 //memory_resource::~memory_resource() {}
28 // new_delete_resource()
30 class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp
31 : public memory_resource
33 void *do_allocate(size_t size
, size_t align
) override
{
34 #ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
35 if (__is_overaligned_for_new(align
))
38 return _VSTD::__libcpp_allocate(size
, align
);
41 void do_deallocate(void *p
, size_t n
, size_t align
) override
{
42 _VSTD::__libcpp_deallocate(p
, n
, align
);
45 bool do_is_equal(memory_resource
const & other
) const noexcept override
46 { return &other
== this; }
49 ~__new_delete_memory_resource_imp() override
= default;
52 // null_memory_resource()
54 class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp
55 : public memory_resource
58 ~__null_memory_resource_imp() = default;
61 virtual void* do_allocate(size_t, size_t) {
64 virtual void do_deallocate(void *, size_t, size_t) {}
65 virtual bool do_is_equal(memory_resource
const & __other
) const noexcept
66 { return &__other
== this; }
71 union ResourceInitHelper
{
73 __new_delete_memory_resource_imp new_delete_res
;
74 __null_memory_resource_imp null_res
;
77 constexpr ResourceInitHelper() : resources() {}
78 ~ResourceInitHelper() {}
81 // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
82 // attribute with a value that's reserved for the implementation (we're the implementation).
83 #include "memory_resource_init_helper.h"
88 memory_resource
* new_delete_resource() noexcept
{
89 return &res_init
.resources
.new_delete_res
;
92 memory_resource
* null_memory_resource() noexcept
{
93 return &res_init
.resources
.null_res
;
96 // default_memory_resource()
98 static memory_resource
*
99 __default_memory_resource(bool set
= false, memory_resource
* new_res
= nullptr) noexcept
101 #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
102 static constinit atomic
<memory_resource
*> __res
{&res_init
.resources
.new_delete_res
};
104 new_res
= new_res
? new_res
: new_delete_resource();
105 // TODO: Can a weaker ordering be used?
106 return _VSTD::atomic_exchange_explicit(
107 &__res
, new_res
, memory_order_acq_rel
);
110 return _VSTD::atomic_load_explicit(
111 &__res
, memory_order_acquire
);
113 #elif !defined(_LIBCPP_HAS_NO_THREADS)
114 static constinit memory_resource
*res
= &res_init
.resources
.new_delete_res
;
115 static mutex res_lock
;
117 new_res
= new_res
? new_res
: new_delete_resource();
118 lock_guard
<mutex
> guard(res_lock
);
119 memory_resource
* old_res
= res
;
123 lock_guard
<mutex
> guard(res_lock
);
127 static constinit memory_resource
*res
= &res_init
.resources
.new_delete_res
;
129 new_res
= new_res
? new_res
: new_delete_resource();
130 memory_resource
* old_res
= res
;
139 memory_resource
* get_default_resource() noexcept
141 return __default_memory_resource();
144 memory_resource
* set_default_resource(memory_resource
* __new_res
) noexcept
146 return __default_memory_resource(true, __new_res
);
149 _LIBCPP_END_NAMESPACE_LFTS_PMR