Exemple #1
0
static void
pool_create(const char *path, const char *layout, size_t poolsize,
	unsigned mode)
{
	PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode);

	if (pop == NULL)
		UT_OUT("!%s: pmemobj_create", path);
	else {
		struct stat stbuf;
		STAT(path, &stbuf);

		UT_OUT("%s: file size %zu mode 0%o",
				path, stbuf.st_size,
				stbuf.st_mode & 0777);

		pmemobj_close(pop);

		int result = pmemobj_check(path, layout);

		if (result < 0)
			UT_OUT("!%s: pmemobj_check", path);
		else if (result == 0)
			UT_OUT("%s: pmemobj_check: not consistent", path);
	}
}
Exemple #2
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_tx_mt");

	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;
	long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
	pthread_t *threads = MALLOC(2 * ncpus * sizeof(threads[0]));

	for (int j = 0; j < ncpus; ++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);

	FREE(threads);

	DONE(NULL);
}
Exemple #3
0
static void
test_reopen(const char *path)
{
	PMEMobjpool *pop1 = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL,
			S_IWUSR | S_IRUSR);
	if (!pop1)
		UT_FATAL("!create");

	PMEMobjpool *pop2 = pmemobj_open(path, LAYOUT);
	if (pop2)
		UT_FATAL("pmemobj_open should not succeed");

	if (errno != EWOULDBLOCK)
		UT_FATAL("!pmemobj_open failed but for unexpected reason");

	pmemobj_close(pop1);

	pop2 = pmemobj_open(path, LAYOUT);
	if (!pop2)
		UT_FATAL("pmemobj_open should succeed after close");

	pmemobj_close(pop2);

	UNLINK(path);
}
Exemple #4
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_pmalloc_oom_mt");

	if (argc != 2)
		FATAL("usage: %s file-name", argv[0]);

	const char *path = argv[1];

	if ((pop = pmemobj_create(path, LAYOUT_NAME,
			PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL)
		FATAL("!pmemobj_create: %s", path);

	pthread_t t;
	pthread_create(&t, NULL, oom_worker, NULL);
	pthread_join(t, NULL);

	int first_thread_allocated = allocated;

	pthread_create(&t, NULL, oom_worker, NULL);
	pthread_join(t, NULL);

	ASSERTeq(first_thread_allocated, allocated);

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #5
0
static void
test_open_in_different_process(int argc, char **argv, int sleep)
{
	PMEMobjpool *pop;

	if (sleep > 0)
		return;

	char *path = argv[1];

	/* before starting the 2nd process, create a pool */
	pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL,
		S_IWUSR | S_IRUSR);
	if (!pop)
		UT_FATAL("!create");

	/*
	 * "X" is pass as an additional param to the new process
	 * created by ut_spawnv to distinguish second process on Windows
	 */
	uintptr_t result = ut_spawnv(argc, argv, "X", NULL);

	if (result == -1)
		UT_FATAL("Create new process failed error: %d", GetLastError());

	pmemobj_close(pop);
}
Exemple #6
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_heap_state");

	if (argc != 2)
		FATAL("usage: %s file-name", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop = NULL;

	if ((pop = pmemobj_create(path, LAYOUT_NAME,
			PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL)
		FATAL("!pmemobj_create: %s", path);

	pmemobj_root(pop, ROOT_SIZE); /* just to trigger allocation */

	pmemobj_close(pop);

	pop = pmemobj_open(path, LAYOUT_NAME);
	ASSERTne(pop, NULL);

	for (int i = 0; i < ALLOCS; ++i) {
		PMEMoid oid;
		pmemobj_alloc(pop, &oid, ALLOC_SIZE, 0, NULL, NULL);
		OUT("%d %lu", i, oid.off);
	}

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #7
0
/*
 * pmemlog_create -- pool create wrapper
 */
PMEMlogpool *
pmemlog_create(const char *path, size_t poolsize, mode_t mode)
{
	return (PMEMlogpool *)pmemobj_create(path,
				POBJ_LAYOUT_NAME(obj_pmemlog_minimal),
				poolsize, mode);
}
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_out_of_memory");

	if (argc < 3)
		FATAL("usage: %s size filename ...", argv[0]);

	size_t size = atoll(argv[1]);

	for (int i = 2; i < argc; i++) {
		const char *path = argv[i];

		PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, 0,
					S_IWUSR | S_IRUSR);
		if (pop == NULL)
			FATAL("!pmemobj_create: %s", path);

		test_alloc(pop, size);

		pmemobj_close(pop);

		ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1);

		ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL);

		test_free(pop);

		pmemobj_close(pop);
	}

	DONE(NULL);
}
Exemple #9
0
int
main(int argc, char *argv[])
{
	if (argc != 2) {
		printf("usage: %s file-name\n", argv[0]);
		return 1;
	}

	PMEMobjpool *pop = pmemobj_create(argv[1], LAYOUT_NAME,
				PMEMOBJ_MIN_POOL, 0666);

	if (pop == NULL) {
		perror("pmemobj_create");
		return 1;
	}

	PMEMoid root = pmemobj_root(pop, sizeof(struct my_root));
	struct my_root *rootp = pmemobj_direct(root);

	char buf[MAX_BUF_LEN];
	if (scanf("%9s", buf) == EOF) {
		fprintf(stderr, "EOF\n");
		return 1;
	}

	rootp->len = strlen(buf);
	pmemobj_persist(pop, &rootp->len, sizeof(rootp->len));

	pmemobj_memcpy_persist(pop, rootp->buf, buf, rootp->len);

	pmemobj_close(pop);

	return 0;
}
Exemple #10
0
int
main(int argc, char *argv[])
{
	if (argc < 3 || argc > 4) {
		printf("usage: %s hashmap_tx|hashmap_atomic|ctree|btree|rbtree"
				" file-name [<seed>]\n", argv[0]);
		return 1;
	}

	const struct map_ops *ops = NULL;
	const char *path = argv[2];
	const char *type = argv[1];
	if (strcmp(type, "hashmap_tx") == 0) {
		ops = MAP_HASHMAP_TX;
	} else if (strcmp(type, "hashmap_atomic") == 0) {
		ops = MAP_HASHMAP_ATOMIC;
	} else if (strcmp(type, "ctree") == 0) {
		ops = MAP_CTREE;
	} else if (strcmp(type, "btree") == 0) {
		ops = MAP_BTREE;
	} else if (strcmp(type, "rbtree") == 0) {
		ops = MAP_RBTREE;
	} else {
		fprintf(stderr, "invalid hasmap type -- '%s'\n", type);
		return 1;
	}

	if (access(path, F_OK) != 0) {
		pop = pmemobj_create(path, POBJ_LAYOUT_NAME(map),
				PM_HASHSET_POOL_SIZE, S_IRUSR | S_IWUSR);
		if (pop == NULL) {
			fprintf(stderr, "failed to create pool: %s\n",
					pmemobj_errormsg());
			return 1;
		}

		struct hashmap_args args;

		if (argc > 3)
			args.seed = atoi(argv[3]);
		else
			args.seed = time(NULL);
		srand(args.seed);


		mapc = map_ctx_init(ops, pop);
		if (!mapc) {
			pmemobj_close(pop);
			perror("map_ctx_init");
			return 1;
		}

		root = POBJ_ROOT(pop, struct root);

		printf("seed: %u\n", args.seed);
		map_new(mapc, &D_RW(root)->map, &args);

		map = D_RO(root)->map;
	} else {
Exemple #11
0
int
art_tree_map_init(struct datastore *ds, struct ds_context *ctx)
{
	int errors = 0;
	char *error_string;

	/* calculate a required pool size */
	if (ctx->psize < PMEMOBJ_MIN_POOL)
		ctx->psize = PMEMOBJ_MIN_POOL;

	if (!ctx->fileio) {
		if (access(ctx->filename, F_OK) != 0) {
			error_string = "pmemobj_create";
			ctx->pop = pmemobj_create(ctx->filename,
				    POBJ_LAYOUT_NAME(arttree_tx),
				    ctx->psize, ctx->fmode);
			ctx->newpool = 1;
		} else {
			error_string = "pmemobj_open";
			ctx->pop = pmemobj_open(ctx->filename,
				    POBJ_LAYOUT_NAME(arttree_tx));
		}
		if (ctx->pop == NULL) {
			perror(error_string);
			errors++;
		}
	} else {
		int flags = O_CREAT | O_RDWR | O_SYNC;

		/* Create a file if it does not exist. */
		if ((ctx->fd = open(ctx->filename, flags, ctx->fmode)) < 0) {
			perror(ctx->filename);
			errors++;
		}

		/* allocate the pmem */
		if ((errno = posix_fallocate(ctx->fd, 0, ctx->psize)) != 0) {
			perror("posix_fallocate");
			errors++;
		}
	}

	if (!errors) {
		pmemobj_ds_set_priv(ds, ctx);
	} else {
		if (ctx->fileio) {
			if (ctx->fd >= 0) {
				close(ctx->fd);
			}
		} else {
			if (ctx->pop) {
				pmemobj_close(ctx->pop);
			}
		}
	}

	return errors;
}
Exemple #12
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_direct");

	if (argc != 3)
		FATAL("usage: %s [directory] [# of pools]", argv[0]);

	int npools = atoi(argv[2]);
	const char *dir = argv[1];
	int r;

	PMEMobjpool *pops[npools];

	char path[MAX_PATH_LEN];
	for (int i = 0; i < npools; ++i) {
		snprintf(path, MAX_PATH_LEN, "%s/testfile%d", dir, i);
		pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL,
				S_IWUSR | S_IRUSR);

		if (pops[i] == NULL)
			FATAL("!pmemobj_create");
	}

	PMEMoid oids[npools];
	PMEMoid tmpoids[npools];

	oids[0] = OID_NULL;
	ASSERTeq(pmemobj_direct(oids[0]), NULL);

	for (int i = 0; i < npools; ++i) {
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, 0};
		ASSERTeq(pmemobj_direct(oids[i]), NULL);

		uint64_t off = pops[i]->heap_offset;
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, off};
		ASSERTeq(pmemobj_direct(oids[i]) - off, pops[i]);

		r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL);
		ASSERTeq(r, 0);
	}

	for (int i = 0; i < npools; ++i) {
		ASSERTne(pmemobj_direct(tmpoids[i]), NULL);

		pmemobj_free(&tmpoids[i]);

		ASSERTeq(pmemobj_direct(tmpoids[i]), NULL);

		pmemobj_close(pops[i]);
		ASSERTeq(pmemobj_direct(oids[i]), NULL);
	}

	DONE(NULL);
}
Exemple #13
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_fragmentation2");

	if (argc < 3)
		UT_FATAL("usage: %s filename workload [seed]", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, DEFAULT_FILE_SIZE,
				S_IWUSR | S_IRUSR);
	if (pop == NULL)
		UT_FATAL("!pmemobj_create: %s", path);

	int w = atoi(argv[2]);

	if (argc > 3)
		seed = (unsigned)atoi(argv[3]);
	else
		seed = time(NULL);

	objects = ZALLOC(sizeof(uint64_t) * MAX_OBJECTS);
	UT_ASSERTne(objects, NULL);

	workloads[w - 1](pop);

	PMEMoid oid;
	size_t remaining = 0;
	size_t chunk = 100; /* calc at chunk level */
	while (pmemobj_alloc(pop, &oid, chunk, 0, NULL, NULL) == 0)
		remaining += pmemobj_alloc_usable_size(oid) + 16;

	size_t allocated_sum = 0;
	oid = pmemobj_root(pop, 1);
	for (size_t n = 0; n < nobjects; ++n) {
		if (objects[n] == 0)
			continue;
		oid.off = objects[n];
		allocated_sum += pmemobj_alloc_usable_size(oid) + 16;
	}

	size_t used = DEFAULT_FILE_SIZE - remaining;
	float frag = ((float)used / allocated_sum) - 1.f;

	UT_ASSERT(frag <= workloads_target[w - 1]);

	pmemobj_close(pop);

	FREE(objects);

	DONE(NULL);
}
Exemple #14
0
static void
test_fault_injection(const char *path, const char *layout, size_t poolsize,
		unsigned mode)
{
	if (!pmemobj_fault_injection_enabled())
		return;

	pmemobj_inject_fault_at(PMEM_MALLOC, 1, "tx_params_new");
	PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode);
	UT_ASSERTeq(pop, NULL);
	UT_ASSERTeq(errno, ENOMEM);
}
Exemple #15
0
	/**
	 * Creates a new transactional object store pool.
	 *
	 * @param path System path to the file to be created. If exists
	 *	the pool can be created in-place depending on the size
	 *	parameter. Existing file must be zeroed.
	 * @param layout Unique identifier of the pool, can be a
	 *	NULL-terminated string.
	 * @param size Size of the pool in bytes. If zero and the file
	 *	exists the pool is created in-place.
	 * @param mode File mode for the new file.
	 *
	 * @return handle to the created pool.
	 *
	 * @throw nvml::pool_error when an error during creation occurs.
	 */
	static pool_base
	create(const std::string &path, const std::string &layout,
	       std::size_t size = PMEMOBJ_MIN_POOL,
	       mode_t mode = S_IWUSR | S_IRUSR)
	{
		pmemobjpool *pop = pmemobj_create(path.c_str(), layout.c_str(),
						  size, mode);
		if (pop == nullptr)
			throw pool_error("Failed creating pool");

		return pool_base(pop);
	}
