diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/mt_allocator.h | 7 | ||||
-rw-r--r-- | libstdc++-v3/src/mt_allocator.cc | 100 |
3 files changed, 63 insertions, 51 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index cc55893..479da1d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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> diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index d4d51d8..5e587ad 100644 --- a/libstdc++-v3/include/ext/mt_allocator.h +++ b/libstdc++-v3/include/ext/mt_allocator.h @@ -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 { diff --git a/libstdc++-v3/src/mt_allocator.cc b/libstdc++-v3/src/mt_allocator.cc index 08f5c87..bb6ab89 100644 --- a/libstdc++-v3/src/mt_allocator.cc +++ b/libstdc++-v3/src/mt_allocator.cc @@ -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. + void* __v = ::operator new(__options._M_chunk_size); + _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); - void* __v = ::operator new(__options._M_chunk_size); - __block = static_cast<_Block_record*>(__v); + // 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) { - 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; - - __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 { @@ -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]; |