#include "unittest.h"
#define THREADS 8
#define LOOPS 8
static PMEMobjpool *pop;
static PMEMoid tab;
static os_mutex_t mtx;
static void *
tx_alloc_free(void *arg)
{
volatile int locked;
for (int i = 0; i < LOOPS; ++i) {
locked = 0;
TX_BEGIN(pop) {
os_mutex_lock(&mtx);
locked = 1;
tab = pmemobj_tx_alloc(128, 1);
} TX_ONCOMMIT {
if (locked)
os_mutex_unlock(&mtx);
} TX_ONABORT {
if (locked)
os_mutex_unlock(&mtx);
} TX_END
locked = 0;
TX_BEGIN(pop) {
os_mutex_lock(&mtx);
locked = 1;
pmemobj_tx_free(tab);
tab = OID_NULL;
} TX_ONCOMMIT {
if (locked)
os_mutex_unlock(&mtx);
} TX_ONABORT {
if (locked)
os_mutex_unlock(&mtx);
} TX_END
}
return NULL;
}
static void *
tx_snap(void *arg)
{
volatile int locked;
for (int i = 0; i < LOOPS; ++i) {
locked = 0;
TX_BEGIN(pop) {
os_mutex_lock(&mtx);
locked = 1;
if (!OID_IS_NULL(tab))
pmemobj_tx_add_range(tab, 0, 8);
} TX_ONCOMMIT {
if (locked)
os_mutex_unlock(&mtx);
} TX_ONABORT {
if (locked)
os_mutex_unlock(&mtx);
} TX_END
locked = 0;
}
return NULL;
}
int
main(int argc, char *argv[])
{
START(argc, argv, "obj_tx_mt");
os_mutex_init(&mtx);
if (argc != 2)
UT_FATAL("usage: %s [file]", argv[0]);
if ((pop = pmemobj_create(argv[1], "mt", PMEMOBJ_MIN_POOL,
S_IWUSR | S_IRUSR)) == NULL)
UT_FATAL("!pmemobj_create");
int i = 0;
os_thread_t *threads = MALLOC(THREADS * sizeof(threads[0]));
for (int j = 0; j < THREADS / 2; ++j) {
PTHREAD_CREATE(&threads[i++], NULL, tx_alloc_free, NULL);
PTHREAD_CREATE(&threads[i++], NULL, tx_snap, NULL);
}
while (i > 0)
PTHREAD_JOIN(&threads[--i], NULL);
pmemobj_close(pop);
os_mutex_destroy(&mtx);
FREE(threads);
DONE(NULL);
}