Exemple #16
0
static void
test_open_in_different_process(int argc, char **argv, int sleep)
{
	pid_t pid = fork();
	PMEMobjpool *pop;
	char *path = argv[1];

	if (pid < 0)
		UT_FATAL("fork failed");

	if (pid == 0) {
		/* child */
		if (sleep)
			usleep(sleep);
		while (os_access(path, R_OK))
			usleep(100 * 1000);

		pop = pmemobj_open(path, LAYOUT);
		if (pop)
			UT_FATAL("pmemobj_open after fork should not succeed");

		if (errno != EWOULDBLOCK)
			UT_FATAL("!pmemobj_open after fork failed but for "
				"unexpected reason");

		exit(0);
	}

	pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL,
		S_IWUSR | S_IRUSR);
	if (!pop)
		UT_FATAL("!create");

	int status;

	if (waitpid(pid, &status, 0) < 0)
		UT_FATAL("!waitpid failed");

	if (!WIFEXITED(status))
		UT_FATAL("child process failed");

	pmemobj_close(pop);

	UNLINK(path);
}
Exemple #17
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_out_of_memory");

	if (argc < 3)
		FATAL("usage: %s size filename ...", argv[0]);

	size_t size = atoll(argv[1]);

	for (int i = 2; i < argc; i++) {
		const char *path = argv[i];

		PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, 0,
					S_IWUSR | S_IRUSR);
		if (pop == NULL)
			FATAL("!pmemobj_create: %s", path);

		test_alloc(pop, size);

		pmemobj_close(pop);

		ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1);

		/*
		 * To prevent subsequent opens from receiving exactly the same
		 * volatile memory addresses a dummy malloc has to be made.
		 * This can expose issues in which traces of previous volatile
		 * state are leftover in the persistent pool.
		 */
		void *heap_touch = MALLOC(1);

		ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL);

		test_free(pop);

		pmemobj_close(pop);

		FREE(heap_touch);
	}

	DONE(NULL);
}
Exemple #18
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_many_size_allocs");

	if (argc != 2)
		FATAL("usage: %s file-name", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop = NULL;

	if ((pop = pmemobj_create(path, LAYOUT_NAME,
			PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL)
		FATAL("!pmemobj_create: %s", path);

	test_allocs(pop, path);

	DONE(NULL);
}
Exemple #19
0
int
main(int argc, char *argv[])
{
	const char path[] = "/pmem-fs/myfile";
	PMEMobjpool *pop;

	/* create the pmemobj pool or open it if it already exists */
	pop = pmemobj_create(path, LAYOUT_NAME, POOL_SIZE, 0666);

	if (pop == NULL)
	    pop = pmemobj_open(path, LAYOUT_NAME);

	if (pop == NULL) {
		perror(path);
		exit(1);
	}

	/* ... */

	pmemobj_close(pop);
}
Exemple #20
0
/*
 * test_create -- allocate all possible objects and log the number. It should
 * exceed what would be possible on a single zone.
 * Additionally, free one object so that we can later check that it can be
 * allocated after the next open.
 */
static void
test_create(const char *path)
{
	PMEMobjpool *pop = NULL;

	if ((pop = pmemobj_create(path, LAYOUT_NAME,
			0, S_IWUSR | S_IRUSR)) == NULL)
		UT_FATAL("!pmemobj_create: %s", path);

	PMEMoid oid;
	int n = 0;
	while (1) {
		if (pmemobj_alloc(pop, &oid, ALLOC_SIZE, 0, NULL, NULL) != 0)
			break;
		n++;
	}

	UT_OUT("allocated: %d", n);
	pmemobj_free(&oid);

	pmemobj_close(pop);
}
Exemple #21
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "heap_interrupt");

	UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(heap_interrupt) != 0);

	if (argc != 4)
		UT_FATAL("usage: %s file [cmd: c/o] [scenario]", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop = NULL;
	int exists = argv[2][0] == 'o';
	int scenario = atoi(argv[3]);

	if (!exists) {
		if ((pop = pmemobj_create(path,
			POBJ_LAYOUT_NAME(heap_interrupt),
			0, S_IWUSR | S_IRUSR)) == NULL) {
			UT_FATAL("failed to create pool\n");
		}
		scenarios[scenario].create(pop);

		/* if we get here, something is wrong with function mocking */
		UT_ASSERT(0);
	} else {
		if ((pop = pmemobj_open(path,
			POBJ_LAYOUT_NAME(heap_interrupt)))
						== NULL) {
			UT_FATAL("failed to open pool\n");
		}
		scenarios[scenario].verify(pop);
	}

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #22
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_ctl_alignment");

	if (argc != 2)
		UT_FATAL("usage: %s file-name", argv[0]);

	const char *path = argv[1];

	if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL * 10,
			S_IWUSR | S_IRUSR)) == NULL)
			UT_FATAL("!pmemobj_create: %s", path);

	test_fail();
	test_aligned_allocs(1024, 512, POBJ_HEADER_NONE);
	test_aligned_allocs(1024, 512, POBJ_HEADER_COMPACT);
	test_aligned_allocs(64, 64, POBJ_HEADER_COMPACT);

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #23
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_pvector");
	if (argc != 2)
		UT_FATAL("usage: %s [file]", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop;
	if ((pop = pmemobj_create(path, "obj_pvector",
			PMEMOBJ_MIN_POOL * 3, S_IWUSR | S_IRUSR)) == NULL)
		UT_FATAL("!pmemobj_create: %s", path);

	PMEMoid root = pmemobj_root(pop, sizeof(struct test_root));
	struct test_root *r = (struct test_root *)pmemobj_direct(root);
	UT_ASSERTne(r, NULL);

	struct pvector_context *ctx = pvector_new(pop, &r->vec);

	uint64_t *val = pvector_push_back(ctx);
	*val = 5;

	val = pvector_push_back(ctx);
	*val = 10;

	val = pvector_push_back(ctx);
	*val = 15;

	uint64_t v;

	int n = 0;
	for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) {
		if (n == 0)
			UT_ASSERTeq(v, 5);
		if (n == 1)
			UT_ASSERTeq(v, 10);
		if (n == 2)
			UT_ASSERTeq(v, 15);
		if (n == 3)
			UT_ASSERT(0);

		n++;
	}

	uint64_t removed = pvector_pop_back(ctx, NULL);
	UT_ASSERTeq(removed, 15);

	n = 0;
	for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) {
		if (n == 0)
			UT_ASSERTeq(v, 5);
		if (n == 1)
			UT_ASSERTeq(v, 10);
		if (n == 3)
			UT_ASSERT(0);
		n++;
	}

	while (pvector_pop_back(ctx, vec_zero_entry) != 0)
		;

	pvector_delete(ctx);

	ctx = pvector_new(pop, &r->vec);
	for (int i = 0; i < PVECTOR_INSERT_VALUES; ++i) {
		val = pvector_push_back(ctx);
		UT_ASSERTne(val, NULL);
		*val = i;
		pmemobj_persist(pop, val, sizeof(*val));
	}

	n = 0;
	for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) {
		UT_ASSERTeq(v, n);
		n++;
	}

	n = 0;
	for (int i = PVECTOR_INSERT_VALUES - 1; i >= 0; --i) {
		v = pvector_pop_back(ctx, NULL);
		UT_ASSERTeq(v, i);
	}

	UT_ASSERTeq(pvector_first(ctx), 0);

	pvector_delete(ctx);

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #24
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_constructor");

	if (argc != 2)
		UT_FATAL("usage: %s file-name", argv[0]);

	const char *path = argv[1];

	PMEMobjpool *pop = NULL;

	int ret;
	TOID(struct root) root;
	TOID(struct node) node;

	if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(constr),
			0, S_IWUSR | S_IRUSR)) == NULL)
		UT_FATAL("!pmemobj_create: %s", path);

	/*
	 * Allocate memory until OOM, so we can check later if the alloc
	 * cancellation didn't damage the heap in any way.
	 */
	int allocs = 0;
	while (pmemobj_alloc(pop, NULL, sizeof (struct node), 1,
			NULL, NULL) == 0)
		allocs++;

	UT_ASSERTne(allocs, 0);

	PMEMoid oid;
	PMEMoid next;
	POBJ_FOREACH_SAFE(pop, oid, next)
		pmemobj_free(&oid);

	errno = 0;
	root.oid = pmemobj_root_construct(pop, sizeof (struct root),
			root_constr_cancel, NULL);
	UT_ASSERT(TOID_IS_NULL(root));
	UT_ASSERTeq(errno, ECANCELED);

	errno = 0;
	ret = pmemobj_alloc(pop, NULL, sizeof (struct node), 1,
			node_constr_cancel, NULL);
	UT_ASSERTeq(ret, -1);
	UT_ASSERTeq(errno, ECANCELED);

	/* the same number of allocations should be possible. */
	while (pmemobj_alloc(pop, NULL, sizeof (struct node), 1,
			NULL, NULL) == 0)
		allocs--;
	UT_ASSERTeq(allocs, 0);
	POBJ_FOREACH_SAFE(pop, oid, next)
		pmemobj_free(&oid);

	root.oid = pmemobj_root_construct(pop, sizeof (struct root),
			NULL, NULL);
	UT_ASSERT(!TOID_IS_NULL(root));

	errno = 0;
	node.oid = pmemobj_list_insert_new(pop, offsetof(struct node, next),
			&D_RW(root)->list, OID_NULL, 0, sizeof (struct node),
			1, node_constr_cancel, NULL);
	UT_ASSERT(TOID_IS_NULL(node));
	UT_ASSERTeq(errno, ECANCELED);

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #25
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_tx_flow");

	if (argc != 2)
		FATAL("usage: %s [file]", argv[0]);

	PMEMobjpool *pop;
	if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL,
	    S_IWUSR | S_IRUSR)) == NULL)
		FATAL("!pmemobj_create");

	int a = 0;
	int b = 0;
	int c = 0;

	TX_BEGIN(pop) {
		a = TEST_VALUE_A;
	} TX_ONCOMMIT {
		ASSERT(a == TEST_VALUE_A);
		b = TEST_VALUE_B;
	} TX_ONABORT { /* not called */
		a = TEST_VALUE_B;
	} TX_FINALLY {
		ASSERT(b == TEST_VALUE_B);
		c = TEST_VALUE_C;
	} TX_END

	ASSERT(a == TEST_VALUE_A);
	ASSERT(b == TEST_VALUE_B);
	ASSERT(c == TEST_VALUE_C);

	a = 0;
	b = 0;
	c = 0;

	TX_BEGIN(pop) {
		a = TEST_VALUE_A;
		pmemobj_tx_abort(EINVAL);
		a = TEST_VALUE_B;
	} TX_ONCOMMIT { /* not called */
		a = TEST_VALUE_B;
	} TX_ONABORT {
		ASSERT(a == TEST_VALUE_A);
		b = TEST_VALUE_B;
	} TX_FINALLY {
		ASSERT(b == TEST_VALUE_B);
		c = TEST_VALUE_C;
	} TX_END

	ASSERT(a == TEST_VALUE_A);
	ASSERT(b == TEST_VALUE_B);
	ASSERT(c == TEST_VALUE_C);

	a = 0;
	b = 0;
	c = 0;

	TX_BEGIN(pop) {
		TX_BEGIN(pop) {
			a = TEST_VALUE_A;
		} TX_ONCOMMIT {
			ASSERT(a == TEST_VALUE_A);
			b = TEST_VALUE_B;
		} TX_END
	} TX_ONCOMMIT {
		c = TEST_VALUE_C;
	} TX_END

	ASSERT(a == TEST_VALUE_A);
	ASSERT(b == TEST_VALUE_B);
	ASSERT(c == TEST_VALUE_C);

	a = 0;
	b = 0;
	c = 0;

	TX_BEGIN(pop) {
		a = TEST_VALUE_C;
		TX_BEGIN(pop) {
			a = TEST_VALUE_A;
			pmemobj_tx_abort(EINVAL);
			a = TEST_VALUE_B;
		} TX_ONCOMMIT { /* not called */
			a = TEST_VALUE_C;
		} TX_ONABORT {
			ASSERT(a == TEST_VALUE_A);
			b = TEST_VALUE_B;
		} TX_FINALLY {
			ASSERT(b == TEST_VALUE_B);
			c = TEST_VALUE_C;
		} TX_END
		a = TEST_VALUE_B;
	} TX_ONCOMMIT { /* not called */
		ASSERT(a == TEST_VALUE_A);
		c = TEST_VALUE_C;
	} TX_ONABORT {
		ASSERT(a == TEST_VALUE_A);
		ASSERT(b == TEST_VALUE_B);
		ASSERT(c == TEST_VALUE_C);
		a = TEST_VALUE_B;
	} TX_FINALLY {
		ASSERT(a == TEST_VALUE_B);
		b = TEST_VALUE_A;
	} TX_END

	ASSERT(a == TEST_VALUE_B);
	ASSERT(b == TEST_VALUE_A);
	ASSERT(c == TEST_VALUE_C);

	a = 0;
	b = 0;
	c = 0;

	pmemobj_tx_begin(pop, NULL, TX_LOCK_NONE);
	pmemobj_tx_abort(EINVAL);
	ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT);
	a = TEST_VALUE_A;
	pmemobj_tx_end();

	ASSERT(a == TEST_VALUE_A);

	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #26
