Пример #1
0
/*
 * pool_test -- test pool
 *
 * This function creates a memory pool in a file (if dir is not NULL),
 * or in RAM (if dir is NULL) and allocates memory for the test.
 */
void
pool_test(const char *dir)
{
	VMEM *vmp = NULL;

	if (dir != NULL) {
		vmp = vmem_pool_create(dir, VMEM_MIN_POOL);
	} else {
		vmp = vmem_pool_create_in_region(mem_pool, VMEM_MIN_POOL);
	}

	if (expect_create_pool == 0) {
		ASSERTeq(vmp, NULL);
		DONE(NULL);
	} else {
		if (vmp == NULL) {
			if (dir == NULL) {
				FATAL("!vmem_pool_create_in_region");
			} else {
				FATAL("!vmem_pool_create");
			}
		}
	}

	char *test = vmem_malloc(vmp, strlen(TEST_STRING_VALUE) + 1);
	ASSERTne(test, NULL);

	strcpy(test, TEST_STRING_VALUE);
	ASSERTeq(strcmp(test, TEST_STRING_VALUE), 0);

	vmem_free(vmp, test);

	vmem_pool_delete(vmp);
}
Пример #2
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "vmem_multiple_pools");

	if (argc < 2 || argc > 3)
		FATAL("usage: %s directory", argv[0]);

	const char *dir = argv[1];

	/* create and destroy pools multiple times */
	size_t repeat;
	size_t pool_id;
	for (repeat = 0; repeat < TEST_REPEAT_CREATE_POOLS; ++repeat) {
		for (pool_id = 0; pool_id < TEST_POOLS_MAX; ++pool_id) {

			/* delete old pool with this same id if exist */
			if (pools[pool_id] != NULL) {
				vmem_pool_delete(pools[pool_id]);
				pools[pool_id] = NULL;
			}

			if (pool_id % 2 == 0) {
				/* for even pool_id, create in region */
				pools[pool_id] = vmem_pool_create_in_region(
					mem_pools[pool_id % 2], VMEM_MIN_POOL);
				if (pools[pool_id] == NULL)
					FATAL("!vmem_pool_create_in_region");
			} else {
				/* for odd pool_id, create in file */
				pools[pool_id] = vmem_pool_create(dir,
					VMEM_MIN_POOL);
				if (pools[pool_id] == NULL)
					FATAL("!vmem_pool_create");
			}

			void *test = vmem_malloc(pools[pool_id],
				sizeof (void *));

			ASSERTne(test, NULL);
			vmem_free(pools[pool_id], test);
		}
	}

	for (pool_id = 0; pool_id < TEST_POOLS_MAX; ++pool_id) {
		if (pools[pool_id] != NULL) {
			vmem_pool_delete(pools[pool_id]);
			pools[pool_id] = NULL;
		}
	}

	DONE(NULL);
}
Пример #3
0
int
main(int argc, char *argv[])
{
	char *dir = NULL;
	void *mem_pool = NULL;
	VMEM *vmp;

	START(argc, argv, "vmem_check_allocations");

	if (argc == 2) {
		dir = argv[1];
	} else if (argc > 2) {
		FATAL("usage: %s [directory]", argv[0]);
	}

	size_t object_size;
	for (object_size = 8; object_size <= TEST_MAX_ALLOCATION_SIZE;
							object_size *= 2) {
		size_t i;
		size_t j;

		if (dir == NULL) {
			mem_pool = MMAP(NULL, VMEM_MIN_POOL,
					PROT_READ|PROT_WRITE,
					MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);

			vmp = vmem_pool_create_in_region(mem_pool,
				VMEM_MIN_POOL);
			if (vmp == NULL)
				FATAL("!vmem_pool_create_in_region");
		} else {
			vmp = vmem_pool_create(dir, VMEM_MIN_POOL);
			if (vmp == NULL)
				FATAL("!vmem_pool_create");
		}

		memset(allocs, 0, TEST_ALLOCS_SIZE);

		for (i = 0; i < TEST_ALLOCS_SIZE; ++i) {
			allocs[i] =  vmem_malloc(vmp, object_size);
			if (allocs[i] == NULL) {
				/* out of memory in pool */
				break;
			}

			/* check that pointer came from mem_pool */
			if (dir == NULL) {
				ASSERTrange(allocs[i],
					mem_pool, VMEM_MIN_POOL);
			}

			/* fill each allocation with a unique value */
			memset(allocs[i], (char)i, object_size);
		}

		ASSERT((i > 0) && (i + 1 < TEST_MAX_ALLOCATION_SIZE));

		/* check for unexpected modifications of the data */
		for (i = 0; i < TEST_ALLOCS_SIZE && allocs[i] != NULL; ++i) {
			char *buffer = allocs[i];
			for (j = 0; j < object_size; ++j) {
				if (buffer[j] != (char)i)
					FATAL("Content of data object was "
						"modified unexpectedly for "
						"object size: %zu, id: %zu",
						object_size, j);
			}
		}

		vmem_pool_delete(vmp);
	}

	DONE(NULL);
}
Пример #4
0
/*
 * main -- entry point, initializes allocated_mem and runs the tasks
 */
