123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- //===------------------------ memory_resource.cpp -------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is dual licensed under the MIT and the University of Illinois Open
- // Source Licenses. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "experimental/memory_resource"
- #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
- #include "atomic"
- #elif !defined(_LIBCPP_HAS_NO_THREADS)
- #include "mutex"
- #endif
- _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
- // memory_resource
- //memory_resource::~memory_resource() {}
- // new_delete_resource()
- class _LIBCPP_TYPE_VIS_ONLY __new_delete_memory_resource_imp
- : public memory_resource
- {
- public:
- ~__new_delete_memory_resource_imp() = default;
- protected:
- virtual void* do_allocate(size_t __size, size_t __align)
- { return __allocate(__size); }
- virtual void do_deallocate(void * __p, size_t, size_t)
- { __deallocate(__p); }
- virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
- { return &__other == this; }
- };
- // null_memory_resource()
- class _LIBCPP_TYPE_VIS_ONLY __null_memory_resource_imp
- : public memory_resource
- {
- public:
- ~__null_memory_resource_imp() = default;
- protected:
- virtual void* do_allocate(size_t, size_t) {
- #ifndef _LIBCPP_NO_EXCEPTIONS
- throw std::bad_alloc();
- #else
- abort();
- #endif
- }
- virtual void do_deallocate(void *, size_t, size_t) {}
- virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
- { return &__other == this; }
- };
- namespace {
- union ResourceInitHelper {
- struct {
- __new_delete_memory_resource_imp new_delete_res;
- __null_memory_resource_imp null_res;
- } resources;
- char dummy;
- _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {}
- ~ResourceInitHelper() {}
- };
- // When compiled in C++14 this initialization should be a constant expression.
- // Only in C++11 is "init_priority" needed to ensure initialization order.
- ResourceInitHelper res_init __attribute__((init_priority (101)));
- } // end namespace
- memory_resource * new_delete_resource() _NOEXCEPT {
- return &res_init.resources.new_delete_res;
- }
- memory_resource * null_memory_resource() _NOEXCEPT {
- return &res_init.resources.null_res;
- }
- // default_memory_resource()
- static memory_resource *
- __default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
- {
- #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
- static atomic<memory_resource*> __res =
- ATOMIC_VAR_INIT(&res_init.resources.new_delete_res);
- if (set) {
- new_res = new_res ? new_res : new_delete_resource();
- // TODO: Can a weaker ordering be used?
- return _VSTD::atomic_exchange_explicit(
- &__res, new_res, memory_order::memory_order_acq_rel);
- }
- else {
- return _VSTD::atomic_load_explicit(
- &__res, memory_order::memory_order_acquire);
- }
- #elif !defined(_LIBCPP_HAS_NO_THREADS)
- static memory_resource * res = &res_init.resources.new_delete_res;
- static mutex res_lock;
- if (set) {
- new_res = new_res ? new_res : new_delete_resource();
- lock_guard<mutex> guard(res_lock);
- memory_resource * old_res = res;
- res = new_res;
- return old_res;
- } else {
- lock_guard<mutex> guard(res_lock);
- return res;
- }
- #else
- static memory_resource* res = &res_init.resources.new_delete_res;
- if (set) {
- new_res = new_res ? new_res : new_delete_resource();
- memory_resource * old_res = res;
- res = new_res;
- return old_res;
- } else {
- return res;
- }
- #endif
- }
- memory_resource * get_default_resource() _NOEXCEPT
- {
- return __default_memory_resource();
- }
- memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
- {
- return __default_memory_resource(true, __new_res);
- }
- _LIBCPP_END_NAMESPACE_LFTS_PMR
|