continue;
}
- RemotePtr<void> page = remote(addr.address() + (i << xbt_pagebits));
- xbt_assert(mc_page_offset((void*)page.address())==0,
+ RemotePtr<void> 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.
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))
"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<std::uint64_t> 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();
}
#include <simgrid_config.h>
-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?
*
* @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))
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<std::size_t, std::uintptr_t> 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<std::size_t,std::uintptr_t> 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
{
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));
}
{
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());
}
// 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;
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;
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))
{
// 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 {