int
main(int argc, char *argv[])
{
	int i, fails = 0;
	double task_duration;
	void **arg = NULL;
	uint64_t pool_size;
	arguments_t arguments;
	int per_thread_args = 0;
	const int min_pool_size = 200;
	arguments.pool_per_thread = 0;
	arguments.allocator = ALLOCATOR_VMEM;
	arguments.dir_path = NULL;
	if (argp_parse(&argp, argc, argv, 0, 0, &arguments)) {
		fprintf(stderr, "argp_parse error");
		return EXIT_FAILURE;
	}
	int pools_count = arguments.pool_per_thread ?
			arguments.thread_count : 1;
	VMEM *pools[pools_count];
	void *pools_data[pools_count];
	allocated_mem = calloc(arguments.ops_count, sizeof (void*));

	if (allocated_mem == NULL) {
		perror("calloc");
		return EXIT_FAILURE;
	}

	if (arguments.allocator == ALLOCATOR_VMEM) {
		if (arguments.pool_per_thread &&
			arguments.thread_count > MAX_THREADS) {
			fprintf(stderr, "Maximum allowed thread count"
				" with pool per thread option enabled is %u\n",
				MAX_THREADS);
			return EXIT_FAILURE;
		}

		pools_count = arguments.pool_per_thread ?
			arguments.thread_count : 1;
		per_thread_args = arguments.pool_per_thread;
		pool_size = arguments.ops_count *
			arguments.allocation_size_max * 2u;

		pool_size /= pools_count;

		if (pool_size < min_pool_size * MB) {
			pool_size = min_pool_size * MB;
		}
		for (i = 0; i < pools_count; ++i) {
			if (arguments.dir_path == NULL) {
				pools_data[i] = malloc(pool_size);
				if (pools_data[i] == NULL) {
					free(allocated_mem);
					perror("malloc");
					return EXIT_FAILURE;
				}
				/* suppress valgrind warnings */
				memset(pools_data[i], 0xFF, pool_size);
				pools[i] = vmem_pool_create_in_region(
						pools_data[i], pool_size);
			} else {
				pools[i] = vmem_pool_create(arguments.dir_path,
						pool_size);
			}
			if (pools[i] == NULL) {
				perror("vmem_pool_create");
				free(allocated_mem);
				return EXIT_FAILURE;
			}
		}
		arg = (void **)pools;
	}

	/* Cache warmup. */
	for (i = 0; i < MAX_TASK; ++i) {
		fails += run_threads(&arguments, tasks[i],
			per_thread_args, arg, &task_duration);
	}

	for (i = 0; i < MAX_TASK; ++i) {
		fails += run_threads(&arguments, tasks[i],
			per_thread_args, arg, &task_duration);
		printf("%f;%f;",
			task_duration, arguments.ops_count/task_duration);
	}

	printf("\n");

	if (arguments.allocator == ALLOCATOR_VMEM) {
		for (i = 0; i < pools_count; ++i) {
			vmem_pool_delete(pools[i]);
			if (arguments.dir_path == NULL) {
				free(pools_data[i]);
			}
		}
	}

	free(allocated_mem);

	return (fails == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Пример #5
0
int
main(int argc, char *argv[])
{
	const int test_value = 123456;
	char *dir = NULL;
	VMEM *vmp;
	size_t alignment;
	unsigned i;
	int *ptr;

	START(argc, argv, "vmem_aligned_alloc");

	if (argc == 2) {
		dir = argv[1];
	} else if (argc > 2) {
		FATAL("usage: %s [directory]", argv[0]);
	}

	/* use custom alloc functions to check for memory leaks */
	vmem_set_funcs(malloc_custom, free_custom,
		realloc_custom, strdup_custom, NULL);

	/* test with address alignment from 2B to 4MB */
	for (alignment = 2; alignment <= 4 * 1024 * 1024; alignment *= 2) {

		custom_alloc_calls = 0;
		if (dir == NULL) {
			vmp = vmem_pool_create_in_region(mem_pool,
				VMEM_MIN_POOL);
			if (vmp == NULL)
				FATAL("!vmem_pool_create_in_region");
		} else {
			vmp = vmem_pool_create(dir, VMEM_MIN_POOL);
			if (vmp == NULL)
				FATAL("!vmem_pool_create");
		}

		for (i = 0; i < MAX_ALLOCS; ++i) {
			ptr = vmem_aligned_alloc(vmp, alignment, sizeof (int));

			/* at least one allocation must succeed */
			ASSERT(i != 0 || ptr != NULL);
			if (ptr == NULL)
				break;

			/* ptr should be usable */
			*ptr = test_value;
			ASSERTeq(*ptr, test_value);

			/* check for correct address alignment */
			ASSERTeq((uintptr_t)(ptr) & (alignment - 1), 0);

			/* check that pointer came from mem_pool */
			if (dir == NULL) {
				ASSERTrange(ptr, mem_pool, VMEM_MIN_POOL);
			}
		}

		vmem_pool_delete(vmp);

		/* check memory leaks */
		ASSERTne(custom_alloc_calls, 0);
		ASSERTeq(custom_allocs, 0);
	}


	DONE(NULL);
}
Пример #6
0
int
main(int argc, char *argv[])
{
	char *dir = NULL;
	VMEM *vmp;
	START(argc, argv, "vmem_freespace");

	if (argc == 2) {
		dir = argv[1];
	} else if (argc > 2) {
		FATAL("usage: %s [directory]", argv[0]);
	}

	if (dir == NULL) {
		/* allocate memory for function vmem_pool_create_in_region() */
		void *mem_pool = MMAP(NULL, VMEM_MIN_POOL, PROT_READ|PROT_WRITE,
					MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);

		vmp = vmem_pool_create_in_region(mem_pool, VMEM_MIN_POOL);
		if (vmp == NULL)
			FATAL("!vmem_pool_create_in_region");
	} else {
		vmp = vmem_pool_create(dir, VMEM_MIN_POOL);
		if (vmp == NULL)
			FATAL("!vmem_pool_create");
	}

	size_t total_space = vmem_pool_freespace(vmp);
	size_t free_space = total_space;

	/* allocate all memory */
	void *prev = NULL;
	void **next;
	while ((next = vmem_malloc(vmp, 128)) != NULL) {
		*next = prev;
		prev = next;
		size_t space = vmem_pool_freespace(vmp);
		/* free space can only decrease */
		ASSERT(space <= free_space);
		free_space = space;
	}

	ASSERTne(prev, NULL);
	/* for small allocations use all memory */
	ASSERTeq(free_space, 0);

	while (prev != NULL) {
		void **act = prev;
		prev = *act;
		vmem_free(vmp, act);
		size_t space = vmem_pool_freespace(vmp);
		/* free space can only increase */
		ASSERT(space >= free_space);
		free_space = space;
	}

	free_space = vmem_pool_freespace(vmp);

	/*
	 * Depending on the distance of the 'mem_pool' from the
	 * chunk alignment (4MB) a different size of free memory
	 * will be wasted on base_alloc inside jemalloc.
	 * Rest of the internal data should not waste more than 10% of space.
	 */
	ASSERT(free_space > ((total_space - 4L * MB) * 9) / 10);

	vmem_pool_delete(vmp);

	DONE(NULL);
}