This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
monotonic_buffer_resource::release()
Section: 20.4.6.3 [mem.res.monotonic.buffer.mem] Status: C++23 Submitter: Arthur O'Dwyer Opened: 2018-06-10 Last modified: 2023-11-22
Priority: 2
View all other issues in [mem.res.monotonic.buffer.mem].
View all issues with C++23 status.
Discussion:
The effects of monotonic_buffer_resource::release()
are defined as:
Calls
upstream_rsrc->deallocate()
as necessary to release all allocated memory.
This doesn't give any instruction on what to do with the memory controlled by the monotonic_buffer_resource
which
was not allocated, i.e., what to do with the initial buffer provided to its constructor.
release()
.
Arthur O'Dwyer's proposed pmr implementation for libc++ reuses the initial buffer after a release()
, on the
assumption that this is what the average library user will be expecting.
#include <memory_resource> int main() { char buffer[100]; { std::pmr::monotonic_buffer_resource mr(buffer, 100, std::pmr::null_memory_resource()); mr.release(); mr.allocate(60); // A } { std::pmr::monotonic_buffer_resource mr(buffer, 100, std::pmr::null_memory_resource()); mr.allocate(60); // B mr.release(); mr.allocate(60); // C } }
Assume that allocation "B" always succeeds.
With the proposed libc++ implementation, allocations "A" and "C" both succeed.
With Boost.Container's implementation, allocations "A" and "C" both fail.
Using another plausible implementation strategy, allocation "A" could succeed but allocation "C"
could fail. I have been informed that MSVC's implementation does this.
release()
which goes underspecified by the Standard is the effect of
release()
on next_buffer_size
. As currently written, my interpretation is that
release()
is not permitted to decrease current_buffer_size
; I'm not sure if this
is a feature or a bug.
Consider this test case (taken from here):
std::pmr::monotonic_buffer_resource mr(std::pmr::new_delete_resource()); for (int i=0; i < 100; ++i) { mr.allocate(1); // D mr.release(); }
Arthur believes it is important that the 100th invocation of line "D" does not attempt to allocate 2100 bytes from the upstream resource.
[2018-06-23 after reflector discussion]
Priority set to 2
Previous resolution [SUPERSEDED]:
This wording is relative to N4750.
[Drafting note: The resolution depicted below would make MSVC's and my-proposed-libc++'s implementations both conforming.]
Modify 20.4.6.3 [mem.res.monotonic.buffer.mem] as indicated:
void release();-1- Effects: Calls
-2- [Note: The memory is released back toupstream_rsrc->deallocate()
as necessary to release all allocated memory. Resets the state of the initial buffer.upstream_rsrc
even if some blocks that were allocated from this have not been deallocated from this. This function has an unspecified effect onnext_buffer_size
. — end note]
[2018-08-23 Batavia Issues processing]
We liked Pablo's wording from the reflector discussion. Status to Open.
Previous resolution [SUPERSEDED]:
This wording is relative to N4750.
Modify 20.4.6.3 [mem.res.monotonic.buffer.mem] as indicated:
void release();-1- Effects: Calls
upstream_rsrc->deallocate()
as necessary to release all allocated memory. Resets*this
to its initial state at construction.
[2020-10-03; Daniel comments and provides improved wording]
The recent wording introduces the very generic term "state" without giving a concrete definition of that term. During reflector discussions different interpretations of that term were expressed. The revised wording below gets rid of that word and replaces it by the actually involved exposition-only members.
[2020-10-06; moved to Tentatively Ready after seven votes in favour in reflector poll]
[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4861.
Modify 20.4.6.3 [mem.res.monotonic.buffer.mem] as indicated:
void release();-1- Effects: Calls
upstream_rsrc->deallocate()
as necessary to release all allocated memory. Resetscurrent_buffer
andnext_buffer_size
to their initial values at construction.