1OID_IS_NULL(3)             PMDK Programmer's Manual             OID_IS_NULL(3)
2
3
4

NAME

6       OID_IS_NULL(),  OID_EQUALS(),  pmemobj_direct(),  pmemobj_oid(), pmemo‐
7       bj_type_num(), pmemobj_pool_by_oid(), pmemobj_pool_by_ptr() - functions
8       that allow mapping operations between object addresses, object handles,
9       oids or type numbers
10

SYNOPSIS

12              #include <libpmemobj.h>
13
14              OID_IS_NULL(PMEMoid oid)
15              OID_EQUALS(PMEMoid lhs, PMEMoid rhs)
16
17              void *pmemobj_direct(PMEMoid oid);
18              PMEMoid pmemobj_oid(const void *addr);
19              uint64_t pmemobj_type_num(PMEMoid oid);
20              PMEMobjpool *pmemobj_pool_by_oid(PMEMoid oid);
21              PMEMobjpool *pmemobj_pool_by_ptr(const void *addr);
22              void *pmemobj_volatile(PMEMobjpool *pop, struct pmemvlt *vlt,
23                  size_t size, void *ptr,
24                  int (*constr)(void *ptr, void *arg), void *arg); (EXPERIMENTAL)
25

DESCRIPTION

27       Each object stored in a persistent memory pool is represented by an ob‐
28       ject  handle  of  type PMEMoid.  In practice, such a handle is a unique
29       Object IDentifier (OID) of global scope, which means that  two  objects
30       from  different  pools  will  never  have  the  same  OID.  The special
31       OID_NULL macro defines a NULL-like handle that does not  represent  any
32       object.   The  size  of  a  single object is limited by PMEMOBJ_MAX_AL‐
33       LOC_SIZE.  Thus an allocation with a requested size greater  than  this
34       value will fail.
35
36       An  OID cannot be used as a direct pointer to an object.  Each time the
37       program attempts to read or write object data, it must obtain the  cur‐
38       rent memory address of the object by converting its OID into a pointer.
39
40       In  contrast to the memory address, the OID value for given object does
41       not change during the life of an object (except for realloc),  and  re‐
42       mains  valid after closing and reopening the pool.  For this reason, if
43       an object contains a reference to another persistent object, for  exam‐
44       ple,  to build some kind of a linked data structure, the reference must
45       be an OID and not a memory address.
46
47       pmemobj_direct() returns a pointer to the PMEMoid  object  with  handle
48       oid.
49
50       pmemobj_oid()  returns a PMEMoid handle to the object pointed to by ad‐
51       dr.
52
53       pmemobj_type_num() returns the type number of the PMEMoid  object  with
54       handle oid.
55
56       pmemobj_pool_by_oid()  returns  a  PMEMobjpool* handle to the pool con‐
57       taining the PMEMoid object with handle oid.
58
59       pmemobj_pool_by_ptr() returns a PMEMobjpool* handle to  the  pool  con‐
60       taining the address addr.
61
62       At  the  time  of  allocation (or reallocation), each object may be as‐
63       signed a number representing its type.  Such a type number may be  used
64       to  arrange  the  persistent objects based on their actual user-defined
65       structure type, thus facilitating implementation of a  simple  run-time
66       type  safety mechanism.  This also allows iterating through all the ob‐
67       jects of a given type that are stored in the  persistent  memory  pool.
68       See pmemobj_first(3) for more information.
69
70       The OID_IS_NULL() macro checks if PMEMoid represents a NULL object.
71
72       The OID_EQUALS() macro compares two PMEMoid objects.
73
74       For  special  cases  where  volatile  (transient)  variables need to be
75       stored on persistent memory, there's a  mechanism  composed  of  struct
76       pmemvlt  type  and  pmemobj_volatile() function.  To use it, the struct
77       pmemvlt needs to be placed in the neighborhood of  transient  data  re‐
78       gion.   The  PMEMvlt macro can be used to construct such a region.  The
79       struct pmemvlt must be zeroed prior to use.  This can be easily done in
80       object  constructor  or  in a transaction directly after an allocation.
81       When the pmemobj_volatile() function is called on a struct pmemvlt,  it
82       will return the pointer to the data and it will ensure that the provid‐
83       ed constructor function is called exactly once in the current  instance
84       of the pmemobj pool.  The constructor is called with the ptr pointer to
85       the data, and this function will return the same pointer  if  the  con‐
86       structor returns 0, otherwise NULL is returned.  The size argument must
87       accurately describe the total size of the volatile memory  region  that
88       will  be  accessed.  Calling pmemobj_volatile() on the same region with
89       different sizes is undefined behavior.  For this mechanism to be effec‐
90       tive, all accesses to transient variables must go through it, otherwise
91       there's a risk of the constructor not being called on the  first  load.
92       Maintaining  transient state on persistent memory is challenging due to
93       difficulties with dynamic resources acquisition and subsequent resource
94       release.  For example, one needs to consider what happens with volatile
95       state of an object which is being freed inside of a transaction,  espe‐
96       cially  with  regards  to  the possibility of an abort.  It's generally
97       recommended to entirely separate the persistent and  transient  states,
98       and  when  it's  not possible, to only store types which do not require
99       lifecycle management (i.e., primitive types)  inside  of  volatile  re‐
100       gions.
101

