00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <bits/c++config.h>
00035 #include <memory>
00036 #include <ext/mt_allocator.h>
00037 #include <ext/pool_allocator.h>
00038
00039 namespace __gnu_internal
00040 {
00041 __glibcxx_mutex_define_initialized(palloc_init_mutex);
00042 }
00043
00044 namespace __gnu_cxx
00045 {
00046
00047 __pool_alloc_base::_Obj* volatile*
00048 __pool_alloc_base::_M_get_free_list(size_t __bytes)
00049 {
00050 size_t __i = ((__bytes + (size_t)_S_align - 1) / (size_t)_S_align - 1);
00051 return _S_free_list + __i;
00052 }
00053
00054 mutex_type&
00055 __pool_alloc_base::_M_get_mutex()
00056 { return __gnu_internal::palloc_init_mutex; }
00057
00058
00059
00060
00061 char*
00062 __pool_alloc_base::_M_allocate_chunk(size_t __n, int& __nobjs)
00063 {
00064 char* __result;
00065 size_t __total_bytes = __n * __nobjs;
00066 size_t __bytes_left = _S_end_free - _S_start_free;
00067
00068 if (__bytes_left >= __total_bytes)
00069 {
00070 __result = _S_start_free;
00071 _S_start_free += __total_bytes;
00072 return __result ;
00073 }
00074 else if (__bytes_left >= __n)
00075 {
00076 __nobjs = (int)(__bytes_left / __n);
00077 __total_bytes = __n * __nobjs;
00078 __result = _S_start_free;
00079 _S_start_free += __total_bytes;
00080 return __result;
00081 }
00082 else
00083 {
00084
00085 if (__bytes_left > 0)
00086 {
00087 _Obj* volatile* __free_list = _M_get_free_list(__bytes_left);
00088 ((_Obj*)(void*)_S_start_free)->_M_free_list_link = *__free_list;
00089 *__free_list = (_Obj*)(void*)_S_start_free;
00090 }
00091
00092 size_t __bytes_to_get = (2 * __total_bytes
00093 + _M_round_up(_S_heap_size >> 4));
00094 try
00095 {
00096 _S_start_free = static_cast<char*>(::operator new(__bytes_to_get));
00097 }
00098 catch (...)
00099 {
00100
00101
00102
00103 size_t __i = __n;
00104 for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
00105 {
00106 _Obj* volatile* __free_list = _M_get_free_list(__i);
00107 _Obj* __p = *__free_list;
00108 if (__p != 0)
00109 {
00110 *__free_list = __p->_M_free_list_link;
00111 _S_start_free = (char*)__p;
00112 _S_end_free = _S_start_free + __i;
00113 return _M_allocate_chunk(__n, __nobjs);
00114
00115
00116 }
00117 }
00118
00119 _S_start_free = _S_end_free = 0;
00120 __throw_exception_again;
00121 }
00122 _S_heap_size += __bytes_to_get;
00123 _S_end_free = _S_start_free + __bytes_to_get;
00124 return _M_allocate_chunk(__n, __nobjs);
00125 }
00126 }
00127
00128
00129
00130
00131 void*
00132 __pool_alloc_base::_M_refill(size_t __n)
00133 {
00134 int __nobjs = 20;
00135 char* __chunk = _M_allocate_chunk(__n, __nobjs);
00136 _Obj* volatile* __free_list;
00137 _Obj* __result;
00138 _Obj* __current_obj;
00139 _Obj* __next_obj;
00140
00141 if (__nobjs == 1)
00142 return __chunk;
00143 __free_list = _M_get_free_list(__n);
00144
00145
00146 __result = (_Obj*)(void*)__chunk;
00147 *__free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
00148 for (int __i = 1; ; __i++)
00149 {
00150 __current_obj = __next_obj;
00151 __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
00152 if (__nobjs - 1 == __i)
00153 {
00154 __current_obj->_M_free_list_link = 0;
00155 break;
00156 }
00157 else
00158 __current_obj->_M_free_list_link = __next_obj;
00159 }
00160 return __result;
00161 }
00162
00163 __pool_alloc_base::_Obj* volatile __pool_alloc_base::_S_free_list[_S_free_list_size];
00164
00165 char* __pool_alloc_base::_S_start_free = 0;
00166
00167 char* __pool_alloc_base::_S_end_free = 0;
00168
00169 size_t __pool_alloc_base::_S_heap_size = 0;
00170 }