<div dir="ltr"><div>A couple of comments/questions:</div><div><br></div>1) I don't see why `persistent_type` is tied to pointer_traits at all? Wouldn't it work the same as a separate trait?<div><br></div><div>2) Given an arbitrary `T` what are the requirements on the "persistent type for T" (e.g.  `pointer_traits<T*>::persistent_type`)?</div><div>Is it intended to be usable exactly like `T` itself? If so how do you plan to achieve this and do you have an example?</div><div>If not how are implementations supposed to access the actual underlying object?</div><div><br></div><div>3) Changing the types of internal node data members is somewhat problematic, at least in terms of implementation.<br></div><div>__tree and __hash_table don't actually invoke the constructors for the node types, and instead only construct the</div><div>"value" member directly using `allocator_traits::construct` as required by [container.requirements.general].</div><div>If the "persistent" types have non-trivial constructors or destructors they won't be called leading to UB. This isn't</div><div>an impossible problem to solve, but it would take a lot of work.</div><div><br></div><div>/Eric</div><div><br></div><div>PS. Email regarding libc++ should be sent to cfe-dev as well.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 16, 2017 at 7:25 AM, Tomasz Kapela via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
I'm part of an engineering team doing research on persistent memory support and<br>
we have stumbled upon an interesting problem. The issue is, we would like to be<br>
able to use the standard library containers in a persistent memory context<br>
(think NVDIMM-N). What I mean is that you allocate a container from said<br>
memory, use it like you normally would. After the application terminates,<br>
expectedly or otherwise, you can place the container back into the newly<br>
created process's address space - it will be in the last consistent state in<br>
which it was before termination (interruption/crash/exit). The obvious way to<br>
achieve this is to substitute the allocator. The programming model is based on<br>
memory mapped files and because of that the pointer type used by the allocator<br>
is a fancy pointer, so that it can do all the offset calculations.<br>
<br>
User data consistency is provided via a transaction mechanism provided by the<br>
library. We snapshot data before modifying them to be able to roll the<br>
transaction back in case of an error. The usage model we are proposing is this<br>
(pseudocode, not the actual API):<br>
<br>
int main() {<br>
    auto handle = pool::open("path/to/file", ...);<br>
    using pvector = std::vector<foo, persistent_allocator<foo>>;<br>
    {<br>
        auto tx = transaction::start(handle); // transactions are per pool file<br>
        auto vec_ptr = allocate_from_persistent_<wbr>memory<pvector>();<br>
        vec_ptr->emplace_back(foo, parameters);<br>
    }<br>
}<br>
<br>
The problem occurs when standard library containers have metadata. For example<br>
rb tree nodes carry their color, which will not be included in the<br>
transaction's undo log. To address this we propose to define a new type in the<br>
std::pointer_traits, which could be used to wrap the containers' metadata in<br>
a user-defined type. This should be fully backward compatible and as such not<br>
mandatory.<br>
<br>
This is a standard level change and we would like to gather feedback for this<br>
idea before we start the whole process. This feature is not persistent memory<br>
specific, even we use it as part of providing transactional data consistency.<br>
<br>
This is in fact a working proof of concept available at<br>
(<a href="https://github.com/pmem/libcxx" rel="noreferrer" target="_blank">https://github.com/pmem/<wbr>libcxx</a>) combined with the allocator from<br>
(<a href="https://github.com/pmem/nvml" rel="noreferrer" target="_blank">https://github.com/pmem/nvml</a>)<wbr>.<br>
<br>
I will be happy to answer any questions you might have and await your<br>
feedback.<br>
<br>
Thanks,<br>
Tom<br>
<br>
<br>
Tomasz Kapela (2):<br>
  pm: change deque typedef<br>
  pm: add persistency_type typedef to pointer_traits<br>
<br>
 include/__hash_table                               | 20 ++++++++------<br>
 include/__tree                                     |  8 +++---<br>
 include/deque                                      |  8 +++---<br>
 include/list                                       |  7 +++--<br>
 include/map                                        |  7 +++--<br>
 include/memory                                     | 31 ++++++++++++++++++++++<br>
 include/set                                        |  9 +++++--<br>
 .../pointer.traits.types/<wbr>persistency_type.pass.cpp | 25 +++++++++++++++++<br>
 8 files changed, 94 insertions(+), 21 deletions(-)<br>
 create mode 100644 test/std/utilities/memory/<wbr>pointer.traits/pointer.traits.<wbr>types/persistency_type.pass.<wbr>cpp<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.9.3<br>
<br>
______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
</font></span></blockquote></div><br></div>