Commit d9cb3e75 by Jonathan Wakely Committed by Jonathan Wakely

libstdc++/70940 Start fixing polymorphic memory resources

	PR libstdc++/70940
	* include/experimental/memory_resource
	(__resource_adaptor_imp::do_allocate): Do not default-construct
	rebound allocator.
	(__resource_adaptor_imp::do_deallocate): Likewise. Use
	allocator_traits to get pointer type.
	(__null_memory_resource::do_allocate): Remove unused parameters.
	(__null_memory_resource::do_deallocate): Likewise.
	(__null_memory_resource::do_is_equal): Likewise. Add return statement.
	* testsuite/experimental/type_erased_allocator/1.cc: Combine with ...
	* testsuite/experimental/type_erased_allocator/1_neg.cc: This, and
	move to ...
	* testsuite/experimental/memory_resource/1.cc: Here.
	* testsuite/experimental/memory_resource/null_memory_resource.cc: New.
	* testsuite/experimental/memory_resource/resource_adaptor.cc: New.

From-SVN: r235868
parent da5b1ec1
2016-05-04 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/70940
* include/experimental/memory_resource
(__resource_adaptor_imp::do_allocate): Do not default-construct
rebound allocator.
(__resource_adaptor_imp::do_deallocate): Likewise. Use
allocator_traits to get pointer type.
(__null_memory_resource::do_allocate): Remove unused parameters.
(__null_memory_resource::do_deallocate): Likewise.
(__null_memory_resource::do_is_equal): Likewise. Add return statement.
* testsuite/experimental/type_erased_allocator/1.cc: Combine with ...
* testsuite/experimental/type_erased_allocator/1_neg.cc: This, and
move to ...
* testsuite/experimental/memory_resource/1.cc: Here.
* testsuite/experimental/memory_resource/null_memory_resource.cc: New.
* testsuite/experimental/memory_resource/resource_adaptor.cc: New.
2016-04-29 Chris Gregory <czipperz@gmail.com> 2016-04-29 Chris Gregory <czipperz@gmail.com>
* config/*: Remove trailing whitespace. * config/*: Remove trailing whitespace.
......
...@@ -282,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -282,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_t __new_size = _S_aligned_size(__bytes, size_t __new_size = _S_aligned_size(__bytes,
_S_supported(__alignment) ? _S_supported(__alignment) ?
__alignment : _S_max_align); __alignment : _S_max_align);
return _Aligned_alloc().allocate(__new_size); return _Aligned_alloc(_M_alloc).allocate(__new_size);
} }
virtual void virtual void
...@@ -292,8 +292,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -292,8 +292,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_t __new_size = _S_aligned_size(__bytes, size_t __new_size = _S_aligned_size(__bytes,
_S_supported(__alignment) ? _S_supported(__alignment) ?
__alignment : _S_max_align); __alignment : _S_max_align);
_Aligned_alloc().deallocate(static_cast<typename using _Ptr = typename allocator_traits<_Aligned_alloc>::pointer;
_Aligned_alloc::pointer>(__p), _Aligned_alloc(_M_alloc).deallocate(static_cast<_Ptr>(__p),
__new_size); __new_size);
} }
...@@ -306,8 +306,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -306,8 +306,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private: private:
// Calculate Aligned Size // Calculate Aligned Size
// Returns a size that is larger than or equal to __size and divided by // Returns a size that is larger than or equal to __size and divisible
// __alignment, where __alignment is required to be the power of 2. // by __alignment, where __alignment is required to be the power of 2.
static size_t static size_t
_S_aligned_size(size_t __size, size_t __alignment) _S_aligned_size(size_t __size, size_t __alignment)
{ return ((__size - 1)|(__alignment - 1)) + 1; } { return ((__size - 1)|(__alignment - 1)) + 1; }
...@@ -342,16 +342,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -342,16 +342,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ {
protected: protected:
void* void*
do_allocate(size_t __bytes, size_t __alignment) do_allocate(size_t, size_t)
{ std::__throw_bad_alloc(); } { std::__throw_bad_alloc(); }
void void
do_deallocate(void* __p, size_t __bytes, size_t __alignment) do_deallocate(void*, size_t, size_t) noexcept
{ } { }
bool bool
do_is_equal(const memory_resource& __other) const noexcept do_is_equal(const memory_resource& __other) const noexcept
{ } { return this == &__other; }
friend memory_resource* null_memory_resource() noexcept; friend memory_resource* null_memory_resource() noexcept;
}; };
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
// with this library; see the file COPYING3. If not see // with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include <memory>
#include <experimental/memory_resource> #include <experimental/memory_resource>
#include <vector> #include <vector>
#include <cstdlib>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_allocator.h> #include <testsuite_allocator.h>
...@@ -36,6 +36,7 @@ struct A ...@@ -36,6 +36,7 @@ struct A
static int ctor_count; static int ctor_count;
static int dtor_count; static int dtor_count;
}; };
int A::ctor_count = 0; int A::ctor_count = 0;
int A::dtor_count = 0; int A::dtor_count = 0;
...@@ -43,7 +44,7 @@ struct CountedResource : public memory_resource ...@@ -43,7 +44,7 @@ struct CountedResource : public memory_resource
{ {
public: public:
CountedResource() = default; CountedResource() = default;
~ CountedResource() = default; ~CountedResource() = default;
static size_t get_alloc_count() { return alloc_count; } static size_t get_alloc_count() { return alloc_count; }
static size_t get_dalloc_count() { return dalloc_count; } static size_t get_dalloc_count() { return dalloc_count; }
...@@ -54,23 +55,23 @@ protected: ...@@ -54,23 +55,23 @@ protected:
void* do_allocate(size_t bytes, size_t alignment) void* do_allocate(size_t bytes, size_t alignment)
{ {
alloc_count += bytes; alloc_count += bytes;
if (auto ptr = std::malloc(bytes)) { if (auto ptr = std::malloc(bytes))
return ptr; return ptr;
}
throw std::bad_alloc(); throw std::bad_alloc();
} }
void do_deallocate(void *p, size_t bytes, size_t alignment) void do_deallocate(void *p, size_t bytes, size_t alignment)
{ {
dalloc_count += bytes; dalloc_count += bytes;
free(p); std::free(p);
} }
bool do_is_equal(const memory_resource& __other) const noexcept bool do_is_equal(const memory_resource& __other) const noexcept
{ return this == &__other; } { return this == &__other; }
}; };
size_t CountedResource::alloc_count = 0;
size_t CountedResource::dalloc_count = 0; size_t CountedResource::alloc_count = 0;
size_t CountedResource::dalloc_count = 0;
void clear() void clear()
{ {
...@@ -81,8 +82,11 @@ void clear() ...@@ -81,8 +82,11 @@ void clear()
} }
// memory resource // memory resource
void test01() void
test01()
{ {
bool test __attribute((unused)) = false;
memory_resource* r = new_delete_resource(); memory_resource* r = new_delete_resource();
VERIFY(get_default_resource() == r); VERIFY(get_default_resource() == r);
void *p = get_default_resource()->allocate(5); void *p = get_default_resource()->allocate(5);
...@@ -101,8 +105,11 @@ void test01() ...@@ -101,8 +105,11 @@ void test01()
} }
// polymorphic_allocator // polymorphic_allocator
void test02() void
test02()
{ {
bool test __attribute((unused)) = false;
clear(); clear();
{ {
CountedResource cr; CountedResource cr;
...@@ -115,7 +122,11 @@ void test02() ...@@ -115,7 +122,11 @@ void test02()
VERIFY(CountedResource::get_dalloc_count() == 5); VERIFY(CountedResource::get_dalloc_count() == 5);
} }
void test03() { void
test03()
{
bool test __attribute((unused)) = false;
clear(); clear();
CountedResource cr; CountedResource cr;
polymorphic_allocator<A> pa(&cr); polymorphic_allocator<A> pa(&cr);
...@@ -129,7 +140,11 @@ void test03() { ...@@ -129,7 +140,11 @@ void test03() {
VERIFY(CountedResource::get_dalloc_count() == 1); VERIFY(CountedResource::get_dalloc_count() == 1);
} }
void test04() { void
test04()
{
bool test __attribute((unused)) = false;
polymorphic_allocator<A> pa1(get_default_resource()); polymorphic_allocator<A> pa1(get_default_resource());
polymorphic_allocator<A> pa2(get_default_resource()); polymorphic_allocator<A> pa2(get_default_resource());
VERIFY(pa1 == pa2); VERIFY(pa1 == pa2);
...@@ -137,10 +152,10 @@ void test04() { ...@@ -137,10 +152,10 @@ void test04() {
VERIFY(pa1 == pa3); VERIFY(pa1 == pa3);
} }
int main() { int main()
{
test01(); test01();
test02(); test02();
test03(); test03();
test04(); test04();
return 0;
} }
// { dg-do run { xfail *-*-* } }
// { dg-options "-std=gnu++14" } // { dg-options "-std=gnu++14" }
// Copyright (C) 2015-2016 Free Software Foundation, Inc. // Copyright (C) 2016 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -20,17 +19,34 @@ ...@@ -20,17 +19,34 @@
#include <experimental/memory_resource> #include <experimental/memory_resource>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using std::experimental::pmr::polymorphic_allocator;
using std::experimental::pmr::null_memory_resource;
using std::experimental::pmr::memory_resource; using std::experimental::pmr::memory_resource;
using std::experimental::pmr::null_memory_resource;
using std::experimental::pmr::new_delete_resource;
// null_memory_resource
void
test06()
{
bool test __attribute((unused)) = false;
void test01() {
memory_resource* r = null_memory_resource(); memory_resource* r = null_memory_resource();
auto p = r->allocate(1); bool caught = false;
void* p = nullptr;
try {
p = r->allocate(1);
} catch (const std::bad_alloc&) {
caught = true;
}
VERIFY( caught );
VERIFY( *r == *r );
VERIFY( r->is_equal(*r) );
VERIFY( !r->is_equal(*new_delete_resource()) );
} }
int main() { int main()
test01(); {
test06();
} }
// { dg-options "-std=gnu++14" }
// Copyright (C) 2016 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/>.
#include <experimental/memory_resource>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using std::experimental::pmr::memory_resource;
using std::experimental::pmr::resource_adaptor;
template<typename T>
struct Allocator : __gnu_test::SimpleAllocator<T>
{
Allocator(int) { } // not default constructible
template<typename U>
Allocator(const Allocator<U>&) { }
};
template<typename T>
bool aligned(void* p)
{
return (reinterpret_cast<std::uintptr_t>(p) % alignof(T)) == 0;
}
// resource_adaptor
void
test05()
{
bool test __attribute((unused)) = false;
using std::max_align_t;
using std::uintptr_t;
void* p = nullptr;
Allocator<int> a1(1), a2(2); // minimal interface allocators
resource_adaptor<decltype(a1)> r1(a1), r2(a2);
VERIFY( r1 == r1 );
VERIFY( r1 == r2 );
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));
__gnu_test::uneq_allocator<double> a3(3), a4(4); // non-equal allocators
resource_adaptor<decltype(a3)> r3(a3), r4(a4);
VERIFY( r3 == r3 );
VERIFY( r4 == r4 );
VERIFY( r3 != r4 );
p = r3.allocate(1);
VERIFY( aligned<max_align_t>(p) );
r3.deallocate(p, 1);
p = r3.allocate(1, alignof(short));
VERIFY( aligned<short>(p) );
r3.deallocate(p, 1, alignof(short));
p = r3.allocate(1, alignof(long));
VERIFY( aligned<long>(p) );
r3.deallocate(p, 1, alignof(long));
// TODO test with an allocator that doesn't use new or malloc, so
// returns pointers that are not suitably aligned for any type.
}
int main()
{
test05();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment