Provided by: libpmemobj-dev_1.13.1-1.1ubuntu2_amd64 bug

NAME

       OID_IS_NULL(),  OID_EQUALS(), pmemobj_direct(), pmemobj_oid(), pmemobj_type_num(), pmemobj_pool_by_oid(),
       pmemobj_pool_by_ptr() - functions that allow mapping operations between object addresses, object handles,
       oids or type numbers

SYNOPSIS

              #include <libpmemobj.h>

              OID_IS_NULL(PMEMoid oid)
              OID_EQUALS(PMEMoid lhs, PMEMoid rhs)

              void *pmemobj_direct(PMEMoid oid);
              PMEMoid pmemobj_oid(const void *addr);
              uint64_t pmemobj_type_num(PMEMoid oid);
              PMEMobjpool *pmemobj_pool_by_oid(PMEMoid oid);
              PMEMobjpool *pmemobj_pool_by_ptr(const void *addr);
              void *pmemobj_volatile(PMEMobjpool *pop, struct pmemvlt *vlt,
                  size_t size, void *ptr,
                  int (*constr)(void *ptr, void *arg), void *arg); (EXPERIMENTAL)

DESCRIPTION

       Each object stored in a persistent memory pool is represented by an object handle of  type  PMEMoid.   In
       practice, such a handle is a unique Object IDentifier (OID) of global scope, which means that two objects
       from different pools will never have the same OID.  The special OID_NULL macro defines a NULL-like handle
       that  does  not  represent any object.  The size of a single object is limited by PMEMOBJ_MAX_ALLOC_SIZE.
       Thus an allocation with a requested size greater than this value will fail.

       An OID cannot be used as a direct pointer to an object.  Each time the program attempts to read or  write
       object  data, it must obtain the current memory address of the object by converting its OID into a point‐
       er.

       In contrast to the memory address, the OID value for given object does not change during the life  of  an
       object (except for realloc), and remains valid after closing and reopening the pool.  For this reason, if
       an  object contains a reference to another persistent object, for example, to build some kind of a linked
       data structure, the reference must be an OID and not a memory address.

       pmemobj_direct() returns a pointer to the PMEMoid object with handle oid.

       pmemobj_oid() returns a PMEMoid handle to the object pointed to by addr.

       pmemobj_type_num() returns the type number of the PMEMoid object with handle oid.

       pmemobj_pool_by_oid() returns a PMEMobjpool* handle to the pool containing the PMEMoid object with handle
       oid.

       pmemobj_pool_by_ptr() returns a PMEMobjpool* handle to the pool containing the address addr.

       At the time of allocation (or reallocation), each object may be assigned a number representing its  type.
       Such  a  type  number  may  be  used to arrange the persistent objects based on their actual user-defined
       structure type, thus facilitating implementation of a simple run-time type safety mechanism.   This  also
       allows  iterating  through all the objects of a given type that are stored in the persistent memory pool.
       See pmemobj_first(3) for more information.

       The OID_IS_NULL() macro checks if PMEMoid represents a NULL object.

       The OID_EQUALS() macro compares two PMEMoid objects.

       For special cases where volatile (transient) variables need to be stored on persistent memory, there’s  a
       mechanism composed of struct pmemvlt type and pmemobj_volatile() function.  To use it, the struct pmemvlt
       needs  to  be placed in the neighborhood of transient data region.  The PMEMvlt macro can be used to con‐
       struct such a region.  The struct pmemvlt must be zeroed prior to use.  This can be easily done in object
       constructor or in a transaction directly after an allocation.  When the  pmemobj_volatile()  function  is
       called  on  a struct pmemvlt, it will return the pointer to the data and it will ensure that the provided
       constructor function is called exactly once in the current instance of the pmemobj pool.  The constructor
       is called with the ptr pointer to the data, and this function will return the same pointer  if  the  con‐
       structor  returns  0,  otherwise  NULL is returned.  The size argument must accurately describe the total
       size of the volatile memory region that will be accessed.  Calling pmemobj_volatile() on the same  region
       with  different  sizes  is undefined behavior.  For this mechanism to be effective, all accesses to tran‐
       sient variables must go through it, otherwise there’s a risk of the constructor not being called  on  the
       first load.  Maintaining transient state on persistent memory is challenging due to difficulties with dy‐
       namic  resources  acquisition  and  subsequent resource release.  For example, one needs to consider what
       happens with volatile state of an object which is being freed inside of a  transaction,  especially  with
       regards  to  the possibility of an abort.  It’s generally recommended to entirely separate the persistent
       and transient states, and when it’s not possible, to only store types which do not require lifecycle man‐
       agement (i.e., primitive types) inside of volatile regions.

RETURN VALUE

       The pmemobj_direct() function returns a pointer to the object represented by oid.  If  oid  is  OID_NULL,
       pmemobj_direct() returns NULL.

       The  pmemobj_oid()  function  returns  a PMEMoid handle to the object pointed to by addr.  If addr is not
       from within a pmemobj pool, OID_NULL is returned.  If addr is not the start of an object (does not  point
       to the beginning of a valid allocation), the resulting PMEMoid can be safely used only with:

       • pmemobj_pool_by_oid()

       • pmemobj_direct()

       • pmemobj_tx_add_range(3)

       The pmemobj_type_num() function returns the type number of the object represented by oid.

       The  pmemobj_pool_by_oid()  function returns a handle to the pool that contains the object represented by
       oid.  If the pool is not open or oid is OID_NULL, pmemobj_pool_by_oid() returns NULL.

       The pmemobj_pool_by_ptr() function returns a handle to the pool that contains the address, or NULL if the
       address does not belong to any open pool.

NOTES

       For performance reasons, on Linux and FreeBSD the pmemobj_direct() function is inlined  by  default.   To
       use  the  non-inlined variant of pmemobj_direct(), define PMEMOBJ_DIRECT_NON_INLINE prior to the #include
       of <libpmemobj.h>, either with #define or with the -D option to the compiler.

EXAMPLES

       The following code shows how to store transient variables on persistent memory.

              struct my_data {
                  PMEMvlt(uint64_t) foo;
                  uint64_t bar;
              };

              int
              my_data_constructor(void *ptr, void *arg)
              {
                  uint64_t *foo = ptr;
                  *foo = 0;

                  return 0;
              }

              PMEMobjpool *pop = ...;

              struct my_data *data = D_RW(...);

              uint64_t *foo = pmemobj_volatile(pop, &data->foo.vlt, &data->foo.value,
                  my_data_constructor, NULL);

              assert(*foo == 0);

SEE ALSO

       libpmemobj(7) and <https://pmem.io>