Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
60f74e5805080bdd111376ed079863412cd8569a
[simgrid.git] / src / mc / mc_checkpoint.c
1 /* Copyright (c) 2008-2012 Da SimGrid Team. All rights reserved.            */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <libgen.h>
7 #include "mc_private.h"
8 #include "xbt/module.h"
9
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
12                                 "Logging specific to mc_checkpoint");
13
14 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size);
15 static void MC_region_restore(mc_mem_region_t reg);
16 static void MC_region_destroy(mc_mem_region_t reg);
17
18 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size);
19
20 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
21 {
22   mc_mem_region_t new_reg = xbt_new0(s_mc_mem_region_t, 1);
23   new_reg->type = type;
24   new_reg->start_addr = start_addr;
25   new_reg->size = size;
26   new_reg->data = xbt_malloc0(size);
27   XBT_DEBUG("New reg data %p, start_addr %p, size %zu", new_reg->data, start_addr, size);
28   memcpy(new_reg->data, start_addr, size);
29   
30   return new_reg;
31 }
32
33 static void MC_region_restore(mc_mem_region_t reg)
34 {
35   /*FIXME: check if start_addr is still mapped, if it is not, then map it
36     before copying the data */
37  
38   XBT_DEBUG("Memcpy : dest %p, src %p, size %zu", reg->start_addr, reg->data, reg->size);
39   memcpy(reg->start_addr, reg->data, reg->size);
40  
41   return;
42 }
43
44 static void MC_region_destroy(mc_mem_region_t reg)
45 {
46   xbt_free(reg->data);
47   xbt_free(reg);
48 }
49
50 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size)
51 {
52   switch(type){
53   case 0 : 
54     XBT_DEBUG("New region heap (%zu)", size);
55     break;
56   case 1 : 
57     XBT_DEBUG("New region libsimgrid (%zu)", size);
58     break;
59   case 2 : 
60     XBT_DEBUG("New region program data (%zu)", size);
61     break;
62   }
63   mc_mem_region_t new_reg = MC_region_new(type, start_addr, size);
64   snapshot->regions = xbt_realloc(snapshot->regions, (snapshot->num_reg + 1) * sizeof(mc_mem_region_t));
65   snapshot->regions[snapshot->num_reg] = new_reg;
66   snapshot->num_reg++;
67   return;
68
69
70 void MC_take_snapshot(mc_snapshot_t snapshot)
71 {
72   unsigned int i = 0;
73   s_map_region_t reg;
74   memory_map_t maps = get_memory_map();
75
76   /* Save the std heap and the writable mapped pages of libsimgrid */
77   while (i < maps->mapsize) {
78     reg = maps->regions[i];
79     if ((reg.prot & PROT_WRITE)){
80       if (maps->regions[i].pathname == NULL){
81         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
82           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
83         }
84       } else {
85         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
86           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
87         } 
88       }
89     }
90     i++;
91   }
92
93   /* FIXME: free the memory map */
94 }
95
96 void MC_take_snapshot_liveness(mc_snapshot_t snapshot)
97 {
98   unsigned int i = 0;
99   s_map_region_t reg;
100   memory_map_t maps = get_memory_map();
101
102   /* Save the std heap and the writable mapped pages of libsimgrid */
103   while (i < maps->mapsize) {
104     reg = maps->regions[i];
105     if ((reg.prot & PROT_WRITE)){
106       if (maps->regions[i].pathname == NULL){
107         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
108           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
109         }
110       } else {
111         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
112           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
113         } else {
114           if (!memcmp(basename(maps->regions[i].pathname), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){
115             MC_snapshot_add_region(snapshot, 2, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
116           } 
117         }
118       }
119     }
120     i++;
121   }
122
123   /* FIXME: free the memory map */
124 }
125
126 void MC_restore_snapshot(mc_snapshot_t snapshot)
127 {
128   unsigned int i;
129   for(i=0; i < snapshot->num_reg; i++){
130     MC_region_restore(snapshot->regions[i]);
131     switch(snapshot->regions[i]->type){
132     case 0 : 
133       XBT_DEBUG("heap restored");
134       break;
135     case 1:
136       XBT_DEBUG("libsimgrid (data) restored");
137       break;
138     case 2:
139       XBT_DEBUG("data program restored");
140       break;
141     }
142
143   }
144
145 }
146
147 void MC_free_snapshot(mc_snapshot_t snapshot)
148 {
149   unsigned int i;
150   for(i=0; i < snapshot->num_reg; i++)
151     MC_region_destroy(snapshot->regions[i]);
152
153   xbt_free(snapshot);
154 }
155
156 static int data_program_region_compare(void *d1, void *d2, size_t size);
157 static int data_libsimgrid_region_compare(void *d1, void *d2, size_t size);
158
159 static int data_program_region_compare(void *d1, void *d2, size_t size){
160   int distance = 0;
161   int i;
162   
163   for(i=0; i<size; i++){
164     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
165       fprintf(stderr,"Different byte (offset=%d) (%p - %p) in data program region\n", i, (char *)d1 + i, (char *)d2 + i);
166       distance++;
167     }
168   }
169   
170   fprintf(stderr, "Hamming distance between data program regions : %d\n", distance);
171
172   return distance;
173 }
174
175 int data_libsimgrid_region_compare(void *d1, void *d2, size_t size){
176   int distance = 0;
177   int i;
178   
179   for(i=0; i<size; i++){
180     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
181       fprintf(stderr, "Different byte (offset=%d) (%p - %p) in data libsimgrid region\n", i, (char *)d1 + i, (char *)d2 + i);
182       distance++;
183     }
184   }
185   
186   fprintf(stderr, "Hamming distance between data libsimgrid regions : %d\n", distance);
187   
188   return distance;
189 }
190
191 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
192
193   
194   if(s1->num_reg != s2->num_reg){
195     XBT_INFO("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg);
196     return 1;
197   }
198
199   int i;
200   int errors = 0;
201
202   for(i=0 ; i< s1->num_reg ; i++){
203
204     if(s1->regions[i]->type != s2->regions[i]->type){
205       XBT_INFO("Different type of region");
206       errors++;
207     }
208
209     switch(s1->regions[i]->type){
210     case 0:
211       if(s1->regions[i]->size != s2->regions[i]->size){
212         XBT_INFO("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
213         errors++;
214       }
215       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
216         XBT_INFO("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
217         errors++;
218       }
219       if(mmalloc_compare_heap(s1->regions[i]->data, s2->regions[i]->data)){
220         XBT_INFO("Different heap (mmalloc_compare)");
221         errors++; 
222       }
223       break;
224     case 1 :
225       if(s1->regions[i]->size != s2->regions[i]->size){
226         XBT_INFO("Different size of libsimgrid (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
227         errors++;
228       }
229       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
230         XBT_INFO("Different start addr of libsimgrid (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
231         errors++;
232       }
233       if(data_libsimgrid_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
234         XBT_INFO("Different memcmp for data in libsimgrid");
235         errors++;
236       }
237       break;
238     case 2 :
239       if(s1->regions[i]->size != s2->regions[i]->size){
240         XBT_INFO("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
241         errors++;
242       }
243       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
244         XBT_INFO("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
245         errors++;
246       }
247       if(data_program_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
248         XBT_INFO("Different memcmp for data in program");
249         errors++;
250       }
251       break;
252     default:
253       break;
254     }
255   }
256
257   return (errors > 0);
258   
259 }
260