1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#define BOOST_CONTAINER_SOURCE
12#include <boost/container/pmr/memory_resource.hpp>
13#include <boost/container/pmr/global_resource.hpp>
14#include <boost/container/throw_exception.hpp>
15#include <boost/container/detail/dlmalloc.hpp> //For global lock
16#include <boost/container/detail/singleton.hpp>
17
18#include <cstddef>
19#include <new>
20
21namespace boost {
22namespace container {
23namespace pmr {
24
25class new_delete_resource_imp
26 : public memory_resource
27{
28 public:
29
30 ~new_delete_resource_imp() BOOST_OVERRIDE
31 {}
32
33 void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
34 { (void)bytes; (void)alignment; return new char[bytes]; }
35
36 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
37 { (void)bytes; (void)alignment; delete[]((char*)p); }
38
39 bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
40 { return &other == this; }
41};
42
43struct null_memory_resource_imp
44 : public memory_resource
45{
46 public:
47
48 ~null_memory_resource_imp() BOOST_OVERRIDE
49 {}
50
51 void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
52 {
53 (void)bytes; (void)alignment;
54 #if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS)
55 throw_bad_alloc();
56 return 0;
57 #else
58 throw std::bad_alloc();
59 #endif
60 }
61
62 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
63 { (void)p; (void)bytes; (void)alignment; }
64
65 bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
66 { return &other == this; }
67};
68
69BOOST_CONTAINER_DECL memory_resource* new_delete_resource() BOOST_NOEXCEPT
70{
71 return &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
72}
73
74BOOST_CONTAINER_DECL memory_resource* null_memory_resource() BOOST_NOEXCEPT
75{
76 return &boost::container::dtl::singleton_default<null_memory_resource_imp>::instance();
77}
78
79#if defined(BOOST_NO_CXX11_HDR_ATOMIC)
80
81static memory_resource *default_memory_resource =
82 &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
83
84BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT
85{
86 if(dlmalloc_global_sync_lock()){
87 memory_resource *previous = default_memory_resource;
88 if(!previous){
89 //function called before main, default_memory_resource is not initialized yet
90 previous = new_delete_resource();
91 }
92 default_memory_resource = r ? r : new_delete_resource();
93 dlmalloc_global_sync_unlock();
94 return previous;
95 }
96 else{
97 return new_delete_resource();
98 }
99}
100
101BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT
102{
103 if(dlmalloc_global_sync_lock()){
104 memory_resource *current = default_memory_resource;
105 if(!current){
106 //function called before main, default_memory_resource is not initialized yet
107 current = new_delete_resource();
108 }
109 dlmalloc_global_sync_unlock();
110 return current;
111 }
112 else{
113 return new_delete_resource();
114 }
115}
116
117#else // #if defined(BOOST_NO_CXX11_HDR_ATOMIC)
118
119} //namespace pmr {
120} //namespace container {
121} //namespace boost {
122
123#include <atomic>
124
125namespace boost {
126namespace container {
127namespace pmr {
128
129std::atomic<memory_resource*>& default_memory_resource_instance() {
130 static std::atomic<memory_resource*> instance(new_delete_resource());
131 return instance;
132}
133
134BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT
135{
136 memory_resource *const res = r ? r : new_delete_resource();
137 return default_memory_resource_instance().exchange(p: res, m: std::memory_order_acq_rel);
138}
139
140BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT
141{ return default_memory_resource_instance().load(m: std::memory_order_acquire); }
142
143#endif
144
145} //namespace pmr {
146} //namespace container {
147} //namespace boost {
148

source code of boost/libs/container/src/global_resource.cpp