/* * 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); }
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); }
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); }
/* * 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; }
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); }
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); }