// <memory_resource> implementation -*- C++ -*-

// Copyright (C) 2018-2021 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.

// 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.

// 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/>.

#include <memory_resource>
#include <algorithm>			// lower_bound, rotate
#include <atomic>
#include <bit>				// has_single_bit, bit_ceil, bit_width
#include <new>
#if ATOMIC_POINTER_LOCK_FREE != 2
# include <bits/std_mutex.h>	// std::mutex, std::lock_guard
# include <bits/move.h>		// std::__exchange
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
  // This was defined inline in 9.1 and 9.2 so code compiled by those
  // versions will not use this symbol.
  memory_resource::~memory_resource() = default;

  namespace
  {
    class newdel_res_t final : public memory_resource
    {
      void*
      do_allocate(size_t __bytes, size_t __alignment) override
      { return ::operator new(__bytes, std::align_val_t(__alignment)); }

      void
      do_deallocate(void* __p, size_t __bytes, size_t __alignment) noexcept
      override
      { ::operator delete(__p, __bytes, std::align_val_t(__alignment)); }

      bool
      do_is_equal(const memory_resource& __other) const noexcept override
      { return &__other == this; }
    };

    class null_res_t final : public memory_resource
    {
      void*
      do_allocate(size_t, size_t) override
      { std::__throw_bad_alloc(); }

      void
      do_deallocate(void*, size_t, size_t) noexcept override
      { }

      bool
      do_is_equal(const memory_resource& __other) const noexcept override
      { return &__other == this; }
    };

    template<typename T>
      struct constant_init
      {
	union {
	  unsigned char unused;
	  T obj;
	};
	constexpr constant_init() : obj() { }

	template<typename U>
	  explicit constexpr constant_init(U arg) : obj(arg) { }

	~constant_init() { /* do nothing, union member is not destroyed */ }
      };

    __constinit constant_init<newdel_res_t> newdel_res{};
    __constinit constant_init<null_res_t> null_res{};
#if ATOMIC_POINTER_LOCK_FREE == 2
    using atomic_mem_res = atomic<memory_resource*>;
# define _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED
#elif defined(_GLIBCXX_HAS_GTHREADS)
    // Can't use pointer-width atomics, define a type using a mutex instead:
    struct atomic_mem_res
    {
# ifdef __GTHREAD_MUTEX_INIT
#  define _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED
      // std::mutex has constexpr constructor
      constexpr
# endif
      atomic_mem_res(memory_resource* r) : val(r) { }

      mutex mx;
      memory_resource* val;

      memory_resource* load()
      {
	lock_guard<mutex> lock(mx);
	return val;
      }

      memory_resource* exchange(memory_resource* r)
      {
	lock_guard<mutex> lock(mx);
	return std::__exchange(val, r);
      }
    };
#else
# define _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED
    // Single-threaded, no need for synchronization
    struct atomic_mem_res
    {
      constexpr
      atomic_mem_res(memory_resource* r) : val(r) { }

      memory_resource* val;

      memory_resource* load() const
      {
	return val;
      }

      memory_resource* exchange(memory_resource* r)
      {
	return std::__exchange(val, r);
      }
    };
#endif // ATOMIC_POINTER_LOCK_FREE == 2

#ifdef _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED
    __constinit constant_init<atomic_mem_res> default_res{&newdel_res.obj};
#else
# include "default_resource.h"
#endif
  } // namespace

  memory_resource*
  new_delete_resource() noexcept
  { return &newdel_res.obj; }

  memory_resource*
  null_memory_resource() noexcept
  { return &null_res.obj; }

  memory_resource*
  set_default_resource(memory_resource* r) noexcept
  {
    if (r == nullptr)
      r = new_delete_resource();
    return default_res.obj.exchange(r);
  }

  memory_resource*
  get_default_resource() noexcept
  { return default_res.obj.load(); }

  // Member functions for std::pmr::monotonic_buffer_resource

  // This was defined inline in 9.1 and 9.2 so code compiled by those
  // versions will not use this symbol.
  monotonic_buffer_resource::~monotonic_buffer_resource() { release(); }

  namespace {

  // aligned_size<N> stores the size and alignment of a memory allocation.
  // The size must be a multiple of N, leaving the low log2(N) bits free
  // to store the base-2 logarithm of the alignment.
  // For example, allocate(1024, 32) is stored as 1024 + log2(32) = 1029.
  template<unsigned N>
  struct aligned_size
  {
    // N must be a power of two
    static_assert( std::__popcount(N) == 1 );

    static constexpr size_t _S_align_mask = N - 1;
    static constexpr size_t _S_size_mask = ~_S_align_mask;

    constexpr
    aligned_size(size_t sz, size_t align) noexcept
    : value(sz | (std::__bit_width(align) - 1u))
    {
      __glibcxx_assert(size() == sz); // sz must be a multiple of N
    }

    constexpr size_t
    size() const noexcept
    { return value & _S_size_mask; }

    constexpr size_t
    alignment() const noexcept
    { return size_t(1) << (value & _S_align_mask); }

    size_t value; // size | log2(alignment)
  };

  // Round n up to a multiple of alignment, which must be a power of two.
  constexpr size_t aligned_ceil(size_t n, size_t alignment)
  {
    return (n + alignment - 1) & ~(alignment - 1);
  }

  } // namespace

  // Memory allocated by the upstream resource is managed in a linked list
  // of _Chunk objects. A _Chunk object recording the size and alignment of
  // the allocated block and a pointer to the previous chunk is placed
  // at end of the block.
  class monotonic_buffer_resource::_Chunk
  {
  public:
    // Return the address and size of a block of memory allocated from __r,
    // of at least __size bytes and aligned to __align.
    // Add a new _Chunk to the front of the linked list at __head.
    static pair<void*, size_t>
    allocate(memory_resource* __r, size_t __size, size_t __align,
	     _Chunk*& __head)
    {
      const size_t __orig_size = __size;

      // Add space for the _Chunk object and round up to 64 bytes.
      __size = aligned_ceil(__size + sizeof(_Chunk), 64);

      // Check for unsigned wraparound
      if (__size < __orig_size) [[unlikely]]
	{
	  // monotonic_buffer_resource::do_allocate is not allowed to throw.
	  // If the required size is too large for size_t then ask the
	  // upstream resource for an impossibly large size and alignment.
	  __size = -1;
	  __align = ~(size_t(-1) >> 1);
	}

      void* __p = __r->allocate(__size, __align);

      // Add a chunk defined by (__p, __size, __align) to linked list __head.
      // We know the end of the buffer is suitably-aligned for a _Chunk
      // because the caller ensured __align is at least alignof(max_align_t).
      void* const __back = (char*)__p + __size - sizeof(_Chunk);
      __head = ::new(__back) _Chunk(__size, __align, __head);
      return { __p, __size - sizeof(_Chunk) };
    }

    // Return every chunk in linked list __head to resource __r.
    static void
    release(_Chunk*& __head, memory_resource* __r) noexcept
    {
      _Chunk* __next = __head;
      __head = nullptr;
      while (__next)
	{
	  _Chunk* __ch = __next;
	  __next = __ch->_M_next;
	  size_t __size = __ch->_M_size.size();
	  size_t __align = __ch->_M_size.alignment();
	  void* __start = (char*)(__ch + 1) - __size;
	  __r->deallocate(__start, __size, __align);
	}
    }

  private:
    _Chunk(size_t __size, size_t __align, _Chunk* __next) noexcept
    : _M_size(__size, __align), _M_next(__next)
    { }

    aligned_size<64> _M_size;
    _Chunk* _M_next;
  };

  void
  monotonic_buffer_resource::_M_new_buffer(size_t bytes, size_t alignment)
  {
    const size_t n = std::max(bytes, _M_next_bufsiz);
    const size_t m = aligned_ceil(alignment, alignof(std::max_align_t));
    auto [p, size] = _Chunk::allocate(_M_upstream, n, m, _M_head);
    _M_current_buf = p;
    _M_avail = size;
    _M_next_bufsiz *= _S_growth_factor;
  }

  void
  monotonic_buffer_resource::_M_release_buffers() noexcept
  {
    _Chunk::release(_M_head, _M_upstream);
  }

  // Helper types for synchronized_pool_resource & unsynchronized_pool_resource

  namespace {

  // Simple bitset with runtime size.
  // Tracks which blocks in a pool chunk are used/unused.
  struct bitset
  {
    using word = uint64_t;
    using size_type // unsigned integer type with no more than 32 bits
      = conditional_t<numeric_limits<size_t>::digits <= 32, size_t, uint32_t>;

    static constexpr unsigned bits_per_word = numeric_limits<word>::digits;

    // The bitset does not own p
    bitset(void* p, size_type num_blocks)
    : _M_words(static_cast<word*>(p)), _M_size(num_blocks),
      _M_next_word(0)
    {
      const size_type last_word = num_blocks / bits_per_word;
      __builtin_memset(_M_words, 0, last_word * sizeof(*_M_words));
      // Set bits beyond _M_size, so they are not treated as free blocks:
      if (const size_type extra_bits = num_blocks % bits_per_word)
	_M_words[last_word] = word(-1) << extra_bits;
      __glibcxx_assert( empty() );
      __glibcxx_assert( free() == num_blocks );
    }

    bitset() = default;
    ~bitset() = default;

    // Number of blocks
    size_type size() const noexcept { return _M_size; }

    // Number of free blocks (unset bits)
    size_type free() const noexcept
    {
      size_type n = 0;
      for (size_type i = _M_next_word; i < nwords(); ++i)
	n += (bits_per_word - std::__popcount(_M_words[i]));
      return n;
    }

    // True if there are no free blocks (all bits are set)
    bool full() const noexcept
    {
      if (_M_next_word >= nwords())
	return true;
      // For a bitset with size() > (max_blocks_per_chunk() - 64) we will
      // have nwords() == (max_word_index() + 1) and so _M_next_word will
      // never be equal to nwords().
      // In that case, check if the last word is full:
      if (_M_next_word == max_word_index())
	return _M_words[_M_next_word] == word(-1);
      return false;
    }

    // True if size() != 0 and all blocks are free (no bits are set).
    bool empty() const noexcept
    {
      if (nwords() == 0)
	return false;
      if (_M_next_word != 0)
	return false;
      for (size_type i = 0; i < nwords() - 1; ++i)
	if (_M_words[i] != 0)
	  return false;
      word last = _M_words[nwords() - 1];
      if (const size_type extra_bits = size() % bits_per_word)
	last <<= (bits_per_word - extra_bits);
      return last == 0;
    }

    void reset() noexcept
    {
      _M_words = nullptr;
      _M_size = _M_next_word = 0;
    }

    bool operator[](size_type n) const noexcept
    {
      __glibcxx_assert( n < _M_size );
      const size_type wd = n / bits_per_word;
      const word bit = word(1) << (n % bits_per_word);
      return _M_words[wd] & bit;
    }

    size_type get_first_unset() noexcept
    {
      const size_type wd = _M_next_word;
      if (wd < nwords())
	{
	  const size_type n = std::__countr_one(_M_words[wd]);
	  if (n < bits_per_word)
	    {
	      const word bit = word(1) << n;
	      _M_words[wd] |= bit;
	      update_next_word();
	      return (wd * bits_per_word) + n;
	    }
	}
      return size_type(-1);
    }

    void set(size_type n) noexcept
    {
      __glibcxx_assert( n < _M_size );
      const size_type wd = n / bits_per_word;
      const word bit = word(1) << (n % bits_per_word);
      _M_words[wd] |= bit;
      if (wd == _M_next_word)
	update_next_word();
    }

    void clear(size_type n) noexcept
    {
      __glibcxx_assert( n < _M_size );
      const size_type wd = n / bits_per_word;
      const word bit = word(1) << (n % bits_per_word);
      _M_words[wd] &= ~bit;
      if (wd < _M_next_word)
	_M_next_word = wd;
    }

    // Update _M_next_word to refer to the next word with an unset bit.
    // The size of the _M_next_word bit-field means it cannot represent
    // the maximum possible nwords() value. To avoid wraparound to zero
    // this function saturates _M_next_word at max_word_index().
    void update_next_word() noexcept
    {
      size_type next = _M_next_word;
      while (_M_words[next] == word(-1) && ++next < nwords())
	{ }
      _M_next_word = std::min(next, max_word_index());
    }

    void swap(bitset& b) noexcept
    {
      std::swap(_M_words, b._M_words);
      size_type tmp = _M_size;
      _M_size = b._M_size;
      b._M_size = tmp;
      tmp = _M_next_word;
      _M_next_word = b._M_next_word;
      b._M_next_word = tmp;
    }

    size_type nwords() const noexcept
    { return (_M_size + bits_per_word - 1) / bits_per_word; }

    // Maximum value that can be stored in bitset::_M_size member (approx 500k)
    static constexpr size_type max_blocks_per_chunk() noexcept
    { return (size_type(1) << _S_size_digits) - 1; }

    // Maximum value that can be stored in bitset::_M_next_word member (8191).
    static constexpr size_type max_word_index() noexcept
    { return (max_blocks_per_chunk() + bits_per_word - 1) / bits_per_word; }

    word* data() const noexcept { return _M_words; }

  private:
    static constexpr unsigned _S_size_digits
      = (numeric_limits<size_type>::digits
	  + std::__bit_width(bits_per_word) - 1) / 2;

    word* _M_words = nullptr;
    // Number of blocks represented by the bitset:
    size_type _M_size : _S_size_digits;
    // Index of the first word with unset bits:
    size_type _M_next_word : numeric_limits<size_type>::digits - _S_size_digits;
  };

  // A "chunk" belonging to a pool.
  // A chunk contains many blocks of the same size.
  // Derived from bitset to reuse its tail-padding.
  struct chunk : bitset
  {
    chunk() = default;

    // p points to the start of a chunk of size bytes in length.
    // The chunk has space for n blocks, followed by a bitset of size n
    // that begins at address words.
    // This object does not own p or words, the caller will free it.
    chunk(void* p, uint32_t bytes, void* words, size_t n)
    : bitset(words, n),
      _M_bytes(bytes),
      _M_p(static_cast<std::byte*>(p))
    { __glibcxx_assert(bytes <= chunk::max_bytes_per_chunk()); }

    chunk(chunk&& c) noexcept
    : bitset(std::move(c)), _M_bytes(c._M_bytes), _M_p(c._M_p)
    {
      c._M_bytes = 0;
      c._M_p = nullptr;
      c.reset();
    }

    chunk& operator=(chunk&& c) noexcept
    {
      swap(c);
      return *this;
    }

    // Allocated size of chunk:
    uint32_t _M_bytes = 0;
    // Start of allocated chunk:
    std::byte* _M_p = nullptr;

    // True if there are free blocks in this chunk
    using bitset::full;
    // Number of blocks in this chunk
    using bitset::size;

    static constexpr uint32_t max_bytes_per_chunk() noexcept
    { return numeric_limits<decltype(_M_bytes)>::max(); }

    // Determine if block with address p and size block_size
    // is contained within this chunk.
    bool owns(void* p, size_t block_size)
    {
      std::less_equal<uintptr_t> less_equal;
      return less_equal(reinterpret_cast<uintptr_t>(_M_p),
			reinterpret_cast<uintptr_t>(p))
	&& less_equal(reinterpret_cast<uintptr_t>(p) + block_size,
		      reinterpret_cast<uintptr_t>(bitset::data()));
    }

    // Allocate next available block of block_size bytes from this chunk.
    void* reserve(size_t block_size) noexcept
    {
      const size_type n = get_first_unset();
      if (n == size_type(-1))
	return nullptr;
      return _M_p + (n * block_size);
    }

    // Deallocate a single block of block_size bytes
    void release(void* vp, size_t block_size)
    {
      __glibcxx_assert( owns(vp, block_size) );
      const size_t offset = static_cast<std::byte*>(vp) - _M_p;
      // Pointer is correctly aligned for a block in this chunk:
      __glibcxx_assert( (offset % block_size) == 0 );
      // Block has been allocated:
      __glibcxx_assert( (*this)[offset / block_size] == true );
      bitset::clear(offset / block_size);
    }

    // Deallocate a single block if it belongs to this chunk.
    bool try_release(void* p, size_t block_size)
    {
      if (!owns(p, block_size))
	return false;
      release(p, block_size);
      return true;
    }

    void swap(chunk& c) noexcept
    {
      std::swap(_M_bytes, c._M_bytes);
      std::swap(_M_p, c._M_p);
      bitset::swap(c);
    }

    bool operator<(const chunk& c) const noexcept
    { return std::less<const void*>{}(_M_p, c._M_p); }

    friend void swap(chunk& l, chunk& r) { l.swap(r); }

    friend bool operator<(const void* p, const chunk& c) noexcept
    { return std::less<const void*>{}(p, c._M_p); }
  };

  // For 64-bit pointers this is the size of three pointers i.e. 24 bytes.
  // For 32-bit and 20-bit pointers it's four pointers (16 bytes).
  // For 16-bit pointers it's five pointers (10 bytes).
  // TODO pad 64-bit to 4*sizeof(void*) to avoid splitting across cache lines?
  static_assert(sizeof(chunk)
      == sizeof(bitset::size_type) + sizeof(uint32_t) + 2 * sizeof(void*));

  // An oversized allocation that doesn't fit in a pool.
  struct big_block
  {
    // The minimum size of a big block.
    // All big_block allocations will be a multiple of this value.
    // Use bit_ceil to get a power of two even for e.g. 20-bit size_t.
    static constexpr size_t min = __bit_ceil(numeric_limits<size_t>::digits);

    constexpr
    big_block(size_t bytes, size_t alignment)
    : _M_size(alloc_size(bytes), alignment)
    {
      // Check for unsigned wraparound
      if (size() < bytes) [[unlikely]]
	{
	  // (sync|unsync)_pool_resource::do_allocate is not allowed to throw.
	  // If the required size is too large for size_t then ask the
	  // upstream resource for an impossibly large size and alignment.
	  _M_size.value = -1;
	}
    }

    void* pointer = nullptr;
    aligned_size<min> _M_size;

    size_t size() const noexcept
    {
      if (_M_size.value == size_t(-1)) [[unlikely]]
	return size_t(-1);
      return _M_size.size();
    }

    size_t align() const noexcept
    { return _M_size.alignment(); }

    // Calculate size to be allocated instead of requested number of bytes.
    // The requested value will be rounded up to a multiple of big_block::min,
    // so the low bits are all zero and can be used to hold the alignment.
    static constexpr size_t alloc_size(size_t bytes) noexcept
    { return aligned_ceil(bytes, min); }

    friend bool operator<(void* p, const big_block& b) noexcept
    { return less<void*>{}(p, b.pointer); }

    friend bool operator<(const big_block& b, void* p) noexcept
    { return less<void*>{}(b.pointer, p); }
  };

  static_assert(sizeof(big_block) == (2 * sizeof(void*)));

  } // namespace

  // A pool that serves blocks of a particular size.
  // Each pool manages a number of chunks.
  // When a pool is full it is replenished by allocating another chunk.
  struct __pool_resource::_Pool
  {
    // Smallest supported block size
    static constexpr unsigned _S_min_block
      = std::max(sizeof(void*), alignof(bitset::word));

    _Pool(size_t __block_size, size_t __blocks_per_chunk)
    : _M_chunks(),
      _M_block_sz(__block_size),
      _M_blocks_per_chunk(__blocks_per_chunk)
    { }

    // Must call release(r) before destruction!
    ~_Pool() { __glibcxx_assert(_M_chunks.empty()); }

    _Pool(_Pool&&) noexcept = default;
    _Pool& operator=(_Pool&&) noexcept = default;

    // Size of blocks in this pool
    size_t block_size() const noexcept
    { return _M_block_sz; }

    // Allocate a block if the pool is not full, otherwise return null.
    void* try_allocate() noexcept
    {
      const size_t blocksz = block_size();
      if (!_M_chunks.empty())
	{
	  auto& last = _M_chunks.back();
	  if (void* p = last.reserve(blocksz))
	    return p;
	  // TODO last is full, so move another chunk to the back instead?
	  for (auto it = _M_chunks.begin(); it != &last; ++it)
	    if (void* p = it->reserve(blocksz))
	      return p;
	}
      return nullptr;
    }

    // Allocate a block from the pool, replenishing from upstream if needed.
    void* allocate(memory_resource* r, const pool_options& opts)
    {
      if (void* p = try_allocate())
	return p;
      replenish(r, opts);
      return _M_chunks.back().reserve(block_size());
    }

    // Return a block to the pool.
    bool deallocate(memory_resource*, void* p)
    {
      const size_t blocksz = block_size();
      if (__builtin_expect(!_M_chunks.empty(), true))
	{
	  auto& last = _M_chunks.back();
	  if (last.try_release(p, blocksz))
	    return true;
	  auto it = std::upper_bound(_M_chunks.begin(), &last, p);
	  if (it != _M_chunks.begin())
	    {
	      it--;
	      if (it->try_release(p, blocksz))
		// If chunk is empty could return to upstream, but we don't
		// currently do that. Pools only increase in size.
		return true;
	    }
	}
      return false;
    }

    void replenish(memory_resource* __r, const pool_options& __opts)
    {
      using word = chunk::word;
      const size_t __blocks = _M_blocks_per_chunk;
      const auto __bits = chunk::bits_per_word;
      const size_t __words = (__blocks + __bits - 1) / __bits;
      const size_t __block_size = block_size();
      size_t __bytes = __blocks * __block_size + __words * sizeof(word);
      size_t __alignment = std::__bit_ceil(__block_size);
      void* __p = __r->allocate(__bytes, __alignment);
      __try
	{
	  size_t __n = __blocks * __block_size;
	  void* __pwords = static_cast<char*>(__p) + __n;
	  _M_chunks.insert(chunk(__p, __bytes, __pwords, __blocks), __r);
	}
      __catch (...)
	{
	  __r->deallocate(__p, __bytes, __alignment);
	}
      if (_M_blocks_per_chunk < __opts.max_blocks_per_chunk)
	{
	  const size_t max_blocks
	    = (chunk::max_bytes_per_chunk() - sizeof(word))
	    / (__block_size + 0.125);
	  _M_blocks_per_chunk = std::min({
	      max_blocks,
	      __opts.max_blocks_per_chunk,
	      (size_t)_M_blocks_per_chunk * 2
	  });
	}
    }

    void release(memory_resource* __r)
    {
      const size_t __alignment = std::__bit_ceil(block_size());
      for (auto& __c : _M_chunks)
	if (__c._M_p)
	  __r->deallocate(__c._M_p, __c._M_bytes, __alignment);
      _M_chunks.clear(__r);
    }

    // A "resourceless vector" instead of pmr::vector, to save space.
    // All resize operations need to be passed a memory resource, which
    // obviously needs to be the same one every time.
    // Chunks are kept sorted by address of their first block, except for
    // the most recently-allocated Chunk which is at the end of the vector.
    struct vector
    {
      using value_type = chunk;
      using size_type = unsigned;
      using iterator = value_type*;

      // A vector owns its data pointer but not memory held by its elements.
      chunk* data = nullptr;
      size_type size = 0;
      size_type capacity = 0;

      vector() = default;

      vector(size_type __n, memory_resource* __r)
      : data(polymorphic_allocator<value_type>(__r).allocate(__n)),
	capacity(__n)
      { }

      // Must call clear(r) before destruction!
      ~vector() { __glibcxx_assert(data == nullptr); }

      vector(vector&& __rval) noexcept
	: data(__rval.data), size(__rval.size), capacity(__rval.capacity)
      {
	__rval.data = nullptr;
	__rval.capacity = __rval.size = 0;
      }

      vector& operator=(vector&& __rval) noexcept
      {
	__glibcxx_assert(data == nullptr);
	data = __rval.data;
	size = __rval.size;
	capacity = __rval.capacity;
	__rval.data = nullptr;
	__rval.capacity = __rval.size = 0;
	return *this;
      }

      // void resize(size_type __n, memory_resource* __r);
      // void reserve(size_type __n, memory_resource* __r);

      void clear(memory_resource* __r)
      {
	if (!data)
	  return;
	// Chunks must be individually freed before clearing the vector.
	std::destroy(begin(), end());
	polymorphic_allocator<value_type>(__r).deallocate(data, capacity);
	data = nullptr;
	capacity = size = 0;
      }

      // Sort existing elements then insert new one at the end.
      iterator insert(chunk&& c, memory_resource* r)
      {
	if (size < capacity)
	  {
	    if (size > 1)
	      {
		auto mid = end() - 1;
		std::rotate(std::lower_bound(begin(), mid, *mid), mid, end());
	      }
	  }
	else if (size > 0)
	  {
	    polymorphic_allocator<value_type> __alloc(r);
	    auto __mid = std::lower_bound(begin(), end() - 1, back());
	    auto __p = __alloc.allocate(capacity * 1.5);
	    // move [begin,__mid) to new storage
	    auto __p2 = std::move(begin(), __mid, __p);
	    // move end-1 to new storage
	    *__p2 = std::move(back());
	    // move [__mid,end-1) to new storage
	    std::move(__mid, end() - 1, ++__p2);
	    std::destroy(begin(), end());
	    __alloc.deallocate(data, capacity);
	    data = __p;
	    capacity *= 1.5;
	  }
	else
	  {
	    polymorphic_allocator<value_type> __alloc(r);
	    data = __alloc.allocate(capacity = 8);
	  }
	auto back = ::new (data + size) chunk(std::move(c));
	__glibcxx_assert(std::is_sorted(begin(), back));
	++size;
	return back;
      }

      iterator begin() const { return data; }
      iterator end() const { return data + size; }

      bool empty() const noexcept { return size == 0; }

      value_type& back() { return data[size - 1]; }
    };

    vector _M_chunks;
    unsigned _M_block_sz; 	// size of blocks allocated from this pool
    unsigned _M_blocks_per_chunk;	// number of blocks to allocate next
  };

  // An oversized allocation that doesn't fit in a pool.
  struct __pool_resource::_BigBlock : big_block
  {
    using big_block::big_block;
  };

  namespace {

  constexpr size_t pool_sizes[] = {
      8, 16, 24,
      32, 48,
      64, 80, 96, 112,
      128, 192,
      256, 320, 384, 448,
      512, 768,
#if __SIZE_WIDTH__ > 16
      1024, 1536,
      2048, 3072,
#if __SIZE_WIDTH__ > 20
      1<<12, 1<<13, 1<<14,
      1<<15, 1<<16, 1<<17,
      1<<20, 1<<21, 1<<22 // 4MB should be enough for anybody
#endif
#endif
  };

  pool_options
  munge_options(pool_options opts)
  {
    // The values in the returned struct may differ from those supplied
    // to the pool resource constructor in that values of zero will be
    // replaced with implementation-defined defaults, and sizes may be
    // rounded to unspecified granularity.

    // max_blocks_per_chunk sets the absolute maximum for the pool resource.
    // Each pool might have a smaller maximum, because pools for very large
    // objects might impose  smaller limit.
    if (opts.max_blocks_per_chunk == 0)
      {
	// Pick a default that depends on the number of bits in size_t.
	opts.max_blocks_per_chunk = __SIZE_WIDTH__ << 8;
      }
    else
      {
	// Round to preferred granularity.
	if (opts.max_blocks_per_chunk < size_t(-4))
	  {
	    // round up
	    opts.max_blocks_per_chunk
	      = aligned_ceil(opts.max_blocks_per_chunk, 4);
	  }
	else
	  {
	    // round down
	    opts.max_blocks_per_chunk &= ~size_t(3);
	  }
      }

    if (opts.max_blocks_per_chunk > chunk::max_blocks_per_chunk())
      {
	opts.max_blocks_per_chunk = chunk::max_blocks_per_chunk();
      }

    // largest_required_pool_block specifies the largest block size that will
    // be allocated from a pool. Larger allocations will come directly from
    // the upstream resource and so will not be pooled.
    if (opts.largest_required_pool_block == 0)
      {
	// Pick a sensible default that depends on the number of bits in size_t
	// (pools with larger block sizes must be explicitly requested by
	// using a non-zero value for largest_required_pool_block).
	opts.largest_required_pool_block = __SIZE_WIDTH__ << 6;
      }
    else
      {
	// Round to preferred granularity
	static_assert(std::__has_single_bit(pool_sizes[0]));
	opts.largest_required_pool_block
	  = aligned_ceil(opts.largest_required_pool_block, pool_sizes[0]);
      }

    if (opts.largest_required_pool_block < big_block::min)
      {
	opts.largest_required_pool_block = big_block::min;
      }
    else if (opts.largest_required_pool_block > std::end(pool_sizes)[-1])
      {
	// Setting _M_opts to the largest pool allows users to query it:
	opts.largest_required_pool_block = std::end(pool_sizes)[-1];
      }
    return opts;
  }

  inline int
  pool_index(size_t block_size, int npools)
  {
    auto p = std::lower_bound(pool_sizes, pool_sizes + npools, block_size);
    int n = p - pool_sizes;
    if (n != npools)
      return n;
    return -1;
  }

  inline int
  select_num_pools(const pool_options& opts)
  {
    auto p = std::lower_bound(std::begin(pool_sizes), std::end(pool_sizes),
			      opts.largest_required_pool_block);
    const int n = p - std::begin(pool_sizes);
    if (p == std::end(pool_sizes))
      return n;
    return n + 1;
  }

#ifdef _GLIBCXX_HAS_GTHREADS
  using shared_lock = std::shared_lock<shared_mutex>;
  using exclusive_lock = lock_guard<shared_mutex>;
#endif

  } // namespace

  __pool_resource::
  __pool_resource(const pool_options& opts, memory_resource* upstream)
  : _M_opts(munge_options(opts)), _M_unpooled(upstream),
    _M_npools(select_num_pools(_M_opts))
  { }

  __pool_resource::~__pool_resource() { release(); }

  void
  __pool_resource::release() noexcept
  {
    memory_resource* res = resource();
    // deallocate oversize allocations
    for (auto& b : _M_unpooled)
      res->deallocate(b.pointer, b.size(), b.align());
    pmr::vector<_BigBlock>{res}.swap(_M_unpooled);
  }

  void*
  __pool_resource::allocate(size_t bytes, size_t alignment)
  {
    auto& b = _M_unpooled.emplace_back(bytes, alignment);
    __try {
      // N.B. need to allocate b.size(), which might be larger than bytes.
      // Also use b.align() instead of alignment parameter, which will be
      // an impossibly large value if (bytes+bookkeeping) > SIZE_MAX.
      void* p = resource()->allocate(b.size(), b.align());
      b.pointer = p;
      if (_M_unpooled.size() > 1)
	{
	  const auto mid = _M_unpooled.end() - 1;
	  // move to right position in vector
	  std::rotate(std::lower_bound(_M_unpooled.begin(), mid, p),
		      mid, _M_unpooled.end());
	}
      return p;
    } __catch(...) {
      _M_unpooled.pop_back();
      __throw_exception_again;
    }
  }

  void
  __pool_resource::deallocate(void* p, size_t bytes [[maybe_unused]],
			      size_t alignment [[maybe_unused]])
  {
    const auto it
      = std::lower_bound(_M_unpooled.begin(), _M_unpooled.end(), p);
    __glibcxx_assert(it != _M_unpooled.end() && it->pointer == p);
    if (it != _M_unpooled.end() && it->pointer == p) // [[likely]]
      {
	const auto b = *it;
	__glibcxx_assert(b.size() == b.alloc_size(bytes));
	__glibcxx_assert(b.align() == alignment);
	_M_unpooled.erase(it);
	// N.B. need to deallocate b.size(), which might be larger than bytes.
	resource()->deallocate(p, b.size(), b.align());
      }
  }

  // Create array of pools, allocated from upstream resource.
  auto
  __pool_resource::_M_alloc_pools()
  -> _Pool*
  {
    polymorphic_allocator<_Pool> alloc{resource()};
    _Pool* p = alloc.allocate(_M_npools);
    for (int i = 0; i < _M_npools; ++i)
      {
	// For last pool use largest_required_pool_block
	const size_t block_size = (i+1 == _M_npools)
	  ? _M_opts.largest_required_pool_block
	  : pool_sizes[i];

	// Decide on initial number of blocks per chunk.
	// At least 16 blocks per chunk seems reasonable,
	// more for smaller blocks:
	size_t blocks_per_chunk = std::max(size_t(16), 1024 / block_size);
	// But don't exceed the requested max_blocks_per_chunk:
	blocks_per_chunk
	  = std::min(blocks_per_chunk, _M_opts.max_blocks_per_chunk);
	// Allow space for bitset to track which blocks are used/unused:
	blocks_per_chunk *= 1 - 1.0 / (__CHAR_BIT__ * block_size);
	// Construct a _Pool for the given block size and initial chunk size:
	alloc.construct(p + i, block_size, blocks_per_chunk);
      }
    return p;
  }

