+2004-06-24 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/concurrence.h (__gnu_cxx::lock): New.
+ * include/ext/pool_allocator.h (__pool_base::_Lock::_S_lock): Remove.
+ (__pool_base::_M_get_mutex): New.
+ * include/bits/allocator.h: Tweak.
+ * src/allocator.cc (__pool_base::_M_get_free_list): Correct offset.
+ * config/linker-map.gnu: Remove __pool_base::_Lock::_S_lock.
+ * include/bits/stl_threads.h: Remove.
+ * include/Makefile.am: Also here.
+ * include/Makefile.in: Regenerate.
+
+ * src/locale_init.cc: Use __gnu_cxx::lock.
+
+ * src/allocator.cc: Move all instantiations...
+ * src/allocator-inst.cc: ...here.
+
2004-06-23 Andrew Pinski <apinski@apple.com>
* linkage.m4: Remove check for libmx.
_ZNSt12__basic_fileIcE6xsputn*;
_ZNSt12__basic_fileIcE7seekoff*;
_ZNSt12__basic_fileIcE8sys_openE*St13_Ios_Openmode;
- _ZNSt12__basic_fileIcE8sys_openEiSt13_Ios_Openmode;
_ZNSt12__basic_fileIcE8xsputn_2*;
_ZNSt12__basic_fileIcE9showmanycEv;
_ZNSt12__basic_fileIcEC*;
GLIBCXX_3.4.2 {
- _ZN9__gnu_cxx11__pool_base5_Lock7_S_lockE;
- _ZN9__gnu_cxx11__pool_base9_M_refillEj;
- _ZN9__gnu_cxx11__pool_base16_M_get_free_listEj;
-
+ _ZN9__gnu_cxx11__pool_base9_M_refillE[jm];
+ _ZN9__gnu_cxx11__pool_base16_M_get_free_listE[jm];
+ _ZN9__gnu_cxx11__pool_base12_M_get_mutexEv;
+
} GLIBCXX_3.4.1;
# Symbols in the support library (libsupc++) have their own tag.
${bits_srcdir}/stl_set.h \
${bits_srcdir}/stl_stack.h \
${bits_srcdir}/stl_tempbuf.h \
- ${bits_srcdir}/stl_threads.h \
${bits_srcdir}/stl_tree.h \
${bits_srcdir}/stl_uninitialized.h \
${bits_srcdir}/stl_vector.h \
${bits_srcdir}/stl_set.h \
${bits_srcdir}/stl_stack.h \
${bits_srcdir}/stl_tempbuf.h \
- ${bits_srcdir}/stl_threads.h \
${bits_srcdir}/stl_tree.h \
${bits_srcdir}/stl_uninitialized.h \
${bits_srcdir}/stl_vector.h \
allocator() throw() { }
- allocator(const allocator& a) throw()
- : ___glibcxx_base_allocator<_Tp>(a) { }
+ allocator(const allocator& __a) throw()
+ : ___glibcxx_base_allocator<_Tp>(__a) { }
template<typename _Tp1>
allocator(const allocator<_Tp1>&) throw() { }
#endif
+namespace __gnu_cxx
+{
+ class lock
+ {
+ // Externally defined and initialized.
+ __gthread_mutex_t* device;
+
+ public:
+ // Acquire the mutex here with a constructor call. This ensures
+ // that it is released in exit or during stack unwinding.
+ explicit lock(__gthread_mutex_t& name) : device(&name)
+ { __glibcxx_mutex_lock(*device); }
+
+ ~lock() throw()
+ { __glibcxx_mutex_unlock(*device); }
+
+ private:
+ lock(const lock&);
+ lock& operator=(const lock&);
+ };
+}
+
#endif
+++ /dev/null
-// Threading support -*- C++ -*-
-
-// Copyright (C) 2001, 2002, 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
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1997-1999
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- */
-
-/** @file stl_threads.h
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
-
-#ifndef _STL_THREADS_H
-#define _STL_THREADS_H 1
-
-#include <cstddef>
-
-// The only supported threading model is GCC's own gthr.h abstraction
-// layer.
-#include "bits/gthr.h"
-
-namespace __gnu_internal
-{
-#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- extern __gthread_mutex_t _GLIBCXX_mutex;
- extern __gthread_mutex_t *_GLIBCXX_mutex_address;
- extern __gthread_once_t _GLIBCXX_once;
- extern void _GLIBCXX_mutex_init(void);
- extern void _GLIBCXX_mutex_address_init(void);
-#endif
-} // namespace __gnu_internal
-
-namespace __gnu_cxx
-{
- // Locking class. Note that this class *does not have a
- // constructor*. It must be initialized either statically, with
- // __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling
- // the _M_initialize member function. (This is similar to the ways
- // that a pthreads mutex can be initialized.) There are explicit
- // member functions for acquiring and releasing the lock.
-
- // There is no constructor because static initialization is
- // essential for some uses, and only a class aggregate (see section
- // 8.5.1 of the C++ standard) can be initialized that way. That
- // means we must have no constructors, no base classes, no virtual
- // functions, and no private or protected members.
- struct _STL_mutex_lock
- {
- // The class must be statically initialized with __STL_MUTEX_INITIALIZER.
-#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- volatile int _M_init_flag;
- __gthread_once_t _M_once;
-#endif
- __gthread_mutex_t _M_lock;
-
- void
- _M_initialize()
- {
-#ifdef __GTHREAD_MUTEX_INIT
- // There should be no code in this path given the usage rules above.
-#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- if (_M_init_flag) return;
- if (__gthread_once(&__gnu_internal::_GLIBCXX_once,
- __gnu_internal::_GLIBCXX_mutex_init) != 0
- && __gthread_active_p())
- abort ();
- __gthread_mutex_lock(&__gnu_internal::_GLIBCXX_mutex);
- if (!_M_init_flag)
- {
- // Even though we have a global lock, we use __gthread_once to be
- // absolutely certain the _M_lock mutex is only initialized once on
- // multiprocessor systems.
- __gnu_internal::_GLIBCXX_mutex_address = &_M_lock;
- if (__gthread_once(&_M_once,
- __gnu_internal::_GLIBCXX_mutex_address_init) != 0
- && __gthread_active_p())
- abort();
- _M_init_flag = 1;
- }
- __gthread_mutex_unlock(&__gnu_internal::_GLIBCXX_mutex);
-#endif
- }
-
- void
- _M_acquire_lock()
- {
-#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- if (!_M_init_flag) _M_initialize();
-#endif
- __gthread_mutex_lock(&_M_lock);
- }
-
- void
- _M_release_lock()
- {
-#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- if (!_M_init_flag) _M_initialize();
-#endif
- __gthread_mutex_unlock(&_M_lock);
- }
- };
-
-#ifdef __GTHREAD_MUTEX_INIT
-#define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT }
-#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
-#ifdef __GTHREAD_MUTEX_INIT_DEFAULT
-#define __STL_MUTEX_INITIALIZER \
- = { 0, __GTHREAD_ONCE_INIT, __GTHREAD_MUTEX_INIT_DEFAULT }
-#else
-#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT }
-#endif
-#endif
-} // namespace __gnu_cxx
-
-#endif
#include <bits/c++config.h>
#include <new>
#include <bits/functexcept.h>
-#include <bits/stl_threads.h>
#include <bits/atomicity.h>
+#include <bits/concurrence.h>
namespace __gnu_cxx
{
enum { _S_max_bytes = 128 };
enum { _S_free_list_size = _S_max_bytes / _S_align };
- // It would be nice to use _STL_auto_lock here. But we need a
- // test whether threads are in use.
- struct _Lock
- {
- static _STL_mutex_lock _S_lock;
- _Lock() { _S_lock._M_acquire_lock(); }
- ~_Lock() { _S_lock._M_release_lock(); }
- };
-
union _Obj
{
union _Obj* _M_free_list_link;
};
static _Obj* volatile _S_free_list[_S_free_list_size];
-
+
// Chunk allocation state.
static char* _S_start_free;
static char* _S_end_free;
_Obj* volatile*
_M_get_free_list(size_t __bytes);
+ __gthread_mutex_t&
+ _M_get_mutex();
+
// Returns an object of size __n, and optionally adds to size __n
// free list.
void*
{
_Obj* volatile* __free_list = _M_get_free_list(__bytes);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
+ lock sentry(_M_get_mutex());
_Obj* __restrict__ __result = *__free_list;
if (__builtin_expect(__result == 0, 0))
__ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes)));
_Obj* volatile* __free_list = _M_get_free_list(__bytes);
_Obj* __q = reinterpret_cast<_Obj*>(__p);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
+ lock sentry(_M_get_mutex());
__q ->_M_free_list_link = *__free_list;
*__free_list = __q;
}
// ISO C++ 14882:
//
-#include <bits/c++config.h>
#include <memory>
+#include <ext/mt_allocator.h>
+#include <ext/pool_allocator.h>
namespace std
{
template class allocator<char>;
template class allocator<wchar_t>;
} // namespace std
+
+namespace __gnu_cxx
+{
+ template class __mt_alloc<char>;
+ template class __mt_alloc<wchar_t>;
+
+ template class __pool_alloc<char>;
+ template class __pool_alloc<wchar_t>;
+} // namespace __gnu_cxx
#include <ext/mt_allocator.h>
#include <ext/pool_allocator.h>
-namespace __gnu_cxx
+namespace __gnu_internal
{
- // Instantiations for __mt_alloc.
- template class __mt_alloc<char>;
- template class __mt_alloc<wchar_t>;
+ __glibcxx_mutex_define_initialized(palloc_init_mutex);
+}
- // Definitions and instantiations for __pool_alloc and base class.
+namespace __gnu_cxx
+{
+ // Definitions for __pool_alloc_base.
__pool_base::_Obj* volatile*
__pool_base::_M_get_free_list(size_t __bytes)
{
size_t __i = ((__bytes + (size_t)_S_align - 1) / (size_t)_S_align - 1);
- return _S_free_list + __i - 1;
+ return _S_free_list + __i;
}
+ __gthread_mutex_t&
+ __pool_base::_M_get_mutex()
+ { return __gnu_internal::palloc_init_mutex; }
+
// Allocate memory in large chunks in order to avoid fragmenting the
// heap too much. Assume that __n is properly aligned. We hold the
// allocation lock.
_S_start_free = static_cast<char*>(::operator new(__bytes_to_get));
if (_S_start_free == 0)
{
- size_t __i;
- _Obj* volatile* __free_list;
- _Obj* __p;
-
// Try to make do with what we have. That can't hurt. We
// do not try smaller requests, since that tends to result
// in disaster on multi-process machines.
- __i = __n;
+ size_t __i = __n;
for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
{
- __free_list = _M_get_free_list(__i);
- __p = *__free_list;
+ _Obj* volatile* __free_list = _M_get_free_list(__i);
+ _Obj* __p = *__free_list;
if (__p != 0)
{
- *__free_list = __p -> _M_free_list_link;
+ *__free_list = __p->_M_free_list_link;
_S_start_free = (char*)__p;
_S_end_free = _S_start_free + __i;
return _M_allocate_chunk(__n, __nobjs);
}
}
_S_end_free = 0; // In case of exception.
- _S_start_free = static_cast<char*>(::operator new(__bytes_to_get));
+
// This should either throw an exception or remedy the situation.
// Thus we assume it succeeded.
+ _S_start_free = static_cast<char*>(::operator new(__bytes_to_get));
}
_S_heap_size += __bytes_to_get;
_S_end_free = _S_start_free + __bytes_to_get;
_Obj* __result;
_Obj* __current_obj;
_Obj* __next_obj;
- int __i;
- if (1 == __nobjs)
+ if (__nobjs == 1)
return __chunk;
__free_list = _M_get_free_list(__n);
// Build free list in chunk.
__result = (_Obj*)(void*)__chunk;
*__free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
- for (__i = 1; ; __i++)
+ for (int __i = 1; ; __i++)
{
__current_obj = __next_obj;
__next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
if (__nobjs - 1 == __i)
{
- __current_obj -> _M_free_list_link = 0;
+ __current_obj->_M_free_list_link = 0;
break;
}
else
- __current_obj -> _M_free_list_link = __next_obj;
+ __current_obj->_M_free_list_link = __next_obj;
}
return __result;
}
char* __pool_base::_S_end_free = 0;
size_t __pool_base::_S_heap_size = 0;
-
- _STL_mutex_lock __pool_base::_Lock::_S_lock __STL_MUTEX_INITIALIZER;
-
- template class __pool_alloc<char>;
- template class __pool_alloc<wchar_t>;
} // namespace __gnu_cxx
locale::locale() throw() : _M_impl(0)
{
- _S_initialize();
- __glibcxx_mutex_lock(__gnu_internal::locale_cons_mutex);
+ _S_initialize();
+ __gnu_cxx::lock sentry(__gnu_internal::locale_cons_mutex);
_S_global->_M_add_reference();
_M_impl = _S_global;
- __glibcxx_mutex_unlock(__gnu_internal::locale_cons_mutex);
}
locale
locale::global(const locale& __other)
{
_S_initialize();
- __glibcxx_mutex_lock(__gnu_internal::locale_global_mutex);
- _Impl* __old = _S_global;
- __other._M_impl->_M_add_reference();
- _S_global = __other._M_impl;
- const string __other_name = __other.name();
- if (__other_name != "*")
- setlocale(LC_ALL, __other_name.c_str());
- __glibcxx_mutex_unlock(__gnu_internal::locale_global_mutex);
+ _Impl* __old;
+ {
+ __gnu_cxx::lock sentry(__gnu_internal::locale_global_mutex);
+ __old = _S_global;
+ __other._M_impl->_M_add_reference();
+ _S_global = __other._M_impl;
+ const string __other_name = __other.name();
+ if (__other_name != "*")
+ setlocale(LC_ALL, __other_name.c_str());
+ }
// Reference count sanity check: one reference removed for the
// subsition of __other locale, one added by return-by-value. Net