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
00081
00082
00083
00084 #if __GNUC__ == 3 && __GNUC_MINOR__ == 4
00085 #include <ext/pool_allocator.h>
00086 #endif
00087 #if __GNUC__ >= 4
00088 #include <ext/mt_allocator.h>
00089 #endif
00090
00091 namespace libcwd {
00092 namespace _private_ {
00093
00094
00095 int const random_salt = 327665;
00096
00097
00098 int const multi_threaded_internal_instance = -1;
00099 int const single_threaded_internal_instance = -2;
00100 int const userspace_instance = -3;
00101
00102 #if __GNUC__ == 3 && __GNUC_MINOR__ < 4
00103 template<bool needs_lock, int pool_instance>
00104 struct CharPoolAlloc : public std::__default_alloc_template<needs_lock, random_salt + pool_instance> {
00105 typedef char* pointer;
00106 };
00107 #elif __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ == 0
00108 template<bool needs_lock, int pool_instance>
00109 struct CharPoolAlloc : public __gnu_cxx::__pool_alloc<needs_lock, random_salt + pool_instance> {
00110 typedef char* pointer;
00111 };
00112 #else // gcc 3.4.1 and higher.
00113 template<int pool_instance>
00114 struct char_wrapper {
00115 char c;
00116 };
00117 #if __GNUC__ == 3
00118
00119 template<bool needs_lock, int pool_instance>
00120 class CharPoolAlloc : public __gnu_cxx::__pool_alloc<char_wrapper<pool_instance> > { };
00121 #else // gcc 4.0 and higher.
00122
00123
00124
00125 template<class __pool_type>
00126 struct static_pool_instance {
00127 __pool_type* ptr;
00128 bool M_internal;
00129 static_pool_instance(void) { }
00130
00131
00132
00133 void create(void);
00134 };
00135
00136
00137 template<int pool_instance, bool needs_lock>
00138 struct pool_instance_and_policy {
00139 typedef __gnu_cxx::__pool<needs_lock> pool_type;
00140 static static_pool_instance<pool_type> _S_pool_instance;
00141
00142
00143 static pool_type& _S_get_pool(void)
00144 { return *_S_pool_instance.ptr; }
00145 static void _S_initialize_once(void)
00146 {
00147 static bool __init;
00148 if (__builtin_expect(__init == false, false))
00149 {
00150 _S_pool_instance.create();
00151 _S_pool_instance.ptr->_M_initialize_once();
00152 __init = true;
00153 }
00154 }
00155 };
00156
00157 #ifdef __GTHREADS
00158
00159
00160 template<int pool_instance>
00161 struct pool_instance_and_policy<pool_instance, true>
00162 {
00163 typedef __gnu_cxx::__pool<true> pool_type;
00164 static static_pool_instance<pool_type> _S_pool_instance;
00165
00166
00167 static pool_type& _S_get_pool(void)
00168 { return *_S_pool_instance.ptr; }
00169 static void _S_initialize_once(void)
00170 {
00171 static bool __init;
00172 if (__builtin_expect(__init == false, false))
00173 {
00174 _S_pool_instance.create();
00175 _S_pool_instance.ptr->_M_initialize_once(_S_initialize);
00176 __init = true;
00177 }
00178 }
00179
00180 static void _S_destroy_thread_key(void* __freelist_pos) { _S_get_pool()._M_destroy_thread_key(__freelist_pos); }
00181 static void _S_initialize(void) { _S_get_pool()._M_initialize(_S_destroy_thread_key); }
00182 };
00183
00184 template<int pool_instance>
00185 static_pool_instance<typename pool_instance_and_policy<pool_instance, true>::pool_type>
00186 pool_instance_and_policy<pool_instance, true>::_S_pool_instance;
00187 #endif // __GTHREADS
00188
00189 template<int pool_instance, bool needs_lock>
00190 static_pool_instance<typename pool_instance_and_policy<pool_instance, needs_lock>::pool_type>
00191 pool_instance_and_policy<pool_instance, needs_lock>::_S_pool_instance;
00192
00193 template<bool needs_lock, int pool_instance>
00194 class CharPoolAlloc : public __gnu_cxx::__mt_alloc<char, pool_instance_and_policy<pool_instance, needs_lock> > { };
00195 #endif // gcc 4.0 and higher.
00196 #endif // gcc 3.4.1 and higher.
00197
00198
00199 #if CWDEBUG_DEBUG
00200 #define LIBCWD_COMMA_INT_INSTANCE , int instance
00201 #define LIBCWD_COMMA_INSTANCE , instance
00202 #define LIBCWD_DEBUGDEBUG_COMMA(x) , x
00203 #else
00204 #define LIBCWD_COMMA_INT_INSTANCE
00205 #define LIBCWD_COMMA_INSTANCE
00206 #define LIBCWD_DEBUGDEBUG_COMMA(x)
00207 #endif
00208
00209 enum pool_nt {
00210 userspace_pool,
00211 internal_pool,
00212 auto_internal_pool
00213 };
00214
00215
00216
00217
00218
00219 template<typename T, class CharAlloc, pool_nt internal LIBCWD_COMMA_INT_INSTANCE>
00220 class allocator_adaptor {
00221 private:
00222
00223 CharAlloc M_char_allocator;
00224
00225 public:
00226
00227 typedef T value_type;
00228 typedef size_t size_type;
00229 typedef ptrdiff_t difference_type;
00230 typedef T* pointer;
00231 typedef T const* const_pointer;
00232 typedef T& reference;
00233 typedef T const& const_reference;
00234
00235
00236 template <class U>
00237 struct rebind {
00238 typedef allocator_adaptor<U, CharAlloc, internal LIBCWD_COMMA_INSTANCE> other;
00239 };
00240
00241
00242 pointer address(reference value) const { return &value; }
00243 const_pointer address(const_reference value) const { return &value; }
00244
00245
00246 allocator_adaptor(void) throw() { }
00247 allocator_adaptor(allocator_adaptor const& a) : M_char_allocator(a.M_char_allocator) { }
00248 template<class U>
00249 allocator_adaptor(allocator_adaptor<U, CharAlloc, internal LIBCWD_COMMA_INSTANCE> const& a) :
00250 M_char_allocator(a.M_char_allocator) { }
00251 template<class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int instance2)>
00252 friend class allocator_adaptor;
00253 ~allocator_adaptor() throw() { }
00254
00255
00256 size_type max_size(void) const { return M_char_allocator.max_size() / sizeof(T); }
00257
00258
00259 pointer allocate(size_type num);
00260 pointer allocate(size_type num, void const* hint);
00261
00262
00263 void deallocate(pointer p, size_type num);
00264
00265
00266 void construct(pointer p, T const& value) { new ((void*)p) T(value); }
00267
00268
00269 void destroy(pointer p) { p->~T(); }
00270
00271 #if CWDEBUG_DEBUG || CWDEBUG_DEBUGM
00272 private:
00273 static void sanity_check(void);
00274 #endif
00275
00276 template <class T1, class CharAlloc1, pool_nt internal1 LIBCWD_DEBUGDEBUG_COMMA(int inst1),
00277 class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int inst2)>
00278 friend inline
00279 bool operator==(allocator_adaptor<T1, CharAlloc1, internal1 LIBCWD_DEBUGDEBUG_COMMA(inst1)> const& a1,
00280 allocator_adaptor<T2, CharAlloc2, internal2 LIBCWD_DEBUGDEBUG_COMMA(inst2)> const& a2);
00281 template <class T1, class CharAlloc1, pool_nt internal1 LIBCWD_DEBUGDEBUG_COMMA(int inst1),
00282 class T2, class CharAlloc2, pool_nt internal2 LIBCWD_DEBUGDEBUG_COMMA(int inst2)>
00283 friend inline
00284 bool operator!=(allocator_adaptor<T1, CharAlloc1, internal1 LIBCWD_DEBUGDEBUG_COMMA(inst1)> const& a1,
00285 allocator_adaptor<T2, CharAlloc2, internal2 LIBCWD_DEBUGDEBUG_COMMA(inst2)> const& a2);
00286 };
00287
00288 #if LIBCWD_THREAD_SAFE
00289
00290
00291
00292
00293 #define LIBCWD_CHARALLOCATOR_USERSPACE(instance) ::libcwd::_private_:: \
00294 allocator_adaptor<char, \
00295 CharPoolAlloc<true, userspace_instance>, \
00296 userspace_pool \
00297 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00298 #endif
00299
00300
00301
00302
00303
00304
00305
00306 #if LIBCWD_THREAD_SAFE
00307 #define LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance) \
00308 ::libcwd::_private_::instance == \
00309 ::libcwd::_private_::multi_threaded_internal_instance || \
00310 ::libcwd::_private_::instance == \
00311 ::libcwd::_private_::memblk_map_instance
00312 #else // !LIBCWD_THREAD_SAFE
00313 #define LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance) false
00314 #endif // !LIBCWD_THREAD_SAFE
00315
00316 #define LIBCWD_CHARALLOCATOR_INTERNAL(instance) ::libcwd::_private_:: \
00317 allocator_adaptor<char, \
00318 CharPoolAlloc<LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance), \
00319 ::libcwd::_private_::instance >, \
00320 internal_pool \
00321 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00322
00323 #define LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(instance) ::libcwd::_private_:: \
00324 allocator_adaptor<char, \
00325 CharPoolAlloc<LIBCWD_ALLOCATOR_POOL_NEEDS_LOCK(instance), \
00326 ::libcwd::_private_::instance >, \
00327 auto_internal_pool \
00328 LIBCWD_DEBUGDEBUG_COMMA(::libcwd::_private_::instance)>
00329
00330 #if LIBCWD_THREAD_SAFE
00331
00332
00333
00334 #define LIBCWD_NS_INTERNAL_ALLOCATOR(instance) LIBCWD_CHARALLOCATOR_INTERNAL(instance)
00335 #else // !LIBCWD_THREAD_SAFE
00336
00337 #define LIBCWD_NS_INTERNAL_ALLOCATOR(instance) LIBCWD_CHARALLOCATOR_INTERNAL(single_threaded_internal_instance)
00338 #endif // !LIBCWD_THREAD_SAFE
00339
00340 #if LIBCWD_THREAD_SAFE
00341
00342
00343
00344 #define LIBCWD_MT_USERSPACE_ALLOCATOR LIBCWD_CHARALLOCATOR_USERSPACE(userspace_instance)
00345 #define LIBCWD_MT_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_INTERNAL(multi_threaded_internal_instance)
00346 #define LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(multi_threaded_internal_instance)
00347 #else // !LIBCWD_THREAD_SAFE
00348
00349
00350
00351 #define LIBCWD_MT_USERSPACE_ALLOCATOR std::allocator<char>
00352 #define LIBCWD_MT_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_INTERNAL(single_threaded_internal_instance)
00353 #define LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR LIBCWD_CHARALLOCATOR_AUTO_INTERNAL(single_threaded_internal_instance)
00354 #endif // !LIBCWD_THREAD_SAFE
00355
00356
00357
00358
00359
00360 typedef LIBCWD_NS_INTERNAL_ALLOCATOR(memblk_map_instance) memblk_map_allocator;
00361
00362
00363 typedef LIBCWD_NS_INTERNAL_ALLOCATOR(object_files_instance) object_files_allocator;
00364
00365
00366
00367 typedef LIBCWD_MT_INTERNAL_ALLOCATOR internal_allocator;
00368
00369
00370
00371 typedef LIBCWD_MT_AUTO_INTERNAL_ALLOCATOR auto_internal_allocator;
00372
00373
00374
00375
00376
00377 typedef LIBCWD_MT_USERSPACE_ALLOCATOR userspace_allocator;
00378
00379 }
00380 }
00381
00382 #endif
00383 #endif
00384