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 */
20 void *actual_heap=NULL; /* The heap we are currently using. Either std_heap or raw_heap. Controlled by macros MC_SET_RAW_MEM/MC_UNSET_RAW_MEM */
22 /* Pointers to the beginning and end of the .data and .bss segment of libsimgrid */
23 /* They are initialized once at memory_init */
24 void *libsimgrid_data_addr_start = NULL;
25 size_t libsimgrid_data_size = 0;
27 /* Initialize the model-checker memory subsystem */
28 /* It creates the heap regions and set the default one */
31 /* Create the first region HEAP_OFFSET bytes after the heap break address */
32 std_heap = mmalloc_get_default_md();
33 xbt_assert(std_heap != NULL);
35 /* Create the second region a page after the first one ends */
36 raw_heap = mmalloc_attach(-1, (char *)(std_heap) + STD_HEAP_SIZE + getpagesize());
37 xbt_assert(raw_heap != NULL);
41 /* Get the start address and size of libsimgrid's data segment */
42 /* CAVEAT: Here we are assuming that get_memory_map() */
43 /* returns an array with the maps sorted from lower addresses to higher ones. */
49 maps = get_memory_map();
51 for(i=0; i < maps->mapsize; i++){
53 if(maps->regions[i].inode != 0){
55 tmp = xbt_strdup(maps->regions[i].pathname);
56 libname = basename(tmp);
59 if (maps->regions[i].perms & MAP_WRITE &&
60 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 && maps->regions[i].perms & MAP_WRITE){
69 libsimgrid_data_addr_start = maps->regions[i].start_addr;
70 libsimgrid_data_size = (size_t)((char *)maps->regions[i+1].start_addr - (char *)maps->regions[i].start_addr);
78 xbt_assert0(libsimgrid_data_addr_start != NULL,
79 "Cannot determine libsimgrid's .data segment address");
84 /* Finish the memory subsystem */
87 mmalloc_detach(std_heap);
88 mmalloc_detach(raw_heap);
92 void *malloc(size_t n) {
93 void *ret = mmalloc(actual_heap, n);
95 DEBUG2("%zu bytes were allocated at %p",n, ret);
99 void *calloc(size_t nmemb, size_t size)
101 size_t total_size = nmemb * size;
103 void *ret = mmalloc(actual_heap, total_size);
105 /* Fill the allocated memory with zeroes to mimic calloc behaviour */
106 memset(ret,'\0', total_size);
108 DEBUG2("%zu bytes were mallocated and zeroed at %p",total_size, ret);
112 void *realloc(void *p, size_t s)
118 ret = mrealloc(actual_heap, p,s);
120 ret = malloc(s); /* FIXME: shouldn't this be mmalloc? */
127 DEBUG2("%zu bytes were reallocated at %p",s,ret);
133 DEBUG1("%p was freed",p);
134 // xbt_assert(actual_heap != NULL); FIXME: I had to comment this
135 return mfree(actual_heap, p);
138 /* FIXME: Horrible hack! because the mmalloc library doesn't provide yet of */
139 /* an API to query about the status of a heap, we simply call mmstats and */
140 /* because I now how does structure looks like, then I redefine it here */
144 size_t bytes_total; /* Total size of the heap. */
145 size_t chunks_used; /* Chunks allocated by the user. */
146 size_t bytes_used; /* Byte total of user-allocated chunks. */
147 size_t chunks_free; /* Chunks in the free list. */
148 size_t bytes_free; /* Byte total of chunks in the free list. */
151 extern struct mstats mmstats(void *);
153 /* Copy std_heap to "to_heap" allocating the required space for it */
154 size_t MC_save_heap(void **to_heap)
156 size_t heap_size = mmstats(std_heap).bytes_total;
158 *to_heap = calloc(heap_size, 1);
160 xbt_assert(*to_heap != NULL);
162 memcpy(*to_heap, std_heap, heap_size);
167 /* Copy the data segment of libsimgrid to "data" allocating the space for it */
168 size_t MC_save_dataseg(void **data)
170 *data = calloc(libsimgrid_data_size, 1);
171 memcpy(*data, libsimgrid_data_addr_start, libsimgrid_data_size);
172 return libsimgrid_data_size;
175 /* Restore std_heap from "src_heap" */
176 void MC_restore_heap(void *src_heap, size_t size)
178 memcpy(std_heap, src_heap, size);
181 /* Restore the data segment of libsimgrid from "src_data" */
182 void MC_restore_dataseg(void *src_data, size_t size)
184 memcpy(libsimgrid_data_addr_start, src_data, size);