concurrence.h (__gnu_cxx::lock): New.
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. From-SVN: r83638
This commit is contained in:
parent
ade83c33bd
commit
838d430929
@ -1,3 +1,20 @@
|
||||
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.
|
||||
|
@ -143,7 +143,6 @@ GLIBCXX_3.4 {
|
||||
_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*;
|
||||
@ -257,10 +256,10 @@ GLIBCXX_3.4.1 {
|
||||
|
||||
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.
|
||||
|
@ -145,7 +145,6 @@ bits_headers = \
|
||||
${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 \
|
||||
|
@ -357,7 +357,6 @@ bits_headers = \
|
||||
${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 \
|
||||
|
@ -94,8 +94,8 @@ namespace std
|
||||
|
||||
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() { }
|
||||
|
@ -62,4 +62,26 @@ __gthread_mutex_lock(&NAME)
|
||||
|
||||
#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
|
||||
|
@ -1,150 +0,0 @@
|
||||
// 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
|
@ -50,8 +50,8 @@
|
||||
#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
|
||||
{
|
||||
@ -80,15 +80,6 @@ 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;
|
||||
@ -96,7 +87,7 @@ namespace __gnu_cxx
|
||||
};
|
||||
|
||||
static _Obj* volatile _S_free_list[_S_free_list_size];
|
||||
|
||||
|
||||
// Chunk allocation state.
|
||||
static char* _S_start_free;
|
||||
static char* _S_end_free;
|
||||
@ -109,6 +100,9 @@ namespace __gnu_cxx
|
||||
_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*
|
||||
@ -216,10 +210,7 @@ namespace __gnu_cxx
|
||||
{
|
||||
_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)));
|
||||
@ -252,10 +243,7 @@ namespace __gnu_cxx
|
||||
_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;
|
||||
}
|
||||
|
@ -31,11 +31,21 @@
|
||||
// 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
|
||||
|
@ -36,20 +36,25 @@
|
||||
#include <ext/mt_allocator.h>
|
||||
#include <ext/pool_allocator.h>
|
||||
|
||||
namespace __gnu_internal
|
||||
{
|
||||
__glibcxx_mutex_define_initialized(palloc_init_mutex);
|
||||
}
|
||||
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
// Instantiations for __mt_alloc.
|
||||
template class __mt_alloc<char>;
|
||||
template class __mt_alloc<wchar_t>;
|
||||
|
||||
// Definitions and instantiations for __pool_alloc and base class.
|
||||
// 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.
|
||||
@ -89,21 +94,17 @@ namespace __gnu_cxx
|
||||
_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);
|
||||
@ -112,9 +113,10 @@ namespace __gnu_cxx
|
||||
}
|
||||
}
|
||||
_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;
|
||||
@ -134,26 +136,25 @@ namespace __gnu_cxx
|
||||
_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;
|
||||
}
|
||||
@ -165,9 +166,4 @@ namespace __gnu_cxx
|
||||
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
|
||||
|
@ -100,25 +100,26 @@ namespace std
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user