aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorStefan Olsson <stefan@snon.net>2004-01-20 06:35:21 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2004-01-20 06:35:21 +0000
commitcec73eb50c290549a9f0f7fea6102cad73bb98e2 (patch)
tree51963941d981c78712e09e47ebd1b2c7ba9a1b75 /libstdc++-v3
parent50f59cd71061055cc039bbe44b5c955747719ebb (diff)
downloadgcc-cec73eb50c290549a9f0f7fea6102cad73bb98e2.zip
gcc-cec73eb50c290549a9f0f7fea6102cad73bb98e2.tar.gz
gcc-cec73eb50c290549a9f0f7fea6102cad73bb98e2.tar.bz2
mt_allocator.h: If a thread...
2004-01-19 Stefan Olsson <stefan@snon.net> * include/ext/mt_allocator.h: If a thread, when it dies, still has memory on it's freelist this memory is not returned to global list. Simplification of deallocate so that memory is always returned to the calling thread id's freelist instead of to global. Fix typos. Add volatile where appropriate. From-SVN: r76200
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/ext/mt_allocator.h103
2 files changed, 31 insertions, 80 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 37889725..9f0b002 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2004-01-19 Stefan Olsson <stefan@snon.net>
+
+ * include/ext/mt_allocator.h: If a thread, when it dies, still has
+ memory on it's freelist this memory is not returned to global
+ list. Simplification of deallocate so that memory is always
+ returned to the calling thread id's freelist instead of to
+ global. Fix typos. Add volatile where appropriate.
+
2004-01-19 Loren J. Rittle <ljrittle@acm.org>
* testsuite/ext/stdio_filebuf/char/10063-2.cc: Treat unbuffered.
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
index b4498fe..78fe2b9 100644
--- a/libstdc++-v3/include/ext/mt_allocator.h
+++ b/libstdc++-v3/include/ext/mt_allocator.h
@@ -1,6 +1,6 @@
// MT-optimized allocator -*- C++ -*-
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -179,11 +179,10 @@ namespace __gnu_cxx
/*
* Points to the next block_record for its thread_id.
*/
- block_record* next;
+ block_record* volatile next;
/*
* The thread id of the thread which has requested this block.
- * All blocks are initially "owned" by global pool thread id 0.
*/
size_t thread_id;
};
@@ -195,8 +194,8 @@ namespace __gnu_cxx
* thread id. Memory to these "arrays" is allocated in _S_init()
* for _S_max_threads + global pool 0.
*/
- block_record** first;
- block_record** last;
+ block_record** volatile first;
+ block_record** volatile last;
/*
* An "array" of counters used to keep track of the amount of blocks
@@ -204,8 +203,8 @@ namespace __gnu_cxx
* Memory to these "arrays" is allocated in _S_init()
* for _S_max_threads + global pool 0.
*/
- size_t* free;
- size_t* used;
+ size_t* volatile free;
+ size_t* volatile used;
/*
* Each bin has its own mutex which is used to ensure data integrity
@@ -221,7 +220,7 @@ namespace __gnu_cxx
* An "array" of bin_records each of which represents a specific
* power of 2 size. Memory to this "array" is allocated in _S_init().
*/
- static bin_record* _S_bin;
+ static bin_record* volatile _S_bin;
public:
pointer
@@ -478,37 +477,24 @@ namespace __gnu_cxx
}
/*
- * Did we allocate this block?
- * - Yes, return it to our freelist
- * - No, return it to global pool
+ * Return this block to our list and update
+ * counters and owner id as needed
*/
- if (thread_id == block->thread_id)
- {
- if (_S_bin[bin].first[thread_id] == NULL)
- _S_bin[bin].first[thread_id] = block;
- else
- _S_bin[bin].last[thread_id]->next = block;
-
- _S_bin[bin].last[thread_id] = block;
-
- _S_bin[bin].free[thread_id]++;
- _S_bin[bin].used[thread_id]--;
- }
+ if (_S_bin[bin].first[thread_id] == NULL)
+ _S_bin[bin].first[thread_id] = block;
else
- {
- __gthread_mutex_lock(_S_bin[bin].mutex);
+ _S_bin[bin].last[thread_id]->next = block;
- if (_S_bin[bin].first[0] == NULL)
- _S_bin[bin].first[0] = block;
- else
- _S_bin[bin].last[0]->next = block;
+ _S_bin[bin].last[thread_id] = block;
- _S_bin[bin].last[0] = block;
+ _S_bin[bin].free[thread_id]++;
- _S_bin[bin].free[0]++;
+ if (thread_id == block->thread_id)
+ _S_bin[bin].used[thread_id]--;
+ else
+ {
_S_bin[bin].used[block->thread_id]--;
-
- __gthread_mutex_unlock(_S_bin[bin].mutex);
+ block->thread_id = thread_id;
}
}
else
@@ -639,13 +625,14 @@ namespace __gnu_cxx
if (!_S_bin[bin].free)
__throw_bad_alloc();
+
_S_bin[bin].used = (size_t*) malloc(sizeof(size_t) * __n);
if (!_S_bin[bin].used)
__throw_bad_alloc();
#ifdef __GTHREADS
- _S_bin[bin].mutex =(__gthread_mutex_t*) malloc(sizeof(__gthread_mutex_t));
+ _S_bin[bin].mutex =(__gthread_mutex_t*) malloc(sizeof(__gthread_mutex_t));
#ifdef __GTHREAD_MUTEX_INIT
{
@@ -677,35 +664,6 @@ namespace __gnu_cxx
_S_thread_key_destr(void* freelist_pos)
{
/*
- * If the thread - when it dies - still has records on its
- * freelist we return them to the global pool here.
- */
- for (size_t bin = 0; bin < _S_no_of_bins; bin++)
- {
- block_record* block =
- _S_bin[bin].first[((thread_record*)freelist_pos)->id];
-
- if (block != NULL)
- {
- __gthread_mutex_lock(_S_bin[bin].mutex);
- while (block != NULL)
- {
- if (_S_bin[bin].first[0] == NULL)
- _S_bin[bin].first[0] = block;
- else
- _S_bin[bin].last[0]->next = block;
-
- _S_bin[bin].last[0] = block;
- block = block->next;
- _S_bin[bin].free[0]++;
- }
-
- _S_bin[bin].last[0]->next = NULL;
- __gthread_mutex_unlock(_S_bin[bin].mutex);
- }
- }
-
- /*
* Return this thread id record to front of thread_freelist
*/
__gthread_mutex_lock(&_S_thread_freelist_mutex);
@@ -727,7 +685,7 @@ namespace __gnu_cxx
*/
if (__gthread_active_p())
{
- thread_record* volatile freelist_pos;
+ thread_record* freelist_pos;
if ((freelist_pos =
(thread_record*)__gthread_getspecific(_S_thread_key)) == NULL)
@@ -743,21 +701,6 @@ namespace __gnu_cxx
__gthread_mutex_unlock(&_S_thread_freelist_mutex);
__gthread_setspecific(_S_thread_key, (void*)freelist_pos);
-
- /*
- * Since thread_ids may/will be reused (espcially in
- * producer/consumer applications) we make sure that the
- * list pointers and free counter is reset BUT as the
- * "old" thread may still be owner of some memory (which
- * is referred to by other threads and thus not freed)
- * we don't reset the used counter.
- */
- for (size_t bin = 0; bin < _S_no_of_bins; bin++)
- {
- _S_bin[bin].first[freelist_pos->id] = NULL;
- _S_bin[bin].last[freelist_pos->id] = NULL;
- _S_bin[bin].free[freelist_pos->id] = 0;
- }
}
return freelist_pos->id;
@@ -839,7 +782,7 @@ namespace __gnu_cxx
#endif
template<typename _Tp> typename __mt_alloc<_Tp>::bin_record*
- __mt_alloc<_Tp>::_S_bin = NULL;
+ volatile __mt_alloc<_Tp>::_S_bin = NULL;
} // namespace __gnu_cxx
#endif