RETURN VALUE

103       The  pmemobj_direct()  function  returns a pointer to the object repre‐
104       sented by oid.  If oid is OID_NULL, pmemobj_direct() returns NULL.
105
106       The pmemobj_oid() function returns  a  PMEMoid  handle  to  the  object
107       pointed  to  by  addr.   If  addr  is  not  from within a pmemobj pool,
108       OID_NULL is returned.  If addr is not the start of an object (does  not
109       point  to  the  beginning of a valid allocation), the resulting PMEMoid
110       can be safely used only with:
111
112pmemobj_pool_by_oid()
113
114pmemobj_direct()
115
116pmemobj_tx_add_range(3)
117
118       The pmemobj_type_num() function returns the type number of  the  object
119       represented by oid.
120
121       The  pmemobj_pool_by_oid()  function  returns a handle to the pool that
122       contains the object represented by oid.  If the pool is not open or oid
123       is OID_NULL, pmemobj_pool_by_oid() returns NULL.
124
125       The  pmemobj_pool_by_ptr()  function  returns a handle to the pool that
126       contains the address, or NULL if the address does  not  belong  to  any
127       open pool.
128

NOTES

130       For  performance  reasons,  on  Linux  and FreeBSD the pmemobj_direct()
131       function is inlined by default.  To  use  the  non-inlined  variant  of
132       pmemobj_direct(),  define  PMEMOBJ_DIRECT_NON_INLINE  prior to the #in‐
133       clude of <libpmemobj.h>, either with #define or with the -D  option  to
134       the compiler.
135

EXAMPLES

137       The following code shows how to store transient variables on persistent
138       memory.
139
140              struct my_data {
141                  PMEMvlt(uint64_t) foo;
142                  uint64_t bar;
143              };
144
145              int
146              my_data_constructor(void *ptr, void *arg)
147              {
148                  uint64_t *foo = ptr;
149                  *foo = 0;
150
151                  return 0;
152              }
153
154              PMEMobjpool *pop = ...;
155
156              struct my_data *data = D_RW(...);
157
158              uint64_t *foo = pmemobj_volatile(pop, &data->foo.vlt, &data->foo.value,
159                  my_data_constructor, NULL);
160
161              assert(*foo == 0);
162

SEE ALSO

164       libpmemobj(7) and <https://pmem.io>
165
166
167
168PMDK - pmemobj API version 2.3    2022-08-25                    OID_IS_NULL(3)
Impressum