diff --git a/src/Makefile b/src/Makefile
index 056ef22f73afa7318a6a2d97c9a4d8ced0f5f299..6292d7e34c4b72d00c70dbd72cf70df6957ffd47 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -56,6 +56,8 @@ HEADERS_INSTALL = include/libpmem.h include/libvmem.h\
include/libpmemblk.h include/libpmemlog.h\
include/libvmmalloc.h
+OBJ_HEADERS_INSTALL = include/libpmemobj/*.h
+
CPP_HEADERS_DESTDIR = $(DESTDIR)$(includedir)/libpmemobj++
MAKE_PKG_CONFIG = $(TOP)/utils/make-pkg-config.sh
@@ -153,6 +155,8 @@ endif
install: all
install -d $(HEADERS_DESTDIR)
install -p -m 0644 $(HEADERS_INSTALL) $(HEADERS_DESTDIR)
+ install -d $(HEADERS_DESTDIR)/libpmemobj
+ install -p -m 0644 $(OBJ_HEADERS_INSTALL) $(HEADERS_DESTDIR)/libpmemobj
install -d $(PKG_CONFIG_DESTDIR)
install -p -m 0644 $(PKG_CONFIG_FILES) $(PKG_CONFIG_DESTDIR)
@@ -164,12 +168,14 @@ uninstall:
# [!q] to skip windows/include/sys/queue.h
cstyle:
$(STYLE_CHECK) check include/*.h
+ $(STYLE_CHECK) check include/libpmemobj/*.h
$(STYLE_CHECK) check include/libpmemobj++/*.hpp
$(STYLE_CHECK) check include/libpmemobj++/detail/*.hpp
$(STYLE_CHECK) check windows/include/*.h
$(STYLE_CHECK) check windows/include/*/[!q]*.h
format:
+ $(STYLE_CHECK) format include/libpmemobj/*.h
$(STYLE_CHECK) format include/libpmemobj++/*.hpp
$(STYLE_CHECK) format include/libpmemobj++/detail/*.hpp
diff --git a/src/examples/libpmemobj/cpp_map/map_cli.cpp b/src/examples/libpmemobj/cpp_map/map_cli.cpp
index b12194b6ebc784690c81993ba6e23404dfeaa575..e90a22ef0ab7580ae9eb0dd62c078f67d368d64d 100644
--- a/src/examples/libpmemobj/cpp_map/map_cli.cpp
+++ b/src/examples/libpmemobj/cpp_map/map_cli.cpp
@@ -35,6 +35,7 @@
#include <iostream>
#include <libpmemobj++/pool.hpp>
#include <memory>
+#include <string.h>
#include <unistd.h>
namespace
diff --git a/src/include/libpmemobj++/condition_variable.hpp b/src/include/libpmemobj++/condition_variable.hpp
index a40310c0fbb00bc1df467e7cd124e3faecd1690a..257e5eb9aca19aa9d2a6388e75ec1d1266309233 100644
--- a/src/include/libpmemobj++/condition_variable.hpp
+++ b/src/include/libpmemobj++/condition_variable.hpp
@@ -41,7 +41,7 @@
#include <chrono>
#include <condition_variable>
-#include "libpmemobj.h"
+#include "libpmemobj/thread.h"
#include "libpmemobj++/detail/conversions.hpp"
#include "libpmemobj++/mutex.hpp"
diff --git a/src/include/libpmemobj++/detail/array_traits.hpp b/src/include/libpmemobj++/detail/array_traits.hpp
index 490eb7986349cdd48f08c1958acf2be3b6d6f329..f7d087483ebe3392b2ed103d76fe75a96e8ee91b 100644
--- a/src/include/libpmemobj++/detail/array_traits.hpp
+++ b/src/include/libpmemobj++/detail/array_traits.hpp
@@ -38,6 +38,8 @@
#ifndef LIBPMEMOBJ_ARRAY_TRAITS_HPP
#define LIBPMEMOBJ_ARRAY_TRAITS_HPP
+#include <stddef.h>
+
namespace nvml
{
diff --git a/src/include/libpmemobj++/detail/check_persistent_ptr_array.hpp b/src/include/libpmemobj++/detail/check_persistent_ptr_array.hpp
index 41f42f90c73ddade2fb183c61e2084ce6aabc810..bf6b3640c3fd28d273b65596056aff4f4460d595 100644
--- a/src/include/libpmemobj++/detail/check_persistent_ptr_array.hpp
+++ b/src/include/libpmemobj++/detail/check_persistent_ptr_array.hpp
@@ -38,6 +38,8 @@
#ifndef LIBPMEMOBJ_CHECK_PERSISTENT_PTR_ARRAY_HPP
#define LIBPMEMOBJ_CHECK_PERSISTENT_PTR_ARRAY_HPP
+#include <stddef.h>
+
#include "libpmemobj++/persistent_ptr.hpp"
namespace nvml
diff --git a/src/include/libpmemobj++/detail/common.hpp b/src/include/libpmemobj++/detail/common.hpp
index c6d0a753233ffbbbfff2cc12effd96d76628afb1..a8d07a3d43caebc1978eed2e37e24bb020b9c7ec 100644
--- a/src/include/libpmemobj++/detail/common.hpp
+++ b/src/include/libpmemobj++/detail/common.hpp
@@ -38,7 +38,7 @@
#ifndef PMEMOBJ_COMMON_HPP
#define PMEMOBJ_COMMON_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/tx_base.h"
#include "libpmemobj++/detail/pexceptions.hpp"
#include <typeinfo>
diff --git a/src/include/libpmemobj++/detail/integer_sequence.hpp b/src/include/libpmemobj++/detail/integer_sequence.hpp
index 87619723a21551d9da5eaaf33972c0482f516de8..79a92f9470d152527e6c9ffbc110291bfe19bda5 100644
--- a/src/include/libpmemobj++/detail/integer_sequence.hpp
+++ b/src/include/libpmemobj++/detail/integer_sequence.hpp
@@ -33,6 +33,8 @@
#ifndef LIBPMEMOBJ_INTEGER_SEQUENCE_HPP
#define LIBPMEMOBJ_INTEGER_SEQUENCE_HPP
+#include <stddef.h>
+
/**
* @file
* Create c++14 style index sequence.
diff --git a/src/include/libpmemobj++/detail/life.hpp b/src/include/libpmemobj++/detail/life.hpp
index 24d315fb2a0ce047bb311fcd9ef1e41a5b5465fe..6957b2d9bdee21eee0fb89ced8bce90b55cbacc5 100644
--- a/src/include/libpmemobj++/detail/life.hpp
+++ b/src/include/libpmemobj++/detail/life.hpp
@@ -38,6 +38,8 @@
#ifndef LIBPMEMOBJ_DESTROYER_HPP
#define LIBPMEMOBJ_DESTROYER_HPP
+#include <stddef.h>
+
#include "libpmemobj++/detail/array_traits.hpp"
namespace nvml
diff --git a/src/include/libpmemobj++/detail/make_atomic_impl.hpp b/src/include/libpmemobj++/detail/make_atomic_impl.hpp
index 446d3679b230148ef66f90a94ce825fe5ddf232c..37000aed59f2bc1f495f6b2362edcf79e1cdaed2 100644
--- a/src/include/libpmemobj++/detail/make_atomic_impl.hpp
+++ b/src/include/libpmemobj++/detail/make_atomic_impl.hpp
@@ -39,6 +39,7 @@
#define LIBPMEMOBJ_MAKE_ATOMIC_IMPL_HPP
#include <new>
+#include <stddef.h>
#include "libpmemobj++/detail/array_traits.hpp"
#include "libpmemobj++/detail/integer_sequence.hpp"
diff --git a/src/include/libpmemobj++/make_persistent.hpp b/src/include/libpmemobj++/make_persistent.hpp
index 45f8ad1c8580d076b40079bb2e1e76070ea7c749..ddb594dbfed2944d22889f161504e86c117cae1c 100644
--- a/src/include/libpmemobj++/make_persistent.hpp
+++ b/src/include/libpmemobj++/make_persistent.hpp
@@ -40,7 +40,7 @@
#ifndef PMEMOBJ_MAKE_PERSISTENT_HPP
#define PMEMOBJ_MAKE_PERSISTENT_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/tx_base.h"
#include "libpmemobj++/detail/check_persistent_ptr_array.hpp"
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/pexceptions.hpp"
diff --git a/src/include/libpmemobj++/make_persistent_array.hpp b/src/include/libpmemobj++/make_persistent_array.hpp
index 9b04576551f3b499a6f9734ad936e2d95bab41b9..baa85329a12c1dde677f67c870493720deb4e2f7 100644
--- a/src/include/libpmemobj++/make_persistent_array.hpp
+++ b/src/include/libpmemobj++/make_persistent_array.hpp
@@ -40,7 +40,7 @@
#ifndef PMEMOBJ_MAKE_PERSISTENT_ARRAY_HPP
#define PMEMOBJ_MAKE_PERSISTENT_ARRAY_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/tx_base.h"
#include "libpmemobj++/detail/array_traits.hpp"
#include "libpmemobj++/detail/check_persistent_ptr_array.hpp"
#include "libpmemobj++/detail/common.hpp"
diff --git a/src/include/libpmemobj++/make_persistent_array_atomic.hpp b/src/include/libpmemobj++/make_persistent_array_atomic.hpp
index 5f2fe8593cfd5cb1d743bd505e4384f27c0c99b5..4be9b901df05fc912fcb862747c8bafd0c8207cb 100644
--- a/src/include/libpmemobj++/make_persistent_array_atomic.hpp
+++ b/src/include/libpmemobj++/make_persistent_array_atomic.hpp
@@ -40,7 +40,7 @@
#ifndef PMEMOBJ_MAKE_PERSISTENT_ARRAY_ATOMIC_HPP
#define PMEMOBJ_MAKE_PERSISTENT_ARRAY_ATOMIC_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/atomic_base.h"
#include "libpmemobj++/detail/array_traits.hpp"
#include "libpmemobj++/detail/check_persistent_ptr_array.hpp"
#include "libpmemobj++/detail/common.hpp"
diff --git a/src/include/libpmemobj++/make_persistent_atomic.hpp b/src/include/libpmemobj++/make_persistent_atomic.hpp
index 856599b9547b9d7f80499933912bc8ea898a3d4c..e50a8a5e639c01f004d2b2ab4a5e37c7db578bc9 100644
--- a/src/include/libpmemobj++/make_persistent_atomic.hpp
+++ b/src/include/libpmemobj++/make_persistent_atomic.hpp
@@ -40,7 +40,7 @@
#ifndef PMEMOBJ_MAKE_PERSISTENT_ATOMIC_HPP
#define PMEMOBJ_MAKE_PERSISTENT_ATOMIC_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/atomic_base.h"
#include "libpmemobj++/detail/check_persistent_ptr_array.hpp"
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/make_atomic_impl.hpp"
diff --git a/src/include/libpmemobj++/mutex.hpp b/src/include/libpmemobj++/mutex.hpp
index b791e94bf8fba570946986d2d0b8b33a97015c29..da2de3526db7cb7adc3942cd63ee6dd6230aea8c 100644
--- a/src/include/libpmemobj++/mutex.hpp
+++ b/src/include/libpmemobj++/mutex.hpp
@@ -38,7 +38,8 @@
#ifndef PMEMOBJ_MUTEX_HPP
#define PMEMOBJ_MUTEX_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/thread.h"
+#include "libpmemobj/tx_base.h"
#include "libpmemobj++/detail/pexceptions.hpp"
namespace nvml
diff --git a/src/include/libpmemobj++/p.hpp b/src/include/libpmemobj++/p.hpp
index 212c501f5e9f8aace8654a6c2d6fceec44059b3a..9aa9ea0db0ff26406597045fa2162d126f7748e7 100644
--- a/src/include/libpmemobj++/p.hpp
+++ b/src/include/libpmemobj++/p.hpp
@@ -38,7 +38,6 @@
#ifndef PMEMOBJ_P_HPP
#define PMEMOBJ_P_HPP
-#include "libpmemobj.h"
#include <memory>
#include "libpmemobj++/detail/common.hpp"
diff --git a/src/include/libpmemobj++/persistent_ptr.hpp b/src/include/libpmemobj++/persistent_ptr.hpp
index 2e6da1c4254ea29be0ae68bfc45b0a877832ccbe..1bc347b99e09b21c3965759faaa7e8f4c4edbdb9 100644
--- a/src/include/libpmemobj++/persistent_ptr.hpp
+++ b/src/include/libpmemobj++/persistent_ptr.hpp
@@ -42,7 +42,6 @@
#include <memory>
#include <ostream>
-#include "libpmemobj.h"
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/specialization.hpp"
#include "libpmemobj++/pool.hpp"
diff --git a/src/include/libpmemobj++/pool.hpp b/src/include/libpmemobj++/pool.hpp
index 54d3200ee310860123d7b6c81faf64dc7132921c..7fe4e9d7d6cb3c25561d083d83b4da4af401100c 100644
--- a/src/include/libpmemobj++/pool.hpp
+++ b/src/include/libpmemobj++/pool.hpp
@@ -39,8 +39,9 @@
#define PMEMOBJ_POOL_HPP
#include <sys/stat.h>
+#include <stddef.h>
-#include "libpmemobj.h"
+#include "libpmemobj/pool_base.h"
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj++/p.hpp"
diff --git a/src/include/libpmemobj++/shared_mutex.hpp b/src/include/libpmemobj++/shared_mutex.hpp
index bb844988db2ba58192a1b6a1053041e52fd42b42..ac4a92deee66684da201785893e0addad04ca4b6 100644
--- a/src/include/libpmemobj++/shared_mutex.hpp
+++ b/src/include/libpmemobj++/shared_mutex.hpp
@@ -38,7 +38,8 @@
#ifndef PMEMOBJ_SHARED_MUTEX_HPP
#define PMEMOBJ_SHARED_MUTEX_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/thread.h"
+#include "libpmemobj/tx_base.h"
namespace nvml
{
diff --git a/src/include/libpmemobj++/timed_mutex.hpp b/src/include/libpmemobj++/timed_mutex.hpp
index 9966698680b616f195ffd92a7d0fac3b7d6c4aff..211449c1782aada2e2a529db1630d3f1e5520db2 100644
--- a/src/include/libpmemobj++/timed_mutex.hpp
+++ b/src/include/libpmemobj++/timed_mutex.hpp
@@ -40,7 +40,7 @@
#include <chrono>
-#include "libpmemobj.h"
+#include "libpmemobj/thread.h"
#include "libpmemobj++/detail/conversions.hpp"
namespace nvml
diff --git a/src/include/libpmemobj++/transaction.hpp b/src/include/libpmemobj++/transaction.hpp
index d04929ddb3fe3ea42755cf5ccf2c32320711b73e..4a5993d11c4a9d94f04b416820dc113a96c514c3 100644
--- a/src/include/libpmemobj++/transaction.hpp
+++ b/src/include/libpmemobj++/transaction.hpp
@@ -41,7 +41,7 @@
#include <functional>
#include <string>
-#include "libpmemobj.h"
+#include "libpmemobj/tx_base.h"
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj++/pool.hpp"
diff --git a/src/include/libpmemobj++/utils.hpp b/src/include/libpmemobj++/utils.hpp
index eae91b6ff51878a8cbf5a2b345d53870da995b9e..3e15b291fe8d8fdb0531f46aadc15b19d9e99825 100644
--- a/src/include/libpmemobj++/utils.hpp
+++ b/src/include/libpmemobj++/utils.hpp
@@ -37,7 +37,7 @@
#ifndef LIBPMEMOBJ_UTILS_HPP
#define LIBPMEMOBJ_UTILS_HPP
-#include "libpmemobj.h"
+#include "libpmemobj/base.h"
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj++/persistent_ptr.hpp"
diff --git a/src/include/libpmemobj.h b/src/include/libpmemobj.h
index d38af32b7a4d01d71ca7ff89e1002d3606c0563d..d1070f39225a883b9c95f27e542d8de568eeaaec 100644
--- a/src/include/libpmemobj.h
+++ b/src/include/libpmemobj.h
@@ -43,1069 +43,11 @@
#ifndef LIBPMEMOBJ_H
#define LIBPMEMOBJ_H 1
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <libpmemobj/atomic.h>
+#include <libpmemobj/iterator.h>
+#include <libpmemobj/lists_atomic.h>
+#include <libpmemobj/pool.h>
+#include <libpmemobj/thread.h>
+#include <libpmemobj/tx.h>
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-
-#include <errno.h>
-#include <sys/types.h>
-#include <setjmp.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <time.h>
-
-/*
- * opaque type internal to libpmemobj
- */
-typedef struct pmemobjpool PMEMobjpool;
-
-/*
- * Version checking...
- */
-
-/*
- * PMEMOBJ_MAJOR_VERSION and PMEMOBJ_MINOR_VERSION provide the current version
- * of the libpmemobj API as provided by this header file. Applications can
- * verify that the version available at run-time is compatible with the version
- * used at compile-time by passing these defines to pmemobj_check_version().
- */
-#define PMEMOBJ_MAJOR_VERSION 1
-#define PMEMOBJ_MINOR_VERSION 0
-const char *pmemobj_check_version(
- unsigned major_required,
- unsigned minor_required);
-
-#define PMEMOBJ_MIN_POOL ((size_t)(1024 * 1024 * 8)) /* 8 MB */
-#define PMEMOBJ_MAX_ALLOC_SIZE ((size_t)0x3FFDFFFC0)
-#define PMEMOBJ_MAX_LAYOUT ((size_t)1024)
-
-/*
- * Pool management...
- */
-PMEMobjpool *pmemobj_open(const char *path, const char *layout);
-PMEMobjpool *pmemobj_create(const char *path, const char *layout,
- size_t poolsize, mode_t mode);
-void pmemobj_close(PMEMobjpool *pop);
-int pmemobj_check(const char *path, const char *layout);
-
-/*
- * Passing NULL to pmemobj_set_funcs() tells libpmemobj to continue to use the
- * default for that function. The replacement functions must not make calls
- * back into libpmemobj.
- */
-void pmemobj_set_funcs(
- void *(*malloc_func)(size_t size),
- void (*free_func)(void *ptr),
- void *(*realloc_func)(void *ptr, size_t size),
- char *(*strdup_func)(const char *s));
-
-const char *pmemobj_errormsg(void);
-
-/*
- * Locking...
- */
-#define _POBJ_CL_ALIGNMENT 64 /* cache line alignment for performance */
-
-typedef struct {
- char padding[_POBJ_CL_ALIGNMENT];
-} PMEMmutex;
-
-typedef struct {
- char padding[_POBJ_CL_ALIGNMENT];
-} PMEMrwlock;
-
-typedef struct {
- char padding[_POBJ_CL_ALIGNMENT];
-} PMEMcond;
-
-void pmemobj_mutex_zero(PMEMobjpool *pop, PMEMmutex *mutexp);
-int pmemobj_mutex_lock(PMEMobjpool *pop, PMEMmutex *mutexp);
-int pmemobj_mutex_timedlock(PMEMobjpool *pop, PMEMmutex *__restrict mutexp,
- const struct timespec *__restrict abs_timeout);
-int pmemobj_mutex_trylock(PMEMobjpool *pop, PMEMmutex *mutexp);
-int pmemobj_mutex_unlock(PMEMobjpool *pop, PMEMmutex *mutexp);
-
-void pmemobj_rwlock_zero(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-int pmemobj_rwlock_rdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-int pmemobj_rwlock_wrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-int pmemobj_rwlock_timedrdlock(PMEMobjpool *pop,
- PMEMrwlock *__restrict rwlockp,
- const struct timespec *__restrict abs_timeout);
-int pmemobj_rwlock_timedwrlock(PMEMobjpool *pop,
- PMEMrwlock *__restrict rwlockp,
- const struct timespec *__restrict abs_timeout);
-int pmemobj_rwlock_tryrdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-int pmemobj_rwlock_trywrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-int pmemobj_rwlock_unlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
-
-void pmemobj_cond_zero(PMEMobjpool *pop, PMEMcond *condp);
-int pmemobj_cond_broadcast(PMEMobjpool *pop, PMEMcond *condp);
-int pmemobj_cond_signal(PMEMobjpool *pop, PMEMcond *condp);
-int pmemobj_cond_timedwait(PMEMobjpool *pop, PMEMcond *__restrict condp,
- PMEMmutex *__restrict mutexp,
- const struct timespec *__restrict abs_timeout);
-int pmemobj_cond_wait(PMEMobjpool *pop, PMEMcond *condp,
- PMEMmutex *__restrict mutexp);
-
-/*
- * Persistent memory object
- */
-
-/*
- * Object handle
- */
-typedef struct pmemoid {
- uint64_t pool_uuid_lo;
- uint64_t off;
-} PMEMoid;
-
-static const PMEMoid OID_NULL = { 0, 0 };
-
-#define TOID_NULL(t) ((TOID(t))OID_NULL)
-#define OID_IS_NULL(o) ((o).off == 0)
-#define OID_EQUALS(lhs, rhs)\
-((lhs).off == (rhs).off &&\
- (lhs).pool_uuid_lo == (rhs).pool_uuid_lo)
-
-/*
- * Type safety macros
- */
-#ifndef _MSC_VER
-
-#define TOID_ASSIGN(o, value)(\
-{\
- (o).oid = value;\
- (o); /* to avoid "error: statement with no effect" */\
-})
-
-#else /* _MSC_VER */
-
-#define TOID_ASSIGN(o, value) ((o).oid = value, (o))
-
-#endif /* _MSC_VER */
-
-#define TOID_EQUALS(lhs, rhs)\
-((lhs).oid.off == (rhs).oid.off &&\
- (lhs).oid.pool_uuid_lo == (rhs).oid.pool_uuid_lo)
-
-/* type number of root object */
-#define POBJ_ROOT_TYPE_NUM 0
-#define _toid_struct
-#define _toid_union
-#define _toid_enum
-#define _POBJ_LAYOUT_REF(name) (sizeof(_pobj_layout_##name##_ref))
-
-/*
- * Typed OID
- */
-#define TOID(t)\
-union _toid_##t##_toid
-
-#ifdef __cplusplus
-#define _TOID_CONSTR(t)\
-_toid_##t##_toid()\
-{ }\
-_toid_##t##_toid(PMEMoid _oid) : oid(_oid)\
-{ }
-#else
-#define _TOID_CONSTR(t)
-#endif
-
-/*
- * Declaration of typed OID
- */
-#define _TOID_DECLARE(t, i)\
-typedef uint8_t _toid_##t##_toid_type_num[(i) + 1];\
-TOID(t)\
-{\
- _TOID_CONSTR(t)\
- PMEMoid oid;\
- t *_type;\
- _toid_##t##_toid_type_num *_type_num;\
-}
-
-/*
- * Declaration of typed OID of an object
- */
-#define TOID_DECLARE(t, i) _TOID_DECLARE(t, i)
-
-/*
- * Declaration of typed OID of a root object
- */
-#define TOID_DECLARE_ROOT(t) _TOID_DECLARE(t, POBJ_ROOT_TYPE_NUM)
-
-/*
- * Type number of specified type
- */
-#define TOID_TYPE_NUM(t) (sizeof(_toid_##t##_toid_type_num) - 1)
-
-/*
- * Type number of object read from typed OID
- */
-#define TOID_TYPE_NUM_OF(o) (sizeof(*(o)._type_num) - 1)
-
-/*
- * NULL check
- */
-#define TOID_IS_NULL(o) ((o).oid.off == 0)
-
-/*
- * Validates whether type number stored in typed OID is the same
- * as type number stored in object's metadata
- */
-#define TOID_VALID(o) (TOID_TYPE_NUM_OF(o) == pmemobj_type_num((o).oid))
-
-/*
- * Checks whether the object is of a given type
- */
-#define OID_INSTANCEOF(o, t) (TOID_TYPE_NUM(t) == pmemobj_type_num(o))
-
-/*
- * Begin of layout declaration
- */
-#define POBJ_LAYOUT_BEGIN(name)\
-typedef uint8_t _pobj_layout_##name##_ref[__COUNTER__ + 1]
-
-/*
- * End of layout declaration
- */
-#define POBJ_LAYOUT_END(name)\
-typedef char _pobj_layout_##name##_cnt[__COUNTER__ + 1 -\
-_POBJ_LAYOUT_REF(name)];
-
-/*
- * Number of types declared inside layout without the root object
- */
-#define POBJ_LAYOUT_TYPES_NUM(name) (sizeof(_pobj_layout_##name##_cnt) - 1)
-
-/*
- * Declaration of typed OID inside layout declaration
- */
-#define POBJ_LAYOUT_TOID(name, t)\
-TOID_DECLARE(t, (__COUNTER__ + 1 - _POBJ_LAYOUT_REF(name)));
-
-/*
- * Declaration of typed OID of root inside layout declaration
- */
-#define POBJ_LAYOUT_ROOT(name, t)\
-TOID_DECLARE_ROOT(t);
-
-/*
- * Name of declared layout
- */
-#define POBJ_LAYOUT_NAME(name) #name
-
-PMEMobjpool *pmemobj_pool_by_ptr(const void *addr);
-PMEMobjpool *pmemobj_pool_by_oid(PMEMoid oid);
-
-#ifndef _WIN32
-
-extern int _pobj_cache_invalidate;
-extern __thread struct _pobj_pcache {
- PMEMobjpool *pop;
- uint64_t uuid_lo;
- int invalidate;
-} _pobj_cached_pool;
-
-/*
- * Returns the direct pointer of an object.
- */
-static inline void *
-pmemobj_direct(PMEMoid oid)
-{
- if (oid.off == 0 || oid.pool_uuid_lo == 0)
- return NULL;
-
- if (_pobj_cache_invalidate != _pobj_cached_pool.invalidate ||
- _pobj_cached_pool.uuid_lo != oid.pool_uuid_lo) {
- _pobj_cached_pool.invalidate = _pobj_cache_invalidate;
-
- if (!(_pobj_cached_pool.pop = pmemobj_pool_by_oid(oid))) {
- _pobj_cached_pool.uuid_lo = 0;
- return NULL;
- }
-
- _pobj_cached_pool.uuid_lo = oid.pool_uuid_lo;
- }
-
- return (void *)((uintptr_t)_pobj_cached_pool.pop + oid.off);
-}
-
-#else /* _WIN32 */
-
-/* XXX - this is temporary (see obj.c for details) */
-
-/*
- * Returns the direct pointer of an object.
- */
-void *pmemobj_direct(PMEMoid oid);
-
-#endif /* _WIN32 */
-
-#define TOID_TYPEOF(o) __typeof__(*(o)._type)
-
-#define TOID_OFFSETOF(o, field) offsetofp(__typeof__((o)._type), field)
-
-/*
- * XXX - DIRECT_RW and DIRECT_RO are not available when compiled using VC++
- * as C code (/TC). Use /TP option.
- */
-#ifndef _MSC_VER
-
-#define DIRECT_RW(o) (\
-{__typeof__(o) _o; _o._type = NULL; (void)_o;\
-(__typeof__(*(o)._type) *)pmemobj_direct((o).oid); })
-#define DIRECT_RO(o) ((const __typeof__(*(o)._type) *)pmemobj_direct((o).oid))
-
-#elif defined(__cplusplus)
-
-/*
- * XXX - On Windows, these macros do not behave exactly the same as on Linux.
- */
-#define DIRECT_RW(o) ((__typeof__((o)._type))pmemobj_direct((o).oid))
-#define DIRECT_RO(o) ((const __typeof__((o)._type))pmemobj_direct((o).oid))
-
-#endif /* (defined(_MSC_VER) || defined(__cplusplus)) */
-
-#define D_RW DIRECT_RW
-#define D_RO DIRECT_RO
-
-/*
- * Non-transactional atomic allocations
- *
- * Those functions can be used outside transactions. The allocations are always
- * aligned to the cache-line boundary.
- */
-
-typedef int (*pmemobj_constr)(PMEMobjpool *pop, void *ptr, void *arg);
-
-/*
- * Allocates a new object from the pool and calls a constructor function before
- * returning. It is guaranteed that allocated object is either properly
- * initialized, or if it's interrupted before the constructor completes, the
- * memory reserved for the object is automatically reclaimed.
- */
-int pmemobj_alloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
- uint64_t type_num, pmemobj_constr constructor, void *arg);
-
-/*
- * Allocates a new zeroed object from the pool.
- */
-int pmemobj_zalloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
- uint64_t type_num);
-
-/*
- * Resizes an existing object.
- */
-int pmemobj_realloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
- uint64_t type_num);
-
-/*
- * Resizes an existing object, if extended new space is zeroed.
- */
-int pmemobj_zrealloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
- uint64_t type_num);
-
-/*
- * Allocates a new object with duplicate of the string s.
- */
-int pmemobj_strdup(PMEMobjpool *pop, PMEMoid *oidp, const char *s,
- uint64_t type_num);
-
-/*
- * Frees an existing object.
- */
-void pmemobj_free(PMEMoid *oidp);
-
-/*
- * Returns the number of usable bytes in the object. May be greater than
- * the requested size of the object because of internal alignment.
- *
- * Can be used with objects allocated by any of the available methods.
- */
-size_t pmemobj_alloc_usable_size(PMEMoid oid);
-
-/*
- * Returns the type number of the object.
- */
-uint64_t pmemobj_type_num(PMEMoid oid);
-
-/*
- * If called for the first time on a newly created pool, the root object
- * of given size is allocated. Otherwise, it returns the existing root object.
- * In such case, the size must be not less than the actual root object size
- * stored in the pool. If it's larger, the root object is automatically
- * resized.
- *
- * This function is thread-safe.
- */
-PMEMoid pmemobj_root(PMEMobjpool *pop, size_t size);
-
-/*
- * Same as above, but calls the constructor function when the object is first
- * created and on all subsequent reallocations.
- */
-PMEMoid pmemobj_root_construct(PMEMobjpool *pop, size_t size,
- pmemobj_constr constructor, void *arg);
-
-/*
- * Returns the size in bytes of the root object. Always equal to the requested
- * size.
- */
-size_t pmemobj_root_size(PMEMobjpool *pop);
-
-/*
- * Pmemobj specific low-level memory manipulation functions.
- *
- * These functions are meant to be used with pmemobj pools, because they provide
- * additional functionality specific to this type of pool. These may include
- * for example replication support. They also take advantage of the knowledge
- * of the type of memory in the pool (pmem/non-pmem) to assure persistence.
- */
-
-/*
- * Pmemobj version of memcpy. Data copied is made persistent.
- */
-void *pmemobj_memcpy_persist(PMEMobjpool *pop, void *dest, const void *src,
- size_t len);
-
-/*
- * Pmemobj version of memset. Data range set is made persistent.
- */
-void *pmemobj_memset_persist(PMEMobjpool *pop, void *dest, int c, size_t len);
-
-/*
- * Pmemobj version of pmem_persist.
- */
-void pmemobj_persist(PMEMobjpool *pop, const void *addr, size_t len);
-
-/*
- * Pmemobj version of pmem_flush.
- */
-void pmemobj_flush(PMEMobjpool *pop, const void *addr, size_t len);
-
-/*
- * Pmemobj version of pmem_drain.
- */
-void pmemobj_drain(PMEMobjpool *pop);
-
-/*
- * The following set of macros and functions allow access to the entire
- * collection of objects, or objects of given type.
- *
- * Use with conjunction with non-transactional allocations. Pmemobj pool acts
- * as a generic container (list) of objects that are not assigned to any
- * user-defined data structures.
- */
-
-/*
- * Returns the first object of the specified type number.
- */
-PMEMoid pmemobj_first(PMEMobjpool *pop);
-
-/*
- * Returns the next object of the same type.
- */
-PMEMoid pmemobj_next(PMEMoid oid);
-
-
-static inline PMEMoid
-POBJ_FIRST_TYPE_NUM(PMEMobjpool *pop, uint64_t type_num)
-{
- PMEMoid _pobj_ret = pmemobj_first(pop);
-
- while (!OID_IS_NULL(_pobj_ret) &&
- pmemobj_type_num(_pobj_ret) != type_num) {
- _pobj_ret = pmemobj_next(_pobj_ret);
- }
- return _pobj_ret;
-}
-
-static inline PMEMoid
-POBJ_NEXT_TYPE_NUM(PMEMoid o)
-{
- PMEMoid _pobj_ret = o;
-
- do {
- _pobj_ret = pmemobj_next(_pobj_ret);\
- } while (!OID_IS_NULL(_pobj_ret) &&
- pmemobj_type_num(_pobj_ret) != pmemobj_type_num(o));
- return _pobj_ret;
-}
-
-
-#define POBJ_FIRST(pop, t) ((TOID(t))POBJ_FIRST_TYPE_NUM(pop, TOID_TYPE_NUM(t)))
-
-#define POBJ_NEXT(o) ((__typeof__(o))POBJ_NEXT_TYPE_NUM((o).oid))
-
-
-#define POBJ_NEW(pop, o, t, constr, arg)\
-pmemobj_alloc((pop), (PMEMoid *)(o), sizeof(t), TOID_TYPE_NUM(t),\
- (constr), (arg))
-
-#define POBJ_ALLOC(pop, o, t, size, constr, arg)\
-pmemobj_alloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t),\
- (constr), (arg))
-
-#define POBJ_ZNEW(pop, o, t)\
-pmemobj_zalloc((pop), (PMEMoid *)(o), sizeof(t), TOID_TYPE_NUM(t))
-
-#define POBJ_ZALLOC(pop, o, t, size)\
-pmemobj_zalloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
-
-#define POBJ_REALLOC(pop, o, t, size)\
-pmemobj_realloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
-
-#define POBJ_ZREALLOC(pop, o, t, size)\
-pmemobj_zrealloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
-
-#define POBJ_FREE(o)\
-pmemobj_free((PMEMoid *)(o))
-
-
-#define POBJ_ROOT(pop, t) (\
-(TOID(t))pmemobj_root((pop), sizeof(t)))
-
-
-/*
- * (debug helper function) logs notice message if used inside a transaction
- */
-void _pobj_debug_notice(const char *func_name, const char *file, int line);
-
-/*
- * Debug helper function and macros
- */
-#ifdef DEBUG
-
-/*
- * (debug helper macro) logs notice message if used inside a transaction
- */
-#define _POBJ_DEBUG_NOTICE_IN_TX()\
- _pobj_debug_notice(__func__, NULL, 0)
-
-/*
- * (debug helper macro) logs notice message if used inside a transaction
- * - to be used only in FOREACH macros
- */
-#define _POBJ_DEBUG_NOTICE_IN_TX_FOR(macro_name)\
- _pobj_debug_notice(macro_name, __FILE__, __LINE__),
-
-#else
-#define _POBJ_DEBUG_NOTICE_IN_TX() do {} while (0)
-#define _POBJ_DEBUG_NOTICE_IN_TX_FOR(macro_name)
-#endif /* DEBUG */
-
-/*
- * Iterates through every existing allocated object.
- */
-#define POBJ_FOREACH(pop, varoid)\
-for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_FOREACH")\
- varoid = pmemobj_first(pop);\
- (varoid).off != 0; varoid = pmemobj_next(varoid))
-
-/*
- * Safe variant of POBJ_FOREACH in which pmemobj_free on varoid is allowed
- */
-#define POBJ_FOREACH_SAFE(pop, varoid, nvaroid)\
-for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_FOREACH_SAFE")\
- varoid = pmemobj_first(pop);\
- (varoid).off != 0 && (nvaroid = pmemobj_next(varoid), 1);\
- varoid = nvaroid)
-
-/*
- * Iterates through every object of the specified type.
- */
-#define POBJ_FOREACH_TYPE(pop, var)\
-POBJ_FOREACH(pop, (var).oid)\
-if (pmemobj_type_num((var).oid) == TOID_TYPE_NUM_OF(var))
-
-/*
- * Safe variant of POBJ_FOREACH_TYPE in which pmemobj_free on var
- * is allowed.
- */
-#define POBJ_FOREACH_SAFE_TYPE(pop, var, nvar)\
-POBJ_FOREACH_SAFE(pop, (var).oid, (nvar).oid)\
-if (pmemobj_type_num((var).oid) == TOID_TYPE_NUM_OF(var))
-
-/*
- * Non-transactional persistent atomic circular doubly-linked list
- */
-#define POBJ_LIST_ENTRY(type)\
-struct {\
- TOID(type) pe_next;\
- TOID(type) pe_prev;\
-}
-
-#define POBJ_LIST_HEAD(name, type)\
-struct name {\
- TOID(type) pe_first;\
- PMEMmutex lock;\
-}
-
-int pmemobj_list_insert(PMEMobjpool *pop, size_t pe_offset, void *head,
- PMEMoid dest, int before, PMEMoid oid);
-
-PMEMoid pmemobj_list_insert_new(PMEMobjpool *pop, size_t pe_offset, void *head,
- PMEMoid dest, int before, size_t size, uint64_t type_num,
- pmemobj_constr constructor, void *arg);
-
-int pmemobj_list_remove(PMEMobjpool *pop, size_t pe_offset, void *head,
- PMEMoid oid, int free);
-
-int pmemobj_list_move(PMEMobjpool *pop, size_t pe_old_offset,
- void *head_old, size_t pe_new_offset, void *head_new,
- PMEMoid dest, int before, PMEMoid oid);
-
-/*
- * similar to offsetof, except that it takes a structure pointer,
- * instead of a structure type name
- */
-#define offsetofp(s, m) ((size_t)&(((s)0)->m))
-
-#define POBJ_LIST_FIRST(head) ((head)->pe_first)
-#define POBJ_LIST_LAST(head, field) (\
-TOID_IS_NULL((head)->pe_first) ?\
-(head)->pe_first :\
-D_RO((head)->pe_first)->field.pe_prev)
-
-#define POBJ_LIST_EMPTY(head) (TOID_IS_NULL((head)->pe_first))
-#define POBJ_LIST_NEXT(elm, field) (D_RO(elm)->field.pe_next)
-#define POBJ_LIST_PREV(elm, field) (D_RO(elm)->field.pe_prev)
-#define POBJ_LIST_DEST_HEAD 1
-#define POBJ_LIST_DEST_TAIL 0
-
-#define POBJ_LIST_FOREACH(var, head, field)\
-for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_LIST_FOREACH")\
- (var) = POBJ_LIST_FIRST((head));\
- TOID_IS_NULL((var)) == 0;\
- TOID_EQUALS(POBJ_LIST_NEXT((var), field),\
- POBJ_LIST_FIRST((head))) ?\
- TOID_ASSIGN((var), OID_NULL) :\
- ((var) = POBJ_LIST_NEXT((var), field)))
-
-#define POBJ_LIST_FOREACH_REVERSE(var, head, field)\
-for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_LIST_FOREACH_REVERSE")\
- (var) = POBJ_LIST_LAST((head), field);\
- TOID_IS_NULL((var)) == 0;\
- TOID_EQUALS(POBJ_LIST_PREV((var), field),\
- POBJ_LIST_LAST((head), field)) ?\
- TOID_ASSIGN((var), OID_NULL) :\
- ((var) = POBJ_LIST_PREV((var), field)))
-
-#define POBJ_LIST_INSERT_HEAD(pop, head, elm, field)\
-pmemobj_list_insert((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), OID_NULL,\
- POBJ_LIST_DEST_HEAD, (elm).oid)
-
-#define POBJ_LIST_INSERT_TAIL(pop, head, elm, field)\
-pmemobj_list_insert((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), OID_NULL,\
- POBJ_LIST_DEST_TAIL, (elm).oid)
-
-#define POBJ_LIST_INSERT_AFTER(pop, head, listelm, elm, field)\
-pmemobj_list_insert((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), (listelm).oid,\
- 0 /* after */, (elm).oid)
-
-#define POBJ_LIST_INSERT_BEFORE(pop, head, listelm, elm, field)\
-pmemobj_list_insert((pop), \
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), (listelm).oid,\
- 1 /* before */, (elm).oid)
-
-#define POBJ_LIST_INSERT_NEW_HEAD(pop, head, field, size, constr, arg)\
-pmemobj_list_insert_new((pop),\
- TOID_OFFSETOF((head)->pe_first, field),\
- (head), OID_NULL, POBJ_LIST_DEST_HEAD, (size),\
- TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
-
-#define POBJ_LIST_INSERT_NEW_TAIL(pop, head, field, size, constr, arg)\
-pmemobj_list_insert_new((pop),\
- TOID_OFFSETOF((head)->pe_first, field),\
- (head), OID_NULL, POBJ_LIST_DEST_TAIL, (size),\
- TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
-
-#define POBJ_LIST_INSERT_NEW_AFTER(pop, head, listelm, field, size,\
- constr, arg)\
-pmemobj_list_insert_new((pop),\
- TOID_OFFSETOF((head)->pe_first, field),\
- (head), (listelm).oid, 0 /* after */, (size),\
- TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
-
-#define POBJ_LIST_INSERT_NEW_BEFORE(pop, head, listelm, field, size,\
- constr, arg)\
-pmemobj_list_insert_new((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), (listelm).oid, 1 /* before */, (size),\
- TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
-
-#define POBJ_LIST_REMOVE(pop, head, elm, field)\
-pmemobj_list_remove((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), (elm).oid, 0 /* no free */)
-
-#define POBJ_LIST_REMOVE_FREE(pop, head, elm, field)\
-pmemobj_list_remove((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head), (elm).oid, 1 /* free */)
-
-#define POBJ_LIST_MOVE_ELEMENT_HEAD(pop, head, head_new, elm, field, field_new)\
-pmemobj_list_move((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
- (head_new), OID_NULL, POBJ_LIST_DEST_HEAD, (elm).oid)
-
-#define POBJ_LIST_MOVE_ELEMENT_TAIL(pop, head, head_new, elm, field, field_new)\
-pmemobj_list_move((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
- (head_new), OID_NULL, POBJ_LIST_DEST_TAIL, (elm).oid)
-
-#define POBJ_LIST_MOVE_ELEMENT_AFTER(pop,\
- head, head_new, listelm, elm, field, field_new)\
-pmemobj_list_move((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
- (head_new),\
- (listelm).oid,\
- 0 /* after */, (elm).oid)
-
-#define POBJ_LIST_MOVE_ELEMENT_BEFORE(pop,\
- head, head_new, listelm, elm, field, field_new)\
-pmemobj_list_move((pop),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
- (head),\
- TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
- (head_new),\
- (listelm).oid,\
- 1 /* before */, (elm).oid)
-
-/*
- * Transactions
- *
- * Stages are changed only by the pmemobj_tx_* functions, each transition
- * to the TX_STAGE_ONABORT is followed by a longjmp to the jmp_buf provided in
- * the pmemobj_tx_begin function.
- */
-enum pobj_tx_stage {
- TX_STAGE_NONE, /* no transaction in this thread */
- TX_STAGE_WORK, /* transaction in progress */
- TX_STAGE_ONCOMMIT, /* successfully committed */
- TX_STAGE_ONABORT, /* tx_begin failed or transaction aborted */
- TX_STAGE_FINALLY, /* always called */
-
- MAX_TX_STAGE
-};
-
-/*
- * Always returns the current transaction stage for a thread.
- */
-enum pobj_tx_stage pmemobj_tx_stage(void);
-
-enum pobj_tx_lock {
- TX_LOCK_NONE,
- TX_LOCK_MUTEX, /* PMEMmutex */
- TX_LOCK_RWLOCK /* PMEMrwlock */
-};
-
-/*
- * Starts a new transaction in the current thread.
- * If called within an open transaction, starts a nested transaction.
- *
- * If successful, transaction stage changes to TX_STAGE_WORK and function
- * returns zero. Otherwise, stage changes to TX_STAGE_ONABORT and an error
- * number is returned.
- */
-int pmemobj_tx_begin(PMEMobjpool *pop, jmp_buf env, ...);
-
-/*
- * Adds lock of given type to current transaction.
- */
-int pmemobj_tx_lock(enum pobj_tx_lock type, void *lockp);
-
-/*
- * Aborts current transaction
- *
- * Causes transition to TX_STAGE_ONABORT.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-void pmemobj_tx_abort(int errnum);
-
-/*
- * Commits current transaction
- *
- * This function must be called during TX_STAGE_WORK.
- */
-void pmemobj_tx_commit(void);
-
-/*
- * Cleanups current transaction. Must always be called after pmemobj_tx_begin,
- * even if starting the transaction failed.
- *
- * If called during TX_STAGE_NONE, has no effect.
- *
- * Always causes transition to TX_STAGE_NONE.
- *
- * If transaction was successful, returns 0. Otherwise returns error code set
- * by pmemobj_tx_abort.
- *
- * This function must *not* be called during TX_STAGE_WORK.
- */
-int pmemobj_tx_end(void);
-
-/*
- * Performs the actions associated with current stage of the transaction,
- * and makes the transition to the next stage. Current stage must always
- * be obtained by calling pmemobj_tx_stage.
- *
- * This function must be called in transaction.
- */
-void pmemobj_tx_process(void);
-
-/*
- * Returns last transaction error code.
- */
-int pmemobj_tx_errno(void);
-
-#ifdef POBJ_TX_CRASH_ON_NO_ONABORT
-#define TX_ONABORT_CHECK do {\
- if (_stage == TX_STAGE_ONABORT)\
- abort();\
- } while (0)
-#else
-#define TX_ONABORT_CHECK do {} while (0)
-#endif
-
-#define _POBJ_TX_BEGIN(pop, ...)\
-{\
- jmp_buf _tx_env;\
- int _stage;\
- int _pobj_errno;\
- if (setjmp(_tx_env)) {\
- errno = pmemobj_tx_errno();\
- } else {\
- _pobj_errno = pmemobj_tx_begin(pop, _tx_env, __VA_ARGS__,\
- TX_LOCK_NONE);\
- if (_pobj_errno)\
- errno = _pobj_errno;\
- }\
- while ((_stage = pmemobj_tx_stage()) != TX_STAGE_NONE) {\
- switch (_stage) {\
- case TX_STAGE_WORK:
-
-#define TX_BEGIN_LOCK(pop, ...)\
-_POBJ_TX_BEGIN(pop, ##__VA_ARGS__)
-
-#define TX_BEGIN(pop) _POBJ_TX_BEGIN(pop, TX_LOCK_NONE)
-
-#define TX_ONABORT\
- pmemobj_tx_process();\
- break;\
- case TX_STAGE_ONABORT:
-
-#define TX_ONCOMMIT\
- pmemobj_tx_process();\
- break;\
- case TX_STAGE_ONCOMMIT:
-
-#define TX_FINALLY\
- pmemobj_tx_process();\
- break;\
- case TX_STAGE_FINALLY:
-
-#define TX_END\
- pmemobj_tx_process();\
- break;\
- default:\
- TX_ONABORT_CHECK;\
- pmemobj_tx_process();\
- break;\
- }\
- }\
- _pobj_errno = pmemobj_tx_end();\
- if (_pobj_errno)\
- errno = _pobj_errno;\
-}
-
-/*
- * Takes a "snapshot" of the memory block of given size and located at given
- * offset 'off' in the object 'oid' and saves it in the undo log.
- * The application is then free to directly modify the object in that memory
- * range. In case of failure or abort, all the changes within this range will
- * be rolled-back automatically.
- *
- * If successful, returns zero.
- * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-int pmemobj_tx_add_range(PMEMoid oid, uint64_t off, size_t size);
-
-/*
- * Takes a "snapshot" of the given memory region and saves it in the undo log.
- * The application is then free to directly modify the object in that memory
- * range. In case of failure or abort, all the changes within this range will
- * be rolled-back automatically. The supplied block of memory has to be within
- * the given pool.
- *
- * If successful, returns zero.
- * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-int pmemobj_tx_add_range_direct(const void *ptr, size_t size);
-
-/*
- * Transactionally allocates a new object.
- *
- * If successful, returns PMEMoid.
- * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-PMEMoid pmemobj_tx_alloc(size_t size, uint64_t type_num);
-
-/*
- * Transactionally allocates new zeroed object.
- *
- * If successful, returns PMEMoid.
- * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-PMEMoid pmemobj_tx_zalloc(size_t size, uint64_t type_num);
-
-/*
- * Transactionally resizes an existing object.
- *
- * If successful, returns PMEMoid.
- * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-PMEMoid pmemobj_tx_realloc(PMEMoid oid, size_t size, uint64_t type_num);
-
-/*
- * Transactionally resizes an existing object, if extended new space is zeroed.
- *
- * If successful, returns PMEMoid.
- * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-PMEMoid pmemobj_tx_zrealloc(PMEMoid oid, size_t size, uint64_t type_num);
-
-/*
- * Transactionally allocates a new object with duplicate of the string s.
- *
- * If successful, returns PMEMoid.
- * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-PMEMoid pmemobj_tx_strdup(const char *s, uint64_t type_num);
-
-/*
- * Transactionally frees an existing object.
- *
- * If successful, returns zero.
- * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
- *
- * This function must be called during TX_STAGE_WORK.
- */
-int pmemobj_tx_free(PMEMoid oid);
-
-
-#define TX_ADD(o)\
-pmemobj_tx_add_range((o).oid, 0, sizeof(*(o)._type))
-
-#define TX_ADD_FIELD(o, field)\
-pmemobj_tx_add_range((o).oid, TOID_OFFSETOF(o, field),\
- sizeof(D_RO(o)->field))
-
-#define TX_ADD_DIRECT(p)\
-pmemobj_tx_add_range_direct(p, sizeof(*p))
-
-#define TX_ADD_FIELD_DIRECT(p, field)\
-pmemobj_tx_add_range_direct(&(p)->field, sizeof((p)->field))
-
-
-#define TX_NEW(t)\
-((TOID(t))pmemobj_tx_alloc(sizeof(t), TOID_TYPE_NUM(t)))
-
-#define TX_ALLOC(t, size)\
-((TOID(t))pmemobj_tx_alloc(size, TOID_TYPE_NUM(t)))
-
-#define TX_ZNEW(t)\
-((TOID(t))pmemobj_tx_zalloc(sizeof(t), TOID_TYPE_NUM(t)))
-
-#define TX_ZALLOC(t, size)\
-((TOID(t))pmemobj_tx_zalloc(size, TOID_TYPE_NUM(t)))
-
-/* XXX - not available when compiled with VC++ as C code (/TC) */
-#ifndef _MSC_VER
-
-#define TX_REALLOC(o, size) (\
-{__typeof__(o) ret = (__typeof__(o))pmemobj_tx_realloc((o).oid, size,\
- TOID_TYPE_NUM_OF(o));\
-ret; })
-
-#define TX_ZREALLOC(o, size) (\
-{__typeof__(o) ret = (__typeof__(o))pmemobj_tx_zrealloc((o).oid, size,\
- TOID_TYPE_NUM_OF(o));\
-ret; })
-
-#elif defined(__cplusplus)
-
-#define TX_REALLOC(o, size)\
-((__typeof__(o))pmemobj_tx_realloc((o).oid, size, TOID_TYPE_NUM_OF(o)))
-
-#define TX_ZREALLOC(o, size)\
-((__typeof__(o))pmemobj_tx_zrealloc((o).oid, size, TOID_TYPE_NUM_OF(o)))
-
-#endif /* (defined(_MSC_VER) || defined(__cplusplus)) */
-
-#define TX_STRDUP(s, type_num)\
-pmemobj_tx_strdup(s, type_num)
-
-#define TX_FREE(o)\
-pmemobj_tx_free((o).oid)
-
-#define TX_SET(o, field, value) (\
- TX_ADD_FIELD(o, field),\
- D_RW(o)->field = value)
-
-#define TX_SET_DIRECT(p, field, value) (\
- TX_ADD_FIELD_DIRECT(p, field),\
- (p)->field = value)
-
-static inline void *
-TX_MEMCPY(void *dest, const void *src, size_t num)
-{
- pmemobj_tx_add_range_direct(dest, num);
- return memcpy(dest, src, num);
-}
-
-static inline void *
-TX_MEMSET(void *dest, int c, size_t num)
-{
- pmemobj_tx_add_range_direct(dest, num);
- return memset(dest, c, num);
-}
-
-#ifdef __cplusplus
-}
-#endif
#endif /* libpmemobj.h */
diff --git a/src/include/libpmemobj/atomic.h b/src/include/libpmemobj/atomic.h
new file mode 100644
index 0000000000000000000000000000000000000000..1db841317e810ed034cf5d9f79473e2fe8d9fb89
--- /dev/null
+++ b/src/include/libpmemobj/atomic.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/atomic.h -- definitions of libpmemobj atomic macros
+ */
+
+#ifndef LIBPMEMOBJ_ATOMIC_H
+#define LIBPMEMOBJ_ATOMIC_H 1
+
+#include <libpmemobj/atomic_base.h>
+#include <libpmemobj/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define POBJ_NEW(pop, o, t, constr, arg)\
+pmemobj_alloc((pop), (PMEMoid *)(o), sizeof(t), TOID_TYPE_NUM(t),\
+ (constr), (arg))
+
+#define POBJ_ALLOC(pop, o, t, size, constr, arg)\
+pmemobj_alloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t),\
+ (constr), (arg))
+
+#define POBJ_ZNEW(pop, o, t)\
+pmemobj_zalloc((pop), (PMEMoid *)(o), sizeof(t), TOID_TYPE_NUM(t))
+
+#define POBJ_ZALLOC(pop, o, t, size)\
+pmemobj_zalloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
+
+#define POBJ_REALLOC(pop, o, t, size)\
+pmemobj_realloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
+
+#define POBJ_ZREALLOC(pop, o, t, size)\
+pmemobj_zrealloc((pop), (PMEMoid *)(o), (size), TOID_TYPE_NUM(t))
+
+#define POBJ_FREE(o)\
+pmemobj_free((PMEMoid *)(o))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/atomic.h */
diff --git a/src/include/libpmemobj/atomic_base.h b/src/include/libpmemobj/atomic_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..9229e35500ae251a886ebb878bb8ade9f55777c0
--- /dev/null
+++ b/src/include/libpmemobj/atomic_base.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/atomic_base.h -- definitions of libpmemobj atomic entry points
+ */
+
+#ifndef LIBPMEMOBJ_ATOMIC_BASE_H
+#define LIBPMEMOBJ_ATOMIC_BASE_H 1
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Non-transactional atomic allocations
+ *
+ * Those functions can be used outside transactions. The allocations are always
+ * aligned to the cache-line boundary.
+ */
+
+/*
+ * Allocates a new object from the pool and calls a constructor function before
+ * returning. It is guaranteed that allocated object is either properly
+ * initialized, or if it's interrupted before the constructor completes, the
+ * memory reserved for the object is automatically reclaimed.
+ */
+int pmemobj_alloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
+ uint64_t type_num, pmemobj_constr constructor, void *arg);
+
+/*
+ * Allocates a new zeroed object from the pool.
+ */
+int pmemobj_zalloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
+ uint64_t type_num);
+
+/*
+ * Resizes an existing object.
+ */
+int pmemobj_realloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
+ uint64_t type_num);
+
+/*
+ * Resizes an existing object, if extended new space is zeroed.
+ */
+int pmemobj_zrealloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size,
+ uint64_t type_num);
+
+/*
+ * Allocates a new object with duplicate of the string s.
+ */
+int pmemobj_strdup(PMEMobjpool *pop, PMEMoid *oidp, const char *s,
+ uint64_t type_num);
+
+/*
+ * Frees an existing object.
+ */
+void pmemobj_free(PMEMoid *oidp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/atomic_base.h */
diff --git a/src/include/libpmemobj/base.h b/src/include/libpmemobj/base.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f968c73138e329850ad572346f1e9f68d6a2bf8
--- /dev/null
+++ b/src/include/libpmemobj/base.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/base.h -- definitions of base libpmemobj entry points
+ */
+
+#ifndef LIBPMEMOBJ_BASE_H
+#define LIBPMEMOBJ_BASE_H 1
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * opaque type internal to libpmemobj
+ */
+typedef struct pmemobjpool PMEMobjpool;
+
+#define PMEMOBJ_MAX_ALLOC_SIZE ((size_t)0x3FFDFFFC0)
+
+/*
+ * Persistent memory object
+ */
+
+/*
+ * Object handle
+ */
+typedef struct pmemoid {
+ uint64_t pool_uuid_lo;
+ uint64_t off;
+} PMEMoid;
+
+static const PMEMoid OID_NULL = { 0, 0 };
+#define OID_IS_NULL(o) ((o).off == 0)
+#define OID_EQUALS(lhs, rhs)\
+((lhs).off == (rhs).off &&\
+ (lhs).pool_uuid_lo == (rhs).pool_uuid_lo)
+
+PMEMobjpool *pmemobj_pool_by_ptr(const void *addr);
+PMEMobjpool *pmemobj_pool_by_oid(PMEMoid oid);
+
+#ifndef _WIN32
+
+extern int _pobj_cache_invalidate;
+extern __thread struct _pobj_pcache {
+ PMEMobjpool *pop;
+ uint64_t uuid_lo;
+ int invalidate;
+} _pobj_cached_pool;
+
+/*
+ * Returns the direct pointer of an object.
+ */
+static inline void *
+pmemobj_direct(PMEMoid oid)
+{
+ if (oid.off == 0 || oid.pool_uuid_lo == 0)
+ return NULL;
+
+ if (_pobj_cache_invalidate != _pobj_cached_pool.invalidate ||
+ _pobj_cached_pool.uuid_lo != oid.pool_uuid_lo) {
+ _pobj_cached_pool.invalidate = _pobj_cache_invalidate;
+
+ if (!(_pobj_cached_pool.pop = pmemobj_pool_by_oid(oid))) {
+ _pobj_cached_pool.uuid_lo = 0;
+ return NULL;
+ }
+
+ _pobj_cached_pool.uuid_lo = oid.pool_uuid_lo;
+ }
+
+ return (void *)((uintptr_t)_pobj_cached_pool.pop + oid.off);
+}
+
+#else /* _WIN32 */
+
+/* XXX - this is temporary (see obj.c for details) */
+
+/*
+ * Returns the direct pointer of an object.
+ */
+void *pmemobj_direct(PMEMoid oid);
+
+#endif /* _WIN32 */
+
+const char *pmemobj_errormsg(void);
+
+/*
+ * Returns the number of usable bytes in the object. May be greater than
+ * the requested size of the object because of internal alignment.
+ *
+ * Can be used with objects allocated by any of the available methods.
+ */
+size_t pmemobj_alloc_usable_size(PMEMoid oid);
+
+/*
+ * Returns the type number of the object.
+ */
+uint64_t pmemobj_type_num(PMEMoid oid);
+
+/*
+ * Pmemobj specific low-level memory manipulation functions.
+ *
+ * These functions are meant to be used with pmemobj pools, because they provide
+ * additional functionality specific to this type of pool. These may include
+ * for example replication support. They also take advantage of the knowledge
+ * of the type of memory in the pool (pmem/non-pmem) to assure persistence.
+ */
+
+/*
+ * Pmemobj version of memcpy. Data copied is made persistent.
+ */
+void *pmemobj_memcpy_persist(PMEMobjpool *pop, void *dest, const void *src,
+ size_t len);
+
+/*
+ * Pmemobj version of memset. Data range set is made persistent.
+ */
+void *pmemobj_memset_persist(PMEMobjpool *pop, void *dest, int c, size_t len);
+
+/*
+ * Pmemobj version of pmem_persist.
+ */
+void pmemobj_persist(PMEMobjpool *pop, const void *addr, size_t len);
+
+/*
+ * Pmemobj version of pmem_flush.
+ */
+void pmemobj_flush(PMEMobjpool *pop, const void *addr, size_t len);
+
+/*
+ * Pmemobj version of pmem_drain.
+ */
+void pmemobj_drain(PMEMobjpool *pop);
+
+/*
+ * Version checking.
+ */
+
+/*
+ * PMEMOBJ_MAJOR_VERSION and PMEMOBJ_MINOR_VERSION provide the current version
+ * of the libpmemobj API as provided by this header file. Applications can
+ * verify that the version available at run-time is compatible with the version
+ * used at compile-time by passing these defines to pmemobj_check_version().
+ */
+#define PMEMOBJ_MAJOR_VERSION 1
+#define PMEMOBJ_MINOR_VERSION 0
+const char *pmemobj_check_version(
+ unsigned major_required,
+ unsigned minor_required);
+
+/*
+ * Passing NULL to pmemobj_set_funcs() tells libpmemobj to continue to use the
+ * default for that function. The replacement functions must not make calls
+ * back into libpmemobj.
+ */
+void pmemobj_set_funcs(
+ void *(*malloc_func)(size_t size),
+ void (*free_func)(void *ptr),
+ void *(*realloc_func)(void *ptr, size_t size),
+ char *(*strdup_func)(const char *s));
+
+typedef int (*pmemobj_constr)(PMEMobjpool *pop, void *ptr, void *arg);
+
+/*
+ * (debug helper function) logs notice message if used inside a transaction
+ */
+void _pobj_debug_notice(const char *func_name, const char *file, int line);
+
+/*
+ * Debug helper function and macros
+ */
+#ifdef DEBUG
+
+/*
+ * (debug helper macro) logs notice message if used inside a transaction
+ */
+#define _POBJ_DEBUG_NOTICE_IN_TX()\
+ _pobj_debug_notice(__func__, NULL, 0)
+
+/*
+ * (debug helper macro) logs notice message if used inside a transaction
+ * - to be used only in FOREACH macros
+ */
+#define _POBJ_DEBUG_NOTICE_IN_TX_FOR(macro_name)\
+ _pobj_debug_notice(macro_name, __FILE__, __LINE__),
+
+#else
+#define _POBJ_DEBUG_NOTICE_IN_TX() do {} while (0)
+#define _POBJ_DEBUG_NOTICE_IN_TX_FOR(macro_name)
+#endif /* DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* libpmemobj/base.h */
diff --git a/src/include/libpmemobj/iterator.h b/src/include/libpmemobj/iterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..f12f6273c84a71d45614ac0113f1bcbebfa34516
--- /dev/null
+++ b/src/include/libpmemobj/iterator.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/iterator.h -- definitions of libpmemobj iterator macros
+ */
+
+#ifndef LIBPMEMOBJ_ITERATOR_H
+#define LIBPMEMOBJ_ITERATOR_H 1
+
+#include <libpmemobj/iterator_base.h>
+#include <libpmemobj/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline PMEMoid
+POBJ_FIRST_TYPE_NUM(PMEMobjpool *pop, uint64_t type_num)
+{
+ PMEMoid _pobj_ret = pmemobj_first(pop);
+
+ while (!OID_IS_NULL(_pobj_ret) &&
+ pmemobj_type_num(_pobj_ret) != type_num) {
+ _pobj_ret = pmemobj_next(_pobj_ret);
+ }
+ return _pobj_ret;
+}
+
+static inline PMEMoid
+POBJ_NEXT_TYPE_NUM(PMEMoid o)
+{
+ PMEMoid _pobj_ret = o;
+
+ do {
+ _pobj_ret = pmemobj_next(_pobj_ret);\
+ } while (!OID_IS_NULL(_pobj_ret) &&
+ pmemobj_type_num(_pobj_ret) != pmemobj_type_num(o));
+ return _pobj_ret;
+}
+
+
+#define POBJ_FIRST(pop, t) ((TOID(t))POBJ_FIRST_TYPE_NUM(pop, TOID_TYPE_NUM(t)))
+
+#define POBJ_NEXT(o) ((__typeof__(o))POBJ_NEXT_TYPE_NUM((o).oid))
+
+/*
+ * Iterates through every existing allocated object.
+ */
+#define POBJ_FOREACH(pop, varoid)\
+for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_FOREACH")\
+ varoid = pmemobj_first(pop);\
+ (varoid).off != 0; varoid = pmemobj_next(varoid))
+
+/*
+ * Safe variant of POBJ_FOREACH in which pmemobj_free on varoid is allowed
+ */
+#define POBJ_FOREACH_SAFE(pop, varoid, nvaroid)\
+for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_FOREACH_SAFE")\
+ varoid = pmemobj_first(pop);\
+ (varoid).off != 0 && (nvaroid = pmemobj_next(varoid), 1);\
+ varoid = nvaroid)
+
+/*
+ * Iterates through every object of the specified type.
+ */
+#define POBJ_FOREACH_TYPE(pop, var)\
+POBJ_FOREACH(pop, (var).oid)\
+if (pmemobj_type_num((var).oid) == TOID_TYPE_NUM_OF(var))
+
+/*
+ * Safe variant of POBJ_FOREACH_TYPE in which pmemobj_free on var
+ * is allowed.
+ */
+#define POBJ_FOREACH_SAFE_TYPE(pop, var, nvar)\
+POBJ_FOREACH_SAFE(pop, (var).oid, (nvar).oid)\
+if (pmemobj_type_num((var).oid) == TOID_TYPE_NUM_OF(var))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/iterator.h */
diff --git a/src/include/libpmemobj/iterator_base.h b/src/include/libpmemobj/iterator_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2ef80f60a3f48e80fd2cec1e42cb0128ce1c1c4
--- /dev/null
+++ b/src/include/libpmemobj/iterator_base.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/iterator_base.h -- definitions of libpmemobj iterator entry points
+ */
+
+#ifndef LIBPMEMOBJ_ITERATOR_BASE_H
+#define LIBPMEMOBJ_ITERATOR_BASE_H 1
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following functions allow access to the entire collection of objects.
+ *
+ * Use with conjunction with non-transactional allocations. Pmemobj pool acts
+ * as a generic container (list) of objects that are not assigned to any
+ * user-defined data structures.
+ */
+
+/*
+ * Returns the first object of the specified type number.
+ */
+PMEMoid pmemobj_first(PMEMobjpool *pop);
+
+/*
+ * Returns the next object of the same type.
+ */
+PMEMoid pmemobj_next(PMEMoid oid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/iterator_base.h */
diff --git a/src/include/libpmemobj/lists_atomic.h b/src/include/libpmemobj/lists_atomic.h
new file mode 100644
index 0000000000000000000000000000000000000000..abfdc5cbe8a307eddba617d5d4e9503fd2e5c744
--- /dev/null
+++ b/src/include/libpmemobj/lists_atomic.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/lists_atomic.h -- definitions of libpmemobj atomic lists macros
+ */
+
+#ifndef LIBPMEMOBJ_LISTS_ATOMIC_H
+#define LIBPMEMOBJ_LISTS_ATOMIC_H 1
+
+#include <libpmemobj/lists_atomic_base.h>
+#include <libpmemobj/thread.h>
+#include <libpmemobj/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Non-transactional persistent atomic circular doubly-linked list
+ */
+#define POBJ_LIST_ENTRY(type)\
+struct {\
+ TOID(type) pe_next;\
+ TOID(type) pe_prev;\
+}
+
+#define POBJ_LIST_HEAD(name, type)\
+struct name {\
+ TOID(type) pe_first;\
+ PMEMmutex lock;\
+}
+
+#define POBJ_LIST_FIRST(head) ((head)->pe_first)
+#define POBJ_LIST_LAST(head, field) (\
+TOID_IS_NULL((head)->pe_first) ?\
+(head)->pe_first :\
+D_RO((head)->pe_first)->field.pe_prev)
+
+#define POBJ_LIST_EMPTY(head) (TOID_IS_NULL((head)->pe_first))
+#define POBJ_LIST_NEXT(elm, field) (D_RO(elm)->field.pe_next)
+#define POBJ_LIST_PREV(elm, field) (D_RO(elm)->field.pe_prev)
+#define POBJ_LIST_DEST_HEAD 1
+#define POBJ_LIST_DEST_TAIL 0
+
+#define POBJ_LIST_FOREACH(var, head, field)\
+for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_LIST_FOREACH")\
+ (var) = POBJ_LIST_FIRST((head));\
+ TOID_IS_NULL((var)) == 0;\
+ TOID_EQUALS(POBJ_LIST_NEXT((var), field),\
+ POBJ_LIST_FIRST((head))) ?\
+ TOID_ASSIGN((var), OID_NULL) :\
+ ((var) = POBJ_LIST_NEXT((var), field)))
+
+#define POBJ_LIST_FOREACH_REVERSE(var, head, field)\
+for (_POBJ_DEBUG_NOTICE_IN_TX_FOR("POBJ_LIST_FOREACH_REVERSE")\
+ (var) = POBJ_LIST_LAST((head), field);\
+ TOID_IS_NULL((var)) == 0;\
+ TOID_EQUALS(POBJ_LIST_PREV((var), field),\
+ POBJ_LIST_LAST((head), field)) ?\
+ TOID_ASSIGN((var), OID_NULL) :\
+ ((var) = POBJ_LIST_PREV((var), field)))
+
+#define POBJ_LIST_INSERT_HEAD(pop, head, elm, field)\
+pmemobj_list_insert((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), OID_NULL,\
+ POBJ_LIST_DEST_HEAD, (elm).oid)
+
+#define POBJ_LIST_INSERT_TAIL(pop, head, elm, field)\
+pmemobj_list_insert((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), OID_NULL,\
+ POBJ_LIST_DEST_TAIL, (elm).oid)
+
+#define POBJ_LIST_INSERT_AFTER(pop, head, listelm, elm, field)\
+pmemobj_list_insert((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), (listelm).oid,\
+ 0 /* after */, (elm).oid)
+
+#define POBJ_LIST_INSERT_BEFORE(pop, head, listelm, elm, field)\
+pmemobj_list_insert((pop), \
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), (listelm).oid,\
+ 1 /* before */, (elm).oid)
+
+#define POBJ_LIST_INSERT_NEW_HEAD(pop, head, field, size, constr, arg)\
+pmemobj_list_insert_new((pop),\
+ TOID_OFFSETOF((head)->pe_first, field),\
+ (head), OID_NULL, POBJ_LIST_DEST_HEAD, (size),\
+ TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
+
+#define POBJ_LIST_INSERT_NEW_TAIL(pop, head, field, size, constr, arg)\
+pmemobj_list_insert_new((pop),\
+ TOID_OFFSETOF((head)->pe_first, field),\
+ (head), OID_NULL, POBJ_LIST_DEST_TAIL, (size),\
+ TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
+
+#define POBJ_LIST_INSERT_NEW_AFTER(pop, head, listelm, field, size,\
+ constr, arg)\
+pmemobj_list_insert_new((pop),\
+ TOID_OFFSETOF((head)->pe_first, field),\
+ (head), (listelm).oid, 0 /* after */, (size),\
+ TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
+
+#define POBJ_LIST_INSERT_NEW_BEFORE(pop, head, listelm, field, size,\
+ constr, arg)\
+pmemobj_list_insert_new((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), (listelm).oid, 1 /* before */, (size),\
+ TOID_TYPE_NUM_OF((head)->pe_first), (constr), (arg))
+
+#define POBJ_LIST_REMOVE(pop, head, elm, field)\
+pmemobj_list_remove((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), (elm).oid, 0 /* no free */)
+
+#define POBJ_LIST_REMOVE_FREE(pop, head, elm, field)\
+pmemobj_list_remove((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head), (elm).oid, 1 /* free */)
+
+#define POBJ_LIST_MOVE_ELEMENT_HEAD(pop, head, head_new, elm, field, field_new)\
+pmemobj_list_move((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
+ (head_new), OID_NULL, POBJ_LIST_DEST_HEAD, (elm).oid)
+
+#define POBJ_LIST_MOVE_ELEMENT_TAIL(pop, head, head_new, elm, field, field_new)\
+pmemobj_list_move((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
+ (head_new), OID_NULL, POBJ_LIST_DEST_TAIL, (elm).oid)
+
+#define POBJ_LIST_MOVE_ELEMENT_AFTER(pop,\
+ head, head_new, listelm, elm, field, field_new)\
+pmemobj_list_move((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
+ (head_new),\
+ (listelm).oid,\
+ 0 /* after */, (elm).oid)
+
+#define POBJ_LIST_MOVE_ELEMENT_BEFORE(pop,\
+ head, head_new, listelm, elm, field, field_new)\
+pmemobj_list_move((pop),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head), field),\
+ (head),\
+ TOID_OFFSETOF(POBJ_LIST_FIRST(head_new), field_new),\
+ (head_new),\
+ (listelm).oid,\
+ 1 /* before */, (elm).oid)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/lists_atomic.h */
diff --git a/src/include/libpmemobj/lists_atomic_base.h b/src/include/libpmemobj/lists_atomic_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b01771ff04ac1e7eb383bf839a52ff4db6625d0
--- /dev/null
+++ b/src/include/libpmemobj/lists_atomic_base.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/lists_atomic_base.h -- definitions of libpmemobj atomic lists
+ */
+
+#ifndef LIBPMEMOBJ_LISTS_ATOMIC_BASE_H
+#define LIBPMEMOBJ_LISTS_ATOMIC_BASE_H 1
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Non-transactional persistent atomic circular doubly-linked list
+ */
+
+int pmemobj_list_insert(PMEMobjpool *pop, size_t pe_offset, void *head,
+ PMEMoid dest, int before, PMEMoid oid);
+
+PMEMoid pmemobj_list_insert_new(PMEMobjpool *pop, size_t pe_offset, void *head,
+ PMEMoid dest, int before, size_t size, uint64_t type_num,
+ pmemobj_constr constructor, void *arg);
+
+int pmemobj_list_remove(PMEMobjpool *pop, size_t pe_offset, void *head,
+ PMEMoid oid, int free);
+
+int pmemobj_list_move(PMEMobjpool *pop, size_t pe_old_offset,
+ void *head_old, size_t pe_new_offset, void *head_new,
+ PMEMoid dest, int before, PMEMoid oid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/lists_atomic_base.h */
diff --git a/src/include/libpmemobj/pool.h b/src/include/libpmemobj/pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..01f6137875ca3b2825e456c35ffaf0923ca2cd99
--- /dev/null
+++ b/src/include/libpmemobj/pool.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/pool.h -- definitions of libpmemobj pool macros
+ */
+
+#ifndef LIBPMEMOBJ_POOL_H
+#define LIBPMEMOBJ_POOL_H 1
+
+#include <libpmemobj/pool_base.h>
+#include <libpmemobj/types.h>
+
+#define POBJ_ROOT(pop, t) (\
+(TOID(t))pmemobj_root((pop), sizeof(t)))
+
+#endif /* libpmemobj/pool.h */
diff --git a/src/include/libpmemobj/pool_base.h b/src/include/libpmemobj/pool_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..538cc1fd6904728482a4f306be51d4fac170d5a8
--- /dev/null
+++ b/src/include/libpmemobj/pool_base.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/pool_base.h -- definitions of libpmemobj pool entry points
+ */
+
+#ifndef LIBPMEMOBJ_POOL_BASE_H
+#define LIBPMEMOBJ_POOL_BASE_H 1
+
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PMEMOBJ_MIN_POOL ((size_t)(1024 * 1024 * 8)) /* 8 MB */
+
+/*
+ * Pool management.
+ */
+PMEMobjpool *pmemobj_open(const char *path, const char *layout);
+PMEMobjpool *pmemobj_create(const char *path, const char *layout,
+ size_t poolsize, mode_t mode);
+void pmemobj_close(PMEMobjpool *pop);
+int pmemobj_check(const char *path, const char *layout);
+
+/*
+ * If called for the first time on a newly created pool, the root object
+ * of given size is allocated. Otherwise, it returns the existing root object.
+ * In such case, the size must be not less than the actual root object size
+ * stored in the pool. If it's larger, the root object is automatically
+ * resized.
+ *
+ * This function is thread-safe.
+ */
+PMEMoid pmemobj_root(PMEMobjpool *pop, size_t size);
+
+/*
+ * Same as above, but calls the constructor function when the object is first
+ * created and on all subsequent reallocations.
+ */
+PMEMoid pmemobj_root_construct(PMEMobjpool *pop, size_t size,
+ pmemobj_constr constructor, void *arg);
+
+/*
+ * Returns the size in bytes of the root object. Always equal to the requested
+ * size.
+ */
+size_t pmemobj_root_size(PMEMobjpool *pop);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* libpmemobj/pool_base.h */
diff --git a/src/include/libpmemobj/thread.h b/src/include/libpmemobj/thread.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b46f39c6b774cc2f8d85b4a6cd025cce90188c6
--- /dev/null
+++ b/src/include/libpmemobj/thread.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/thread.h -- definitions of libpmemobj thread/locking entry points
+ */
+
+#ifndef LIBPMEMOBJ_THREAD_H
+#define LIBPMEMOBJ_THREAD_H 1
+
+#include <time.h>
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Locking.
+ */
+#define _POBJ_CL_ALIGNMENT 64 /* cache line alignment for performance */
+
+typedef struct {
+ char padding[_POBJ_CL_ALIGNMENT];
+} PMEMmutex;
+
+typedef struct {
+ char padding[_POBJ_CL_ALIGNMENT];
+} PMEMrwlock;
+
+typedef struct {
+ char padding[_POBJ_CL_ALIGNMENT];
+} PMEMcond;
+
+void pmemobj_mutex_zero(PMEMobjpool *pop, PMEMmutex *mutexp);
+int pmemobj_mutex_lock(PMEMobjpool *pop, PMEMmutex *mutexp);
+int pmemobj_mutex_timedlock(PMEMobjpool *pop, PMEMmutex *__restrict mutexp,
+ const struct timespec *__restrict abs_timeout);
+int pmemobj_mutex_trylock(PMEMobjpool *pop, PMEMmutex *mutexp);
+int pmemobj_mutex_unlock(PMEMobjpool *pop, PMEMmutex *mutexp);
+
+void pmemobj_rwlock_zero(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+int pmemobj_rwlock_rdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+int pmemobj_rwlock_wrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+int pmemobj_rwlock_timedrdlock(PMEMobjpool *pop,
+ PMEMrwlock *__restrict rwlockp,
+ const struct timespec *__restrict abs_timeout);
+int pmemobj_rwlock_timedwrlock(PMEMobjpool *pop,
+ PMEMrwlock *__restrict rwlockp,
+ const struct timespec *__restrict abs_timeout);
+int pmemobj_rwlock_tryrdlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+int pmemobj_rwlock_trywrlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+int pmemobj_rwlock_unlock(PMEMobjpool *pop, PMEMrwlock *rwlockp);
+
+void pmemobj_cond_zero(PMEMobjpool *pop, PMEMcond *condp);
+int pmemobj_cond_broadcast(PMEMobjpool *pop, PMEMcond *condp);
+int pmemobj_cond_signal(PMEMobjpool *pop, PMEMcond *condp);
+int pmemobj_cond_timedwait(PMEMobjpool *pop, PMEMcond *__restrict condp,
+ PMEMmutex *__restrict mutexp,
+ const struct timespec *__restrict abs_timeout);
+int pmemobj_cond_wait(PMEMobjpool *pop, PMEMcond *condp,
+ PMEMmutex *__restrict mutexp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/thread.h */
diff --git a/src/include/libpmemobj/tx.h b/src/include/libpmemobj/tx.h
new file mode 100644
index 0000000000000000000000000000000000000000..516bb2bbd2c316e68031a8f737c492b4425bbad4
--- /dev/null
+++ b/src/include/libpmemobj/tx.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/tx.h -- definitions of libpmemobj transactional macros
+ */
+
+#ifndef LIBPMEMOBJ_TX_H
+#define LIBPMEMOBJ_TX_H 1
+
+#include <errno.h>
+#include <string.h>
+
+#include <libpmemobj/tx_base.h>
+#include <libpmemobj/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef POBJ_TX_CRASH_ON_NO_ONABORT
+#define TX_ONABORT_CHECK do {\
+ if (_stage == TX_STAGE_ONABORT)\
+ abort();\
+ } while (0)
+#else
+#define TX_ONABORT_CHECK do {} while (0)
+#endif
+
+#define _POBJ_TX_BEGIN(pop, ...)\
+{\
+ jmp_buf _tx_env;\
+ int _stage;\
+ int _pobj_errno;\
+ if (setjmp(_tx_env)) {\
+ errno = pmemobj_tx_errno();\
+ } else {\
+ _pobj_errno = pmemobj_tx_begin(pop, _tx_env, __VA_ARGS__,\
+ TX_LOCK_NONE);\
+ if (_pobj_errno)\
+ errno = _pobj_errno;\
+ }\
+ while ((_stage = pmemobj_tx_stage()) != TX_STAGE_NONE) {\
+ switch (_stage) {\
+ case TX_STAGE_WORK:
+
+#define TX_BEGIN_LOCK(pop, ...)\
+_POBJ_TX_BEGIN(pop, ##__VA_ARGS__)
+
+#define TX_BEGIN(pop) _POBJ_TX_BEGIN(pop, TX_LOCK_NONE)
+
+#define TX_ONABORT\
+ pmemobj_tx_process();\
+ break;\
+ case TX_STAGE_ONABORT:
+
+#define TX_ONCOMMIT\
+ pmemobj_tx_process();\
+ break;\
+ case TX_STAGE_ONCOMMIT:
+
+#define TX_FINALLY\
+ pmemobj_tx_process();\
+ break;\
+ case TX_STAGE_FINALLY:
+
+#define TX_END\
+ pmemobj_tx_process();\
+ break;\
+ default:\
+ TX_ONABORT_CHECK;\
+ pmemobj_tx_process();\
+ break;\
+ }\
+ }\
+ _pobj_errno = pmemobj_tx_end();\
+ if (_pobj_errno)\
+ errno = _pobj_errno;\
+}
+
+#define TX_ADD(o)\
+pmemobj_tx_add_range((o).oid, 0, sizeof(*(o)._type))
+
+#define TX_ADD_FIELD(o, field)\
+pmemobj_tx_add_range((o).oid, TOID_OFFSETOF(o, field),\
+ sizeof(D_RO(o)->field))
+
+#define TX_ADD_DIRECT(p)\
+pmemobj_tx_add_range_direct(p, sizeof(*p))
+
+#define TX_ADD_FIELD_DIRECT(p, field)\
+pmemobj_tx_add_range_direct(&(p)->field, sizeof((p)->field))
+
+
+#define TX_NEW(t)\
+((TOID(t))pmemobj_tx_alloc(sizeof(t), TOID_TYPE_NUM(t)))
+
+#define TX_ALLOC(t, size)\
+((TOID(t))pmemobj_tx_alloc(size, TOID_TYPE_NUM(t)))
+
+#define TX_ZNEW(t)\
+((TOID(t))pmemobj_tx_zalloc(sizeof(t), TOID_TYPE_NUM(t)))
+
+#define TX_ZALLOC(t, size)\
+((TOID(t))pmemobj_tx_zalloc(size, TOID_TYPE_NUM(t)))
+
+/* XXX - not available when compiled with VC++ as C code (/TC) */
+#ifndef _MSC_VER
+
+#define TX_REALLOC(o, size) (\
+{__typeof__(o) ret = (__typeof__(o))pmemobj_tx_realloc((o).oid, size,\
+ TOID_TYPE_NUM_OF(o));\
+ret; })
+
+#define TX_ZREALLOC(o, size) (\
+{__typeof__(o) ret = (__typeof__(o))pmemobj_tx_zrealloc((o).oid, size,\
+ TOID_TYPE_NUM_OF(o));\
+ret; })
+
+#elif defined(__cplusplus)
+
+#define TX_REALLOC(o, size)\
+((__typeof__(o))pmemobj_tx_realloc((o).oid, size, TOID_TYPE_NUM_OF(o)))
+
+#define TX_ZREALLOC(o, size)\
+((__typeof__(o))pmemobj_tx_zrealloc((o).oid, size, TOID_TYPE_NUM_OF(o)))
+
+#endif /* (defined(_MSC_VER) || defined(__cplusplus)) */
+
+#define TX_STRDUP(s, type_num)\
+pmemobj_tx_strdup(s, type_num)
+
+#define TX_FREE(o)\
+pmemobj_tx_free((o).oid)
+
+#define TX_SET(o, field, value) (\
+ TX_ADD_FIELD(o, field),\
+ D_RW(o)->field = value)
+
+#define TX_SET_DIRECT(p, field, value) (\
+ TX_ADD_FIELD_DIRECT(p, field),\
+ (p)->field = value)
+
+static inline void *
+TX_MEMCPY(void *dest, const void *src, size_t num)
+{
+ pmemobj_tx_add_range_direct(dest, num);
+ return memcpy(dest, src, num);
+}
+
+static inline void *
+TX_MEMSET(void *dest, int c, size_t num)
+{
+ pmemobj_tx_add_range_direct(dest, num);
+ return memset(dest, c, num);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/tx.h */
diff --git a/src/include/libpmemobj/tx_base.h b/src/include/libpmemobj/tx_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c48fe8b73b4e86e537f760dbb825a83e4b48efb
--- /dev/null
+++ b/src/include/libpmemobj/tx_base.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/tx_base.h -- definitions of libpmemobj transactional entry points
+ */
+
+#ifndef LIBPMEMOBJ_TX_BASE_H
+#define LIBPMEMOBJ_TX_BASE_H 1
+
+#include <setjmp.h>
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Transactions
+ *
+ * Stages are changed only by the pmemobj_tx_* functions, each transition
+ * to the TX_STAGE_ONABORT is followed by a longjmp to the jmp_buf provided in
+ * the pmemobj_tx_begin function.
+ */
+enum pobj_tx_stage {
+ TX_STAGE_NONE, /* no transaction in this thread */
+ TX_STAGE_WORK, /* transaction in progress */
+ TX_STAGE_ONCOMMIT, /* successfully committed */
+ TX_STAGE_ONABORT, /* tx_begin failed or transaction aborted */
+ TX_STAGE_FINALLY, /* always called */
+
+ MAX_TX_STAGE
+};
+
+/*
+ * Always returns the current transaction stage for a thread.
+ */
+enum pobj_tx_stage pmemobj_tx_stage(void);
+
+enum pobj_tx_lock {
+ TX_LOCK_NONE,
+ TX_LOCK_MUTEX, /* PMEMmutex */
+ TX_LOCK_RWLOCK /* PMEMrwlock */
+};
+
+/*
+ * Starts a new transaction in the current thread.
+ * If called within an open transaction, starts a nested transaction.
+ *
+ * If successful, transaction stage changes to TX_STAGE_WORK and function
+ * returns zero. Otherwise, stage changes to TX_STAGE_ONABORT and an error
+ * number is returned.
+ */
+int pmemobj_tx_begin(PMEMobjpool *pop, jmp_buf env, ...);
+
+/*
+ * Adds lock of given type to current transaction.
+ */
+int pmemobj_tx_lock(enum pobj_tx_lock type, void *lockp);
+
+/*
+ * Aborts current transaction
+ *
+ * Causes transition to TX_STAGE_ONABORT.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+void pmemobj_tx_abort(int errnum);
+
+/*
+ * Commits current transaction
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+void pmemobj_tx_commit(void);
+
+/*
+ * Cleanups current transaction. Must always be called after pmemobj_tx_begin,
+ * even if starting the transaction failed.
+ *
+ * If called during TX_STAGE_NONE, has no effect.
+ *
+ * Always causes transition to TX_STAGE_NONE.
+ *
+ * If transaction was successful, returns 0. Otherwise returns error code set
+ * by pmemobj_tx_abort.
+ *
+ * This function must *not* be called during TX_STAGE_WORK.
+ */
+int pmemobj_tx_end(void);
+
+/*
+ * Performs the actions associated with current stage of the transaction,
+ * and makes the transition to the next stage. Current stage must always
+ * be obtained by calling pmemobj_tx_stage.
+ *
+ * This function must be called in transaction.
+ */
+void pmemobj_tx_process(void);
+
+/*
+ * Returns last transaction error code.
+ */
+int pmemobj_tx_errno(void);
+
+/*
+ * Takes a "snapshot" of the memory block of given size and located at given
+ * offset 'off' in the object 'oid' and saves it in the undo log.
+ * The application is then free to directly modify the object in that memory
+ * range. In case of failure or abort, all the changes within this range will
+ * be rolled-back automatically.
+ *
+ * If successful, returns zero.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+int pmemobj_tx_add_range(PMEMoid oid, uint64_t off, size_t size);
+
+/*
+ * Takes a "snapshot" of the given memory region and saves it in the undo log.
+ * The application is then free to directly modify the object in that memory
+ * range. In case of failure or abort, all the changes within this range will
+ * be rolled-back automatically. The supplied block of memory has to be within
+ * the given pool.
+ *
+ * If successful, returns zero.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+int pmemobj_tx_add_range_direct(const void *ptr, size_t size);
+
+/*
+ * Transactionally allocates a new object.
+ *
+ * If successful, returns PMEMoid.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+PMEMoid pmemobj_tx_alloc(size_t size, uint64_t type_num);
+
+/*
+ * Transactionally allocates new zeroed object.
+ *
+ * If successful, returns PMEMoid.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+PMEMoid pmemobj_tx_zalloc(size_t size, uint64_t type_num);
+
+/*
+ * Transactionally resizes an existing object.
+ *
+ * If successful, returns PMEMoid.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+PMEMoid pmemobj_tx_realloc(PMEMoid oid, size_t size, uint64_t type_num);
+
+/*
+ * Transactionally resizes an existing object, if extended new space is zeroed.
+ *
+ * If successful, returns PMEMoid.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+PMEMoid pmemobj_tx_zrealloc(PMEMoid oid, size_t size, uint64_t type_num);
+
+/*
+ * Transactionally allocates a new object with duplicate of the string s.
+ *
+ * If successful, returns PMEMoid.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an OID_NULL is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+PMEMoid pmemobj_tx_strdup(const char *s, uint64_t type_num);
+
+/*
+ * Transactionally frees an existing object.
+ *
+ * If successful, returns zero.
+ * Otherwise, state changes to TX_STAGE_ONABORT and an error number is returned.
+ *
+ * This function must be called during TX_STAGE_WORK.
+ */
+int pmemobj_tx_free(PMEMoid oid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libpmemobj/tx_base.h */
diff --git a/src/include/libpmemobj/types.h b/src/include/libpmemobj/types.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cc3597b5d9e6b712c16773e437d48f784b13e89
--- /dev/null
+++ b/src/include/libpmemobj/types.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2014-2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * libpmemobj/types.h -- definitions of libpmemobj type-safe macros
+ */
+
+#ifndef LIBPMEMOBJ_TYPES_H
+#define LIBPMEMOBJ_TYPES_H 1
+
+#include <libpmemobj/base.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TOID_NULL(t) ((TOID(t))OID_NULL)
+#define PMEMOBJ_MAX_LAYOUT ((size_t)1024)
+
+/*
+ * similar to offsetof, except that it takes a structure pointer,
+ * instead of a structure type name
+ */
+#define offsetofp(s, m) ((size_t)&(((s)0)->m))
+
+/*
+ * Type safety macros
+ */
+#ifndef _MSC_VER
+
+#define TOID_ASSIGN(o, value)(\
+{\
+ (o).oid = value;\
+ (o); /* to avoid "error: statement with no effect" */\
+})
+
+#else /* _MSC_VER */
+
+#define TOID_ASSIGN(o, value) ((o).oid = value, (o))
+
+#endif /* _MSC_VER */
+
+#define TOID_EQUALS(lhs, rhs)\
+((lhs).oid.off == (rhs).oid.off &&\
+ (lhs).oid.pool_uuid_lo == (rhs).oid.pool_uuid_lo)
+
+/* type number of root object */
+#define POBJ_ROOT_TYPE_NUM 0
+#define _toid_struct
+#define _toid_union
+#define _toid_enum
+#define _POBJ_LAYOUT_REF(name) (sizeof(_pobj_layout_##name##_ref))
+
+/*
+ * Typed OID
+ */
+#define TOID(t)\
+union _toid_##t##_toid
+
+#ifdef __cplusplus
+#define _TOID_CONSTR(t)\
+_toid_##t##_toid()\
+{ }\
+_toid_##t##_toid(PMEMoid _oid) : oid(_oid)\
+{ }
+#else
+#define _TOID_CONSTR(t)
+#endif
+
+/*
+ * Declaration of typed OID
+ */
+#define _TOID_DECLARE(t, i)\
+typedef uint8_t _toid_##t##_toid_type_num[(i) + 1];\
+TOID(t)\
+{\
+ _TOID_CONSTR(t)\
+ PMEMoid oid;\
+ t *_type;\
+ _toid_##t##_toid_type_num *_type_num;\
+}
+
+/*
+ * Declaration of typed OID of an object
+ */
+#define TOID_DECLARE(t, i) _TOID_DECLARE(t, i)
+
+/*
+ * Declaration of typed OID of a root object
+ */
+#define TOID_DECLARE_ROOT(t) _TOID_DECLARE(t, POBJ_ROOT_TYPE_NUM)
+
+/*
+ * Type number of specified type
+ */
+#define TOID_TYPE_NUM(t) (sizeof(_toid_##t##_toid_type_num) - 1)
+
+/*
+ * Type number of object read from typed OID
+ */
+#define TOID_TYPE_NUM_OF(o) (sizeof(*(o)._type_num) - 1)
+
+/*
+ * NULL check
+ */
+#define TOID_IS_NULL(o) ((o).oid.off == 0)
+
+/*
+ * Validates whether type number stored in typed OID is the same
+ * as type number stored in object's metadata
+ */
+#define TOID_VALID(o) (TOID_TYPE_NUM_OF(o) == pmemobj_type_num((o).oid))
+
+/*
+ * Checks whether the object is of a given type
+ */
+#define OID_INSTANCEOF(o, t) (TOID_TYPE_NUM(t) == pmemobj_type_num(o))
+
+/*
+ * Begin of layout declaration
+ */
+#define POBJ_LAYOUT_BEGIN(name)\
+typedef uint8_t _pobj_layout_##name##_ref[__COUNTER__ + 1]
+
+/*
+ * End of layout declaration
+ */
+#define POBJ_LAYOUT_END(name)\
+typedef char _pobj_layout_##name##_cnt[__COUNTER__ + 1 -\
+_POBJ_LAYOUT_REF(name)];
+
+/*
+ * Number of types declared inside layout without the root object
+ */
+#define POBJ_LAYOUT_TYPES_NUM(name) (sizeof(_pobj_layout_##name##_cnt) - 1)
+
+/*
+ * Declaration of typed OID inside layout declaration
+ */
+#define POBJ_LAYOUT_TOID(name, t)\
+TOID_DECLARE(t, (__COUNTER__ + 1 - _POBJ_LAYOUT_REF(name)));
+
+/*
+ * Declaration of typed OID of root inside layout declaration
+ */
+#define POBJ_LAYOUT_ROOT(name, t)\
+TOID_DECLARE_ROOT(t);
+
+/*
+ * Name of declared layout
+ */
+#define POBJ_LAYOUT_NAME(name) #name
+
+#define TOID_TYPEOF(o) __typeof__(*(o)._type)
+
+#define TOID_OFFSETOF(o, field) offsetofp(__typeof__((o)._type), field)
+
+/*
+ * XXX - DIRECT_RW and DIRECT_RO are not available when compiled using VC++
+ * as C code (/TC). Use /TP option.
+ */
+#ifndef _MSC_VER
+
+#define DIRECT_RW(o) (\
+{__typeof__(o) _o; _o._type = NULL; (void)_o;\
+(__typeof__(*(o)._type) *)pmemobj_direct((o).oid); })
+#define DIRECT_RO(o) ((const __typeof__(*(o)._type) *)pmemobj_direct((o).oid))
+
+#elif defined(__cplusplus)
+
+/*
+ * XXX - On Windows, these macros do not behave exactly the same as on Linux.
+ */
+#define DIRECT_RW(o) ((__typeof__((o)._type))pmemobj_direct((o).oid))
+#define DIRECT_RO(o) ((const __typeof__((o)._type))pmemobj_direct((o).oid))
+
+#endif /* (defined(_MSC_VER) || defined(__cplusplus)) */
+
+#define D_RW DIRECT_RW
+#define D_RO DIRECT_RO
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* libpmemobj/types.h */
diff --git a/src/libpmemobj/tx.h b/src/libpmemobj/tx.h
index c8823de224a7eba60acf6585d0385ed2a932e961..409f9f34441fda210b76a22dd76ab8ea068dd2c0 100644
--- a/src/libpmemobj/tx.h
+++ b/src/libpmemobj/tx.h
@@ -34,8 +34,8 @@
* tx.h -- internal definitions for transactions
*/
-#ifndef LIBPMEMOBJ_TX_H
-#define LIBPMEMOBJ_TX_H 1
+#ifndef LIBPMEMOBJ_INTERNAL_TX_H
+#define LIBPMEMOBJ_INTERNAL_TX_H 1
#include <stdint.h>
#include "pvector.h"
diff --git a/src/test/Makefile b/src/test/Makefile
index 4c036091e5f67c3ea1187985c9d108d52902ab33..c0f93fc7a76d309bda59deb543e4e5ae07952b11 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -76,6 +76,7 @@ OBJ_TESTS = \
obj_heap\
obj_heap_interrupt\
obj_heap_state\
+ obj_include\
obj_lane\
obj_list_insert\
obj_list_move\
diff --git a/src/test/obj_include/.gitignore b/src/test/obj_include/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..a7efaff4d04939f1eeaa9941221664487bbd8fb4
--- /dev/null
+++ b/src/test/obj_include/.gitignore
@@ -0,0 +1,2 @@
+obj_inc
+*.tmpo
diff --git a/src/test/obj_include/Makefile b/src/test/obj_include/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..044dbc929cc10906ce2a186cae70b9f76a581646
--- /dev/null
+++ b/src/test/obj_include/Makefile
@@ -0,0 +1,83 @@
+#
+# Copyright 2016, Intel Corporation
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# src/test/obj_include/Makefile -- build include tests
+#
+TARGET = obj_inc
+OBJS = obj_inc.o\
+ obj_inc_atomic_base.tmpo obj_inc_atomic.tmpo\
+ obj_inc_base.tmpo\
+ obj_inc_iter_base.tmpo obj_inc_iter.tmpo\
+ obj_inc_lists_atomic_base.tmpo obj_inc_lists_atomic.tmpo\
+ obj_inc_pool_base.tmpo obj_inc_pool.tmpo\
+ obj_inc_thread.tmpo\
+ obj_inc_tx_base.tmpo obj_inc_tx.tmpo\
+ obj_inc_types.tmpo
+
+LIBPMEM=y
+LIBPMEMOBJ=y
+
+include ../Makefile.inc
+
+%.tmpo: obj_inc.c Makefile
+ @mkdir -p .deps
+ $(CC) -MD -c $(CFLAGS) $(INCS) $< -o $@
+ $(create-deps)
+
+clean-tmpo:
+ rm -f *.tmpo
+
+clean: clean-tmpo
+
+obj_inc.o: CFLAGS+=-DBUILD_MAIN
+
+obj_inc_atomic_base.tmpo: CFLAGS+=-include libpmemobj/atomic_base.h
+obj_inc_atomic.tmpo: CFLAGS+=-include libpmemobj/atomic.h
+
+obj_inc_base.tmpo: CFLAGS+=-include libpmemobj/base.h
+
+obj_inc_iter_base.tmpo: CFLAGS+=-include libpmemobj/iterator_base.h
+obj_inc_iter.tmpo: CFLAGS+=-include libpmemobj/iterator.h
+
+obj_inc_lists_atomic_base.tmpo: CFLAGS+=-include libpmemobj/lists_atomic_base.h
+obj_inc_lists_atomic.tmpo: CFLAGS+=-include libpmemobj/lists_atomic.h
+
+obj_inc_pool_base.tmpo: CFLAGS+=-include libpmemobj/pool_base.h
+obj_inc_pool.tmpo: CFLAGS+=-include libpmemobj/pool.h
+
+obj_inc_thread.tmpo: CFLAGS+=-include libpmemobj/thread.h
+
+obj_inc_tx_base.tmpo: CFLAGS+=-include libpmemobj/tx_base.h
+obj_inc_tx.tmpo: CFLAGS+=-include libpmemobj/tx.h
+
+obj_inc_types.tmpo: CFLAGS+=-include libpmemobj/types.h
diff --git a/src/test/obj_include/TEST0 b/src/test/obj_include/TEST0
new file mode 100755
index 0000000000000000000000000000000000000000..afc8312cb5b2ca5dcea2c38286446d00c3b84f6a
--- /dev/null
+++ b/src/test/obj_include/TEST0
@@ -0,0 +1,45 @@
+#!/bin/bash -e
+#
+# Copyright 2016, Intel Corporation
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# src/test/obj_include/TEST0 - if it compiles it's perfect
+#
+export UNITTEST_NAME=obj_include/TEST0
+export UNITTEST_NUM=0
+
+# standard unit test setup
+. ../unittest/unittest.sh
+
+setup
+
+pass
diff --git a/src/test/obj_include/obj_inc.c b/src/test/obj_include/obj_inc.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbc09697445ba91b816aa1c9087bc0ef2db2ce27
--- /dev/null
+++ b/src/test/obj_include/obj_inc.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef BUILD_MAIN
+int
+main()
+{
+ return 0;
+}
+#endif
diff --git a/utils/build-dpkg.sh b/utils/build-dpkg.sh
index 0a4c3111162cefb3ea2b46ca49b32a7b0bb0a1db..e7c84cde6615741d10d3bd8a1bf7b45a705a87cc 100755
--- a/utils/build-dpkg.sh
+++ b/utils/build-dpkg.sh
@@ -518,6 +518,7 @@ usr/lib/nvml_debug/libpmemobj.so.* usr/lib/nvml_dbg/
usr/lib/libpmemobj.so
usr/lib/pkgconfig/libpmemobj.pc
usr/include/libpmemobj.h
+usr/include/libpmemobj/*.h
usr/share/man/man3/libpmemobj.3.gz
EOF
diff --git a/utils/build-rpm.sh b/utils/build-rpm.sh
index 878ee2b9cc1f5cf3c93434e3346c48cd063c7b10..f9b97232558e30f2e83c4f4d8fd9251cea99865c 100755
--- a/utils/build-rpm.sh
+++ b/utils/build-rpm.sh
@@ -336,6 +336,7 @@ Development files for NVML libpmemobj library
%{_libdir}/nvml_debug/libpmemobj.so.*
%{_libdir}/nvml_debug/libpmemobj.a
%{_includedir}/libpmemobj.h
+%{_includedir}/libpmemobj/*.h
%{_mandir}/man3/libpmemobj.3.gz
%package -n libpmempool