#define _GNU_SOURCE
#include "obj.h"
#include "pmalloc.h"
#include "unittest.h"
static struct {
int n_persist;
int n_msync;
int n_flush;
int n_drain;
} ops_counter;
FUNC_MOCK(pmem_persist, void, const void *addr, size_t len)
FUNC_MOCK_RUN_DEFAULT {
ops_counter.n_persist++;
_FUNC_REAL(pmem_persist)(addr, len);
}
FUNC_MOCK_END
FUNC_MOCK(pmem_msync, int, const void *addr, size_t len)
FUNC_MOCK_RUN_DEFAULT {
ops_counter.n_msync++;
return _FUNC_REAL(pmem_msync)(addr, len);
}
FUNC_MOCK_END
FUNC_MOCK(pmem_flush, void, const void *addr, size_t len)
FUNC_MOCK_RUN_DEFAULT {
ops_counter.n_flush++;
_FUNC_REAL(pmem_flush)(addr, len);
}
FUNC_MOCK_END
FUNC_MOCK(pmem_drain, void, void)
FUNC_MOCK_RUN_DEFAULT {
ops_counter.n_drain++;
_FUNC_REAL(pmem_drain)();
}
FUNC_MOCK_END
static void
reset_counters(void)
{
memset(&ops_counter, 0, sizeof(ops_counter));
}
static void
print_reset_counters(const char *task)
{
UT_OUT("%d\t;%d\t;%d\t;%d\t;%s",
ops_counter.n_persist, ops_counter.n_msync,
ops_counter.n_flush, ops_counter.n_drain, task);
reset_counters();
}
struct foo {
int val;
uint64_t dest;
PMEMoid bar;
PMEMoid bar2;
};
int
main(int argc, char *argv[])
{
START(argc, argv, "obj_persist_count");
if (argc != 2)
UT_FATAL("usage: %s file-name", argv[0]);
const char *path = argv[1];
PMEMobjpool *pop;
if ((pop = pmemobj_create(path, "persist_count",
PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL)
UT_FATAL("!pmemobj_create: %s", path);
UT_OUT("persist\t;msync\t;flush\t;drain\t;task");
print_reset_counters("pool_create");
pmemobj_alloc(pop, NULL, sizeof(struct foo), 0, NULL, NULL);
reset_counters();
PMEMoid root = pmemobj_root(pop, sizeof(struct foo));
UT_ASSERT(!OID_IS_NULL(root));
print_reset_counters("root_alloc");
PMEMoid oid;
int ret = pmemobj_alloc(pop, &oid, sizeof(struct foo), 0, NULL, NULL);
UT_ASSERTeq(ret, 0);
print_reset_counters("atomic_alloc");
pmemobj_free(&oid);
print_reset_counters("atomic_free");
struct foo *f = pmemobj_direct(root);
TX_BEGIN(pop) {
f->bar = pmemobj_tx_alloc(sizeof(struct foo), 0);
UT_ASSERT(!OID_IS_NULL(f->bar));
} TX_END
print_reset_counters("tx_alloc");
TX_BEGIN(pop) {
f->bar2 = pmemobj_tx_alloc(sizeof(struct foo), 0);
UT_ASSERT(!OID_IS_NULL(f->bar2));
} TX_END
print_reset_counters("tx_alloc_next");
TX_BEGIN(pop) {
pmemobj_tx_free(f->bar);
} TX_END
print_reset_counters("tx_free");
TX_BEGIN(pop) {
pmemobj_tx_free(f->bar2);
} TX_END
print_reset_counters("tx_free_next");
TX_BEGIN(pop) {
pmemobj_tx_add_range_direct(&f->val, sizeof(f->val));
} TX_END
print_reset_counters("tx_add");
TX_BEGIN(pop) {
pmemobj_tx_add_range_direct(&f->val, sizeof(f->val));
} TX_END
print_reset_counters("tx_add_next");
pmalloc(pop, &f->dest, sizeof(f->val), 0, 0);
print_reset_counters("pmalloc");
pfree(pop, &f->dest);
print_reset_counters("pfree");
uint64_t stack_var;
pmalloc(pop, &stack_var, sizeof(f->val), 0, 0);
print_reset_counters("pmalloc_stack");
pfree(pop, &stack_var);
print_reset_counters("pfree_stack");
pmemobj_close(pop);
DONE(NULL);
}
#ifdef _MSC_VER
MSVC_CONSTR(libpmemobj_init)
MSVC_DESTR(libpmemobj_fini)
#endif