#ifdef _GLIBCXX_HAS_GTHREADS
  // synchronized_pool_resource members.

  /* Notes on implementation and thread safety:
   *
   * Each synchronized_pool_resource manages an linked list of N+1 _TPools
   * objects, where N is the number of threads using the pool resource.
   * Each _TPools object has its own set of pools, with their own chunks.
   * The first element of the list, _M_tpools[0], can be used by any thread.
   * The rest of the list contains a _TPools object for each thread,
   * accessed via the thread-specific key _M_key (and referred to for
   * exposition as _M_tpools[_M_key]).
   * The first element, _M_tpools[0], contains "orphaned chunks" which were
   * allocated by a thread which has since exited, and so there is no
   * _M_tpools[_M_key] for that thread. Orphaned chunks are never reused,
   * they're only held in _M_tpools[0] so they can be deallocated.
   * A thread can access its own thread-specific set of pools via _M_key
   * while holding a shared lock on _M_mx. Accessing _M_impl._M_unpooled
   * or _M_tpools[0] or any other thread's _M_tpools[_M_key] requires an
   * exclusive lock.
   * The upstream_resource() pointer can be obtained without a lock, but
   * any dereference of that pointer requires an exclusive lock.
   * The _M_impl._M_opts and _M_impl._M_npools members are immutable,
   * and can safely be accessed concurrently.
   *
   * In a single-threaded program (i.e. __gthread_active_p() == false)
   * the pool resource only needs one set of pools and never has orphaned
   * chunks, so just uses _M_tpools[0] directly, and _M_tpools->next is null.
   */

  extern "C" {
    static void destroy_TPools(void*);
  }

  struct synchronized_pool_resource::_TPools
  {
    // Exclusive lock must be held in the thread where this constructor runs.
    explicit
    _TPools(synchronized_pool_resource& owner, exclusive_lock&)
    : owner(owner), pools(owner._M_impl._M_alloc_pools())
    {
      // __builtin_printf("%p constructing\n", this);
      __glibcxx_assert(pools);
    }

    // Exclusive lock must be held in the thread where this destructor runs.
    ~_TPools()
    {
      __glibcxx_assert(pools);
      if (pools)
	{
	  memory_resource* r = owner.upstream_resource();
	  for (int i = 0; i < owner._M_impl._M_npools; ++i)
	    pools[i].release(r);
	  std::destroy_n(pools, owner._M_impl._M_npools);
	  polymorphic_allocator<__pool_resource::_Pool> a(r);
	  a.deallocate(pools, owner._M_impl._M_npools);
	}
      if (prev)
	prev->next = next;
      if (next)
	next->prev = prev;
    }

    // Exclusive lock must be held in the thread where this function runs.
    void move_nonempty_chunks()
    {
      __glibcxx_assert(pools);
      __glibcxx_assert(__gthread_active_p());
      if (!pools)
	return;
      memory_resource* const r = owner.upstream_resource();
      auto* const shared = owner._M_tpools->pools;
      // move all non-empty chunks to the shared _TPools
      for (int i = 0; i < owner._M_impl._M_npools; ++i)
	for (auto& c : pools[i]._M_chunks)
	  if (!c.empty())
	    shared[i]._M_chunks.insert(std::move(c), r);
    }

    synchronized_pool_resource& owner;
    __pool_resource::_Pool* pools = nullptr;
    _TPools* prev = nullptr;
    _TPools* next = nullptr;

    static void destroy(_TPools* p)
    {
      exclusive_lock l(p->owner._M_mx);
      // __glibcxx_assert(p != p->owner._M_tpools);
      p->move_nonempty_chunks();
      polymorphic_allocator<_TPools> a(p->owner.upstream_resource());
      p->~_TPools();
      a.deallocate(p, 1);
    }
  };

  // Called when a thread exits
  extern "C" {
    static void destroy_TPools(void* p)
    {
      using _TPools = synchronized_pool_resource::_TPools;
      _TPools::destroy(static_cast<_TPools*>(p));
    }
  }

  // Constructor
  synchronized_pool_resource::
  synchronized_pool_resource(const pool_options& opts,
			     memory_resource* upstream)
  : _M_impl(opts, upstream)
  {
    if (__gthread_active_p())
      if (int err = __gthread_key_create(&_M_key, destroy_TPools))
	__throw_system_error(err);
    exclusive_lock l(_M_mx);
    _M_tpools = _M_alloc_shared_tpools(l);
  }

  // Destructor
  synchronized_pool_resource::~synchronized_pool_resource()
  {
    release();
    if (__gthread_active_p())
      __gthread_key_delete(_M_key); // does not run destroy_TPools
  }

  void
  synchronized_pool_resource::release()
  {
    exclusive_lock l(_M_mx);
    if (_M_tpools)
      {
	if (__gthread_active_p())
	  {
	    __gthread_key_delete(_M_key); // does not run destroy_TPools
	    __gthread_key_create(&_M_key, destroy_TPools);
	  }
	polymorphic_allocator<_TPools> a(upstream_resource());
	// destroy+deallocate each _TPools
	do
	  {
	    _TPools* p = _M_tpools;
	    _M_tpools = _M_tpools->next;
	    p->~_TPools();
	    a.deallocate(p, 1);
	  }
	while (_M_tpools);
      }
    // release unpooled memory
    _M_impl.release();
  }

  // Caller must hold shared or exclusive lock to ensure the pointer
  // isn't invalidated before it can be used.
  auto
  synchronized_pool_resource::_M_thread_specific_pools() noexcept
  {
    __pool_resource::_Pool* pools = nullptr;
    __glibcxx_assert(__gthread_active_p());
    if (auto tp = static_cast<_TPools*>(__gthread_getspecific(_M_key)))
      {
	pools = tp->pools;
	// __glibcxx_assert(tp->pools);
      }
    return pools;
  }

  // Override for memory_resource::do_allocate
  void*
  synchronized_pool_resource::
  do_allocate(size_t bytes, size_t alignment)
  {
    const auto block_size = std::max(bytes, alignment);
    const pool_options opts = _M_impl._M_opts;
    if (block_size <= opts.largest_required_pool_block)
      {
	const ptrdiff_t index = pool_index(block_size, _M_impl._M_npools);
	if (__gthread_active_p())
	  {
	    // Try to allocate from the thread-specific pool.
	    shared_lock l(_M_mx);
	    if (auto pools = _M_thread_specific_pools()) // [[likely]]
	      {
		// Need exclusive lock to replenish so use try_allocate:
		if (void* p = pools[index].try_allocate())
		  return p;
		// Need to take exclusive lock and replenish pool.
	      }
	    // Need to allocate or replenish thread-specific pools using
	    // upstream resource, so need to hold exclusive lock.
	  }
	else // single-threaded
	  {
	    if (!_M_tpools) // [[unlikely]]
	      {
		exclusive_lock dummy(_M_mx);
		_M_tpools = _M_alloc_shared_tpools(dummy);
	      }
	    return _M_tpools->pools[index].allocate(upstream_resource(), opts);
	  }

	// N.B. Another thread could call release() now lock is not held.
	exclusive_lock excl(_M_mx);
	if (!_M_tpools) // [[unlikely]]
	  _M_tpools = _M_alloc_shared_tpools(excl);
	auto pools = _M_thread_specific_pools();
	if (!pools)
	  pools = _M_alloc_tpools(excl)->pools;
	return pools[index].allocate(upstream_resource(), opts);
      }
    exclusive_lock l(_M_mx);
    return _M_impl.allocate(bytes, alignment); // unpooled allocation
  }

  // Override for memory_resource::do_deallocate
  void
  synchronized_pool_resource::
  do_deallocate(void* p, size_t bytes, size_t alignment)
  {
    size_t block_size = std::max(bytes, alignment);
    if (block_size <= _M_impl._M_opts.largest_required_pool_block)
      {
	const ptrdiff_t index = pool_index(block_size, _M_impl._M_npools);
	__glibcxx_assert(index != -1);
	if (__gthread_active_p())
	  {
	    shared_lock l(_M_mx);
	    if (auto pools = _M_thread_specific_pools())
	      {
		// No need to lock here, no other thread is accessing this pool.
		if (pools[index].deallocate(upstream_resource(), p))
		  return;
	      }
	    // Block might have come from a different thread's pool,
	    // take exclusive lock and check every pool.
	  }
	else // single-threaded
	  {
	    __glibcxx_assert(_M_tpools != nullptr);
	    if (_M_tpools) // [[likely]]
	      _M_tpools->pools[index].deallocate(upstream_resource(), p);
	    return;
	  }

	// TODO store {p, bytes, alignment} somewhere and defer returning
	// the block to the correct thread-specific pool until we next
	// take the exclusive lock.

	exclusive_lock excl(_M_mx);
	auto my_pools = _M_thread_specific_pools();
	for (_TPools* t = _M_tpools; t != nullptr; t = t->next)
	  {
	    if (t->pools != my_pools)
	      if (t->pools) // [[likely]]
		{
		  if (t->pools[index].deallocate(upstream_resource(), p))
		    return;
		}
	  }
	// Not necessarily an error to reach here, release() could have been
	// called on another thread between releasing the shared lock and
	// acquiring the exclusive lock.
	return;
      }
    exclusive_lock l(_M_mx);
    _M_impl.deallocate(p, bytes, alignment);
  }

  // Allocate a thread-specific _TPools object and add it to the linked list.
  auto
  synchronized_pool_resource::_M_alloc_tpools(exclusive_lock& l)
  -> _TPools*
  {
    __glibcxx_assert(_M_tpools != nullptr);
    __glibcxx_assert(__gthread_active_p());
    // dump_list(_M_tpools);
    polymorphic_allocator<_TPools> a(upstream_resource());
    _TPools* p = a.allocate(1);
    bool constructed = false;
    __try
      {
	a.construct(p, *this, l);
	constructed = true;
	// __glibcxx_assert(__gthread_getspecific(_M_key) == nullptr);
	if (int err = __gthread_setspecific(_M_key, p))
	  __throw_system_error(err);
      }
    __catch(...)
      {
	if (constructed)
	  a.destroy(p);
	a.deallocate(p, 1);
	__throw_exception_again;
      }
    p->prev = _M_tpools;
    p->next = _M_tpools->next;
    _M_tpools->next = p;
    if (p->next)
      p->next->prev = p;
    return p;
  }

  // Allocate the shared _TPools object, _M_tpools[0]
  auto
  synchronized_pool_resource::_M_alloc_shared_tpools(exclusive_lock& l)
  -> _TPools*
  {
    __glibcxx_assert(_M_tpools == nullptr);
    polymorphic_allocator<_TPools> a(upstream_resource());
    _TPools* p = a.allocate(1);
    __try
      {
	a.construct(p, *this, l);
      }
    __catch(...)
      {
	a.deallocate(p, 1);
	__throw_exception_again;
      }
    // __glibcxx_assert(p->next == nullptr);
    // __glibcxx_assert(p->prev == nullptr);
    return p;
  }
