mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			PR libstdc++/70940 make pmr::resource_adaptor return aligned memory
PR libstdc++/70940 * include/experimental/memory_resource (__resource_adaptor_imp::do_deallocate): Add missing return. * testsuite/experimental/memory_resource/new_delete_resource.cc: New. * testsuite/experimental/memory_resource/resource_adaptor.cc: Test resource_adaptor with std::allocator, __gnu_cxx::new_allocator and __gnu_cxx::malloc_allocator. From-SVN: r261851
This commit is contained in:
		
							parent
							
								
									7956c508dd
								
							
						
					
					
						commit
						e9df6a8f03
					
				|  | @ -1,5 +1,13 @@ | |||
| 2018-06-21  Jonathan Wakely  <jwakely@redhat.com> | ||||
| 
 | ||||
| 	PR libstdc++/70940 | ||||
| 	* include/experimental/memory_resource | ||||
| 	(__resource_adaptor_imp::do_deallocate): Add missing return. | ||||
| 	* testsuite/experimental/memory_resource/new_delete_resource.cc: New. | ||||
| 	* testsuite/experimental/memory_resource/resource_adaptor.cc: Test | ||||
| 	resource_adaptor with std::allocator, __gnu_cxx::new_allocator and | ||||
| 	__gnu_cxx::malloc_allocator. | ||||
| 
 | ||||
