root/lang/c/mpio/trunk/mp/mempool.pre.h @ 19040

Revision 18183, 5.0 kB (checked in by frsyuki, 5 years ago)

lang/c/mpio: added mp::coroutine, mp::async, mp::byte_array, mp::short_queue, removed mp::io

Line 
1//
2// mp::mempool
3//
4// Copyright (C) 2008 FURUHASHI Sadayuki
5//
6//    Licensed under the Apache License, Version 2.0 (the "License");
7//    you may not use this file except in compliance with the License.
8//    You may obtain a copy of the License at
9//
10//        http://www.apache.org/licenses/LICENSE-2.0
11//
12//    Unless required by applicable law or agreed to in writing, software
13//    distributed under the License is distributed on an "AS IS" BASIS,
14//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//    See the License for the specific language governing permissions and
16//    limitations under the License.
17//
18
19#ifndef MP_MEMPOOL_H__
20#define MP_MEMPOOL_H__
21
22#include <stdexcept>
23#include <cstdlib>
24#include <limits>
25#include "mp/utility.h"
26
27#ifndef MP_POOL_DEFAULT_ALLOCATION_SIZE
28#define MP_POOL_DEFAULT_ALLOCATION_SIZE 32*1024
29#endif
30
31#ifndef MP_POOL_DEFAULT_LOTS_IN_CHUNK
32#define MP_POOL_DEFAULT_LOTS_IN_CHUNK 4
33#endif
34
35#ifndef MP_POOL_ALLOCATOR_DEFAULT_OBJECTS_IN_CHUNK
36#define MP_POOL_ALLOCATOR_DEFAULT_OBJECTS_IN_CHUNK 1024
37#endif
38
39namespace mp {
40
41static const size_t POOL_DEFAULT_ALLOCATION_SIZE = MP_POOL_DEFAULT_ALLOCATION_SIZE;
42static const size_t POOL_DEFAULT_LOTS_IN_CHUNK = MP_POOL_DEFAULT_LOTS_IN_CHUNK;
43static const size_t POOL_ALLOCATOR_DEFAULT_OBJECTS_IN_CHUNK = MP_POOL_ALLOCATOR_DEFAULT_OBJECTS_IN_CHUNK;
44
45template < size_t EstimatedAllocationSize = POOL_DEFAULT_ALLOCATION_SIZE,
46           size_t OptimalLotsInChunk = POOL_DEFAULT_LOTS_IN_CHUNK >
47class mempool {
48public:
49        mempool();
50        ~mempool();
51
52public:
53        //! Allocate memory from the pool.
54        /* The allocated memory have to be freed using free() function. */
55        inline void* malloc(size_t size);
56
57        //! Free the allocated memory.
58        inline void free(void* x);
59
60        //! Template version of malloc()
61        template <size_t size>
62                inline void* malloc();
63
64public:
65        //! Destroy the constructed object.
66        template <typename T>
67                inline void destroy(T* x);
68
69        //! Allocate memory from the pool and construct object.
70        template <typename T>
71                inline T* construct();
72MP_ARGS_BEGIN
73        template <typename T, MP_ARGS_TEMPLATE>
74                inline T* construct(MP_ARGS_PARAMS);
75MP_ARGS_END
76
77private:
78        struct chunk_t {
79                chunk_t* next;
80                chunk_t* prev;
81                size_t free;
82                size_t lots;
83                size_t size;
84        };
85        struct data_t {
86                chunk_t* chunk;
87        };
88
89private:
90        chunk_t* m_free;
91        chunk_t* m_used;
92
93private:
94        void* expand_free(size_t req);
95        void splice_to_used(chunk_t* chunk);
96        void splice_to_free(chunk_t* chunk);
97
98private:
99        mempool(const mempool&);
100};
101
102
103template < typename ThreadTag = main_thread_tag,
104           size_t EstimatedAllocationSize = POOL_DEFAULT_ALLOCATION_SIZE,
105           size_t OptimalLotsInChunk = POOL_DEFAULT_LOTS_IN_CHUNK >
106class singleton_mempool {
107public:
108        typedef mempool<EstimatedAllocationSize, OptimalLotsInChunk> pool_type;
109
110        static void* malloc(size_t size)
111                { return pool().malloc(size); }
112
113        static void free(void* x)
114                { pool().free(x); }
115
116        template <size_t size>
117        static void* malloc()
118                { return pool().malloc<size>(); }
119
120public:
121        template <typename T>
122        static void destroy(T* x)
123                { return pool().destroy<T>(x); }
124
125        template <typename T>
126        static T* construct()
127                { return pool().construct<T>(); }
128MP_ARGS_BEGIN
129        template <typename T, MP_ARGS_TEMPLATE>
130        static T* construct(MP_ARGS_PARAMS)
131                { return pool().construct<T, MP_ARGS_TYPES>(MP_ARGS_FUNC); }
132MP_ARGS_END
133
134private:
135        static pool_type& pool()
136        {
137                static pool_type object;
138                return object;
139        }
140};
141
142
143template < typename T,
144                typename ThreadTag = main_thread_tag,
145                size_t OptimalObjectsInChunk = POOL_ALLOCATOR_DEFAULT_OBJECTS_IN_CHUNK >
146class mempool_allocator {
147private:
148        typedef singleton_mempool<ThreadTag, sizeof(T), OptimalObjectsInChunk> pool;
149
150public:
151        typedef size_t size_type;
152        typedef ptrdiff_t difference_type;
153        typedef T* pointer;
154        typedef const T* const_pointer;
155        typedef T& reference;
156        typedef const T& const_reference;
157        typedef T value_type;
158
159        template <class U>
160        struct rebind { typedef mempool_allocator<U> other; };
161
162        mempool_allocator() throw() {}
163        mempool_allocator(const mempool_allocator&) throw() {}
164        template <class U> mempool_allocator(const mempool_allocator<U>&) throw() {}
165
166        ~mempool_allocator() throw() {}
167
168        pointer address(reference r)
169                { return &r; }
170
171        const_pointer address(const_reference s)
172                { return &s; }
173
174        size_type max_size() throw()
175                { return std::numeric_limits<size_t>::max() / sizeof(T); }
176
177        pointer allocate(size_type num, const_pointer hint = 0)
178        {
179                const pointer p = static_cast<pointer>( pool::malloc(sizeof(T) * num) );
180                if (p == 0) { throw std::bad_alloc(); }
181                return p;
182        }
183
184        void deallocate(pointer p, size_type num)
185        {
186                if(p == 0) { return; }
187                pool::free(p);
188        }
189
190        void construct(pointer p, const T& r)
191                { new ( reinterpret_cast<void*>(p) ) T(r); }
192
193        void destroy(pointer p)
194                { p->~T(); }
195};
196
197
198}  // namespace mp
199
200template <class T1, class T2>
201bool operator==(const mp::mempool_allocator<T1>&, const mp::mempool_allocator<T2>&) throw() { return true; }
202
203template <class T1, class T2>
204bool operator!=(const mp::mempool_allocator<T1>&, const mp::mempool_allocator<T2>&) throw() { return false; }
205
206#include "mp/mempool_impl.h"
207
208#endif /* mp/mempool.h */
209
Note: See TracBrowser for help on using the browser.