4 #include "xbt/sysdep.h"
10 extern char *basename(__const char *__filename);
12 #define STD_HEAP_SIZE 20480000 /* Maximum size of the system's heap */
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory, mc,
15 "Logging specific to MC (memory)");
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 */
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;
26 /* Initialize the model-checker memory subsystem */
27 /* It creates the heap regions and set the default one */
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);
34 /* Create the second region a page after the first one ends */
37 (char *) (std_heap) + STD_HEAP_SIZE + getpagesize());
38 xbt_assert(raw_heap != NULL);
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. */
50 maps = get_memory_map();
52 for (i = 0; i < maps->mapsize; i++) {
54 if (maps->regions[i].inode != 0) {
56 tmp = xbt_strdup(maps->regions[i].pathname);
57 libname = basename(tmp);
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 */
64 /* FIXME: we should save the data of more segments, in a list of block to save */
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);
81 xbt_assert0(libsimgrid_data_addr_start != NULL,
82 "Cannot determine libsimgrid's .data segment address");
87 /* Finish the memory subsystem */
88 #include "xbt_modinter.h"
89 void MC_memory_exit(void)
92 mmalloc_detach(raw_heap);
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 */
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. */
108 extern struct mstats mmstats(void *);
110 /* Copy std_heap to "to_heap" allocating the required space for it */
111 size_t MC_save_heap(void **to_heap)
113 size_t heap_size = mmstats(std_heap).bytes_total;
115 *to_heap = calloc(heap_size, 1);
117 xbt_assert(*to_heap != NULL);
119 memcpy(*to_heap, std_heap, heap_size);
124 /* Copy the data segment of libsimgrid to "data" allocating the space for it */
125 size_t MC_save_dataseg(void **data)
127 *data = calloc(libsimgrid_data_size, 1);
128 memcpy(*data, libsimgrid_data_addr_start, libsimgrid_data_size);
129 return libsimgrid_data_size;
132 /* Restore std_heap from "src_heap" */
133 void MC_restore_heap(void *src_heap, size_t size)
135 memcpy(std_heap, src_heap, size);
138 /* Restore the data segment of libsimgrid from "src_data" */
139 void MC_restore_dataseg(void *src_data, size_t size)
141 memcpy(libsimgrid_data_addr_start, src_data, size);