Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
868ea757f0c91f460e3e9779435f88438a336175
[simgrid.git] / src / mc / mc_smx.cpp
1 /* Copyright (c) 2015. 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 <cassert>
8 #include <cstdlib>
9
10 #include <xbt/log.h>
11 #include <xbt/dynar.h>
12 #include <xbt/str.h>
13 #include <xbt/swag.h>
14
15 #include "src/simix/smx_private.h"
16
17 #include "src/mc/mc_smx.h"
18 #include "src/mc/ModelChecker.hpp"
19
20 using simgrid::mc::remote;
21
22 extern "C" {
23
24 static inline
25 bool is_in_vector(smx_process_t p, std::vector<simgrid::mc::SimixProcessInformation>& ps)
26 {
27   return (uintptr_t) p >= (uintptr_t) &ps[0]
28     && (uintptr_t) p < (uintptr_t) &ps[ps.size()];
29 }
30
31 static inline
32 mc_smx_process_info_t MC_smx_process_get_info(smx_process_t p)
33 {
34   assert(is_in_vector(p, mc_model_checker->process().smx_process_infos)
35     || is_in_vector(p, mc_model_checker->process().smx_old_process_infos));
36   mc_smx_process_info_t process_info =
37     (mc_smx_process_info_t)
38       ((char*) p - offsetof(s_mc_smx_process_info_t, copy));
39   return process_info;
40 }
41
42 /** Load the remote swag of processes into a dynar
43  *
44  *  @param process     MCed process
45  *  @param target      Local dynar (to be filled with copies of `s_smx_process_t`)
46  *  @param remote_swag Address of the process SWAG in the remote list
47  */
48 static void MC_process_refresh_simix_process_list(
49   simgrid::mc::Process* process,
50   std::vector<simgrid::mc::SimixProcessInformation>& target, xbt_swag_t remote_swag)
51 {
52   target.clear();
53
54   // swag = REMOTE(*simix_global->process_list)
55   s_xbt_swag_t swag;
56   process->read_bytes(&swag, sizeof(swag), remote(remote_swag));
57
58   // Load each element of the dynar from the MCed process:
59   int i = 0;
60   for (smx_process_t p = (smx_process_t) swag.head; p; ++i) {
61
62     simgrid::mc::SimixProcessInformation info;
63     info.address = p;
64     info.hostname = nullptr;
65     process->read_bytes(&info.copy, sizeof(info.copy), remote(p));
66     target.push_back(std::move(info));
67
68     // Lookup next process address:
69     p = (smx_process_t) xbt_swag_getNext(&info.copy, swag.offset);
70   }
71   assert(i == swag.count);
72 }
73
74 void MC_process_smx_refresh(simgrid::mc::Process* process)
75 {
76   xbt_assert(mc_mode == MC_MODE_SERVER);
77   if (process->cache_flags & MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES)
78     return;
79
80   // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global`
81
82   // simix_global_p = REMOTE(simix_global);
83   smx_global_t simix_global_p;
84   process->read_variable("simix_global", &simix_global_p, sizeof(simix_global_p));
85
86   // simix_global = REMOTE(*simix_global)
87   s_smx_global_t simix_global;
88   process->read_bytes(&simix_global, sizeof(simix_global),
89     remote(simix_global_p));
90
91   MC_process_refresh_simix_process_list(
92     process, process->smx_process_infos, simix_global.process_list);
93   MC_process_refresh_simix_process_list(
94     process, process->smx_old_process_infos, simix_global.process_to_destroy);
95
96   process->cache_flags |= MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES;
97 }
98
99 /** Get the issuer of a simcall (`req->issuer`)
100  *
101  *  In split-process mode, it does the black magic necessary to get an address
102  *  of a (shallow) copy of the data structure the issuer SIMIX process in the local
103  *  address space.
104  *
105  *  @param process the MCed process
106  *  @param req     the simcall (copied in the local process)
107  */
108 smx_process_t MC_smx_simcall_get_issuer(smx_simcall_t req)
109 {
110   if (mc_mode == MC_MODE_CLIENT)
111     return req->issuer;
112
113   MC_process_smx_refresh(&mc_model_checker->process());
114
115   // This is the address of the smx_process in the MCed process:
116   void* address = req->issuer;
117
118   unsigned i;
119   mc_smx_process_info_t p;
120
121   // Lookup by address:
122   MC_PROCESS_FOREACH(mc_model_checker->process().smx_process_infos, i, p)
123     if (p->address == address)
124       return &p->copy;
125   MC_PROCESS_FOREACH(mc_model_checker->process().smx_old_process_infos, i, p)
126     if (p->address == address)
127       return &p->copy;
128
129   xbt_die("Issuer not found");
130 }
131
132 smx_process_t MC_smx_resolve_process(smx_process_t process_remote_address)
133 {
134   if (!process_remote_address)
135     return nullptr;
136   if (mc_mode == MC_MODE_CLIENT)
137     return process_remote_address;
138
139   mc_smx_process_info_t process_info = MC_smx_resolve_process_info(process_remote_address);
140   if (process_info)
141     return &process_info->copy;
142   else
143     return nullptr;
144 }
145
146 mc_smx_process_info_t MC_smx_resolve_process_info(smx_process_t process_remote_address)
147 {
148   if (mc_mode == MC_MODE_CLIENT)
149     xbt_die("No process_info for local process is not enabled.");
150
151   unsigned index;
152   mc_smx_process_info_t process_info;
153   MC_PROCESS_FOREACH(mc_model_checker->process().smx_process_infos, index, process_info)
154     if (process_info->address == process_remote_address)
155       return process_info;
156   MC_PROCESS_FOREACH(mc_model_checker->process().smx_old_process_infos, index, process_info)
157     if (process_info->address == process_remote_address)
158       return process_info;
159   xbt_die("Process info not found");
160 }
161
162 const char* MC_smx_process_get_host_name(smx_process_t p)
163 {
164   if (mc_mode == MC_MODE_CLIENT)
165     return sg_host_get_name(p->host);
166
167   simgrid::mc::Process* process = &mc_model_checker->process();
168
169   /* Horrible hack to find the offset of the id in the simgrid::s4u::Host.
170
171      Offsetof is not supported for non-POD types but this should
172      work in pratice for the targets currently supported by the MC
173      as long as we do not add funny features to the Host class
174      (such as virtual base).
175
176      We are using a (C++11) unrestricted union in order to avoid
177      any construction/destruction of the simgrid::s4u::Host.
178   */
179   union fake_host {
180     simgrid::s4u::Host host;
181     fake_host() {}
182     ~fake_host() {}
183   };
184   fake_host foo;
185   const size_t offset = (char*) &foo.host.name() - (char*) &foo.host;
186
187   // Read the simgrid::xbt::string in the MCed process:
188   mc_smx_process_info_t info = MC_smx_process_get_info(p);
189   simgrid::xbt::string_data remote_string;
190   auto remote_string_address = remote(
191     (simgrid::xbt::string_data*) ((char*) p->host + offset));
192   process->read_bytes(&remote_string, sizeof(remote_string), remote_string_address);
193   char hostname[remote_string.len];
194   process->read_bytes(hostname, remote_string.len + 1, remote(remote_string.data));
195   info->hostname = mc_model_checker->get_host_name(hostname);
196   return info->hostname;
197 }
198
199 const char* MC_smx_process_get_name(smx_process_t p)
200 {
201   simgrid::mc::Process* process = &mc_model_checker->process();
202   if (mc_mode == MC_MODE_CLIENT)
203     return p->name;
204   if (!p->name)
205     return nullptr;
206
207   mc_smx_process_info_t info = MC_smx_process_get_info(p);
208   if (info->name.empty()) {
209     char* name = process->read_string(p->name);
210     info->name = name;
211     free(name);
212   }
213   return info->name.c_str();
214 }
215
216 #ifdef HAVE_SMPI
217 int MC_smpi_process_count(void)
218 {
219   if (mc_mode == MC_MODE_CLIENT)
220     return smpi_process_count();
221   else {
222     int res;
223     mc_model_checker->process().read_variable("process_count",
224       &res, sizeof(res));
225     return res;
226   }
227 }
228 #endif
229
230 unsigned long MC_smx_get_maxpid(void)
231 {
232   unsigned long maxpid;
233   mc_model_checker->process().read_variable("simix_process_maxpid",
234     &maxpid, sizeof(maxpid));
235   return maxpid;
236 }
237
238 }