X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/41ac2593deb812baee12c58b6b7c4911a2da8cd7..15ab58c0b9a3d96ed52f5db885b72724a96af934:/src/mc/mc_snapshot.c diff --git a/src/mc/mc_snapshot.c b/src/mc/mc_snapshot.c index 998b85bbc9..7f3629145b 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,8 +25,39 @@ mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot) return NULL; } +static inline __attribute__((always_inline)) void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region) { + 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); +} + +/** \brief Translate a pointer from process address space to snapshot address space + * + * The address space contains snapshot of the main/application memory: + * this function finds the address in a given snaphot for a given + * real/application address. + * + * For read only memory regions and other regions which are not int the + * snapshot, the address is not changed. + * + * \param addr Application address + * \param snapshot The snapshot of interest (if NULL no translation is done) + * \return Translated address in the snapshot address space + * */ +static inline __attribute__((always_inline)) +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); + xbt_assert(mc_region_contain(region, (void*) addr), "Trying to read out of the region boundary."); if (!region) { @@ -38,10 +72,7 @@ void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region) // 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); + return mc_translate_address_region(addr, region); } else { @@ -49,18 +80,6 @@ void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t 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 @@ -148,26 +167,50 @@ void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, void* target, size_t } } +/** Compare memory between snapshots (with known regions) + * + * @param addr1 Address in the first snapshot + * @param snapshot2 Region of the address in the first snapshot + * @param addr2 Address in the second snapshot + * @param snapshot2 Region of the address in the second snapshot + * @return same as memcmp + * */ int mc_snapshot_region_memcp( void* addr1, mc_mem_region_t region1, void* addr2, mc_mem_region_t region2, size_t size) { - 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 + * + * @param addr1 Address in the first snapshot + * @param snapshot1 First snapshot + * @param addr2 Address in the second snapshot + * @param snapshot2 Second snapshot + * @return same as memcmp + * */ int mc_snapshot_memcp( void* addr1, mc_snapshot_t snapshot1, void* addr2, mc_snapshot_t snapshot2, size_t size) { - 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); }