1 /* Copyright (c) 2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
11 #include <boost/utility.hpp>
12 #include <boost/unordered_map.hpp>
13 #include <boost/unordered_set.hpp>
17 #include "mc_private.h"
20 #ifndef MC_PAGE_SNAPSHOT_H
21 #define MC_PAGE_SNAPSHOT_H
23 /** @brief Manager for snapshot pages
25 * Page management: the free pages are stored as a simple linked-list.
26 * The number of the first page if stored in `free_pages`.
27 * Each free page store the number of the next free page.
29 struct s_mc_pages_store {
31 typedef uint64_t hash_type;
32 typedef boost ::unordered_set<size_t> page_set_type;
33 typedef boost::unordered_map<hash_type, page_set_type> pages_map_type;
38 /** Number of available pages in virtual memory */
40 /** Top of the used pages (index of the next available page) */
42 /** Page reference count */
43 std::vector<uint64_t> page_counts_;
44 /** Index of available pages before the top */
45 std::vector<size_t> free_pages_;
46 /** Index from page hash to page index */
47 pages_map_type hash_index_;
50 void resize(size_t size);
52 void remove_page(size_t pageno);
54 public: // Constructors
55 explicit s_mc_pages_store(size_t size);
60 /** @brief Decrement the refcount for a given page */
61 void unref_page(size_t pageno) {
62 if ((--this->page_counts_[pageno]) == 0) {
63 this->remove_page(pageno);
67 /** @brief Increment the refcount for a given page */
68 void ref_page(size_t pageno) {
69 ++this->page_counts_[pageno];
72 /** @brief Store a page
74 * Either allocate a new page in the store or reuse
75 * a shared page if is is already in the page store.
77 size_t store_page(void* page);
79 /** @brief Get a page from its page number
81 * @param Number of the memory page in the store
82 * @return Start of the page
84 const void* get_page(size_t pageno) const {
85 return mc_page_from_number(this->memory_, pageno);
88 public: // Debug/test methods
90 /** @brief Get the number of references for a page */
91 size_t get_ref(size_t pageno) {
92 return this->page_counts_[pageno];
95 /** @brief Get the number of used pages */
97 return this->top_index_ - this->free_pages_.size();
100 /** @brief Get the capacity of the page store
102 * The capacity is expanded by a system call (mremap).
105 return this->capacity_;