]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - libstdc++-v3/include/bits/pthread_allocimpl.h
Imported gcc-4.4.3
[msp430-gcc.git] / libstdc++-v3 / include / bits / pthread_allocimpl.h
diff --git a/libstdc++-v3/include/bits/pthread_allocimpl.h b/libstdc++-v3/include/bits/pthread_allocimpl.h
deleted file mode 100644 (file)
index 050b206..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-// POSIX thread-related memory allocation -*- C++ -*-
-
-// Copyright (C) 2001 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) 1996
- * 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 pthread_allocimpl.h
- *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
- */
-
-#ifndef _CPP_BITS_PTHREAD_ALLOCIMPL_H
-#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1
-
-// Pthread-specific node allocator.
-// This is similar to the default allocator, except that free-list
-// information is kept separately for each thread, avoiding locking.
-// This should be reasonably fast even in the presence of threads.
-// The down side is that storage may not be well-utilized.
-// It is not an error to allocate memory in thread A and deallocate
-// it in thread B.  But this effectively transfers ownership of the memory,
-// so that it can only be reallocated by thread B.  Thus this can effectively
-// result in a storage leak if it's done on a regular basis.
-// It can also result in frequent sharing of
-// cache lines among processors, with potentially serious performance
-// consequences.
-
-#include <bits/c++config.h>
-#include <cerrno>
-#include <bits/stl_alloc.h>
-#ifndef __RESTRICT
-#  define __RESTRICT
-#endif
-
-#include <new>
-
-namespace std
-{
-
-#define __STL_DATA_ALIGNMENT 8
-
-union _Pthread_alloc_obj {
-    union _Pthread_alloc_obj * __free_list_link;
-    char __client_data[__STL_DATA_ALIGNMENT];    /* The client sees this.    */
-};
-
-// Pthread allocators don't appear to the client to have meaningful
-// instances.  We do in fact need to associate some state with each
-// thread.  That state is represented by
-// _Pthread_alloc_per_thread_state<_Max_size>.
-
-template<size_t _Max_size>
-struct _Pthread_alloc_per_thread_state {
-  typedef _Pthread_alloc_obj __obj;
-  enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT };
-  _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; 
-  _Pthread_alloc_per_thread_state<_Max_size> * __next; 
-       // Free list link for list of available per thread structures.
-       // When one of these becomes available for reuse due to thread
-       // termination, any objects in its free list remain associated
-       // with it.  The whole structure may then be used by a newly
-       // created thread.
-  _Pthread_alloc_per_thread_state() : __next(0)
-  {
-    memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *));
-  }
-  // Returns an object of size __n, and possibly adds to size n free list.
-  void *_M_refill(size_t __n);
-};
-
-// Pthread-specific allocator.
-// The argument specifies the largest object size allocated from per-thread
-// free lists.  Larger objects are allocated using malloc_alloc.
-// Max_size must be a power of 2.
-template <size_t _Max_size = 128>
-class _Pthread_alloc_template {
-
-public: // but only for internal use:
-
-  typedef _Pthread_alloc_obj __obj;
-
-  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-  // if it is inconvenient to allocate the requested number.
-  static char *_S_chunk_alloc(size_t __size, int &__nobjs);
-
-  enum {_S_ALIGN = __STL_DATA_ALIGNMENT};
-
-  static size_t _S_round_up(size_t __bytes) {
-    return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1));
-  }
-  static size_t _S_freelist_index(size_t __bytes) {
-    return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1);
-  }
-
-private:
-  // Chunk allocation state. And other shared state.
-  // Protected by _S_chunk_allocator_lock.
-  static pthread_mutex_t _S_chunk_allocator_lock;
-  static char *_S_start_free;
-  static char *_S_end_free;
-  static size_t _S_heap_size;
-  static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states;
-  static pthread_key_t _S_key;
-  static bool _S_key_initialized;
-        // Pthread key under which per thread state is stored. 
-        // Allocator instances that are currently unclaimed by any thread.
-  static void _S_destructor(void *instance);
-        // Function to be called on thread exit to reclaim per thread
-        // state.
-  static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state();
-        // Return a recycled or new per thread state.
-  static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state();
-        // ensure that the current thread has an associated
-        // per thread state.
-  class _M_lock;
-  friend class _M_lock;
-  class _M_lock {
-      public:
-        _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); }
-        ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); }
-  };
-
-public:
-
-  /* n must be > 0      */
-  static void * allocate(size_t __n)
-  {
-    __obj * volatile * __my_free_list;
-    __obj * __RESTRICT __result;
-    _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
-    if (__n > _Max_size) {
-        return(malloc_alloc::allocate(__n));
-    }
-    if (!_S_key_initialized ||
-        !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*)
-                                 pthread_getspecific(_S_key))) {
-        __a = _S_get_per_thread_state();
-    }
-    __my_free_list = __a -> __free_list + _S_freelist_index(__n);
-    __result = *__my_free_list;
-    if (__result == 0) {
-        void *__r = __a -> _M_refill(_S_round_up(__n));
-        return __r;
-    }
-    *__my_free_list = __result -> __free_list_link;
-    return (__result);
-  };
-
-  /* p may not be 0 */
-  static void deallocate(void *__p, size_t __n)
-  {
-    __obj *__q = (__obj *)__p;
-    __obj * volatile * __my_free_list;
-    _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
-    if (__n > _Max_size) {
-        malloc_alloc::deallocate(__p, __n);
-        return;
-    }
-    if (!_S_key_initialized ||
-        !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *)
-                pthread_getspecific(_S_key))) {
-        __a = _S_get_per_thread_state();
-    }
-    __my_free_list = __a->__free_list + _S_freelist_index(__n);
-    __q -> __free_list_link = *__my_free_list;
-    *__my_free_list = __q;
-  }
-
-  static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz);
-
-} ;
-
-typedef _Pthread_alloc_template<> pthread_alloc;
-
-
-template <size_t _Max_size>
-void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance)
-{
-    _M_lock __lock_instance;   // Need to acquire lock here.
-    _Pthread_alloc_per_thread_state<_Max_size>* __s =
-        (_Pthread_alloc_per_thread_state<_Max_size> *)__instance;
-    __s -> __next = _S_free_per_thread_states;
-    _S_free_per_thread_states = __s;
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state()
-{    
-    /* lock already held here. */
-    if (0 != _S_free_per_thread_states) {
-        _Pthread_alloc_per_thread_state<_Max_size> *__result =
-                                       _S_free_per_thread_states;
-        _S_free_per_thread_states = _S_free_per_thread_states -> __next;
-        return __result;
-    } else {
-        return new _Pthread_alloc_per_thread_state<_Max_size>;
-    }
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state()
-{
-    /*REFERENCED*/
-    _M_lock __lock_instance;   // Need to acquire lock here.
-    int __ret_code;
-    _Pthread_alloc_per_thread_state<_Max_size> * __result;
-    if (!_S_key_initialized) {
-        if (pthread_key_create(&_S_key, _S_destructor)) {
-           std::__throw_bad_alloc();  // defined in funcexcept.h
-        }
-        _S_key_initialized = true;
-    }
-    __result = _S_new_per_thread_state();
-    __ret_code = pthread_setspecific(_S_key, __result);
-    if (__ret_code) {
-      if (__ret_code == ENOMEM) {
-       std::__throw_bad_alloc();
-      } else {
-       // EINVAL
-       abort();
-      }
-    }
-    return __result;
-}
-
-/* We allocate memory in large chunks in order to avoid fragmenting     */
-/* the malloc heap too much.                                            */
-/* We assume that size is properly aligned.                             */
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_chunk_alloc(size_t __size, int &__nobjs)
-{
-  {
-    char * __result;
-    size_t __total_bytes;
-    size_t __bytes_left;
-    /*REFERENCED*/
-    _M_lock __lock_instance;         // Acquire lock for this routine
-
-    __total_bytes = __size * __nobjs;
-    __bytes_left = _S_end_free - _S_start_free;
-    if (__bytes_left >= __total_bytes) {
-        __result = _S_start_free;
-        _S_start_free += __total_bytes;
-        return(__result);
-    } else if (__bytes_left >= __size) {
-        __nobjs = __bytes_left/__size;
-        __total_bytes = __size * __nobjs;
-        __result = _S_start_free;
-        _S_start_free += __total_bytes;
-        return(__result);
-    } else {
-        size_t __bytes_to_get =
-               2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
-        // Try to make use of the left-over piece.
-        if (__bytes_left > 0) {
-            _Pthread_alloc_per_thread_state<_Max_size>* __a = 
-                (_Pthread_alloc_per_thread_state<_Max_size>*)
-                       pthread_getspecific(_S_key);
-            __obj * volatile * __my_free_list =
-                        __a->__free_list + _S_freelist_index(__bytes_left);
-
-            ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
-            *__my_free_list = (__obj *)_S_start_free;
-        }
-#       ifdef _SGI_SOURCE
-          // Try to get memory that's aligned on something like a
-          // cache line boundary, so as to avoid parceling out
-          // parts of the same line to different threads and thus
-          // possibly different processors.
-          {
-            const int __cache_line_size = 128;  // probable upper bound
-            __bytes_to_get &= ~(__cache_line_size-1);
-            _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); 
-            if (0 == _S_start_free) {
-              _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
-            }
-          }
-#       else  /* !SGI_SOURCE */
-          _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
-#       endif
-        _S_heap_size += __bytes_to_get;
-        _S_end_free = _S_start_free + __bytes_to_get;
-    }
-  }
-  // lock is released here
-  return(_S_chunk_alloc(__size, __nobjs));
-}
-
-
-/* Returns an object of size n, and optionally adds to size n free list.*/
-/* We assume that n is properly aligned.                                */
-/* We hold the allocation lock.                                         */
-template <size_t _Max_size>
-void *_Pthread_alloc_per_thread_state<_Max_size>
-::_M_refill(size_t __n)
-{
-    int __nobjs = 128;
-    char * __chunk =
-       _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs);
-    __obj * volatile * __my_free_list;
-    __obj * __result;
-    __obj * __current_obj, * __next_obj;
-    int __i;
-
-    if (1 == __nobjs)  {
-        return(__chunk);
-    }
-    __my_free_list = __free_list
-                + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n);
-
-    /* Build free list in chunk */
-      __result = (__obj *)__chunk;
-      *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
-      for (__i = 1; ; __i++) {
-        __current_obj = __next_obj;
-        __next_obj = (__obj *)((char *)__next_obj + __n);
-        if (__nobjs - 1 == __i) {
-            __current_obj -> __free_list_link = 0;
-            break;
-        } else {
-            __current_obj -> __free_list_link = __next_obj;
-        }
-      }
-    return(__result);
-}
-
-template <size_t _Max_size>
-void *_Pthread_alloc_template<_Max_size>
-::reallocate(void *__p, size_t __old_sz, size_t __new_sz)
-{
-    void * __result;
-    size_t __copy_sz;
-
-    if (__old_sz > _Max_size
-       && __new_sz > _Max_size) {
-        return(realloc(__p, __new_sz));
-    }
-    if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
-    __result = allocate(__new_sz);
-    __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
-    memcpy(__result, __p, __copy_sz);
-    deallocate(__p, __old_sz);
-    return(__result);
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0;
-
-template <size_t _Max_size>
-pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key;
-
-template <size_t _Max_size>
-bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false;
-
-template <size_t _Max_size>
-pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock
-= PTHREAD_MUTEX_INITIALIZER;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_start_free = 0;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_end_free = 0;
-
-template <size_t _Max_size>
-size_t _Pthread_alloc_template<_Max_size>
-::_S_heap_size = 0;
-
-
-template <class _Tp>
-class pthread_allocator {
-  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
-public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef _Tp*       pointer;
-  typedef const _Tp* const_pointer;
-  typedef _Tp&       reference;
-  typedef const _Tp& const_reference;
-  typedef _Tp        value_type;
-
-  template <class _NewType> struct rebind {
-    typedef pthread_allocator<_NewType> other;
-  };
-
-  pthread_allocator() throw() {}
-  pthread_allocator(const pthread_allocator& a) throw() {}
-  template <class _OtherType>
-       pthread_allocator(const pthread_allocator<_OtherType>&)
-               throw() {}
-  ~pthread_allocator() throw() {}
-
-  pointer address(reference __x) const { return &__x; }
-  const_pointer address(const_reference __x) const { return &__x; }
-
-  // __n is permitted to be 0.  The C++ standard says nothing about what
-  // the return value is when __n == 0.
-  _Tp* allocate(size_type __n, const void* = 0) {
-    return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp)))
-                    : 0;
-  }
-
-  // p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type __n)
-    { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
-  size_type max_size() const throw() 
-    { return size_t(-1) / sizeof(_Tp); }
-
-  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-  void destroy(pointer _p) { _p->~_Tp(); }
-};
-
-template<>
-class pthread_allocator<void> {
-public:
-  typedef size_t      size_type;
-  typedef ptrdiff_t   difference_type;
-  typedef void*       pointer;
-  typedef const void* const_pointer;
-  typedef void        value_type;
-
-  template <class _NewType> struct rebind {
-    typedef pthread_allocator<_NewType> other;
-  };
-};
-
-template <size_t _Max_size>
-inline bool operator==(const _Pthread_alloc_template<_Max_size>&,
-                       const _Pthread_alloc_template<_Max_size>&)
-{
-  return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator==(const pthread_allocator<_T1>&,
-                       const pthread_allocator<_T2>& a2) 
-{
-  return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator!=(const pthread_allocator<_T1>&,
-                       const pthread_allocator<_T2>&)
-{
-  return false;
-}
-
-template <class _Tp, size_t _Max_size>
-struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type;
-  typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > 
-          allocator_type;
-};
-
-template <class _Tp, class _Atype, size_t _Max>
-struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type;
-  typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type;
-};
-
-template <class _Tp, class _Atype>
-struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type;
-  typedef pthread_allocator<_Tp> allocator_type;
-};
-
-
-} // namespace std
-
-#endif /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */
-
-// Local Variables:
-// mode:C++
-// End: