Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7b191a93489c6ce50490713e1f19f3ccd4330ba1
[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 =
36       mmalloc_attach(-1,
37                      (char *) (std_heap) + STD_HEAP_SIZE + getpagesize());
38   xbt_assert(raw_heap != NULL);
39
40   MC_SET_RAW_MEM;
41
42 /* Get the start address and size of libsimgrid's data segment */
43 /* CAVEAT: Here we are assuming that get_memory_map() */
44 /* returns an array with the maps sorted from lower addresses to higher ones.  */
45   int i;
46   char *libname, *tmp;
47
48   /* Get memory map */
49   memory_map_t maps;
50   maps = get_memory_map();
51
52   for (i = 0; i < maps->mapsize; i++) {
53
54     if (maps->regions[i].inode != 0) {
55
56       tmp = xbt_strdup(maps->regions[i].pathname);
57       libname = basename(tmp);
58
59 #if 0
60       if (maps->regions[i].perms & MAP_WRITE && maps->regions[i].pathname[0] != '\0' && /* do not take anonymous segments: what are they? */
61           strcmp("[heap]", maps->regions[i].pathname) &&        /* do not take standard heap: mmalloc saves it already */
62           strcmp("[stack]", maps->regions[i].pathname)  /* this is maestro's stack. No need to save it */
63           ) {
64         /* FIXME: we should save the data of more segments, in a list of block to save */
65       }
66 #endif
67       /* for now, we only save the data of libsimgrid (FIXME) */
68       if (strncmp("libsimgrid.so.", libname, 14) == 0
69           && maps->regions[i].perms & MAP_WRITE) {
70         libsimgrid_data_addr_start = maps->regions[i].start_addr;
71         libsimgrid_data_size =
72             (size_t) ((char *) maps->regions[i + 1].start_addr -
73                       (char *) maps->regions[i].start_addr);
74         xbt_free(tmp);
75         break;
76       }
77       xbt_free(tmp);
78     }
79   }
80
81   xbt_assert0(libsimgrid_data_addr_start != NULL,
82               "Cannot determine libsimgrid's .data segment address");
83
84   MC_UNSET_RAW_MEM;
85 }
86
87 /* Finish the memory subsystem */
88 #include "xbt_modinter.h"
89 void MC_memory_exit(void)
90 {
91   if (raw_heap)
92     mmalloc_detach(raw_heap);
93 }
94
95
96 /* FIXME: Horrible hack! because the mmalloc library doesn't provide yet of */
97 /* an API to query about the status of a heap, we simply call mmstats and */
98 /* because I now how does structure looks like, then I redefine it here */
99
100 struct mstats {
101   size_t bytes_total;           /* Total size of the heap. */
102   size_t chunks_used;           /* Chunks allocated by the user. */
103   size_t bytes_used;            /* Byte total of user-allocated chunks. */
104   size_t chunks_free;           /* Chunks in the free list. */
105   size_t bytes_free;            /* Byte total of chunks in the free list. */
106 };
107
108 extern struct mstats mmstats(void *);
109
110 /* Copy std_heap to "to_heap" allocating the required space for it */
111 size_t MC_save_heap(void **to_heap)
112 {
113   size_t heap_size = mmstats(std_heap).bytes_total;
114
115   *to_heap = calloc(heap_size, 1);
116
117   xbt_assert(*to_heap != NULL);
118
119   memcpy(*to_heap, std_heap, heap_size);
120
121   return heap_size;
122 }
123
124 /* Copy the data segment of libsimgrid to "data" allocating the space for it */
125 size_t MC_save_dataseg(void **data)
126 {
127   *data = calloc(libsimgrid_data_size, 1);
128   memcpy(*data, libsimgrid_data_addr_start, libsimgrid_data_size);
129   return libsimgrid_data_size;
130 }
131
132 /* Restore std_heap from "src_heap" */
133 void MC_restore_heap(void *src_heap, size_t size)
134 {
135   memcpy(std_heap, src_heap, size);
136 }
137
138 /* Restore the data segment of libsimgrid from "src_data" */
139 void MC_restore_dataseg(void *src_data, size_t size)
140 {
141   memcpy(libsimgrid_data_addr_start, src_data, size);
142 }