mt_allocator.h (__pool::_M_get_align): New.

2004-10-17  Benjamin Kosnik  <bkoz@redhat.com>

	* include/ext/mt_allocator.h (__pool::_M_get_align): New.
	(__mt_alloc::allocate): Use it.
	* src/mt_allocator.cc (__pool::_M_reclaim_block): Use it.
	(__pool::_M_reserve_block): Simplify block allocation.

From-SVN: r89171
This commit is contained in:
Benjamin Kosnik 2004-10-17 15:22:03 +00:00 committed by Benjamin Kosnik
parent a815571193
commit 7befac7140
3 changed files with 68 additions and 56 deletions

View File

@ -1,3 +1,10 @@
2004-10-17 Benjamin Kosnik <bkoz@redhat.com>
* include/ext/mt_allocator.h (__pool::_M_get_align): New.
(__mt_alloc::allocate): Use it.
* src/mt_allocator.cc (__pool::_M_reclaim_block): Use it.
(__pool::_M_reserve_block): Simplify block allocation.
2004-10-17 Dhruv Matani <dhruvbird@gmx.net>
Paolo Carlini <pcarlini@suse.de>

View File

@ -169,6 +169,10 @@ namespace __gnu_cxx
_M_get_binmap(size_t __bytes)
{ return _M_binmap[__bytes]; }
const size_t
_M_get_align()
{ return _M_options._M_align; }
explicit __pool_base()
: _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { }
@ -708,8 +712,7 @@ namespace __gnu_cxx
__bin._M_first[__thread_id] = __block->_M_next;
__pool._M_adjust_freelist(__bin, __block, __thread_id);
const __pool_base::_Tune& __options = __pool._M_get_options();
__c = reinterpret_cast<char*>(__block) + __options._M_align;
__c = reinterpret_cast<char*>(__block) + __pool._M_get_align();
}
else
{

View File

@ -58,7 +58,6 @@ namespace __gnu_cxx
{
_Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp;
}
::operator delete(__bin._M_first);
@ -75,8 +74,7 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes];
_Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options();
char* __c = __p - __options._M_align;
char* __c = __p - _M_get_align();
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
// Single threaded application - return to global pool.
@ -91,27 +89,29 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes];
_Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options();
const size_t __bin_size = ((__options._M_min_bin << __which)
+ __options._M_align);
size_t __block_count = __options._M_chunk_size / __bin_size;
const size_t __bin_size = (__options._M_min_bin << __which)
+ __options._M_align;
size_t __block_count = __options._M_chunk_size - sizeof(_Block_address);
__block_count /= __bin_size;
// Get a new block dynamically, set it up for use.
void* __v = ::operator new(__options._M_chunk_size);
_Block_record* __block = static_cast<_Block_record*>(__v);
_Block_address* __address = static_cast<_Block_address*>(__v);
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[__thread_id] = __block;
while (--__block_count > 0)
{
char* __c = reinterpret_cast<char*>(__block) + __bin_size;
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
}
__block->_M_next = NULL;
_Block_address* __address = new _Block_address;
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
__block = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block->_M_next;
@ -187,7 +187,6 @@ namespace __gnu_cxx
{
_Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp;
}
::operator delete(__bin._M_first);
@ -206,7 +205,6 @@ namespace __gnu_cxx
{
_Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp;
}
::operator delete(__bin._M_first);
@ -224,8 +222,8 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes];
const _Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options();
char* __c = __p - __options._M_align;
// Know __p not null, assume valid block.
char* __c = __p - _M_get_align();
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
if (__gthread_active_p())
{
@ -233,18 +231,22 @@ namespace __gnu_cxx
// in order to avoid too much contention we wait until the
// number of records is "high enough".
const size_t __thread_id = _M_get_thread_id();
long __remove = ((__bin._M_free[__thread_id]
* __options._M_freelist_headroom)
- __bin._M_used[__thread_id]);
if (__remove > static_cast<long>(100 * (_M_bin_size - __which)
* __options._M_freelist_headroom)
&& __remove > static_cast<long>(__bin._M_free[__thread_id]))
const _Tune& __options = _M_get_options();
const unsigned long __limit = 100 * (_M_bin_size - __which)
* __options._M_freelist_headroom;
unsigned long __remove = __bin._M_free[__thread_id];
__remove *= __options._M_freelist_headroom;
if (__remove >= __bin._M_used[__thread_id])
__remove -= __bin._M_used[__thread_id];
else
__remove = 0;
if (__remove > __limit && __remove > __bin._M_free[__thread_id])
{
_Block_record* __tmp = __bin._M_first[__thread_id];
_Block_record* __first = __tmp;
_Block_record* __first = __bin._M_first[__thread_id];
_Block_record* __tmp = __first;
__remove /= __options._M_freelist_headroom;
const long __removed = __remove;
const unsigned long __removed = __remove;
while (--__remove > 0)
__tmp = __tmp->_M_next;
__bin._M_first[__thread_id] = __tmp->_M_next;
@ -256,7 +258,7 @@ namespace __gnu_cxx
__bin._M_free[0] += __removed;
__gthread_mutex_unlock(__bin._M_mutex);
}
// Return this block to our list and update counters and
// owner id as needed.
--__bin._M_used[__block->_M_thread_id];
@ -283,7 +285,8 @@ namespace __gnu_cxx
const _Tune& __options = _M_get_options();
const size_t __bin_size = ((__options._M_min_bin << __which)
+ __options._M_align);
size_t __block_count = __options._M_chunk_size / __bin_size;
size_t __block_count = __options._M_chunk_size - sizeof(_Block_address);
__block_count /= __bin_size;
// Are we using threads?
// - Yes, check if there are free blocks on the global
@ -302,28 +305,26 @@ namespace __gnu_cxx
__gthread_mutex_lock(__bin._M_mutex);
if (__bin._M_first[0] == NULL)
{
// No need to hold the lock when we are adding a whole
// chunk to our own list.
__gthread_mutex_unlock(__bin._M_mutex);
void* __v = ::operator new(__options._M_chunk_size);
__block = static_cast<_Block_record*>(__v);
__bin._M_free[__thread_id] = __block_count;
__bin._M_first[__thread_id] = __block;
while (--__block_count > 0)
{
char* __c = reinterpret_cast<char*>(__block) + __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
}
__block->_M_next = NULL;
__gthread_mutex_lock(__bin._M_mutex);
_Block_address* __address = new _Block_address;
_Block_address* __address = static_cast<_Block_address*>(__v);
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
__gthread_mutex_unlock(__bin._M_mutex);
// No need to hold the lock when we are adding a whole
// chunk to our own list.
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
__block = reinterpret_cast<_Block_record*>(__c);
__bin._M_free[__thread_id] = __block_count;
__bin._M_first[__thread_id] = __block;
while (--__block_count > 0)
{
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
}
__block->_M_next = NULL;
}
else
{
@ -353,20 +354,21 @@ namespace __gnu_cxx
else
{
void* __v = ::operator new(__options._M_chunk_size);
__block = static_cast<_Block_record*>(__v);
__bin._M_first[0] = __block;
_Block_address* __address = static_cast<_Block_address*>(__v);
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[0] = __block;
while (--__block_count > 0)
{
char* __c = reinterpret_cast<char*>(__block) + __bin_size;
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
}
__block->_M_next = NULL;
_Block_address* __address = new _Block_address;
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
}
__block = __bin._M_first[__thread_id];