aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/include/ext/mt_allocator.h7
-rw-r--r--libstdc++-v3/src/mt_allocator.cc100
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];