Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<memory_resource>: std::pmr::pool_options::max_blocks_per_chunk ignored in std::pmr::unsynchronized_pool_resource #3408

Closed
fsb4000 opened this issue Feb 11, 2023 · 0 comments · Fixed by #3510
Labels
bug Something isn't working fixed Something works now, yay!

Comments

@fsb4000
Copy link
Contributor

fsb4000 commented Feb 11, 2023

Describe the bug
Copied from DevCom:

Since I have set max_blocks_per_chunk to 1, I would expect the allocated size to be rounded up to the next power of two, which is 0x10000, and the chunk size to be equal to that or maybe a little bit larger. Instead, 0x40038 is allocated from the upstream resource, so about four times as much as expected.

As far as I can tell, this happens because max_blocks_per_chunk is not applied when initializing _Next_capacity. It is simply initialized to _Default_next_capacity, which is 4. max_blocks_per_chunk is applied when updating _Next_capacity in _Increase_capacity, but that only happens after the first chunk has already been allocated.

This is causing me trouble because I need to handle large allocations and am compiling my code for x86, where the address space is not that large.

Command-line test case

C:\Temp>type repro.cpp
#include <memory_resource>
#include <vector>
#include <iostream>

struct logging_resource : public std::pmr::memory_resource
{
 void* do_allocate(std::size_t bytes, std::size_t alignment) override
 {
   log.push_back(bytes);
   return std::pmr::new_delete_resource()->allocate(bytes, alignment);
 }

 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override
 {
   std::pmr::new_delete_resource()->deallocate(p, bytes, alignment);
 }

 bool do_is_equal(const std::pmr::memory_resource& other)
   const noexcept override
 {
   return this == &other;
 }

  std::vector<ptrdiff_t> log;
};

int main()
{
  logging_resource upstream;
  std::pmr::pool_options options = {
    .max_blocks_per_chunk = 1,
    .largest_required_pool_block = 0};
  std::pmr::unsynchronized_pool_resource res(options, &upstream);

  size_t size = 0x8001;
  void* p = res.allocate(size);

  for (auto e : upstream.log) std::cout << std::hex << "0x" << e << std::endl;

  res.deallocate(p, size);

  return 0;
}

C:\Temp>cl test.cpp /EHsc /std:c++20
Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31335 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

repro.cpp
Microsoft (R) Incremental Linker Version 19.32.31335
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:repro.exe
repro.obj

C:\Temp>.\repro.exe
0x30
0x40038

Expected behavior
I would expect the allocated size to be rounded up to the next power of two, which is 0x10000, and the chunk size to be equal to that or maybe a little bit larger

STL version
Microsoft Visual Studio Community 2022 Preview
Version 17.5.0 Preview 3.0

Additional context
This is DevCom-10276910 / VSO-1745984 / AB#1745984

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Feb 12, 2023
CaseyCarter added a commit to CaseyCarter/STL that referenced this issue Feb 27, 2023
... even when less than `_Default_next_capacity`.

Fixes microsoft#3408
@StephanTLavavej StephanTLavavej added the fixed Something works now, yay! label Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants