Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use %zu to format a sizeof value.
[simgrid.git] / src / mc / mc_checkpoint.c
1 #include <libgen.h>
2 #include "private.h"
3
4
5 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
6                                 "Logging specific to mc_checkpoint");
7
8 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size);
9 static void MC_region_restore(mc_mem_region_t reg);
10 static void MC_region_destroy(mc_mem_region_t reg);
11
12 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size);
13
14 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
15 {
16   mc_mem_region_t new_reg = xbt_new0(s_mc_mem_region_t, 1);
17   new_reg->type = type;
18   new_reg->start_addr = start_addr;
19   new_reg->size = size;
20   new_reg->data = xbt_malloc0(size);
21   XBT_DEBUG("New reg data %p, start_addr %p", new_reg->data, start_addr);
22   memcpy(new_reg->data, start_addr, size);
23   
24   return new_reg;
25 }
26
27 static void MC_region_restore(mc_mem_region_t reg)
28 {
29   /*FIXME: check if start_addr is still mapped, if it is not, then map it
30     before copying the data */
31   if(reg->type == 3){
32     memory_map_t maps = get_memory_map();
33     MC_UNSET_RAW_MEM;
34     unsigned int i=0;
35     s_map_region r;
36     while(i < maps->mapsize){
37       r = maps->regions[i];
38       if (maps->regions[i].pathname != NULL){
39         if (!memcmp(maps->regions[i].pathname, "[stack]", 7)){
40           size_t diff = (char*)reg->start_addr - (char*)r.start_addr;
41           void *segment = malloc(reg->size + diff);
42           XBT_DEBUG("Size of segment : %zu", sizeof(segment));
43           memcpy((char *)segment + diff, reg->data, reg->size);
44           memcpy(r.start_addr, segment, sizeof(segment));
45           XBT_DEBUG("Memcpy region ok");
46           break;
47         }
48       }
49       i++;
50     }
51   }else{
52     XBT_DEBUG("Memcpy : dest %p, src %p, size %zu", reg->start_addr, reg->data, reg->size);
53     memcpy(reg->start_addr, reg->data, reg->size);
54   }
55   
56   return;
57 }
58
59 static void MC_region_destroy(mc_mem_region_t reg)
60 {
61   xbt_free(reg->data);
62   xbt_free(reg);
63 }
64
65 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size)
66 {
67   switch(type){
68   case 0 : 
69     XBT_DEBUG("New region heap (%zu)", size);
70     break;
71   case 1 : 
72     XBT_DEBUG("New region libsimgrid (%zu)", size);
73     break;
74   case 2 : 
75     XBT_DEBUG("New region program (%zu)", size);
76     break;
77   case 3 : 
78     XBT_DEBUG("New region stack (%zu)", size);
79     break;
80   }
81   mc_mem_region_t new_reg = MC_region_new(type, start_addr, size);
82   snapshot->regions = xbt_realloc(snapshot->regions, (snapshot->num_reg + 1) * sizeof(mc_mem_region_t));
83   snapshot->regions[snapshot->num_reg] = new_reg;
84   snapshot->num_reg++;
85   return;
86
87
88 void MC_take_snapshot(mc_snapshot_t snapshot)
89 {
90   unsigned int i = 0;
91   s_map_region reg;
92   memory_map_t maps = get_memory_map();
93
94   /* Save the std heap and the writable mapped pages of libsimgrid */
95   while (i < maps->mapsize) {
96     reg = maps->regions[i];
97     if ((reg.prot & PROT_WRITE)){
98       if (maps->regions[i].pathname == NULL){
99         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
100           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
101         }
102       } else {
103         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
104           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
105         } 
106       }
107     }
108     i++;
109   }
110
111   /* FIXME: free the memory map */
112 }
113
114
115 void MC_take_snapshot_liveness(mc_snapshot_t snapshot)
116 {
117   unsigned int i = 0;
118   s_map_region reg;
119   memory_map_t maps = get_memory_map();
120
121   for(i=0; i< snapshot->num_reg; i++){
122     MC_region_destroy(snapshot->regions[i]);
123   }
124
125   snapshot->num_reg = 0;
126
127   i = 0;
128
129   /* Save the std heap and the writable mapped pages of libsimgrid */
130   while (i < maps->mapsize) {
131     reg = maps->regions[i];
132     if ((reg.prot & PROT_WRITE)){
133       if (maps->regions[i].pathname == NULL){
134         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
135           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
136         }
137       } else {
138         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
139           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
140         } else {
141           if (!memcmp(basename(maps->regions[i].pathname), basename(prog_name), strlen(basename(prog_name)))){
142             MC_snapshot_add_region(snapshot, 2, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
143           } /*else {
144             if (!memcmp(maps->regions[i].pathname, "[stack]", 7)){
145               MC_snapshot_add_region(snapshot, 3, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
146             }
147             }*/
148         }
149       }
150     }
151     i++;
152   }
153
154   /* FIXME: free the memory map */
155 }
156
157 void MC_take_snapshot_to_restore_liveness(mc_snapshot_t snapshot)
158 {
159   unsigned int i = 0;
160   s_map_region reg;
161   memory_map_t maps = get_memory_map();
162
163   for(i=0; i< snapshot->num_reg; i++){
164     MC_region_destroy(snapshot->regions[i]);
165   }
166
167   snapshot->num_reg = 0;
168
169   i = 0;
170
171   /* Save the std heap and the writable mapped pages of libsimgrid */
172   while (i < maps->mapsize) {
173     reg = maps->regions[i];
174     if ((reg.prot & PROT_WRITE)){
175       if (maps->regions[i].pathname == NULL){
176         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
177           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
178         }
179       } else {
180         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
181           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
182         } else {
183           if (!memcmp(basename(maps->regions[i].pathname), basename(prog_name), strlen(basename(prog_name)))){
184             MC_snapshot_add_region(snapshot, 2, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
185           } 
186         }
187       }
188     }
189     i++;
190   }
191
192   /* FIXME: free the memory map */
193 }
194
195 void MC_restore_snapshot(mc_snapshot_t snapshot)
196 {
197   unsigned int i;
198   for(i=0; i < snapshot->num_reg; i++){
199     MC_region_restore(snapshot->regions[i]);
200     switch(snapshot->regions[i]->type){
201     case 0 : 
202       XBT_DEBUG("heap restored");
203       break;
204     case 1:
205       XBT_DEBUG("libsimgrid (data) restored");
206       break;
207     case 2:
208       XBT_DEBUG("program (data) restored");
209       break;
210     case 3:
211       XBT_DEBUG("stack restored");
212       break;
213     }
214
215   }
216
217 }
218
219 void MC_free_snapshot(mc_snapshot_t snapshot)
220 {
221   unsigned int i;
222   for(i=0; i < snapshot->num_reg; i++)
223     MC_region_destroy(snapshot->regions[i]);
224
225   xbt_free(snapshot);
226 }
227
228