From: Gabriel Corona Date: Wed, 9 Mar 2016 11:51:18 +0000 (+0100) Subject: [mc] Move pseudo-MMU code in its own namespace X-Git-Tag: v3_13~453^2~10 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2ecea197a211a8d17dff04a55dec0b7b0d81b37a [mc] Move pseudo-MMU code in its own namespace --- diff --git a/src/mc/ChunkedData.cpp b/src/mc/ChunkedData.cpp index 89dc272219..4e8499e453 100644 --- a/src/mc/ChunkedData.cpp +++ b/src/mc/ChunkedData.cpp @@ -44,8 +44,9 @@ ChunkedData::ChunkedData(PageStore& store, AddressSpace& as, continue; } - RemotePtr page = remote(addr.address() + (i << xbt_pagebits)); - xbt_assert(mc_page_offset((void*)page.address())==0, + RemotePtr page = remote((void*) + simgrid::mc::mmu::join(i, addr.address())); + xbt_assert(simgrid::mc::mmu::split(page.address()).second == 0, "Not at the beginning of a page"); /* Adding another copy (and a syscall) will probably slow things a lot. diff --git a/src/mc/PageStore.hpp b/src/mc/PageStore.hpp index 8ed78ad023..ac0ac6f531 100644 --- a/src/mc/PageStore.hpp +++ b/src/mc/PageStore.hpp @@ -174,7 +174,7 @@ void PageStore::ref_page(size_t pageno) inline __attribute__((always_inline)) const void* PageStore::get_page(std::size_t pageno) const { - return mc_page_from_number(this->memory_, pageno); + return (void*) simgrid::mc::mmu::join(pageno, (std::uintptr_t) this->memory_); } inline __attribute__((always_inline)) diff --git a/src/mc/RegionSnapshot.cpp b/src/mc/RegionSnapshot.cpp index 333aed2ed3..0c80a3bd95 100644 --- a/src/mc/RegionSnapshot.cpp +++ b/src/mc/RegionSnapshot.cpp @@ -140,14 +140,14 @@ RegionSnapshot sparse_region(RegionType region_type, "Not at the beginning of a page"); xbt_assert((((uintptr_t)permanent_addr) & (xbt_pagesize-1)) == 0, "Not at the beginning of a page"); - size_t page_count = mc_page_count(size); + size_t page_count = simgrid::mc::mmu::chunkCount(size); std::vector pagemap; const size_t* ref_page_numbers = nullptr; if (use_soft_dirty) { pagemap.resize(page_count); process->read_pagemap(pagemap.data(), - mc_page_number(nullptr, permanent_addr), page_count); + simgrid::mc::mmu::split((std::size_t) permanent_addr).first, page_count); ref_page_numbers = ref_region->page_data().pagenos(); } diff --git a/src/mc/mc_mmu.h b/src/mc/mc_mmu.h index 11172088ae..1438db4d0f 100644 --- a/src/mc/mc_mmu.h +++ b/src/mc/mc_mmu.h @@ -16,7 +16,16 @@ #include -SG_BEGIN_DECL() + +namespace simgrid { +namespace mc { +// TODO, do not depend on xbt_pagesize/xbt_pagebits but our own chunk size +namespace mmu { + +static int chunkSize() +{ + return xbt_pagesize; +} /** @brief How many memory pages are necessary to store size bytes? * @@ -24,7 +33,7 @@ SG_BEGIN_DECL() * @return Number of memory pages */ static inline __attribute__ ((always_inline)) -size_t mc_page_count(size_t size) +std::size_t chunkCount(std::size_t size) { size_t page_count = size >> xbt_pagebits; if (size & (xbt_pagesize-1)) @@ -32,47 +41,37 @@ size_t mc_page_count(size_t size) return page_count; } -/** @brief Get the virtual memory page number of a given address - * - * @param address Address - * @return Virtual memory page number of the given address - */ +/** @brief Split into chunk number and remaining offset */ static inline __attribute__ ((always_inline)) -size_t mc_page_number(const void* base, const void* address) +std::pair split(std::uintptr_t offset) { - xbt_assert(address>=base, "The address is not in the range"); - return ((std::uintptr_t) address - (std::uintptr_t) base) >> xbt_pagebits; + return { + offset >> xbt_pagebits, + offset & (xbt_pagesize-1) + }; } -/** @brief Get the offset of an address within a memory page - * - * @param address Address - * @return Offset within the memory page - */ +/** Merge chunk number and remaining offset info a global offset */ static inline __attribute__ ((always_inline)) -size_t mc_page_offset(const void* address) +std::uintptr_t join(std::size_t page, std::uintptr_t offset) { - return ((std::uintptr_t) address) & (xbt_pagesize-1); + return ((std::uintptr_t) page << xbt_pagebits) + offset; } -/** @brief Get the virtual address of a virtual memory page - * - * @param base Address of the first page - * @param page Index of the page - */ static inline __attribute__ ((always_inline)) -void* mc_page_from_number(const void* base, size_t page) +std::uintptr_t join(std::pair value) { - return (void*) ((char*)base + (page << xbt_pagebits)); + return join(value.first, value.second); } static inline __attribute__ ((always_inline)) -bool mc_same_page(const void* a, const void* b) +bool sameChunk(std::uintptr_t a, std::uintptr_t b) { - return ((std::uintptr_t) a >> xbt_pagebits) - == ((std::uintptr_t) b >> xbt_pagebits); + return (a >> xbt_pagebits) == (b >> xbt_pagebits); } -SG_END_DECL() +} +} +} #endif diff --git a/src/mc/mc_page_snapshot.cpp b/src/mc/mc_page_snapshot.cpp index 217b58ea04..7677ad1fe0 100644 --- a/src/mc/mc_page_snapshot.cpp +++ b/src/mc/mc_page_snapshot.cpp @@ -35,7 +35,7 @@ void mc_restore_page_snapshot_region(simgrid::mc::Process* process, { for (size_t i = 0; i != pages_copy.page_count(); ++i) { // Otherwise, copy the page: - void* target_page = mc_page_from_number(start_addr, i); + void* target_page = (void*) simgrid::mc::mmu::join(i, (std::uintptr_t) start_addr); const void* source_page = pages_copy.page(i); process->write_bytes(source_page, xbt_pagesize, remote(target_page)); } @@ -47,7 +47,7 @@ void mc_region_restore_sparse(simgrid::mc::Process* process, mc_mem_region_t reg { xbt_assert(((reg->permanent_address().address()) & (xbt_pagesize-1)) == 0, "Not at the beginning of a page"); - xbt_assert(mc_page_count(reg->size()) == reg->page_data().page_count()); + xbt_assert(simgrid::mc::mmu::chunkCount(reg->size()) == reg->page_data().page_count()); mc_restore_page_snapshot_region(process, (void*) reg->permanent_address().address(), reg->page_data()); } diff --git a/src/mc/mc_snapshot.cpp b/src/mc/mc_snapshot.cpp index f408e67ef0..12a3ef6086 100644 --- a/src/mc/mc_snapshot.cpp +++ b/src/mc/mc_snapshot.cpp @@ -74,8 +74,11 @@ const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, cons // Last byte of the memory area: void* end = (char*) addr + size - 1; + // TODO, we assume the chunks are aligned to natural chunk boundaries. + // We should remove this assumption. + // Page of the last byte of the memory area: - size_t page_end = mc_page_number(nullptr, end); + size_t page_end = simgrid::mc::mmu::split((std::uintptr_t) end).first; void* dest = target; @@ -83,9 +86,11 @@ const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, cons xbt_die("Missing destination buffer for fragmented memory access"); // Read each page: - while (mc_page_number(nullptr, addr) != page_end) { + while (simgrid::mc::mmu::split((std::uintptr_t) addr).first != page_end) { void* snapshot_addr = mc_translate_address_region_chunked((uintptr_t) addr, region); - void* next_page = mc_page_from_number(nullptr, mc_page_number(NULL, addr) + 1); + void* next_page = (void*) simgrid::mc::mmu::join( + simgrid::mc::mmu::split((std::uintptr_t) addr).first + 1, + 0); size_t readable = (char*) next_page - (char*) addr; memcpy(dest, snapshot_addr, readable); addr = (char*) addr + readable; diff --git a/src/mc/mc_snapshot.h b/src/mc/mc_snapshot.h index baaed85e7b..ff3551f95d 100644 --- a/src/mc/mc_snapshot.h +++ b/src/mc/mc_snapshot.h @@ -38,10 +38,11 @@ XBT_PRIVATE void mc_region_restore_sparse(simgrid::mc::Process* process, mc_mem_ static inline __attribute__((always_inline)) void* mc_translate_address_region_chunked(uintptr_t addr, mc_mem_region_t region) { - size_t pageno = mc_page_number((void*)region->start().address(), (void*) addr); - const void* snapshot_page = - region->page_data().page(pageno); - return (char*) snapshot_page + mc_page_offset((void*) addr); + auto split = simgrid::mc::mmu::split(addr - region->start().address()); + auto pageno = split.first; + auto offset = split.second; + const void* snapshot_page = region->page_data().page(pageno); + return (char*) snapshot_page + offset; } static inline __attribute__((always_inline)) @@ -249,7 +250,7 @@ const void* MC_region_read( { // Last byte of the region: void* end = (char*) addr + size - 1; - if (mc_same_page(addr, end) ) { + if (simgrid::mc::mmu::sameChunk((std::uintptr_t) addr, (std::uintptr_t) end) ) { // The memory is contained in a single page: return mc_translate_address_region_chunked((uintptr_t) addr, region); } else {