diff options
Diffstat (limited to 'test/shmalloc.c')
-rw-r--r-- | test/shmalloc.c | 305 |
1 files changed, 0 insertions, 305 deletions
diff --git a/test/shmalloc.c b/test/shmalloc.c deleted file mode 100644 index a596d173e7..0000000000 --- a/test/shmalloc.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -#include "common.h" -#include "compile_time_macros.h" -#include "console.h" -#include "link_defs.h" -#include "shared_mem.h" -#include "test_util.h" - -/* - * Total size of memory in the malloc pool (shared between free and allocated - * buffers. - */ -static int total_size; - -/* - * Number of randomized allocation/free attempts, large enough to execute all - * branches in the malloc/free module. - */ -static int counter = 500000; - -/* - * A good random number generator approximation. Guaranteed to generate the - * same sequence on all test runs. - */ -static uint32_t next = 127; -static uint32_t myrand(void) -{ - next = next * 1103515245 + 12345; - return ((uint32_t)(next/65536) % 32768); -} - -/* Keep track of buffers allocated by the test function. */ -static struct { - void *buf; - size_t buffer_size; -} allocations[12]; /* Up to 12 buffers could be allocated concurrently. */ - -/* - * Verify that allocated and free buffers do not overlap, and that our and - * malloc's ideas of the number of allocated buffers match. - */ - -static int check_for_overlaps(void) -{ - int i; - int allocation_match; - int allocations_count, allocated_count; - - allocations_count = allocated_count = 0; - for (i = 0; i < ARRAY_SIZE(allocations); i++) { - struct shm_buffer *allocced_buf; - - if (!allocations[i].buf) - continue; - - /* - * Indication of finding the allocated buffer in internal - * malloc structures. - */ - allocation_match = 0; - - /* number of buffers allocated by the test program. */ - allocations_count++; - - /* - * Number of allocated buffers malloc knows about, calculated - * multiple times to keep things simple. - */ - allocated_count = 0; - for (allocced_buf = allocced_buf_chain; - allocced_buf; - allocced_buf = allocced_buf->next_buffer) { - int allocated_size, allocation_size; - - allocated_count++; - if (allocations[i].buf != (allocced_buf + 1)) - continue; - - allocated_size = allocced_buf->buffer_size; - allocation_size = allocations[i].buffer_size; - - /* - * Verify that size requested by the allocator matches - * the value used by malloc, i.e. does not exceed the - * allocated size and is no less than two buffer - * structures lower (which can happen when the - * requested size was rounded up to cover gaps smaller - * than the buffer header structure size). - */ - if ((allocation_size > allocated_size) || - ((allocated_size - allocation_size) >= - (2 * sizeof(struct shm_buffer) + sizeof(int)))) { - ccprintf("inconsistency: allocated (size %d)" - " allocation %d(size %d)\n", - allocated_size, i, allocation_size); - return 0; - } - - if (allocation_match++) { - ccprintf("inconsistency: duplicated match\n"); - return 0; - } - } - if (!allocation_match) { - ccprintf("missing match %pP!\n", allocations[i].buf); - return 0; - } - } - if (allocations_count != allocated_count) { - ccprintf("count mismatch (%d != %d)!\n", - allocations_count, allocated_count); - return 0; - } - return 1; -} - -/* - * Verify that shared memory is in a consistent state, i.e. that there is no - * overlaps between allocated and free buffers, and that all memory is - * accounted for (is either allocated or available). - */ - -static int shmem_is_ok(int line) -{ - int count = 0; - int running_size = 0; - struct shm_buffer *pbuf = free_buf_chain; - - if (pbuf && pbuf->prev_buffer) { - ccprintf("Bad free buffer list start %pP\n", pbuf); - goto bailout; - } - - while (pbuf) { - struct shm_buffer *top; - - running_size += pbuf->buffer_size; - if (count++ > 100) - goto bailout; /* Is there a loop? */ - - top = (struct shm_buffer *)((uintptr_t)pbuf + - pbuf->buffer_size); - if (pbuf->next_buffer) { - if (top >= pbuf->next_buffer) { - ccprintf("%s:%d" - " - inconsistent buffer size at %pP\n", - __func__, __LINE__, pbuf); - goto bailout; - } - if (pbuf->next_buffer->prev_buffer != pbuf) { - ccprintf("%s:%d" - " - inconsistent next buffer at %pP\n", - __func__, __LINE__, pbuf); - goto bailout; - } - } - pbuf = pbuf->next_buffer; - } - - if (pbuf) { /* Must be a loop. */ - ccprintf("Too many buffers in the chain\n"); - goto bailout; - } - - /* Make sure there were at least 5 buffers allocated at one point. */ - if (count > 5) - set_map_bit(1 << 24); - - /* Add allocated sizes. */ - for (pbuf = allocced_buf_chain; pbuf; pbuf = pbuf->next_buffer) - running_size += pbuf->buffer_size; - - if (total_size) { - if (total_size != running_size) - goto bailout; - } else { - /* Remember total size for future reference. */ - total_size = running_size; - } - - if (!check_for_overlaps()) - goto bailout; - - return 1; - - bailout: - ccprintf("Line %d, counter %d. The list has been corrupted, " - "total size %d, running size %d\n", - line, counter, total_size, running_size); - return 0; -} - -/* - * Bitmap used to keep track of branches taken by malloc/free routines. Once - * all bits in the 0..(MAX_MASK_BIT - 1) range are set, consider the test - * completed. - */ -static uint32_t test_map; - -void run_test(int argc, char **argv) -{ - int index; - const int shmem_size = shared_mem_size(); - - while (counter--) { - char *shptr; - uint32_t r_data; - - r_data = myrand(); - - if (!(counter % 50000)) - ccprintf("%d\n", counter); - - /* - * If all bits we care about are set in the map - the test is - * over. - */ - if ((test_map & ALL_PATHS_MASK) == ALL_PATHS_MASK) { - if (test_map & ~ALL_PATHS_MASK) { - ccprintf("Unexpected mask bits set: %x" - ", counter %d\n", - test_map & ~ALL_PATHS_MASK, - counter); - test_fail(); - return; - } - ccprintf("Done testing, counter at %d\n", counter); - test_pass(); - return; - } - - /* Pick a random allocation entry. */ - index = r_data % ARRAY_SIZE(allocations); - if (allocations[index].buf) { - /* - * If there is a buffer associated with the entry - - * release it. - */ - shared_mem_release(allocations[index].buf); - allocations[index].buf = 0; - if (!shmem_is_ok(__LINE__)) { - test_fail(); - return; - } - } else { - size_t alloc_size = r_data % (shmem_size / 2); - - /* - * If the allocation entry is empty - allocate a - * buffer of a random size up to max shared memory. - */ - if (shared_mem_acquire(alloc_size, &shptr) == - EC_SUCCESS) { - allocations[index].buf = (void *) shptr; - allocations[index].buffer_size = alloc_size; - - /* - * Make sure every allocated byte is - * modified. - */ - while (alloc_size--) - shptr[alloc_size] = - shptr[alloc_size] ^ 0xff; - - if (!shmem_is_ok(__LINE__)) { - test_fail(); - return; - } - } - } - } - - /* - * The test is over, free all still allcated buffers, if any. Keep - * verifying memory consistency after each free() invocation. - */ - for (index = 0; index < ARRAY_SIZE(allocations); index++) - if (allocations[index].buf) { - shared_mem_release(allocations[index].buf); - allocations[index].buf = NULL; - if (!shmem_is_ok(__LINE__)) { - test_fail(); - return; - } - } - - ccprintf("Did not pass all paths, map %x != %x\n", - test_map, ALL_PATHS_MASK); - test_fail(); -} - -void set_map_bit(uint32_t mask) -{ - test_map |= mask; -} |