Hi, everyone,
I want to implement a persistent memory allocation and I find two allocation interface, pmemobj_alloc and pmemobj_tx_alloc.
I learned how to use them from official document and source code. In my opinion, the first is non-transactional function and it will alloc a memory from PM, but if system crashes before I persist the addr of this memory, there will be a memory leak or other exception.
The second, pmemobj_tx_alloc, it needs to be used in a transaction. In the example of official document, as following:
TOID(struct my_root) root = POBJ_ROOT(pop);
TX_BEGIN(pop) {
TX_ADD(root); /* we are going to operate on the root object */
TOID(struct rectangle) rect = TX_NEW(struct rectangle);
D_RW(rect)->x = 5;
D_RW(rect)->y = 10;
D_RW(root)->rect = rect;
} TX_END
Firstly, I need to record the undo log of origin addr(TX_ADD(root) in the example), which will record the addr of allocated memory. After TX_NEW but before TX_END, the memory is not actually allocated, but the addr is set to new memory(not actually allocated). Only after the transaction commits, the memory will be actually allocated.
If transaction aborts or system crashes, the memory won't be allocated and there is no memory leak. When restarting, system will use undo log(TX_ADD(root) in the example) to reset root to nullptr.
Is my understanding above correct? I think the example in the official document can prevent memory leak. If it is correct, I will follow it to implement my application.