summaryrefslogtreecommitdiffstats
path: root/libcxx/src/experimental/memory_resource.cpp
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-05-07 01:04:55 +0000
committerEric Fiselier <eric@efcs.ca>2016-05-07 01:04:55 +0000
commit15551efd432d797ce49c320ade8ab516d783491c (patch)
tree5ca73490b77bf70ff23f61e369e7d3c9a8955b30 /libcxx/src/experimental/memory_resource.cpp
parent7fa7dc36fed383098cd20f2bb94480e9562f17cf (diff)
downloadbcm5719-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.cpp129
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
OpenPOWER on IntegriCloud