1 // thread-local real-time safe allocator class
2 // Copyright (C) 2008 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef UTILITIES_TL_ALLOCATOR_HPP
20 #define UTILITIES_TL_ALLOCATOR_HPP
30 #include <boost/array.hpp>
31 #include <boost/static_assert.hpp>
32 #include <boost/mpl/modulus.hpp>
33 #include <boost/mpl/arithmetic.hpp>
34 #include <boost/thread/tss.hpp>
36 #include "branch_hints.hpp"
45 template <std::size_t bytes
>
48 BOOST_STATIC_ASSERT((boost::mpl::modulus
<boost::mpl::int_
<bytes
>, boost::mpl::int_
<sizeof(long)> >::value
== 0));
52 static const std::size_t poolsize
= bytes
/sizeof(long);
53 typedef std::size_t size_type
;
54 typedef std::ptrdiff_t difference_type
;
56 tl_allocator(void) throw()
58 if (likely(initialized
))
61 memset(pool
, bytes
, 0);
62 init_memory_pool(bytes
, pool
);
65 void * allocate(size_type n
)
67 void * ret
= malloc_ex(n
, pool
);
70 throw std::bad_alloc();
75 void deallocate(void * p
)
80 size_type
max_size() const throw()
85 static __thread
long pool
[poolsize
];
86 static __thread
bool initialized
;
89 template <std::size_t bytes
>
90 long __thread tl_allocator
<bytes
>::pool
[];
92 template <std::size_t bytes
>
93 bool __thread tl_allocator
<bytes
>::initialized
= false;
97 template <std::size_t bytes
>
100 BOOST_STATIC_ASSERT((boost::mpl::modulus
<boost::mpl::int_
<bytes
>, boost::mpl::int_
<sizeof(long)> >::value
== 0));
101 static const std::size_t poolsize
= bytes
/sizeof(long);
109 init_memory_pool(bytes
, pool
.begin());
114 destroy_memory_pool(pool
.begin());
117 boost::array
<long, poolsize
> pool
;
121 typedef std::size_t size_type
;
122 typedef std::ptrdiff_t difference_type
;
124 tl_allocator(void) throw()
126 if (likely(pool
.get()))
128 pool
.reset(new pool_t());
131 tl_allocator(tl_allocator
const & rhs
) throw()
134 void * allocate(size_type n
)
136 void * ret
= malloc_ex(n
, pool
->pool
.begin());
139 throw std::bad_alloc();
144 void deallocate(void * p
)
146 free_ex(p
, pool
->pool
.begin());
149 size_type
max_size() const throw()
154 typedef boost::thread_specific_ptr
<pool_t
> pool_ptr
;
155 static pool_ptr pool
;
158 template <std::size_t bytes
>
159 typename tl_allocator
<bytes
>::pool_ptr tl_allocator
<bytes
>::pool
;
167 * realtime allocator:
168 * allocates from a thread-local memory pool via the malloc implementation of tlsf
170 * it is not completely stl compliant
171 * memory allocated from one instance can be deallocated from each other instance
172 * of this class as long as it is done from the same thread
175 template <typename T
, std::size_t bytes
= 8 * 1024 * 1024>
179 typedef std::size_t size_type
;
180 typedef std::ptrdiff_t difference_type
;
182 typedef const T
* const_pointer
;
183 typedef T
& reference
;
184 typedef const T
& const_reference
;
185 typedef T value_type
;
187 template <class U
> struct rebind
189 typedef tl_allocator
<U
, bytes
> other
;
192 tl_allocator(void) throw()
195 template <class U
, std::size_t bytes_
>
196 tl_allocator(tl_allocator
<U
, bytes_
> const & rhs
) throw()
199 pointer
address(reference x
) const
204 const_pointer
address(const_reference x
) const
209 pointer
allocate(size_type n
,
210 const_pointer hint
= 0)
212 return static_cast<pointer
> (allocator
.allocate(n
* sizeof(T
)));
215 void deallocate(pointer p
, size_type n
)
217 allocator
.deallocate(p
);
220 size_type
max_size() const throw()
225 void construct(pointer p
, const T
& val
)
230 void destroy(pointer p
)
236 detail::tl_allocator
<bytes
> allocator
;
239 } /* namespace nova */
241 #endif /* UTILITIES_TL_ALLOCATOR_HPP */