Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mv src/mc/private.h src/mc/mc_private.h
[simgrid.git] / src / mc / mc_checkpoint.c
1 #include <libgen.h>
2 #include "mc_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, size %zu", new_reg->data, start_addr, size);
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 data (%zu)", size);
76     break;
77   }
78   mc_mem_region_t new_reg = MC_region_new(type, start_addr, size);
79   snapshot->regions = xbt_realloc(snapshot->regions, (snapshot->num_reg + 1) * sizeof(mc_mem_region_t));
80   snapshot->regions[snapshot->num_reg] = new_reg;
81   snapshot->num_reg++;
82   return;
83
84
85 void MC_take_snapshot(mc_snapshot_t snapshot)
86 {
87   unsigned int i = 0;
88   s_map_region reg;
89   memory_map_t maps = get_memory_map();
90
91   /* Save the std heap and the writable mapped pages of libsimgrid */
92   while (i < maps->mapsize) {
93     reg = maps->regions[i];
94     if ((reg.prot & PROT_WRITE)){
95       if (maps->regions[i].pathname == NULL){
96         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
97           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
98         }
99       } else {
100         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
101           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
102         } 
103       }
104     }
105     i++;
106   }
107
108   /* FIXME: free the memory map */
109 }
110
111
112 void MC_take_snapshot_liveness(mc_snapshot_t snapshot)
113 {
114   unsigned int i = 0;
115   s_map_region reg;
116   memory_map_t maps = get_memory_map();
117
118   for(i=0; i< snapshot->num_reg; i++){
119     MC_region_destroy(snapshot->regions[i]);
120   }
121
122   snapshot->num_reg = 0;
123
124   i = 0;
125
126   /* Save the std heap and the writable mapped pages of libsimgrid */
127   while (i < maps->mapsize) {
128     reg = maps->regions[i];
129     if ((reg.prot & PROT_WRITE)){
130       if (maps->regions[i].pathname == NULL){
131         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
132           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
133         }
134       }else {
135         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
136           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
137         } 
138       }
139     }
140     i++;
141   }
142
143   /* FIXME: free the memory map */
144 }
145
146 void MC_take_snapshot_to_restore_liveness(mc_snapshot_t snapshot)
147 {
148   unsigned int i = 0;
149   s_map_region reg;
150   memory_map_t maps = get_memory_map();
151
152   for(i=0; i< snapshot->num_reg; i++){
153     MC_region_destroy(snapshot->regions[i]);
154   }
155
156   snapshot->num_reg = 0;
157
158   i = 0;
159
160   /* Save the std heap and the writable mapped pages of libsimgrid */
161   while (i < maps->mapsize) {
162     reg = maps->regions[i];
163     if ((reg.prot & PROT_WRITE)){
164       if (maps->regions[i].pathname == NULL){
165         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
166           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
167         }
168       } else {
169         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
170           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
171         } else {
172           if (!memcmp(basename(maps->regions[i].pathname), basename(prog_name), strlen(basename(prog_name)))){
173             MC_snapshot_add_region(snapshot, 2, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
174           } 
175         }
176       }
177     }
178     i++;
179   }
180
181   /* FIXME: free the memory map */
182 }
183
184 void MC_restore_snapshot(mc_snapshot_t snapshot)
185 {
186   unsigned int i;
187   for(i=0; i < snapshot->num_reg; i++){
188     MC_region_restore(snapshot->regions[i]);
189     switch(snapshot->regions[i]->type){
190     case 0 : 
191       XBT_DEBUG("heap restored");
192       break;
193     case 1:
194       XBT_DEBUG("libsimgrid (data) restored");
195       break;
196     case 2:
197       XBT_DEBUG("data program restored");
198       break;
199     }
200
201   }
202
203 }
204
205 void MC_free_snapshot(mc_snapshot_t snapshot)
206 {
207   unsigned int i;
208   for(i=0; i < snapshot->num_reg; i++)
209     MC_region_destroy(snapshot->regions[i]);
210
211   xbt_free(snapshot);
212 }
213
214