From 7befac71407d4fd95853d0efd43f5c1d37e66866 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Sun, 17 Oct 2004 15:22:03 +0000 Subject: [PATCH] mt_allocator.h (__pool::_M_get_align): New. 2004-10-17 Benjamin Kosnik * 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 --- libstdc++-v3/ChangeLog | 7 ++ libstdc++-v3/include/ext/mt_allocator.h | 7 +- libstdc++-v3/src/mt_allocator.cc | 110 ++++++++++++------------ 3 files changed, 68 insertions(+), 56 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index cc55893293d..479da1dbe64 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2004-10-17 Benjamin Kosnik + + * 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 Paolo Carlini diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index d4d51d8a55e..5e587ad43da 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(__block) + __options._M_align; + __c = reinterpret_cast(__block) + __pool._M_get_align(); } else { diff --git a/libstdc++-v3/src/mt_allocator.cc b/libstdc++-v3/src/mt_allocator.cc index 08f5c87c0dd..bb6ab899caf 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(__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(__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(100 * (_M_bin_size - __which) - * __options._M_freelist_headroom) - && __remove > static_cast(__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(__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(__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(__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(__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];