X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/66248ebaa3e1745f85dfa34c56ff0f16fb874c13..719a77db362a51309e90a75253788223936b276c:/src/mc/mc_snapshot.c diff --git a/src/mc/mc_snapshot.c b/src/mc/mc_snapshot.c index c733664f01..a7bd4dfea8 100644 --- a/src/mc/mc_snapshot.c +++ b/src/mc/mc_snapshot.c @@ -4,8 +4,11 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include + #include "mc_private.h" #include "mc_mmu.h" +#include "mc_page_store.h" mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot) { @@ -22,45 +25,6 @@ mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot) return NULL; } -void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region) -{ - xbt_assert(mc_region_contain(region, (void*) addr), "Trying to read out of the region boundary."); - - if (!region) { - return (void *) addr; - } - - // Flat snapshot: - else if (region->data) { - uintptr_t offset = addr - (uintptr_t) region->start_addr; - return (void *) ((uintptr_t) region->data + offset); - } - - // Per-page snapshot: - else if (region->page_numbers) { - size_t pageno = mc_page_number(region->start_addr, (void*) addr); - size_t snapshot_pageno = region->page_numbers[pageno]; - const void* snapshot_page = mc_page_store_get_page(mc_model_checker->pages, snapshot_pageno); - return (char*) snapshot_page + mc_page_offset((void*) addr); - } - - else { - xbt_die("No data for this memory region"); - } -} - -void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot) -{ - - // If not in a process state/clone: - if (!snapshot) { - return (uintptr_t *) addr; - } - - mc_mem_region_t region = mc_get_snapshot_region((void*) addr, snapshot); - return mc_translate_address_region(addr, region); -} - /** @brief Read memory from a snapshot region broken across fragmented pages * * @param addr Process (non-snapshot) address of the data @@ -69,7 +33,7 @@ void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot) * @param size Size of the data to read in bytes * @return Pointer where the data is located (target buffer of original location) */ -static void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size) +void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size) { void* end = (char*) addr + size - 1; size_t page_end = mc_page_number(NULL, end); @@ -93,43 +57,6 @@ static void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, voi return target; } -/** @brief Read memory from a snapshot region - * - * @param addr Process (non-snapshot) address of the data - * @param region Snapshot memory region where the data is located - * @param target Buffer to store the value - * @param size Size of the data to read in bytes - * @return Pointer where the data is located (target buffer of original location) - */ -void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size) -{ - uintptr_t offset = (uintptr_t) addr - (uintptr_t) region->start_addr; - - xbt_assert(addr >= region->start_addr && (char*) addr+size < (char*)region->start_addr+region->size, - "Trying to read out of the region boundary."); - - // Linear memory region: - if (region->data) { - return (void*) ((uintptr_t) region->data + offset); - } - - // Fragmented memory region: - else if (region->page_numbers) { - void* end = (char*) addr + size - 1; - if( mc_same_page(addr, end) ) { - // The memory is contained in a single page: - return mc_translate_address_region((uintptr_t) addr, region); - } else { - // The memory spans several pages: - return mc_snapshot_read_fragmented(addr, region, target, size); - } - } - - else { - xbt_die("No data available for this region"); - } -} - /** @brief Read memory from a snapshot * * @param addr Process (non-snapshot) address of the data @@ -160,13 +87,23 @@ int mc_snapshot_region_memcp( void* addr1, mc_mem_region_t region1, void* addr2, mc_mem_region_t region2, size_t size) { - // TODO, optimize this, avoid alloca - void* buffer1 = mc_snapshot_read_region(addr1, region1, alloca(size), size); - void* buffer2 = mc_snapshot_read_region(addr2, region2, alloca(size), size); + // Using alloca() for large allocations may trigger stack overflow: + // use malloc if the buffer is too big. + + bool stack_alloc = size < 64; + void* buffer = stack_alloc ? alloca(2*size) : malloc(2*size); + void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer, size); + void* buffer2 = mc_snapshot_read_region(addr2, region2, (char*) buffer + size, size); + int res; if (buffer1 == buffer2) { - return 0; + res = 0; + } else { + res = memcmp(buffer1, buffer2, size); + } + if (!stack_alloc) { + free(buffer); } - return memcmp(buffer1, buffer2, size); + return res; } /** Compare memory between snapshots @@ -181,11 +118,7 @@ int mc_snapshot_memcp( void* addr1, mc_snapshot_t snapshot1, void* addr2, mc_snapshot_t snapshot2, size_t size) { - // TODO, optimize this, avoid alloca - void* buffer1 = mc_snapshot_read(addr1, snapshot1, alloca(size), size); - void* buffer2 = mc_snapshot_read(addr2, snapshot2, alloca(size), size); - if (buffer1 == buffer2) { - return 0; - } - return memcmp(buffer1, buffer2, size); + mc_mem_region_t region1 = mc_get_snapshot_region(addr1, snapshot1); + mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2); + return mc_snapshot_region_memcp(addr1, region1, addr2, region2, size); }