00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #ifndef LIBCWD_PRIVATE_ALLOCATOR_H
00019 #define LIBCWD_PRIVATE_ALLOCATOR_H
00020
00021 #ifndef LIBCWD_CONFIG_H
00022 #include <libcwd/config.h>
00023 #endif
00024
00025 #if CWDEBUG_ALLOC // This file is not used when --disable-alloc was used.
00026
00027 #ifndef LIBCWD_PRIVATE_MUTEX_INSTANCES_H
00028 #include <libcwd/private_mutex_instances.h>
00029 #endif
00030 #ifndef LIBCWD_CORE_DUMP_H
00031 #include <libcwd/core_dump.h>
00032 #endif
00033 #ifndef LIBCW_CSTDDEF
00034 #define LIBCW_CSTDDEF
00035 #include <cstddef>
00036 #endif
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #if __GNUC_MINOR__ >= 4
00081 #include <ext/pool_allocator.h>
00082 #endif
00083
00084 namespace libcwd {
00085 namespace _private_ {
00086
00087
00088 int const random_salt = 327665;
00089
00090 #if __GNUC_MINOR__ < 4
00091 template<bool needs_lock, int pool_instance>
00092 struct CharPoolAlloc : public std::__default_alloc_template<needs_lock, random_salt + pool_instance> {
00093 typedef char* pointer;
00094 };
00095 #elif __GNUC_MINOR__ == 4
00096 template<bool needs_lock, int pool_instance>
00097 struct CharPoolAlloc : public __gnu_cxx::__pool_alloc<needs_lock, random_salt + pool_instance> {
00098 typedef char* pointer;
00099 };
00100 #else
00101 template<int pool_instance>
00102 struct char_wrapper {
00103 char c;
00104 };
00105
00106 template<bool needs_lock, int pool_instance>
00107 class CharPoolAlloc : public __gnu_cxx::__pool_alloc<char_wrapper<pool_instance> > { };
00108 #endif
00109
00110
00111 int const multi_threaded_internal_instance = -1;
00112 int const single_threaded_internal_instance = -2;
00113 int const userspace_instance = -3;
00114
00115
00116 #if CWDEBUG_DEBUG
00117 #define LIBCWD_COMMA_INT_INSTANCE , int instance
00118 #define LIBCWD_COMMA_INSTANCE , instance
00119 #define LIBCWD_DEBUGDEBUG_COMMA(x) , x
00120 #else
00121 #define LIBCWD_COMMA_INT_INSTANCE
00122 #define LIBCWD_COMMA_INSTANCE
00123 #define LIBCWD_DEBUGDEBUG_COMMA(x)
00124 #endif
00125
00126 enum pool_nt {
00127 userspace_pool,
00128 internal_pool,
00129 auto_internal_pool
00130 };
00131
00132
00133
00134
00135
00136 template<typename T, class CharAlloc, pool_nt internal LIBCWD_COMMA_INT_INSTANCE>
00137 class allocator_adaptor {
00138 private:
00139
00140 CharAlloc M_char_allocator;
00141
00142 public:
00143
00144 typedef T value_type;
00145 typedef size_t size_type;
00146 typedef ptrdiff_t difference_type;
00147 typedef T* pointer;
00148 typedef T const* const_pointer;
00149 typedef T& reference;
00150 typedef T const& const_reference;
00151
00152
00153 template <class U>
00154 struct rebind {
00155 typedef allocator_adaptor<U, CharAlloc, internal LIBCWD_COMMA_INSTANCE> other;
00156 };
00157
00158
00159 pointer address(reference value) const { return &value; }
00160 const_pointer address(const_reference value) const { return &value; }
00161
00162
00163 allocator_adaptor(void) throw() { }
00164 allocator_adaptor(allocator_adaptor const& a) : M_char_allocator(a.M_char_allocator) { }
00165 template<class U>
00166 allocator_adaptor(allocator_adaptor<U, CharAlloc, internal LIBCWD_COMMA_INSTANCE> const& a) :
00167 M_char_allocator(a.M_char_allocator) { }
00168 template<class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int instance2)>
00169 friend class allocator_adaptor;
00170 ~allocator_adaptor() throw() { }
00171
00172
00173 size_type max_size(void) const { return M_char_allocator.max_size() / sizeof(T); }
00174
00175
00176 pointer allocate(size_type num);
00177 pointer allocate(size_type num, void const* hint);
00178
00179
00180 void deallocate(pointer p, size_type num);
00181
00182
00183 void construct(pointer p, T const& value) { new ((void*)p) T(value); }
00184
00185
00186 void destroy(pointer p) { p->~T(); }
00187
00188 #if CWDEBUG_DEBUG || CWDEBUG_DEBUGM
00189 private:
00190 static void sanity_check(void);
00191 #endif
00192
00193 template <class T1, class CharAlloc1, pool_nt internal1 LIBCWD_DEBUGDEBUG_COMMA(int inst1),
00194 class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int inst2)>
00195 friend inline
00196 bool operator==(allocator_adaptor<T1, CharAlloc1, internal1 LIBCWD_DEBUGDEBUG_COMMA(inst1)> const& a1,
00197 allocator_adaptor<T2, CharAlloc2, internal2 LIBCWD_DEBUGDEBUG_COMMA(inst2)> const& a2);
00198 template <class T1, class CharAlloc1, pool_nt internal1 LIBCWD_DEBUGDEBUG_COMMA(int inst1),
00199 class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int inst2)>
00200 friend inline
00201 bool operator!=(allocator_adaptor<T1, CharAlloc1, internal1 LIBCWD_DEBUGDEBUG_COMMA(inst1)> const& a1,
00202 allocator_adaptor<T2, CharAlloc2, internal2 LIBCWD_DEBUGDEBUG_COMMA(inst2)> const& a2);
00203 };
00204
00205 #if LIBCWD_THREAD_SAFE
00206
00207
00208
00209
00210 #define LIBCWD_CHARALLOCATOR_USERSPACE(instance) ::libcwd::_private_:: \
00211 allocator_adaptor<char, \
00212 CharPoolAlloc<true, userspace_instance>, \
00213 userspace_pool \
00214 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00215 #endif
00216
00217
00218
00219
00220
00221
00222
00223 #if LIBCWD_THREAD_SAFE
00224 #define LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance) \
00225 ::libcwd::_private_::instance == \
00226 ::libcwd::_private_::multi_threaded_internal_instance || \
00227 ::libcwd::_private_::instance == \
00228 ::libcwd::_private_::memblk_map_instance
00229 #else // !LIBCWD_THREAD_SAFE
00230 #define LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance) false
00231 #endif // !LIBCWD_THREAD_SAFE
00232
00233 #define LIBCWD_CHARALLOCATOR_INTERNAL(instance) ::libcwd::_private_:: \
00234 allocator_adaptor<char, \
00235 CharPoolAlloc<LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance), \
00236 ::libcwd::_private_::instance >, \
00237 internal_pool \
00238 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00239
00240 #define LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(instance) ::libcwd::_private_:: \
00241 allocator_adaptor<char, \
00242 CharPoolAlloc<LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance), \
00243 ::libcwd::_private_::instance >, \
00244 auto_internal_pool \
00245 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00246
00247 #if LIBCWD_THREAD_SAFE
00248
00249
00250
00251 #define LIBCWD_NS_INTERNAL_ALLOCATOR(instance) LIBCWD_CHARALLOCATOR_INTERNAL(instance)
00252 #else // !LIBCWD_THREAD_SAFE
00253
00254 #define LIBCWD_NS_INTERNAL_ALLOCATOR(instance) LIBCWD_CHARALLOCATOR_INTERNAL(single_threaded_internal_instance)
00255 #endif // !LIBCWD_THREAD_SAFE
00256
00257 #if LIBCWD_THREAD_SAFE
00258
00259
00260
00261 #define LIBCWD_MT_USERSPACE_ALLOCATOR LIBCWD_CHARALLOCATOR_USERSPACE(userspace_instance)
00262 #define LIBCWD_MT_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_INTERNAL(multi_threaded_internal_instance)
00263 #define LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(multi_threaded_internal_instance)
00264 #else // !LIBCWD_THREAD_SAFE
00265
00266
00267
00268 #define LIBCWD_MT_USERSPACE_ALLOCATOR std::allocator<char>
00269 #define LIBCWD_MT_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_INTERNAL(single_threaded_internal_instance)
00270 #define LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(single_threaded_internal_instance)
00271 #endif // !LIBCWD_THREAD_SAFE
00272
00273
00274
00275
00276
00277 typedef LIBCWD_NS_INTERNAL_ALLOCATOR(memblk_map_instance) memblk_map_allocator;
00278
00279
00280 typedef LIBCWD_NS_INTERNAL_ALLOCATOR(object_files_instance) object_files_allocator;
00281
00282
00283
00284 typedef LIBCWD_MT_INTERNAL_ALLOCATOR internal_allocator;
00285
00286
00287
00288 typedef LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR auto_internal_allocator;
00289
00290
00291
00292
00293
00294 typedef LIBCWD_MT_USERSPACE_ALLOCATOR userspace_allocator;
00295
00296 }
00297 }
00298
00299 #endif // CWDEBUG_ALLOC
00300 #endif // LIBCWD_PRIVATE_ALLOCATOR_H
00301