quick_allocator.hpp
Go to the documentation of this file.
1 #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
3 
4 // MS compatible compilers support #pragma once
5 
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma once
8 #endif
9 
10 //
11 // detail/quick_allocator.hpp
12 //
13 // Copyright (c) 2003 David Abrahams
14 // Copyright (c) 2003 Peter Dimov
15 //
16 // Distributed under the Boost Software License, Version 1.0. (See
17 // accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19 //
20 
21 #include <boost/config.hpp>
22 
26 
27 #include <new> // ::operator new, ::operator delete
28 #include <cstddef> // std::size_t
29 
30 namespace boost
31 {
32 
33 namespace detail
34 {
35 
36 template<unsigned size, unsigned align_> union freeblock
37 {
40  char bytes[size];
42 };
43 
44 template<unsigned size, unsigned align_> struct allocator_impl
45 {
47 
48  // It may seem odd to use such small pages.
49  //
50  // However, on a typical Windows implementation that uses
51  // the OS allocator, "normal size" pages interact with the
52  // "ordinary" operator new, slowing it down dramatically.
53  //
54  // 512 byte pages are handled by the small object allocator,
55  // and don't interfere with ::new.
56  //
57  // The other alternative is to use much bigger pages (1M.)
58  //
59  // It is surprisingly easy to hit pathological behavior by
60  // varying the page size. g++ 2.96 on Red Hat Linux 7.2,
61  // for example, passionately dislikes 496. 512 seems OK.
62 
63 #if defined(BOOST_QA_PAGE_SIZE)
64 
65  enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
66 
67 #else
68 
69  enum { items_per_page = 512 / size }; // 1048560 / size
70 
71 #endif
72 
73 #ifdef BOOST_HAS_THREADS
74 
75  static lightweight_mutex & mutex()
76  {
78  static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
79  return *pm;
80  }
81 
82  static lightweight_mutex * mutex_init;
83 
84 #endif
85 
86  static block * free;
87  static block * page;
88  static unsigned last;
89 
90  static inline void * alloc()
91  {
92 #ifdef BOOST_HAS_THREADS
93  lightweight_mutex::scoped_lock lock( mutex() );
94 #endif
95  if(block * x = free)
96  {
97  free = x->next;
98  return x;
99  }
100  else
101  {
102  if(last == items_per_page)
103  {
104  // "Listen to me carefully: there is no memory leak"
105  // -- Scott Meyers, Eff C++ 2nd Ed Item 10
106  page = ::new block[items_per_page];
107  last = 0;
108  }
109 
110  return &page[last++];
111  }
112  }
113 
114  static inline void * alloc(std::size_t n)
115  {
116  if(n != size) // class-specific new called for a derived object
117  {
118  return ::operator new(n);
119  }
120  else
121  {
122 #ifdef BOOST_HAS_THREADS
123  lightweight_mutex::scoped_lock lock( mutex() );
124 #endif
125  if(block * x = free)
126  {
127  free = x->next;
128  return x;
129  }
130  else
131  {
132  if(last == items_per_page)
133  {
134  page = ::new block[items_per_page];
135  last = 0;
136  }
137 
138  return &page[last++];
139  }
140  }
141  }
142 
143  static inline void dealloc(void * pv)
144  {
145  if(pv != 0) // 18.4.1.1/13
146  {
147 #ifdef BOOST_HAS_THREADS
148  lightweight_mutex::scoped_lock lock( mutex() );
149 #endif
150  block * pb = static_cast<block *>(pv);
151  pb->next = free;
152  free = pb;
153  }
154  }
155 
156  static inline void dealloc(void * pv, std::size_t n)
157  {
158  if(n != size) // class-specific delete called for a derived object
159  {
160  ::operator delete(pv);
161  }
162  else if(pv != 0) // 18.4.1.1/13
163  {
164 #ifdef BOOST_HAS_THREADS
165  lightweight_mutex::scoped_lock lock( mutex() );
166 #endif
167  block * pb = static_cast<block *>(pv);
168  pb->next = free;
169  free = pb;
170  }
171  }
172 };
173 
174 #ifdef BOOST_HAS_THREADS
175 
176 template<unsigned size, unsigned align_>
177  lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
178 
179 #endif
180 
181 template<unsigned size, unsigned align_>
182  freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
183 
184 template<unsigned size, unsigned align_>
185  freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
186 
187 template<unsigned size, unsigned align_>
189 
190 template<class T>
191 struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
192 {
193 };
194 
195 } // namespace detail
196 
197 } // namespace boost
198 
199 #endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
config.hpp
boost::type_with_alignment
Definition: type_with_alignment.hpp:82
boost::detail::freeblock::aligner
aligner_type aligner
Definition: quick_allocator.hpp:39
boost::detail::allocator_impl::dealloc
static void dealloc(void *pv)
Definition: quick_allocator.hpp:143
alignment_of.hpp
boost::detail::allocator_impl::block
freeblock< size, align_ > block
Definition: quick_allocator.hpp:46
boost
BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE.
boost::detail::allocator_impl::last
static unsigned last
Definition: quick_allocator.hpp:88
boost::detail::freeblock::aligner_type
boost::type_with_alignment< align_ >::type aligner_type
Definition: quick_allocator.hpp:38
boost::detail::allocator_impl::items_per_page
@ items_per_page
Definition: quick_allocator.hpp:69
boost::detail::freeblock::bytes
char bytes[size]
Definition: quick_allocator.hpp:40
boost::alignment_of
Definition: alignment_of.hpp:28
boost::detail::allocator_impl
Definition: quick_allocator.hpp:44
type_with_alignment.hpp
boost::detail::allocator_impl::alloc
static void * alloc(std::size_t n)
Definition: quick_allocator.hpp:114
boost::detail::quick_allocator
Definition: quick_allocator.hpp:191
boost::detail::freeblock::next
freeblock * next
Definition: quick_allocator.hpp:41
boost::detail::allocator_impl::dealloc
static void dealloc(void *pv, std::size_t n)
Definition: quick_allocator.hpp:156
boost::detail::lightweight_mutex
Definition: lwm_nop.hpp:26
boost::detail::lightweight_mutex::scoped_lock
Definition: lwm_pthreads.hpp:60
boost::detail::allocator_impl::page
static block * page
Definition: quick_allocator.hpp:87
lightweight_mutex.hpp
boost::detail::allocator_impl::free
static block * free
Definition: quick_allocator.hpp:86
boost::detail::freeblock
Definition: quick_allocator.hpp:36
boost::detail::allocator_impl::alloc
static void * alloc()
Definition: quick_allocator.hpp:90


sick_visionary_ros
Author(s): SICK AG TechSupport 3D Snapshot
autogenerated on Thu Feb 8 2024 03:45:47