| 	PR libstdc++/70940 | ||||
| 	* include/experimental/memory_resource (__resource_adaptor_common): | ||||
| 	New base class. | ||||
|  |  | |||
|  | @ -408,7 +408,10 @@ namespace pmr { | |||
|       { | ||||
| 	auto __ptr = static_cast<char*>(__p); | ||||
| 	if (__alignment == 1) | ||||
| 	  _M_alloc.deallocate(__ptr, __bytes); | ||||
| 	  { | ||||
| 	    _M_alloc.deallocate(__ptr, __bytes); | ||||
| 	    return; | ||||
| 	  } | ||||
| 
 | ||||
| 	const _AlignMgr __mgr(__bytes, __alignment); | ||||
| 	// Use the stored token to retrieve the original pointer to deallocate. | ||||
|  |  | |||
|  | @ -0,0 +1,132 @@ | |||
| // Copyright (C) 2018 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 3, 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 COPYING3.  If not see
 | ||||
| // <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| // { dg-do run { target c++14 } }
 | ||||
| 
 | ||||
| #include <experimental/memory_resource> | ||||
| #include <testsuite_hooks.h> | ||||
| 
 | ||||
| bool new_called = false; | ||||
| bool delete_called = false; | ||||
| 
 | ||||
| void* operator new(std::size_t n) | ||||
| { | ||||
|   new_called = true; | ||||
|   if (void* p = malloc(n)) | ||||
|     return p; | ||||
|   throw std::bad_alloc(); | ||||
| } | ||||
| 
 | ||||
| void operator delete(void* p) | ||||
| { | ||||
|   delete_called = true; | ||||
|   std::free(p); | ||||
| } | ||||
| 
 | ||||
| void operator delete(void* p, std::size_t) | ||||
| { | ||||
|   ::operator delete(p); | ||||
| } | ||||
| 
 | ||||
| template<std::size_t A> | ||||
|   bool aligned(void* p) | ||||
|   { | ||||
|     return (reinterpret_cast<std::uintptr_t>(p) % A) == 0; | ||||
|   } | ||||
| 
 | ||||
| template<typename T> | ||||
|   bool aligned(void* p) | ||||
|   { return aligned<alignof(T)>(p); } | ||||
| 
 | ||||
| // Extended alignments:
 | ||||
| constexpr std::size_t al6 = (1ul << 6), al12 = (1ul << 12), al18 = (1ul << 18); | ||||
| 
 | ||||
| using std::experimental::pmr::memory_resource; | ||||
| using std::experimental::pmr::new_delete_resource; | ||||
| 
 | ||||
| memory_resource* global = nullptr; | ||||
| 
 | ||||
| void | ||||
| test01() | ||||
| { | ||||
|   memory_resource* r1 = new_delete_resource(); | ||||
|   VERIFY( *r1 == *r1 ); | ||||
|   memory_resource* r2 = new_delete_resource(); | ||||
|   VERIFY( r1 == r2 ); | ||||
|   VERIFY( *r1 == *r2 ); | ||||
|   global = r1; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| test02() | ||||
| { | ||||
|   memory_resource* r1 = new_delete_resource(); | ||||
|   VERIFY( r1 == global ); | ||||
|   VERIFY( *r1 == *global ); | ||||
| 
 | ||||
|   new_called = false; | ||||
|   delete_called = false; | ||||
|   void* p = r1->allocate(1); | ||||
|   VERIFY( new_called ); | ||||
|   VERIFY( ! delete_called ); | ||||
| 
 | ||||
|   new_called = false; | ||||
|   r1->deallocate(p, 1); | ||||
|   VERIFY( ! new_called ); | ||||
|   VERIFY( delete_called ); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| test03() | ||||
| { | ||||
|   using std::max_align_t; | ||||
|   using std::size_t; | ||||
|   void* p = nullptr; | ||||
| 
 | ||||
|   memory_resource* r1 = new_delete_resource(); | ||||
|   p = r1->allocate(1); | ||||
|   VERIFY( aligned<max_align_t>(p) ); | ||||
|   r1->deallocate(p, 1); | ||||
|   p = r1->allocate(1, alignof(short)); | ||||
|   VERIFY( aligned<short>(p) ); | ||||
|   r1->deallocate(p, 1, alignof(short)); | ||||
|   p = r1->allocate(1, alignof(long)); | ||||
|   VERIFY( aligned<long>(p) ); | ||||
|   r1->deallocate(p, 1, alignof(long)); | ||||
|   constexpr size_t big_al = alignof(max_align_t) * 8; | ||||
|   p = r1->allocate(1, big_al); | ||||
|   VERIFY( aligned<big_al>(p) ); | ||||
|   r1->deallocate(p, 1, big_al); | ||||
| 
 | ||||
|   // Test extended alignments
 | ||||
|   p = r1->allocate(1024, al6); | ||||
|   VERIFY( aligned<al6>(p) ); | ||||
|   r1->deallocate(p, 1024, al6); | ||||
|   p = r1->allocate(1024, al12); | ||||
|   VERIFY( aligned<al12>(p) ); | ||||
|   r1->deallocate(p, 1024, al12); | ||||
|   p = r1->allocate(1024, al18); | ||||
|   VERIFY( aligned<al18>(p) ); | ||||
|   r1->deallocate(p, 1024, al18); | ||||
| } | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|   test01(); | ||||
|   test02(); | ||||
|   test03(); | ||||
| } | ||||
|  | @ -20,6 +20,8 @@ | |||
| 
 | ||||
| #include <experimental/memory_resource> | ||||
| #include <ext/debug_allocator.h> | ||||
| #include <ext/new_allocator.h> | ||||
| #include <ext/malloc_allocator.h> | ||||
| #include <testsuite_hooks.h> | ||||
| #include <testsuite_allocator.h> | ||||
| 
 | ||||
|  | @ -91,8 +93,8 @@ test05() | |||
|   VERIFY( aligned<big_al>(p) ); | ||||
|   r3.deallocate(p, 1, big_al); | ||||
| 
 | ||||
|   __gnu_cxx::debug_allocator<std::allocator<short>> a5; | ||||
|   resource_adaptor<decltype(a5)> r5(a5), r6(a5); | ||||
|   __gnu_cxx::debug_allocator<std::allocator<short>> a5, a6; | ||||
|   resource_adaptor<decltype(a5)> r5(a5), r6(a6); | ||||
|   VERIFY( r5 == r5 ); | ||||
|   VERIFY( r5 == r6 ); | ||||
|   VERIFY( r5 != r1 ); | ||||
|  | @ -121,6 +123,99 @@ test05() | |||
|   p = r5.allocate(1024, al18); | ||||
|   VERIFY( aligned<al18>(p) ); | ||||
|   r5.deallocate(p, 1024, al18); | ||||
| 
 | ||||
|   __gnu_cxx::new_allocator<short> a7, a8; | ||||
|   resource_adaptor<decltype(a7)> r7(a7), r8(a8); | ||||
|   VERIFY( r7 == r7 ); | ||||
|   VERIFY( r7 == r8 ); | ||||
|   VERIFY( r7 != r1 ); | ||||
|   VERIFY( r7 != r3 ); | ||||
|   VERIFY( r7 != r5 ); | ||||
|   p = r7.allocate(1); | ||||
|   VERIFY( aligned<max_align_t>(p) ); | ||||
|   r7.deallocate(p, 1); | ||||
|   p = r7.allocate(1, alignof(short)); | ||||
|   VERIFY( aligned<short>(p) ); | ||||
|   r7.deallocate(p, 1, alignof(short)); | ||||
|   p = r7.allocate(1, alignof(long)); | ||||
|   VERIFY( aligned<long>(p) ); | ||||
|   r7.deallocate(p, 1, alignof(long)); | ||||
|   p = r7.allocate(1, big_al); | ||||
|   VERIFY( aligned<big_al>(p) ); | ||||
|   r7.deallocate(p, 1, big_al); | ||||
|   // Test extended alignments
 | ||||
|   p = r7.allocate(1024, al6); | ||||
|   VERIFY( aligned<al6>(p) ); | ||||
|   r7.deallocate(p, 1024, al6); | ||||
|   p = r7.allocate(1024, al12); | ||||
|   VERIFY( aligned<al12>(p) ); | ||||
|   r7.deallocate(p, 1024, al12); | ||||
|   p = r7.allocate(1024, al18); | ||||
|   VERIFY( aligned<al18>(p) ); | ||||
|   r7.deallocate(p, 1024, al18); | ||||
| 
 | ||||
|   __gnu_cxx::malloc_allocator<short> a9, a10; | ||||
|   resource_adaptor<decltype(a9)> r9(a9), r10(a10); | ||||
|   VERIFY( r9 == r9 ); | ||||
|   VERIFY( r9 == r10 ); | ||||
|   VERIFY( r9 != r1 ); | ||||
|   VERIFY( r9 != r3 ); | ||||
|   VERIFY( r9 != r5 ); | ||||
|   VERIFY( r9 != r7 ); | ||||
|   p = r9.allocate(1); | ||||
|   VERIFY( aligned<max_align_t>(p) ); | ||||
|   r9.deallocate(p, 1); | ||||
|   p = r9.allocate(1, alignof(short)); | ||||
|   VERIFY( aligned<short>(p) ); | ||||
|   r9.deallocate(p, 1, alignof(short)); | ||||
|   p = r9.allocate(1, alignof(long)); | ||||
|   VERIFY( aligned<long>(p) ); | ||||
|   r9.deallocate(p, 1, alignof(long)); | ||||
|   p = r9.allocate(1, big_al); | ||||
|   VERIFY( aligned<big_al>(p) ); | ||||
|   r9.deallocate(p, 1, big_al); | ||||
|   // Test extended alignments
 | ||||
|   p = r9.allocate(1024, al6); | ||||
|   VERIFY( aligned<al6>(p) ); | ||||
|   r9.deallocate(p, 1024, al6); | ||||
|   p = r9.allocate(1024, al12); | ||||
|   VERIFY( aligned<al12>(p) ); | ||||
|   r9.deallocate(p, 1024, al12); | ||||
|   p = r9.allocate(1024, al18); | ||||
|   VERIFY( aligned<al18>(p) ); | ||||
|   r9.deallocate(p, 1024, al18); | ||||
| 
 | ||||
|   std::allocator<short> a11, a12; | ||||
|   resource_adaptor<decltype(a11)> r11(a11), r12(a12); | ||||
|   VERIFY( r11 == r11 ); | ||||
|   VERIFY( r11 == r12 ); | ||||
|   VERIFY( r11 != r1 ); | ||||
|   VERIFY( r11 != r3 ); | ||||
|   VERIFY( r11 != r5 ); | ||||
|   VERIFY( r11 != r7 ); | ||||
|   VERIFY( r11 != r9 ); | ||||
|   p = r11.allocate(1); | ||||
|   VERIFY( aligned<max_align_t>(p) ); | ||||
|   r11.deallocate(p, 1); | ||||
|   p = r11.allocate(1, alignof(short)); | ||||
|   VERIFY( aligned<short>(p) ); | ||||
|   r11.deallocate(p, 1, alignof(short)); | ||||
|   p = r11.allocate(1, alignof(long)); | ||||
|   VERIFY( aligned<long>(p) ); | ||||
|   r11.deallocate(p, 1, alignof(long)); | ||||
|   p = r11.allocate(1, big_al); | ||||
|   VERIFY( aligned<big_al>(p) ); | ||||
|   r11.deallocate(p, 1, big_al); | ||||
|   // Test extended alignments
 | ||||
|   p = r11.allocate(1024, al6); | ||||
|   VERIFY( aligned<al6>(p) ); | ||||
|   r11.deallocate(p, 1024, al6); | ||||
|   p = r11.allocate(1024, al12); | ||||
|   VERIFY( aligned<al12>(p) ); | ||||
|   r11.deallocate(p, 1024, al12); | ||||
|   p = r11.allocate(1024, al18); | ||||
|   VERIFY( aligned<al18>(p) ); | ||||
|   r11.deallocate(p, 1024, al18); | ||||
| } | ||||
| 
 | ||||
| int main() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Jonathan Wakely
						Jonathan Wakely