- const void* source_page = mc_model_checker->pages->get_page(pagenos[i]);
- memcpy(target_page, source_page, xbt_pagesize);
- }
-}
-
-// ***** Soft dirty tracking
-
-/** @brief Like pread() but without partial reads */
-static size_t pread_whole(int fd, void* buf, size_t count, off_t offset) {
- size_t res = 0;
-
- char* data = (char*) buf;
- while(count) {
- ssize_t n = pread(fd, buf, count, offset);
- // EOF
- if (n==0)
- return res;
-
- // Error (or EINTR):
- if (n==-1) {
- if (errno == EINTR)
- continue;
- else
- return -1;
- }
-
- // It might be a partial read:
- count -= n;
- data += n;
- offset += n;
- res += n;
- }
-
- return res;
-}
-
-static inline __attribute__ ((always_inline))
-void mc_ensure_fd(int* fd, const char* path, int flags) {
- if (*fd != -1)
- return;
- *fd = open(path, flags);
- if (*fd == -1) {
- xbt_die("Could not open file %s", path);
- }
-}
-
-/** @brief Reset the soft-dirty bits
- *
- * This is done after checkpointing and after checkpoint restoration
- * (if per page checkpoiting is used) in order to know which pages were
- * modified.
- *
- * See https://www.kernel.org/doc/Documentation/vm/soft-dirty.txt
- * */
-void mc_softdirty_reset() {
- mc_ensure_fd(&mc_model_checker->fd_clear_refs, "/proc/self/clear_refs", O_WRONLY|O_CLOEXEC);
- if( ::write(mc_model_checker->fd_clear_refs, "4\n", 2) != 2) {
- xbt_die("Could not reset softdirty bits");
- }
-}
-
-/** @brief Read memory page informations
- *
- * For each virtual memory page of the process,
- * /proc/self/pagemap provides a 64 bit field of information.
- * We are interested in the soft-dirty bit: with this we can track which
- * pages were modified between snapshots/restorations and avoid
- * copying data which was not modified.
- *
- * See https://www.kernel.org/doc/Documentation/vm/pagemap.txt
- *
- * @param pagemap Output buffer for pagemap informations
- * @param start_addr Address of the first page
- * @param page_count Number of pages
- */
-static void mc_read_pagemap(uint64_t* pagemap, size_t page_start, size_t page_count)
-{
- mc_ensure_fd(&mc_model_checker->fd_pagemap, "/proc/self/pagemap", O_RDONLY|O_CLOEXEC);
- size_t bytesize = sizeof(uint64_t) * page_count;
- off_t offset = sizeof(uint64_t) * page_start;
- if (pread_whole(mc_model_checker->fd_pagemap, pagemap, bytesize, offset) != bytesize) {
- xbt_die("Could not read pagemap");