static PMEMobjpool * pmemobj_open_mock(const char *fname) { size_t size; int is_pmem; void *addr = pmem_map_file(fname, 0, 0, 0, &size, &is_pmem); if (!addr) { UT_OUT("!%s: pmem_map_file", fname); return NULL; } UT_ASSERT(size > PMEMOBJ_POOL_HDR_SIZE); PMEMobjpool *pop = (PMEMobjpool *)addr; VALGRIND_REMOVE_PMEM_MAPPING((char *)addr + sizeof(pop->hdr), 4096); pop->addr = addr; pop->size = size; pop->is_pmem = is_pmem; pop->rdonly = 0; if (pop->is_pmem) { pop->persist_local = pmem_persist; pop->flush_local = pmem_flush; pop->drain_local = pmem_drain; } else { pop->persist_local = (persist_local_fn)pmem_msync; pop->flush_local = (persist_local_fn)pmem_msync; pop->drain_local = pmem_drain_nop; } pop->persist = obj_persist; pop->flush = obj_flush; pop->drain = obj_drain; pop->redo = redo_log_config_new(pop->addr, (redo_persist_fn)pop->persist, (redo_flush_fn)pop->flush, redo_log_check_offset, pop, pop, REDO_NUM_ENTRIES); return pop; }
static PMEMobjpool * pmemobj_open_mock(const char *fname, size_t redo_size) { size_t size; int is_pmem; void *addr = pmem_map_file(fname, 0, 0, 0, &size, &is_pmem); if (!addr) { UT_OUT("!%s: pmem_map_file", fname); return NULL; } UT_ASSERT(size >= PMEMOBJ_POOL_HDR_SIZE + redo_size); PMEMobjpool *pop = (PMEMobjpool *)addr; VALGRIND_REMOVE_PMEM_MAPPING((char *)addr + sizeof(pop->hdr), 4096); pop->addr = addr; pop->is_pmem = is_pmem; pop->rdonly = 0; pop->set = MALLOC(sizeof(*pop->set)); pop->set->poolsize = size; if (pop->is_pmem) { pop->persist_local = pmem_persist; pop->flush_local = pmem_flush; pop->drain_local = pmem_drain; } else { pop->persist_local = obj_msync_nofail; pop->flush_local = obj_msync_nofail; pop->drain_local = pmem_drain_nop; } pop->p_ops.persist = obj_persist; pop->p_ops.flush = obj_flush; pop->p_ops.drain = obj_drain; pop->p_ops.base = pop; pop->heap_offset = PMEMOBJ_POOL_HDR_SIZE + redo_size; pop->heap_size = size - pop->heap_offset; pop->redo = redo_log_config_new(pop->addr, &pop->p_ops, redo_log_check_offset, pop, REDO_NUM_ENTRIES); return pop; }
static void test_mock_pool_allocs() { void *real_address = ZALLOC(MOCK_POOL_SIZE * 2); addr = (void *)ALIGN_CEILING((uint64_t)real_address, (uint64_t)Ut_pagesize); mock_pop = &addr->p; mock_pop->addr = addr; mock_pop->size = MOCK_POOL_SIZE; mock_pop->rdonly = 0; mock_pop->is_pmem = 0; mock_pop->heap_offset = offsetof(struct mock_pop, ptr); UT_ASSERTeq(mock_pop->heap_offset % Ut_pagesize, 0); mock_pop->heap_size = MOCK_POOL_SIZE - mock_pop->heap_offset; mock_pop->nlanes = 1; mock_pop->lanes_offset = sizeof(PMEMobjpool); mock_pop->is_master_replica = 1; mock_pop->persist_local = (persist_local_fn)pmem_msync; mock_pop->flush_local = (flush_local_fn)pmem_msync; mock_pop->drain_local = drain_empty; mock_pop->p_ops.persist = obj_persist; mock_pop->p_ops.flush = obj_flush; mock_pop->p_ops.drain = obj_drain; mock_pop->p_ops.memcpy_persist = obj_memcpy; mock_pop->p_ops.memset_persist = obj_memset; mock_pop->p_ops.base = mock_pop; mock_pop->p_ops.pool_size = mock_pop->size; mock_pop->redo = redo_log_config_new(addr, &mock_pop->p_ops, redo_log_check_offset, mock_pop, REDO_NUM_ENTRIES); void *heap_start = (char *)mock_pop + mock_pop->heap_offset; uint64_t heap_size = mock_pop->heap_size; heap_init(heap_start, heap_size, &mock_pop->p_ops); heap_boot(&mock_pop->heap, heap_start, heap_size, mock_pop, &mock_pop->p_ops); /* initialize runtime lanes structure */ mock_pop->lanes_desc.runtime_nlanes = (unsigned)mock_pop->nlanes; lane_boot(mock_pop); UT_ASSERTne(mock_pop->heap.rt, NULL); test_malloc_free_loop(MALLOC_FREE_SIZE); /* * Allocating till OOM and freeing the objects in a loop for different * buckets covers basically all code paths except error cases. */ test_oom_allocs(TEST_HUGE_ALLOC_SIZE); test_oom_allocs(TEST_TINY_ALLOC_SIZE); test_oom_allocs(TEST_HUGE_ALLOC_SIZE); test_oom_allocs(TEST_SMALL_ALLOC_SIZE); test_oom_allocs(TEST_MEGA_ALLOC_SIZE); test_realloc(TEST_SMALL_ALLOC_SIZE, TEST_MEDIUM_ALLOC_SIZE); test_realloc(TEST_HUGE_ALLOC_SIZE, TEST_MEGA_ALLOC_SIZE); lane_cleanup(mock_pop); heap_cleanup(&mock_pop->heap); FREE(real_address); }