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 _S_start_free = static_cast<char*>(::operator
new(__bytes_to_get));
00095
if (_S_start_free == 0)
00096 {
00097
00098
00099
00100 size_t __i = __n;
00101
for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
00102 {
00103 _Obj*
volatile* __free_list = _M_get_free_list(__i);
00104 _Obj* __p = *__free_list;
00105
if (__p != 0)
00106 {
00107 *__free_list = __p->_M_free_list_link;
00108 _S_start_free = (
char*)__p;
00109 _S_end_free = _S_start_free + __i;
00110
return _M_allocate_chunk(__n, __nobjs);
00111
00112
00113 }
00114 }
00115 _S_end_free = 0;
00116
00117
00118
00119 _S_start_free = static_cast<char*>(::operator
new(__bytes_to_get));
00120 }
00121 _S_heap_size += __bytes_to_get;
00122 _S_end_free = _S_start_free + __bytes_to_get;
00123
return _M_allocate_chunk(__n, __nobjs);
00124 }
00125 }
00126
00127
00128
00129
00130
void*
00131 __pool_alloc_base::_M_refill(size_t __n)
00132 {
00133
int __nobjs = 20;
00134
char* __chunk = _M_allocate_chunk(__n, __nobjs);
00135 _Obj*
volatile* __free_list;
00136 _Obj* __result;
00137 _Obj* __current_obj;
00138 _Obj* __next_obj;
00139
00140
if (__nobjs == 1)
00141
return __chunk;
00142 __free_list = _M_get_free_list(__n);
00143
00144
00145 __result = (_Obj*)(
void*)__chunk;
00146 *__free_list = __next_obj = (_Obj*)(
void*)(__chunk + __n);
00147
for (
int __i = 1; ; __i++)
00148 {
00149 __current_obj = __next_obj;
00150 __next_obj = (_Obj*)(
void*)((
char*)__next_obj + __n);
00151
if (__nobjs - 1 == __i)
00152 {
00153 __current_obj->_M_free_list_link = 0;
00154
break;
00155 }
00156
else
00157 __current_obj->_M_free_list_link = __next_obj;
00158 }
00159
return __result;
00160 }
00161
00162 __pool_alloc_base::_Obj*
volatile __pool_alloc_base::_S_free_list[_S_free_list_size];
00163
00164
char* __pool_alloc_base::_S_start_free = 0;
00165
00166
char* __pool_alloc_base::_S_end_free = 0;
00167
00168 size_t __pool_alloc_base::_S_heap_size = 0;
00169 }