93
At a low level, the translation can be done manually via functions such as
pmemobj_direct() that appear in the preader.c example in Listing 7-2. Because manual
translations require explicit type casts and are error prone, we recommend tagging every
object with a type. This allows some form of type safety, and thanks to macros, can be
checked at compile time.
For example, a persistent variable declared via TOID(struct foo) x can be read via
D_RO(x)->field. In a pool with the following layout:
POBJ_LAYOUT_BEGIN(cathouse);
POBJ_LAYOUT_TOID(cathouse, struct canaries);
POBJ_LAYOUT_TOID(cathouse, int);
POBJ_LAYOUT_END(cathouse);
The field val declared on the first line can be accessed using any of the subsequent
three operations:
TOID(int) val;
TOID_ASSIGN(val, oid_of_val); // Assigns 'oid_of_val' to typed OID 'val'
D_RW(val) = 42; // Returns a typed write pointer to 'val' and writes 42
return D_RO(val); // Returns a typed read-only (const) pointer to 'val'
Allocating Memory
Using malloc() to allocate memory is quite normal to C developers and those who use
languages that do not fully handle automatic memory allocation and deallocation. For
persistent memory, you can use pmemobj_alloc(), pmemobj_reserve(), or pmemobj_
xreserve() to reserve memory for a transient object and use it the same way you would
use malloc(). We recommend that you free allocated memory using pmemobj_free() or
POBJ_FREE() when the application no longer requires it to avoid a runtime memory leak.
Because these are volatile memory allocations, they will not cause a persistent leak after
a crash or graceful application exit.
Chapter 7 libpmemobj: a Native traNsaCtioNal objeCt store
Précédent

- 120/457

Suivant