Licensing changes to GPLv3 resp. GPLv3 with GCC Runtime Exception.
[gcc.git] / libstdc++-v3 / include / ext / mt_allocator.h
index 07de3eddea2a5ab0b6a97e76b0066a985d8d9448..f03f3a61030cb2113c996905ac9392ac32596c67 100644 (file)
@@ -1,11 +1,12 @@
 // MT-optimized allocator -*- C++ -*-
 
-// Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// 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)
+// Free Software Foundation; either version 3, or (at your option)
 // any later version.
 
 // This library is distributed in the hope that it will be useful,
 // 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-// 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.
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
 
 /** @file ext/mt_allocator.h
  *  This file is a GNU extension to the Standard C++ Library.
@@ -37,8 +33,8 @@
 #include <new>
 #include <cstdlib>
 #include <bits/functexcept.h>
-#include <bits/gthr.h>
-#include <bits/atomicity.h>
+#include <ext/atomicity.h>
+#include <bits/move.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 
@@ -47,11 +43,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 
   typedef void (*__destroy_handler)(void*);
 
-  /// @brief  Base class for pool object.
+  /// Base class for pool object.
   struct __pool_base
   {
     // Using short int as type for the binmap implies we are never
-    // caching blocks larger than 65535 with this allocator.
+    // caching blocks larger than 32768 with this allocator.
     typedef unsigned short int _Binmap_type;
 
     // Variables used to configure the behavior of the allocator,
@@ -74,19 +70,23 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       // Allocation requests (after round-up to power of 2) below
       // this value will be handled by the allocator. A raw new/
       // call will be used for requests larger than this value.
+      // NB: Must be much smaller than _M_chunk_size and in any
+      // case <= 32768.
       size_t   _M_max_bytes; 
-      
+
       // Size in bytes of the smallest bin.
-      // NB: Must be a power of 2 and >= _M_align.
+      // NB: Must be a power of 2 and >= _M_align (and of course
+      // much smaller than _M_max_bytes).
       size_t   _M_min_bin;
-      
+
       // In order to avoid fragmenting and minimize the number of
       // new() calls we always request new memory using this
       // value. Based on previous discussions on the libstdc++
-      // mailing list we have choosen the value below.
+      // mailing list we have chosen the value below.
       // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
+      // NB: At least one order of magnitude > _M_max_bytes. 
       size_t   _M_chunk_size;
-      
+
       // The maximum number of supported threads. For
       // single-threaded operation, use one. Maximum values will
       // vary depending on details of the underlying system. (For
@@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports
       // 65534)
       size_t   _M_max_threads;
-      
+
       // Each time a deallocation occurs in a threaded application
       // we make sure that there are no more than
       // _M_freelist_headroom % of used memory on the freelist. If
@@ -148,7 +148,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     _M_get_binmap(size_t __bytes)
     { return _M_binmap[__bytes]; }
 
-    const size_t
+    size_t
     _M_get_align()
     { return _M_options._M_align; }
 
@@ -195,13 +195,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       union _Block_record
       {
        // Points to the block_record of the next free block.
-       _Block_record* volatile         _M_next;
+       _Block_record*                  _M_next;
       };
 
       struct _Bin_record
       {
        // An "array" of pointers to the first free block.
-       _Block_record** volatile        _M_first;
+       _Block_record**                 _M_first;
 
        // A list of the initial addresses of all allocated blocks.
        _Block_address*                 _M_address;
@@ -244,7 +244,7 @@ _GLIBCXX_BEGIN_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
       // _M_initialize().
-      _Bin_record* volatile    _M_bin;
+      _Bin_record*              _M_bin;
       
       // Actual value calculated in _M_initialize().
       size_t                   _M_bin_size;     
@@ -271,7 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       struct _Thread_record
       {
        // Points to next free thread id record. NULL if last record in list.
-       _Thread_record* volatile        _M_next;
+       _Thread_record*                 _M_next;
        
        // Thread id ranging from 1 to _S_max_threads.
        size_t                          _M_id;
@@ -280,7 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       union _Block_record
       {
        // Points to the block_record of the next free block.
-       _Block_record* volatile         _M_next;
+       _Block_record*                  _M_next;
        
        // The thread id of the thread which has requested this block.
        size_t                          _M_thread_id;
@@ -291,17 +291,22 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
        // An "array" of pointers to the first free block for each
        // thread id. Memory to this "array" is allocated in
        // _S_initialize() for _S_max_threads + global pool 0.
-       _Block_record** volatile        _M_first;
+       _Block_record**                 _M_first;
        
        // A list of the initial addresses of all allocated blocks.
        _Block_address*                 _M_address;
 
        // An "array" of counters used to keep track of the amount of
        // blocks that are on the freelist/used for each thread id.
-       // Memory to these "arrays" is allocated in _S_initialize() for
-       // _S_max_threads + global pool 0.
-       size_t* volatile                _M_free;
-       size_t* volatile                _M_used;
+       // - Note that the second part of the allocated _M_used "array"
+       //   actually hosts (atomic) counters of reclaimed blocks:  in
+       //   _M_reserve_block and in _M_reclaim_block those numbers are
+       //   subtracted from the first ones to obtain the actual size
+       //   of the "working set" of the given thread.
+       // - Memory to these "arrays" is allocated in _S_initialize()
+       //   for _S_max_threads + global pool 0.
+       size_t*                         _M_free;
+       size_t*                         _M_used;
        
        // Each bin has its own mutex which is used to ensure data
        // integrity while changing "ownership" on a block.  The mutex
@@ -365,7 +370,7 @@ _GLIBCXX_BEGIN_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
       // _M_initialize().
-      _Bin_record* volatile    _M_bin;
+      _Bin_record*             _M_bin;
 
       // Actual value calculated in _M_initialize().
       size_t                   _M_bin_size;
@@ -446,7 +451,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     };
 #endif
 
-  /// @brief  Policy for shared __pool objects.
+  /// Policy for shared __pool objects.
   template<template <bool> class _PoolTp, bool _Thread>
     struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread>
     {
@@ -541,7 +546,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     };
 #endif
 
-  /// @brief  Policy for individual __pool objects.
+  /// Policy for individual __pool objects.
   template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
     struct __per_type_pool_policy 
     : public __per_type_pool_base<_Tp, _PoolTp, _Thread>
@@ -556,7 +561,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
   };
 
 
-  /// @brief  Base class for _Tp dependent member functions.
+  /// Base class for _Tp dependent member functions.
   template<typename _Tp>
     class __mt_alloc_base 
     {
@@ -585,7 +590,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       // 402. wrong new expression in [some_] allocator::construct
       void 
       construct(pointer __p, const _Tp& __val) 
-      { ::new(__p) _Tp(__val); }
+      { ::new((void *)__p) _Tp(__val); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      template<typename... _Args>
+        void
+        construct(pointer __p, _Args&&... __args)
+       { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); }
+#endif
 
       void 
       destroy(pointer __p) { __p->~_Tp(); }
@@ -603,9 +615,10 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
    *  size per thread plus a "global" one. Steps are taken to limit
    *  the per thread freelist sizes (by returning excess back to
    *  the "global" list).
+   *  @ingroup allocators
    *
    *  Further details:
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html
+   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch32.html
    */
   template<typename _Tp, 
           typename _Poolp = __common_pool_policy<__pool, __thread_default> >