diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-05-07 01:04:55 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-05-07 01:04:55 +0000 |
commit | 15551efd432d797ce49c320ade8ab516d783491c (patch) | |
tree | 5ca73490b77bf70ff23f61e369e7d3c9a8955b30 /libcxx/src/experimental/memory_resource.cpp | |
parent | 7fa7dc36fed383098cd20f2bb94480e9562f17cf (diff) | |
download | bcm5719-llvm-15551efd432d797ce49c320ade8ab516d783491c.tar.gz bcm5719-llvm-15551efd432d797ce49c320ade8ab516d783491c.zip |
Add <experimental/memory_resource>
Reviewers: mclow.lists, EricWF
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D20007
llvm-svn: 268829
Diffstat (limited to 'libcxx/src/experimental/memory_resource.cpp')
-rw-r--r-- | libcxx/src/experimental/memory_resource.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/libcxx/src/experimental/memory_resource.cpp b/libcxx/src/experimental/memory_resource.cpp new file mode 100644 index 00000000000..fe338e0b9e7 --- /dev/null +++ b/libcxx/src/experimental/memory_resource.cpp @@ -0,0 +1,129 @@ +//===------------------------ 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" +#else +#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_HAS_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; } +}; + +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))); + +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); + } +#else + 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; + } +#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
\ No newline at end of file |