0
int
main(int argc, char *argv[])
{
	unsigned int res = 0;
	PMEMobjpool *pop;
	const char *path;

	START(argc, argv, "ex_linkedlist");

	if (argc != 2) {
		UT_FATAL("usage: %s file-name", argv[0]);
	}
	path = argv[1];

	if (access(path, F_OK) != 0) {
		if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(list),
			PMEMOBJ_MIN_POOL, 0666)) == NULL) {
			UT_FATAL("!pmemobj_create: %s", path);
		}
	} else {
		if ((pop = pmemobj_open(path,
				POBJ_LAYOUT_NAME(list))) == NULL) {
			UT_FATAL("!pmemobj_open: %s", path);
		}
	}

	TOID(struct base) base = POBJ_ROOT(pop, struct base);
	TOID(struct tqueuehead) tqhead = D_RO(base)->tqueue;
	TOID(struct slisthead) slhead = D_RO(base)->slist;
	TX_BEGIN(pop) {
		tqhead = TX_NEW(struct tqueuehead);
		slhead = TX_NEW(struct slisthead);
	} TX_ONABORT {
		abort();
	} TX_END

	init_tqueue(pop, tqhead);
	init_slist(pop, slhead);

	int i = 0;
	TOID(struct tqnode) tqelement;
	POBJ_TAILQ_FOREACH(tqelement, tqhead, tnd) {
		if (D_RO(tqelement)->data != expectedResTQ[i]) {
			res = 1;
			break;
		}
		i++;
	}
	PRINT_RES(res, tail queue);

	i = 0;
	res = 0;
	TOID(struct snode) slelement;
	POBJ_SLIST_FOREACH(slelement, slhead, snd) {
		if (D_RO(slelement)->data != expectedResSL[i]) {
			res = 1;
			break;
		}
		i++;
	}
	PRINT_RES(res, singly linked list);
	pmemobj_close(pop);

	DONE(NULL);
}
Exemple #27
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_direct");

	if (argc != 3)
		UT_FATAL("usage: %s [directory] [# of pools]", argv[0]);

	int npools = atoi(argv[2]);
	const char *dir = argv[1];
	int r;

	pthread_mutex_init(&lock1, NULL);
	pthread_mutex_init(&lock2, NULL);
	pthread_cond_init(&sync_cond1, NULL);
	pthread_cond_init(&sync_cond2, NULL);
	cond1 = cond2 = 0;

	PMEMobjpool **pops = MALLOC(npools * sizeof(PMEMobjpool *));
	UT_ASSERTne(pops, NULL);

	char path[MAX_PATH_LEN];
	for (int i = 0; i < npools; ++i) {
		snprintf(path, MAX_PATH_LEN, "%s/testfile%d", dir, i);
		pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL,
				S_IWUSR | S_IRUSR);

		if (pops[i] == NULL)
			UT_FATAL("!pmemobj_create");
	}

	PMEMoid *oids = MALLOC(npools * sizeof(PMEMoid));
	UT_ASSERTne(oids, NULL);
	PMEMoid *tmpoids = MALLOC(npools * sizeof(PMEMoid));
	UT_ASSERTne(tmpoids, NULL);

	oids[0] = OID_NULL;
	UT_ASSERTeq(pmemobj_direct(oids[0]), NULL);

	for (int i = 0; i < npools; ++i) {
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, 0};
		UT_ASSERTeq(pmemobj_direct(oids[i]), NULL);

		uint64_t off = pops[i]->heap_offset;
		oids[i] = (PMEMoid) {pops[i]->uuid_lo, off};
		UT_ASSERTeq((char *)pmemobj_direct(oids[i]) - off,
			(char *)pops[i]);

		r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL);
		UT_ASSERTeq(r, 0);
	}

	r = pmemobj_alloc(pops[0], &thread_oid, 100, 2, NULL, NULL);
	UT_ASSERTeq(r, 0);
	UT_ASSERTne(pmemobj_direct(thread_oid), NULL);

	pthread_t t;
	PTHREAD_CREATE(&t, NULL, test_worker, NULL);

	/* wait for the worker thread to perform the first check */
	pthread_mutex_lock(&lock1);
	while (!cond1)
		pthread_cond_wait(&sync_cond1, &lock1);
	pthread_mutex_unlock(&lock1);

	for (int i = 0; i < npools; ++i) {
		UT_ASSERTne(pmemobj_direct(tmpoids[i]), NULL);

		pmemobj_free(&tmpoids[i]);

		UT_ASSERTeq(pmemobj_direct(tmpoids[i]), NULL);
		pmemobj_close(pops[i]);
		UT_ASSERTeq(pmemobj_direct(oids[i]), NULL);
	}

	/* signal the worker that we're free and closed */
	pthread_mutex_lock(&lock2);
	cond2 = 1;
	pthread_cond_signal(&sync_cond2);
	pthread_mutex_unlock(&lock2);

	PTHREAD_JOIN(t, NULL);
	pthread_cond_destroy(&sync_cond1);
	pthread_cond_destroy(&sync_cond2);
	pthread_mutex_destroy(&lock1);
	pthread_mutex_destroy(&lock2);
	FREE(pops);
	FREE(tmpoids);
	FREE(oids);

	DONE(NULL);
}
Exemple #28
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "out_err_mt");

	if (argc != 5)
		UT_FATAL("usage: %s filename1 filename2 filename3 dir",
				argv[0]);

	PMEMobjpool *pop = pmemobj_create(argv[1], "test",
		PMEMOBJ_MIN_POOL, 0666);
	PMEMlogpool *plp = pmemlog_create(argv[2],
		PMEMLOG_MIN_POOL, 0666);
	PMEMblkpool *pbp = pmemblk_create(argv[3],
		128, PMEMBLK_MIN_POOL, 0666);
