/* * Copyright (C) 2018 Philippe Gerum * * SPDX-License-Identifier: MIT */ #include #include #include #include "memcheck/memcheck.h" smokey_test_plugin(memory_pshared, MEMCHECK_ARGS, "Check for the pshared allocator sanity.\n" MEMCHECK_HELP_STRINGS ); #define MIN_HEAP_SIZE 8192 #define MAX_HEAP_SIZE (1024 * 1024 * 2) #define RANDOM_ROUNDS 1024 #define PATTERN_HEAP_SIZE (128*1024) #define PATTERN_ROUNDS 128 static struct heapobj heap; static int do_pshared_init(void *heap, void *mem, size_t arena_size) { /* mem is ignored, pshared uses its own memory. */ return heapobj_init(heap, "memcheck", arena_size); } static void do_pshared_destroy(void *heap) { heapobj_destroy(heap); } static void *do_pshared_alloc(void *heap, size_t size) { return heapobj_alloc(heap, size); } static int do_pshared_free(void *heap, void *block) { heapobj_free(heap, block); return 0; /* Hope for the best. */ } static size_t do_pshared_used_size(void *heap) { return heapobj_inquire(heap); } static size_t do_pshared_usable_size(void *heap) { return heapobj_get_size(heap); } static size_t do_pshared_arena_size(size_t heap_size) { struct heapobj h; size_t overhead; int ret; ret = heapobj_init(&h, "memcheck", heap_size); if (ret) return 0; overhead = heap_size - heapobj_get_size(&h); heapobj_destroy(&h); /* * pshared must have no external overhead, since * heapobj_init() allocates the memory it needs. Make sure * this assumption is correct for any tested size. */ return overhead == 0 ? heap_size : 0; } static struct memcheck_descriptor pshared_descriptor = { .name = "pshared", .init = HEAP_INIT_T(do_pshared_init), .destroy = HEAP_DESTROY_T(do_pshared_destroy), .alloc = HEAP_ALLOC_T(do_pshared_alloc), .free = HEAP_FREE_T(do_pshared_free), .get_usable_size = HEAP_USABLE_T(do_pshared_usable_size), .get_used_size = HEAP_USED_T(do_pshared_used_size), .get_arena_size = do_pshared_arena_size, .seq_min_heap_size = MIN_HEAP_SIZE, .seq_max_heap_size = MAX_HEAP_SIZE, .random_rounds = RANDOM_ROUNDS, .pattern_heap_size = PATTERN_HEAP_SIZE, .pattern_rounds = PATTERN_ROUNDS, /* heapobj-pshared has overgead even for ^2 sizes, can't check for ZEROOVRD. */ .valid_flags = MEMCHECK_ALL_FLAGS & ~MEMCHECK_ZEROOVRD, .heap = &heap, }; static int run_memory_pshared(struct smokey_test *t, int argc, char *const argv[]) { return memcheck_run(&pshared_descriptor, t, argc, argv); } static int memcheck_pshared_tune(void) { /* * We create test pools from the main one: make sure the * latter is large enough. */ set_config_tunable(mem_pool_size, MAX_HEAP_SIZE + 1024 * 1024); return 0; } static struct setup_descriptor memcheck_pshared_setup = { .name = "memcheck_pshared", .tune = memcheck_pshared_tune, }; user_setup_call(memcheck_pshared_setup);