some questions about transactional allocation(pmemobj_tx_alloc).

38 views
Skip to first unread message

Shaonan Ma

unread,
Nov 25, 2019, 2:40:10 AM11/25/19
to pmem
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.


Piotr Balcer

unread,
Nov 25, 2019, 3:22:10 AM11/25/19
to pmem
Hi,

Yes, your description is mostly accurate.

Two things though:
1. Atomic allocation is also crash-safe - memory allocation and pointer assignment is fail-safe atomic.
2. In transactions, persistent allocation is performed during commit, not after. Meaning that all operations within a transaction, including allocations, are fail-safe atomic.

Piotr

Shaonan Ma

unread,
Nov 25, 2019, 3:35:26 AM11/25/19
to pmem
Thank you very much for your reply.

Let me try to implement it first.

在 2019年11月25日星期一 UTC+8下午4:22:10,Piotr Balcer写道:

Shaonan Ma

unread,
Nov 25, 2019, 9:27:15 PM11/25/19
to pmem
Now I implement the transactional allocation in my application, but there is segmentation fault.

I found when I created a pool, it failed and the pool is nullptr. I have never encountered this problem.

My code of creating pool is following:

void init_pmem() {
// create pool
const char *pool_name = "/mnt/pmem0/matianmao/fast_fair.data";
const char *layout_name = "xxx";
size_t pool_size = 1024 * 1024 * 1024 * 16; // 16GB

if (access(pool_name, 0)) {
pmem_pool = pmemobj_create(pool_name, layout_name, pool_size, 0666);
if(pmem_pool == nullptr){
std::cout<<"[xxx]\tcreate fail\n";
assert(0);
}
std::cout << "[xxx]\tcreate\n";
} else {
pmem_pool = pmemobj_open(pool_name, layout_name);
std::cout << "[xxx]\topen\n";
}
std::cout << "[xxx]\topen pmem pool successfully\n";
}

I will clean the file each time and I will pmemobj_create a new pool. But I always got a nullptr pool.

I wrote it in other programs and it worked. So I hope anyone can tell me why.

在 2019年11月25日星期一 UTC+8下午4:35:26,Shaonan Ma写道:

Shaonan Ma

unread,
Nov 25, 2019, 9:31:24 PM11/25/19
to pmem
Oh, I found the bug. 1024 * 1024 * 1024 * 16 overflow the int. 
I'm so stupid!

在 2019年11月26日星期二 UTC+8上午10:27:15,Shaonan Ma写道:
Reply all
Reply to author
Forward
0 new messages