#ifndef _WIN32
	/* XXX - vmem not implemented in windows yet */
	VMEM *vmp = vmem_create(argv[4], VMEM_MIN_POOL);
#endif

	util_init();

	pmem_check_version(10000, 0);
	pmemobj_check_version(10001, 0);
	pmemlog_check_version(10002, 0);
	pmemblk_check_version(10003, 0);
#ifndef _WIN32
	/* XXX - vmem not implemented in windows yet */
	vmem_check_version(10004, 0);
#endif
	pmempool_check_version(10005, 0);
	print_errors("version check");

	void *ptr = NULL;
	/*
	 * We are testing library error reporting and we don't want this test
	 * to fail under memcheck.
	 */
	VALGRIND_DO_DISABLE_ERROR_REPORTING;
	pmem_msync(ptr, 1);
	VALGRIND_DO_ENABLE_ERROR_REPORTING;
	print_errors("pmem_msync");

	pmemlog_append(plp, NULL, PMEMLOG_MIN_POOL);
	print_errors("pmemlog_append");

	size_t nblock = pmemblk_nblock(pbp);
	pmemblk_set_error(pbp, nblock + 1);
	print_errors("pmemblk_set_error");

#ifndef _WIN32
	/* XXX - vmem not implemented in windows yet */
	VMEM *vmp2 = vmem_create_in_region(NULL, 1);
	UT_ASSERTeq(vmp2, NULL);
	print_errors("vmem_create_in_region");
