1 //  static pool class
2 //  Copyright (C) 2009 Tim Blechmann
3 //
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.
8 //
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.
13 //
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.
18 
19 #pragma once
20 
21 extern "C" {
22 #include "tlsf.h"
23 }
24 
25 #include <array>
26 #include <mutex>
27 
28 #include "nova-tt/spin_lock.hpp"
29 #include "nova-tt/dummy_mutex.hpp"
30 #include "nova-tt/mlock.hpp"
31 
32 namespace nova {
33 
34 template <std::size_t bytes, bool blocking = false> class static_pool {
35     static_assert(bytes % sizeof(long) == 0, "static_pool: bytes not an integer mutiple of sizeof(long)");
36 
37     static const std::size_t poolsize = bytes / sizeof(long);
38 
39     typedef typename boost::mpl::if_c<blocking, std::mutex, dummy_mutex>::type mutex_type;
40 
41     typedef typename std::lock_guard<mutex_type> scoped_lock;
42 
43     struct data : mutex_type {
44         std::array<long, poolsize> pool;
45     };
46 
47     void lock_memory(void) { mlock(data_.pool.data(), poolsize * sizeof(long)); }
48 
49 public:
50     static_pool(bool lock = false) throw() {
51         /* first lock, then assign */
52         if (lock)
53             lock_memory();
54 
55         data_.pool.fill(0);
sized_array(size_type size=0,T const & def=T ())56         std::size_t status = init_memory_pool(bytes, data_.pool.begin());
57         assert(status > 0);
58     }
59 
60     static_pool(static_pool const&) = delete;
61 
62     ~static_pool() throw() {
63         scoped_lock lock(data_);
64         destroy_memory_pool(data_.pool.begin());
65     }
66 
init_from_int(int_type size)67     void* malloc(std::size_t size) {
68         scoped_lock lock(data_);
69         return malloc_ex(size, data_.pool.begin());
70     }
71 
72     void free(void* p) {
73         scoped_lock lock(data_);
init_from_container(Container const & container)74         free_ex(p, data_.pool.begin());
75     }
76 
77     std::size_t get_max_size(void) { return ::get_max_size(data_.pool.begin()); }
78 
79 private:
80     data data_;
81 };
82 
83 } /* namespace nova */
84