This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Saner ;) per_type defaults


Hi everyone, hi Benjamin,

seriously, some time ago I noticed the below problem, easy to reproduce:
if we keep the size of the chunk fixed and scale only max_bytes, it can
easily happen that the allocator decide to take charge of the allocation
(i.e., not passed down to new) but cannot really fulfill it. The easiest
fix seems to me just scaling with sizeof the size of the chunk too (as
default, of course, other settings may be more suited in specific
circumstances).

Took also the occasion to wrap a bit ;)

Ok with you?

Tested x86-linux, also checked with the default allocator changed to
per_type.

Paolo.

////////////////
2005-01-26  Paolo Carlini  <pcarlini@suse.de>

	* include/ext/mt_allocator.h
	(struct __per_type_pool_policy<,, false>::_S_get_pool,
	struct __per_type_pool_policy<,, true>::_S_get_pool): Scale
	_M_chunk_size too with sizeof(_Tp), otherwise the allocator
	breaks down as soon as sizeof(_Tp) >~ _S_chunk_size / 128;
	reduce to 64 the multiplier for _M_max_bytes (safer wrt
	_Binmap_type being a short); trivial reformattings.
diff -urN libstdc++-v3-orig/include/ext/mt_allocator.h libstdc++-v3/include/ext/mt_allocator.h
--- libstdc++-v3-orig/include/ext/mt_allocator.h	2004-11-24 05:11:13.000000000 +0100
+++ libstdc++-v3/include/ext/mt_allocator.h	2005-01-26 16:04:05.000000000 +0100
@@ -1,6 +1,6 @@
 // MT-optimized allocator -*- C++ -*-
 
-// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004, 2005 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
@@ -494,14 +494,25 @@
       _S_get_pool()
       { 
 	// Sane defaults for the _PoolTp.
-	const static size_t __align = __alignof__(_Tp) >= sizeof(typename pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename pool_type::_Block_record);
-	static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_base::_Tune::_S_chunk_size, __pool_base::_Tune::_S_max_threads, __pool_base::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false);
+	typedef typename pool_type::_Block_record _Block_record;
+	const static size_t __align = (__alignof__(_Tp) >= sizeof(_Block_record)
+				       ? __alignof__(_Tp)
+				       : sizeof(_Block_record));
+
+	typedef typename __pool_base::_Tune _Tune;
+	static _Tune _S_tune(__align, sizeof(_Tp) * 64,
+			     sizeof(_Tp) * 2 >= __align ? sizeof(_Tp) * 2
+			                                : __align,
+			     sizeof(_Tp) * _Tune::_S_chunk_size,
+			     _Tune::_S_max_threads,
+			     _Tune::_S_freelist_headroom,
+			     getenv("GLIBCXX_FORCE_NEW") ? true : false);
 	static pool_type _S_pool(_S_tune);
 	return _S_pool;
       }
 
       static void
-      _S_initialize_once() 
+      _S_initialize_once()
       { 
 	static bool __init;
 	if (__builtin_expect(__init == false, false))
@@ -529,14 +540,25 @@
       _S_get_pool()
       { 
 	// Sane defaults for the _PoolTp.
-	const static size_t __align = __alignof__(_Tp) >= sizeof(typename pool_type::_Block_record) ? __alignof__(_Tp) : sizeof(typename pool_type::_Block_record);
-	static __pool_base::_Tune _S_tune(__align, sizeof(_Tp) * 128, (sizeof(_Tp) * 2) >= __align ? sizeof(_Tp) * 2 : __align, __pool_base::_Tune::_S_chunk_size, __pool_base::_Tune::_S_max_threads, __pool_base::_Tune::_S_freelist_headroom, getenv("GLIBCXX_FORCE_NEW") ? true : false);
+	typedef typename pool_type::_Block_record _Block_record;
+	const static size_t __align = (__alignof__(_Tp) >= sizeof(_Block_record)
+				       ? __alignof__(_Tp)
+				       : sizeof(_Block_record));
+
+	typedef typename __pool_base::_Tune _Tune;
+	static _Tune _S_tune(__align, sizeof(_Tp) * 64,
+			     sizeof(_Tp) * 2 >= __align ? sizeof(_Tp) * 2
+                                                        : __align,
+			     sizeof(_Tp) * _Tune::_S_chunk_size,
+			     _Tune::_S_max_threads,
+			     _Tune::_S_freelist_headroom,
+			     getenv("GLIBCXX_FORCE_NEW") ? true : false);
 	static pool_type _S_pool(_S_tune);
 	return _S_pool;
       }
 
       static void
-      _S_initialize_once() 
+      _S_initialize_once()
       { 
 	static bool __init;
 	if (__builtin_expect(__init == false, false))
diff -urN libstdc++-v3-orig/testsuite/ext/mt_allocator/check_allocate_big_per_type.cc libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_big_per_type.cc
--- libstdc++-v3-orig/testsuite/ext/mt_allocator/check_allocate_big_per_type.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_big_per_type.cc	2005-01-26 16:05:31.000000000 +0100
@@ -0,0 +1,55 @@
+// 2005-01-26  Paolo Carlini  <pcarlini@suse.de>
+//
+// Copyright (C) 2005 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.
+
+#include <memory>
+#include <ext/mt_allocator.h>
+#include <cstring>
+#include <testsuite_hooks.h>
+
+struct big { char array[256]; };
+
+// __per_type_pool_policy
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef big value_type;
+
+  using __gnu_cxx::__pool;
+  using __gnu_cxx::__per_type_pool_policy;
+
+#ifdef __GTHREADS
+  typedef __per_type_pool_policy<value_type, __pool, true> policy_type;
+#else
+  typedef __per_type_pool_policy<value_type, __pool, false> policy_type;
+#endif
+  typedef __gnu_cxx::__mt_alloc<value_type, policy_type> allocator_type;
+
+  allocator_type a;
+  allocator_type::pointer p1 = a.allocate(64);
+  std::memset((void*)p1, 0, sizeof(big) * 64);
+  a.deallocate(p1, 64);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]