#endif

	run_mt_test(do_test);

	pmemobj_close(pop);
	pmemlog_close(plp);
	pmemblk_close(pbp);
#ifndef _WIN32
	/* XXX - vmem not implemented in windows yet */
	vmem_delete(vmp);
#endif

	PMEMpoolcheck *ppc;
	struct pmempool_check_args args = {0, };
	ppc = pmempool_check_init(&args, sizeof(args) / 2);
	UT_ASSERTeq(ppc, NULL);
	print_errors("pmempool_check_init");

	DONE(NULL);
}
Exemple #29
0
/*
 * pmemlog_create -- pool create wrapper
 */
PMEMlogpool *
pmemlog_create(const char *path, size_t poolsize, mode_t mode)
{
	return (PMEMlogpool *)pmemobj_create(path, LAYOUT_NAME,
				poolsize, mode);
}
Exemple #30
0
/*
 * pobj_init - common part of the benchmark initialization functions.
 * Parses command line arguments, set variables and creates persistent pools.
 */
static int
pobj_init(struct benchmark *bench, struct benchmark_args *args)
{
	unsigned i = 0;
	size_t psize;
	size_t n_objs;

	assert(bench != nullptr);
	assert(args != nullptr);

	enum file_type type = util_file_get_type(args->fname);
	if (type == OTHER_ERROR) {
		fprintf(stderr, "could not check type of file %s\n",
			args->fname);
		return -1;
	}

	auto *bench_priv =
		(struct pobj_bench *)malloc(sizeof(struct pobj_bench));
	if (bench_priv == nullptr) {
		perror("malloc");
		return -1;
	}
	assert(args->opts != nullptr);

	bench_priv->args_priv = (struct pobj_args *)args->opts;
	bench_priv->args_priv->obj_size = args->dsize;
	bench_priv->args_priv->range =
		bench_priv->args_priv->min_size > 0 ? true : false;
	bench_priv->n_pools =
		!bench_priv->args_priv->one_pool ? args->n_threads : 1;
	bench_priv->pool = bench_priv->n_pools > 1 ? diff_num : one_num;
	bench_priv->obj = !bench_priv->args_priv->one_obj ? diff_num : one_num;

	if ((args->is_poolset || type == TYPE_DEVDAX) &&
	    bench_priv->n_pools > 1) {
		fprintf(stderr,
			"cannot use poolset nor device dax for multiple pools,"
			" please use -P|--one-pool option instead");
		goto free_bench_priv;
	}
	/*
	 * Multiplication by FACTOR prevents from out of memory error
	 * as the actual size of the allocated persistent objects
	 * is always larger than requested.
	 */
	n_objs = bench_priv->args_priv->n_objs;
	if (bench_priv->n_pools == 1)
		n_objs *= args->n_threads;
	psize = PMEMOBJ_MIN_POOL +
		n_objs * args->dsize * args->n_threads * FACTOR;

	/* assign type_number determining function */
	bench_priv->type_mode =
		parse_type_mode(bench_priv->args_priv->type_num);
	switch (bench_priv->type_mode) {
		case MAX_TYPE_MODE:
			fprintf(stderr, "unknown type mode");
			goto free_bench_priv;
		case TYPE_MODE_RAND:
			if (random_types(bench_priv, args))
				goto free_bench_priv;
			break;
		default:
			bench_priv->random_types = nullptr;
	}
	bench_priv->fn_type_num = type_mode_func[bench_priv->type_mode];

	/* assign size determining function */
	bench_priv->fn_size =
		bench_priv->args_priv->range ? range_size : static_size;
	bench_priv->rand_sizes = nullptr;
	if (bench_priv->args_priv->range) {
		if (bench_priv->args_priv->min_size > args->dsize) {
			fprintf(stderr, "Invalid allocation size");
			goto free_random_types;
		}
		bench_priv->rand_sizes =
			rand_sizes(bench_priv->args_priv->min_size,
				   bench_priv->args_priv->obj_size,
				   bench_priv->args_priv->n_objs);
		if (bench_priv->rand_sizes == nullptr)
			goto free_random_types;
	}

	assert(bench_priv->n_pools > 0);
	bench_priv->pop = (PMEMobjpool **)calloc(bench_priv->n_pools,
						 sizeof(PMEMobjpool *));
	if (bench_priv->pop == nullptr) {
		perror("calloc");
		goto free_random_sizes;
	}

	bench_priv->sets = (const char **)calloc(bench_priv->n_pools,
						 sizeof(const char *));
	if (bench_priv->sets == nullptr) {
		perror("calloc");
		goto free_pop;
	}
	if (bench_priv->n_pools > 1) {
		assert(!args->is_poolset);
		if (util_file_mkdir(args->fname, DIR_MODE) != 0) {
			fprintf(stderr, "cannot create directory\n");
			goto free_sets;
		}
		size_t path_len = (strlen(PART_NAME) + strlen(args->fname)) +
			MAX_DIGITS + 1;
		for (i = 0; i < bench_priv->n_pools; i++) {
			bench_priv->sets[i] =
				(char *)malloc(path_len * sizeof(char));
			if (bench_priv->sets[i] == nullptr) {
				perror("malloc");
				goto free_sets;
			}
			int ret =
				snprintf((char *)bench_priv->sets[i], path_len,
					 "%s%s%02x", args->fname, PART_NAME, i);
			if (ret < 0 || ret >= (int)path_len) {
				perror("snprintf");
				goto free_sets;
			}
			bench_priv->pop[i] =
				pmemobj_create(bench_priv->sets[i], LAYOUT_NAME,
					       psize, FILE_MODE);
			if (bench_priv->pop[i] == nullptr) {
				perror(pmemobj_errormsg());
				goto free_sets;
			}
		}
	} else {
		if (args->is_poolset || type == TYPE_DEVDAX) {
			if (args->fsize < psize) {
				fprintf(stderr, "file size too large\n");
				goto free_pools;
			}
			psize = 0;
		}
		bench_priv->sets[0] = args->fname;
		bench_priv->pop[0] = pmemobj_create(
			bench_priv->sets[0], LAYOUT_NAME, psize, FILE_MODE);
		if (bench_priv->pop[0] == nullptr) {
			perror(pmemobj_errormsg());
			goto free_pools;
		}
	}
	pmembench_set_priv(bench, bench_priv);

	return 0;
free_sets:
	for (; i > 0; i--) {
		pmemobj_close(bench_priv->pop[i - 1]);
		free((char *)bench_priv->sets[i - 1]);
	}
free_pools:
	free(bench_priv->sets);
free_pop:
	free(bench_priv->pop);
free_random_sizes:
	free(bench_priv->rand_sizes);
free_random_types:
	free(bench_priv->random_types);
free_bench_priv:
	free(bench_priv);

	return -1;
}