Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fight for better integration of mmalloc, mc and xbt
[simgrid.git] / src / mc / mc_memory.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "mc/mc.h"
4 #include "xbt/sysdep.h"
5 #include "private.h"
6 #include "xbt/log.h"
7 #include <unistd.h>
8 #define _GNU_SOURCE
9
10 extern char *basename (__const char *__filename);
11
12 #define STD_HEAP_SIZE   20480000  /* Maximum size of the system's heap */
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory, mc,
15                                 "Logging specific to MC (memory)");
16
17 /* Pointers to each of the heap regions to use */
18 void *std_heap=NULL; /* memory erased each time the MC stuff rollbacks to the beginning. Almost everything goes here */
19 void *raw_heap=NULL; /* memory persistent over the MC rollbacks. Only MC stuff should go there */
20
21 /* Pointers to the beginning and end of the .data and .bss segment of libsimgrid */
22 /* They are initialized once at memory_init */
23 void *libsimgrid_data_addr_start = NULL;
24 size_t libsimgrid_data_size = 0;
25
26 /* Initialize the model-checker memory subsystem */
27 /* It creates the heap regions and set the default one */
28 void MC_memory_init()
29 {
30 /* Create the first region HEAP_OFFSET bytes after the heap break address */
31   std_heap = mmalloc_get_default_md();
32   xbt_assert(std_heap != NULL);
33
34 /* Create the second region a page after the first one ends */
35   raw_heap = mmalloc_attach(-1, (char *)(std_heap) + STD_HEAP_SIZE + getpagesize());
36   xbt_assert(raw_heap != NULL);
37
38   MC_SET_RAW_MEM;
39
40 /* Get the start address and size of libsimgrid's data segment */
41 /* CAVEAT: Here we are assuming that get_memory_map() */
42 /* returns an array with the maps sorted from lower addresses to higher ones.  */
43   int i;
44   char *libname, *tmp;
45
46   /* Get memory map */
47   memory_map_t maps;
48   maps = get_memory_map();
49   
50   for(i=0; i < maps->mapsize; i++){
51  
52     if(maps->regions[i].inode != 0){
53  
54       tmp = xbt_strdup(maps->regions[i].pathname);
55       libname = basename(tmp);
56  
57 #if 0
58       if (maps->regions[i].perms & MAP_WRITE &&
59           maps->regions[i].pathname[0] != '\0' &&  /* do not take anonymous segments: what are they? */
60           strcmp("[heap]",maps->regions[i].pathname) && /* do not take standard heap: mmalloc saves it already */
61           strcmp("[stack]",maps->regions[i].pathname) /* this is maestro's stack. No need to save it */
62           ) {
63         /* FIXME: we should save the data of more segments, in a list of block to save */
64       }
65 #endif
66       /* for now, we only save the data of libsimgrid (FIXME) */
67       if( strncmp("libsimgrid.so.", libname, 14) == 0 && maps->regions[i].perms & MAP_WRITE){
68         libsimgrid_data_addr_start = maps->regions[i].start_addr;
69         libsimgrid_data_size = (size_t)((char *)maps->regions[i+1].start_addr - (char *)maps->regions[i].start_addr);
70         xbt_free(tmp);
71         break;
72       }        
73       xbt_free(tmp);
74     }
75   }
76   
77   xbt_assert0(libsimgrid_data_addr_start != NULL, 
78              "Cannot determine libsimgrid's .data segment address");
79              
80   MC_UNSET_RAW_MEM;
81 }
82
83 /* Finish the memory subsystem */
84 #include "xbt_modinter.h"
85 void MC_memory_exit(void) {
86   if (raw_heap)
87     mmalloc_detach(raw_heap);
88 }
89
90
91 /* FIXME: Horrible hack! because the mmalloc library doesn't provide yet of */
92 /* an API to query about the status of a heap, we simply call mmstats and */
93 /* because I now how does structure looks like, then I redefine it here */
94
95 struct mstats
96   {
97     size_t bytes_total;         /* Total size of the heap. */
98     size_t chunks_used;         /* Chunks allocated by the user. */
99     size_t bytes_used;          /* Byte total of user-allocated chunks. */
100     size_t chunks_free;         /* Chunks in the free list. */
101     size_t bytes_free;          /* Byte total of chunks in the free list. */
102   };
103
104 extern struct mstats mmstats(void *);
105
106 /* Copy std_heap to "to_heap" allocating the required space for it */
107 size_t MC_save_heap(void **to_heap)
108 {  
109   size_t heap_size = mmstats(std_heap).bytes_total;
110   
111   *to_heap = calloc(heap_size, 1);
112
113   xbt_assert(*to_heap != NULL);
114   
115   memcpy(*to_heap, std_heap, heap_size);
116   
117   return heap_size;
118 }
119
120 /* Copy the data segment of libsimgrid to "data" allocating the space for it */
121 size_t MC_save_dataseg(void **data)
122 {
123   *data = calloc(libsimgrid_data_size, 1);
124   memcpy(*data, libsimgrid_data_addr_start, libsimgrid_data_size);
125   return libsimgrid_data_size;
126 }
127
128 /* Restore std_heap from "src_heap" */
129 void MC_restore_heap(void *src_heap, size_t size)
130 {  
131   memcpy(std_heap, src_heap, size);
132 }
133
134 /* Restore the data segment of libsimgrid from "src_data" */
135 void MC_restore_dataseg(void *src_data, size_t size)
136 {
137   memcpy(libsimgrid_data_addr_start, src_data, size);
138 }
139
140
141
142
143