#endif // _GLIBCXX_HAS_GTHREADS

  // unsynchronized_pool_resource member functions

  // Constructor
  unsynchronized_pool_resource::
  unsynchronized_pool_resource(const pool_options& opts,
			       memory_resource* upstream)
  : _M_impl(opts, upstream), _M_pools(_M_impl._M_alloc_pools())
  { }

  // Destructor
  unsynchronized_pool_resource::~unsynchronized_pool_resource()
  { release(); }

  // Return all memory to upstream resource.
  void
  unsynchronized_pool_resource::release()
  {
    // release pooled memory
    if (_M_pools)
      {
	memory_resource* res = upstream_resource();
	polymorphic_allocator<_Pool> alloc{res};
	for (int i = 0; i < _M_impl._M_npools; ++i)
	  {
	    _M_pools[i].release(res);
	    alloc.destroy(_M_pools + i);
	  }
	alloc.deallocate(_M_pools, _M_impl._M_npools);
	_M_pools = nullptr;
      }

    // release unpooled memory
    _M_impl.release();
  }

  // Find the right pool for a block of size block_size.
  auto
  unsynchronized_pool_resource::_M_find_pool(size_t block_size) noexcept
  {
    __pool_resource::_Pool* pool = nullptr;
    if (_M_pools) // [[likely]]
      {
	int index = pool_index(block_size, _M_impl._M_npools);
	if (index != -1)
	  pool = _M_pools + index;
      }
    return pool;
  }

  // Override for memory_resource::do_allocate
  void*
  unsynchronized_pool_resource::do_allocate(size_t bytes, size_t alignment)
  {
    const auto block_size = std::max(bytes, alignment);
    if (block_size <= _M_impl._M_opts.largest_required_pool_block)
      {
	// Recreate pools if release() has been called:
	if (__builtin_expect(_M_pools == nullptr, false))
	  _M_pools = _M_impl._M_alloc_pools();
	if (auto pool = _M_find_pool(block_size))
	  return pool->allocate(upstream_resource(), _M_impl._M_opts);
      }
    return _M_impl.allocate(bytes, alignment);
  }

  // Override for memory_resource::do_deallocate
  void
  unsynchronized_pool_resource::
  do_deallocate(void* p, size_t bytes, size_t alignment)
  {
    size_t block_size = std::max(bytes, alignment);
    if (block_size <= _M_impl._M_opts.largest_required_pool_block)
      {
	if (auto pool = _M_find_pool(block_size))
	  {
	    pool->deallocate(upstream_resource(), p);
	    return;
	  }
      }
    _M_impl.deallocate(p, bytes, alignment);
  }

} // namespace pmr
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
