aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2018-06-21 17:24:00 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2018-06-21 17:24:00 +0100
commite9df6a8f03d5c6422350865a374e5f5b948c05ed (patch)
tree6ae33deaf8e4e7a756d753319c1e7ec4190f3031
parent7956c508ddf36901d06bdb3f5a1ae099ee656924 (diff)
downloadgcc-e9df6a8f03d5c6422350865a374e5f5b948c05ed.zip
gcc-e9df6a8f03d5c6422350865a374e5f5b948c05ed.tar.gz
gcc-e9df6a8f03d5c6422350865a374e5f5b948c05ed.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/experimental/memory_resource5
-rw-r--r--libstdc++-v3/testsuite/experimental/memory_resource/new_delete_resource.cc132
-rw-r--r--libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc99
4 files changed, 241 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 699ec13..6b9690c 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,6 +1,14 @@
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.
(__resource_adaptor_common::_AlignMgr): Helper for obtaining aligned
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 3d2dce1..8f5a8df 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -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.
diff --git a/libstdc++-v3/testsuite/experimental/memory_resource/new_delete_resource.cc b/libstdc++-v3/testsuite/experimental/memory_resource/new_delete_resource.cc
new file mode 100644
index 0000000..692e520
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/new_delete_resource.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc
index 4e39e77..46cb113 100644
--- a/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc
@@ -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()