- // Otherwise, copy the page:
- void* target_page = mc_page_from_number(region->start_addr, i);
- const void* source_page = mc_model_checker->pages->get_page(region->page_numbers[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;
-
- char* data = (char*) buf;
- while(count) {
- ssize_t n = pread(fd, buf, count, offset);
- // EOF
- if (n==0)
- return res;
-
- // Error (or EAGAIN):
- if (n==-1) {
- if (errno == EAGAIN)
- continue;
- else
- return -1;
- }
-
- count -= n;
- data += n;
- offset += n;
- res += n;
- }
-
- return res;
-}
-
-static 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 softdirty bits
- *
- * This is done after checkpointing and after checkpoint restoration
- * (if per page checkpoiting is used) in order to know which pages were
- * modified.
- * */
-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 /proc/self/pagemap informations in order to find properties on the pages