Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Page-level sparse snapshot: work-in-progress, working page_store
[simgrid.git] / src / mc / mc_page_store.h
1 /* Copyright (c) 2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include <stdint.h>
8
9 #include <vector>
10
11 #include <boost/utility.hpp>
12 #include <boost/unordered_map.hpp>
13 #include <boost/unordered_set.hpp>
14
15 #include <xbt.h>
16
17 #include "mc_private.h"
18 #include "mc_mmu.h"
19
20 #ifndef MC_PAGE_SNAPSHOT_H
21 #define MC_PAGE_SNAPSHOT_H
22
23 /** @brief Manager for snapshot pages
24  *
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.
28  */
29 struct s_mc_pages_store {
30 private: // Types
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;
34
35 private: // Fields:
36   /** First page */
37   void* memory_;
38   /** Number of available pages in virtual memory */
39   size_t capacity_;
40   /** Top of the used pages (index of the next available page) */
41   size_t top_index_;
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_;
48
49 private: // Methods
50   void resize(size_t size);
51   size_t alloc_page();
52   void remove_page(size_t pageno);
53
54 public: // Constructors
55   explicit s_mc_pages_store(size_t size);
56   ~s_mc_pages_store();
57
58 public: // Methods
59
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);
64     }
65   }
66
67   /** @brief Increment the refcount for a given page */
68   void ref_page(size_t pageno) {
69     ++this->page_counts_[pageno];
70   }
71
72   /** @brief Store a page
73    *
74    *  Either allocate a new page in the store or reuse
75    *  a shared page if is is already in the page store.
76    */
77   size_t store_page(void* page);
78
79   /** @brief Get a page from its page number
80    *
81    *  @param Number of the memory page in the store
82    *  @return Start of the page
83    */
84   const void* get_page(size_t pageno) const {
85     return mc_page_from_number(this->memory_, pageno);
86   }
87
88 public: // Debug/test methods
89
90   /** @brief Get the number of references for a page */
91   size_t get_ref(size_t pageno) {
92     return this->page_counts_[pageno];
93   }
94
95   /** @brief Get the number of used pages */
96   size_t size() {
97     return this->top_index_ - this->free_pages_.size();
98   }
99
100   /** @brief Get the capacity of the page store
101    *
102    *  The capacity is expanded by a system call (mremap).
103    * */
104   size_t capacity() {
105     return this->capacity_;
106   }
107
108 };
109
110 #endif
111