Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Access memory from another process
[simgrid.git] / src / mc / mc_record.c
1 /* Copyright (c) 2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include <xbt.h>
11 #include <simgrid/simix.h>
12
13 #include "mc_record.h"
14 #include "mc_base.h"
15
16 #ifdef HAVE_MC
17 #include "mc_private.h"
18 #include "mc_model_checker.h"
19 #include "mc_state.h"
20 #endif
21
22 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_record, mc,
23   " Logging specific to MC record/replay facility");
24
25 char* MC_record_path = NULL;
26
27 void MC_record_replay(mc_record_item_t start, size_t len)
28 {
29   MC_wait_for_requests();
30   mc_record_item_t end = start + len;
31
32   // Choose the recorded simcall and execute it:
33   for (mc_record_item_t item=start;item!=end; ++item) {
34
35     XBT_DEBUG("Executing %i$%i", item->pid, item->value);
36 /*
37     if (xbt_dynar_is_empty(simix_global->process_to_run))
38       xbt_die("Unexpected end of application.");
39 */
40
41     // Choose a request:
42     smx_process_t process = SIMIX_process_from_PID(item->pid);
43     if (!process)
44       xbt_die("Unexpected process.");
45     smx_simcall_t simcall = &(process->simcall);
46     if(!simcall || simcall->call == SIMCALL_NONE)
47       xbt_die("No simcall for this process.");
48     if (!MC_request_is_visible(simcall) || !MC_request_is_enabled(simcall))
49       xbt_die("Unexpected simcall.");
50
51     // Execute the request:
52     SIMIX_simcall_handle(simcall, item->value);
53     MC_wait_for_requests();
54   }
55 }
56
57 xbt_dynar_t MC_record_from_string(const char* data)
58 {
59   XBT_INFO("path=%s", data);
60   if (!data || !data[0])
61     return NULL;
62
63   xbt_dynar_t dynar = xbt_dynar_new(sizeof(s_mc_record_item_t), NULL);
64
65   const char* current = data;
66   while (*current) {
67
68     s_mc_record_item_t item = { 0, 0 };
69     int count = sscanf(current, "%u/%u", &item.pid, &item.value);
70     if(count != 2 && count != 1)
71       goto fail;
72     xbt_dynar_push(dynar, &item);
73
74     // Find next chunk:
75     char* end = strchr(current, ';');
76     if(end==NULL)
77       break;
78     else
79       current = end + 1;
80   }
81
82   return dynar;
83
84 fail:
85   xbt_dynar_free(&dynar);
86   return NULL;
87 }
88
89 #ifdef HAVE_MC
90 char* MC_record_stack_to_string(xbt_fifo_t stack)
91 {
92   xbt_fifo_item_t start = xbt_fifo_get_last_item(stack);
93
94   if (!start) {
95     char* res = (char*) malloc(1 * sizeof(char));
96     res[0] = '\0';
97     return res;
98   }
99
100   char* buffer;
101   size_t size;
102   FILE* file = open_memstream(&buffer, &size);
103
104   xbt_fifo_item_t item;
105   for (item = start; item; item = xbt_fifo_get_prev_item(item)) {
106
107     // Find (pid, value):
108     mc_state_t state = (mc_state_t) xbt_fifo_get_item_content(item);
109     int value = 0;
110     smx_simcall_t saved_req = MC_state_get_executed_request(state, &value);
111     int pid = saved_req->issuer->pid;
112
113     // Serialization the (pid, value) pair:
114     const char* sep = (item!=start) ? ";" : "";
115     if (value)
116       fprintf(file, "%s%u/%u", sep, pid, value);
117     else
118       fprintf(file, "%s%u", sep, pid);
119   }
120
121   fclose(file);
122   return buffer;
123 }
124
125 void MC_record_dump_path(xbt_fifo_t stack)
126 {
127   if (MC_record_is_active()) {
128     char* path = MC_record_stack_to_string(stack);
129     XBT_INFO("Path = %s", path);
130     free(path);
131   }
132 }
133 #endif
134
135 void MC_record_replay_from_string(const char* path_string)
136 {
137   xbt_dynar_t path = MC_record_from_string(path_string);
138   mc_record_item_t start = &xbt_dynar_get_as(path, 0, s_mc_record_item_t);
139   MC_record_replay(start, xbt_dynar_length(path));
140   xbt_dynar_free(&path);
141 }
142
143 void MC_record_replay_init()
144 {
145   mc_time = xbt_new0(double, simix_process_maxpid);
146 }