Commit 7befac71 by Benjamin Kosnik Committed by Benjamin Kosnik

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
parent a8155711
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> 2004-10-17 Dhruv Matani <dhruvbird@gmx.net>
Paolo Carlini <pcarlini@suse.de> Paolo Carlini <pcarlini@suse.de>
......
...@@ -169,6 +169,10 @@ namespace __gnu_cxx ...@@ -169,6 +169,10 @@ namespace __gnu_cxx
_M_get_binmap(size_t __bytes) _M_get_binmap(size_t __bytes)
{ return _M_binmap[__bytes]; } { return _M_binmap[__bytes]; }
const size_t
_M_get_align()
{ return _M_options._M_align; }
explicit __pool_base() explicit __pool_base()
: _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { } : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { }
...@@ -708,8 +712,7 @@ namespace __gnu_cxx ...@@ -708,8 +712,7 @@ namespace __gnu_cxx
__bin._M_first[__thread_id] = __block->_M_next; __bin._M_first[__thread_id] = __block->_M_next;
__pool._M_adjust_freelist(__bin, __block, __thread_id); __pool._M_adjust_freelist(__bin, __block, __thread_id);
const __pool_base::_Tune& __options = __pool._M_get_options(); __c = reinterpret_cast<char*>(__block) + __pool._M_get_align();
__c = reinterpret_cast<char*>(__block) + __options._M_align;
} }
else else
{ {
......
...@@ -58,7 +58,6 @@ namespace __gnu_cxx ...@@ -58,7 +58,6 @@ namespace __gnu_cxx
{ {
_Block_address* __tmp = __bin._M_address->_M_next; _Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial); ::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp; __bin._M_address = __tmp;
} }
::operator delete(__bin._M_first); ::operator delete(__bin._M_first);
...@@ -75,8 +74,7 @@ namespace __gnu_cxx ...@@ -75,8 +74,7 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes]; const size_t __which = _M_binmap[__bytes];
_Bin_record& __bin = _M_bin[__which]; _Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options(); char* __c = __p - _M_get_align();
char* __c = __p - __options._M_align;
_Block_record* __block = reinterpret_cast<_Block_record*>(__c); _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
// Single threaded application - return to global pool. // Single threaded application - return to global pool.
...@@ -91,27 +89,29 @@ namespace __gnu_cxx ...@@ -91,27 +89,29 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes]; const size_t __which = _M_binmap[__bytes];
_Bin_record& __bin = _M_bin[__which]; _Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options(); const _Tune& __options = _M_get_options();
const size_t __bin_size = ((__options._M_min_bin << __which) const size_t __bin_size = (__options._M_min_bin << __which)
+ __options._M_align); + __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;
// Get a new block dynamically, set it up for use. // Get a new block dynamically, set it up for use.
void* __v = ::operator new(__options._M_chunk_size); 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; __bin._M_first[__thread_id] = __block;
while (--__block_count > 0) while (--__block_count > 0)
{ {
char* __c = reinterpret_cast<char*>(__block) + __bin_size; __c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c); __block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next; __block = __block->_M_next;
} }
__block->_M_next = NULL; __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]; __block = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block->_M_next; __bin._M_first[__thread_id] = __block->_M_next;
...@@ -187,7 +187,6 @@ namespace __gnu_cxx ...@@ -187,7 +187,6 @@ namespace __gnu_cxx
{ {
_Block_address* __tmp = __bin._M_address->_M_next; _Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial); ::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp; __bin._M_address = __tmp;
} }
::operator delete(__bin._M_first); ::operator delete(__bin._M_first);
...@@ -206,7 +205,6 @@ namespace __gnu_cxx ...@@ -206,7 +205,6 @@ namespace __gnu_cxx
{ {
_Block_address* __tmp = __bin._M_address->_M_next; _Block_address* __tmp = __bin._M_address->_M_next;
::operator delete(__bin._M_address->_M_initial); ::operator delete(__bin._M_address->_M_initial);
delete __bin._M_address;
__bin._M_address = __tmp; __bin._M_address = __tmp;
} }
::operator delete(__bin._M_first); ::operator delete(__bin._M_first);
...@@ -224,8 +222,8 @@ namespace __gnu_cxx ...@@ -224,8 +222,8 @@ namespace __gnu_cxx
const size_t __which = _M_binmap[__bytes]; const size_t __which = _M_binmap[__bytes];
const _Bin_record& __bin = _M_bin[__which]; const _Bin_record& __bin = _M_bin[__which];
const _Tune& __options = _M_get_options(); // Know __p not null, assume valid block.
char* __c = __p - __options._M_align; char* __c = __p - _M_get_align();
_Block_record* __block = reinterpret_cast<_Block_record*>(__c); _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
if (__gthread_active_p()) if (__gthread_active_p())
{ {
...@@ -233,18 +231,22 @@ namespace __gnu_cxx ...@@ -233,18 +231,22 @@ namespace __gnu_cxx
// in order to avoid too much contention we wait until the // in order to avoid too much contention we wait until the
// number of records is "high enough". // number of records is "high enough".
const size_t __thread_id = _M_get_thread_id(); const size_t __thread_id = _M_get_thread_id();
const _Tune& __options = _M_get_options();
long __remove = ((__bin._M_free[__thread_id] const unsigned long __limit = 100 * (_M_bin_size - __which)
* __options._M_freelist_headroom) * __options._M_freelist_headroom;
- __bin._M_used[__thread_id]);
if (__remove > static_cast<long>(100 * (_M_bin_size - __which) unsigned long __remove = __bin._M_free[__thread_id];
* __options._M_freelist_headroom) __remove *= __options._M_freelist_headroom;
&& __remove > static_cast<long>(__bin._M_free[__thread_id])) 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 = __bin._M_first[__thread_id];
_Block_record* __first = __tmp; _Block_record* __tmp = __first;
__remove /= __options._M_freelist_headroom; __remove /= __options._M_freelist_headroom;
const long __removed = __remove; const unsigned long __removed = __remove;
while (--__remove > 0) while (--__remove > 0)
__tmp = __tmp->_M_next; __tmp = __tmp->_M_next;
__bin._M_first[__thread_id] = __tmp->_M_next; __bin._M_first[__thread_id] = __tmp->_M_next;
...@@ -256,7 +258,7 @@ namespace __gnu_cxx ...@@ -256,7 +258,7 @@ namespace __gnu_cxx
__bin._M_free[0] += __removed; __bin._M_free[0] += __removed;
__gthread_mutex_unlock(__bin._M_mutex); __gthread_mutex_unlock(__bin._M_mutex);
} }
// Return this block to our list and update counters and // Return this block to our list and update counters and
// owner id as needed. // owner id as needed.
--__bin._M_used[__block->_M_thread_id]; --__bin._M_used[__block->_M_thread_id];
...@@ -283,7 +285,8 @@ namespace __gnu_cxx ...@@ -283,7 +285,8 @@ namespace __gnu_cxx
const _Tune& __options = _M_get_options(); const _Tune& __options = _M_get_options();
const size_t __bin_size = ((__options._M_min_bin << __which) const size_t __bin_size = ((__options._M_min_bin << __which)
+ __options._M_align); + __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? // Are we using threads?
// - Yes, check if there are free blocks on the global // - Yes, check if there are free blocks on the global
...@@ -302,28 +305,26 @@ namespace __gnu_cxx ...@@ -302,28 +305,26 @@ namespace __gnu_cxx
__gthread_mutex_lock(__bin._M_mutex); __gthread_mutex_lock(__bin._M_mutex);
if (__bin._M_first[0] == NULL) if (__bin._M_first[0] == NULL)
{ {
// No need to hold the lock when we are adding a whole void* __v = ::operator new(__options._M_chunk_size);
// chunk to our own list. _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); __gthread_mutex_unlock(__bin._M_mutex);
void* __v = ::operator new(__options._M_chunk_size); // No need to hold the lock when we are adding a whole
__block = static_cast<_Block_record*>(__v); // 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_free[__thread_id] = __block_count;
__bin._M_first[__thread_id] = __block; __bin._M_first[__thread_id] = __block;
while (--__block_count > 0) while (--__block_count > 0)
{ {
char* __c = reinterpret_cast<char*>(__block) + __bin_size; __c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c); __block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next; __block = __block->_M_next;
} }
__block->_M_next = NULL; __block->_M_next = NULL;
__gthread_mutex_lock(__bin._M_mutex);
_Block_address* __address = new _Block_address;
__address->_M_initial = __v;
__address->_M_next = __bin._M_address;
__bin._M_address = __address;
__gthread_mutex_unlock(__bin._M_mutex);
} }
else else
{ {
...@@ -353,20 +354,21 @@ namespace __gnu_cxx ...@@ -353,20 +354,21 @@ namespace __gnu_cxx
else else
{ {
void* __v = ::operator new(__options._M_chunk_size); void* __v = ::operator new(__options._M_chunk_size);
__block = static_cast<_Block_record*>(__v); _Block_address* __address = static_cast<_Block_address*>(__v);
__bin._M_first[0] = __block; __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) while (--__block_count > 0)
{ {
char* __c = reinterpret_cast<char*>(__block) + __bin_size; __c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c); __block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next; __block = __block->_M_next;
} }
__block->_M_next = NULL; __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]; __block = __bin._M_first[__thread_id];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment