Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove unused type definitions.
[simgrid.git] / src / mc / mc_smx.cpp
1 /* Copyright (c) 2015-2019. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "simgrid/s4u/Host.hpp"
7
8 #include "src/mc/ModelChecker.hpp"
9 #include "src/mc/mc_smx.hpp"
10
11 using simgrid::mc::remote;
12
13 /** HACK, Statically "upcast" a s_smx_actor_t into a ActorInformation
14  *
15  *  This gets 'actorInfo' from '&actorInfo->copy'. It upcasts in the
16  *  sense that we could achieve the same thing by having ActorInformation
17  *  inherit from s_smx_actor_t but we don't really want to do that.
18  */
19 static inline simgrid::mc::ActorInformation* actor_info_cast(smx_actor_t actor)
20 {
21   simgrid::mc::ActorInformation temp;
22   std::size_t offset = (char*) temp.copy.getBuffer() - (char*)&temp;
23
24   simgrid::mc::ActorInformation* process_info = (simgrid::mc::ActorInformation*)((char*)actor - offset);
25   return process_info;
26 }
27
28 /** Load the remote list of processes into a vector
29  *
30  *  @param process      MCed process
31  *  @param target       Local vector (to be filled with copies of `s_smx_actor_t`)
32  *  @param remote_dynar Address of the process dynar in the remote list
33  */
34 static void MC_process_refresh_simix_actor_dynar(simgrid::mc::RemoteClient* process,
35                                                  std::vector<simgrid::mc::ActorInformation>& target,
36                                                  simgrid::mc::RemotePtr<s_xbt_dynar_t> remote_dynar)
37 {
38   target.clear();
39
40   s_xbt_dynar_t dynar;
41   process->read_bytes(&dynar, sizeof(dynar), remote_dynar);
42
43   smx_actor_t* data = static_cast<smx_actor_t*>(::operator new(dynar.elmsize * dynar.used));
44   process->read_bytes(data, dynar.elmsize * dynar.used, simgrid::mc::RemotePtr<void>(dynar.data));
45
46   // Load each element of the vector from the MCed process:
47   for (unsigned int i = 0; i < dynar.used; ++i) {
48
49     simgrid::mc::ActorInformation info;
50     info.address  = simgrid::mc::RemotePtr<simgrid::kernel::actor::ActorImpl>(data[i]);
51     info.hostname = nullptr;
52     process->read_bytes(&info.copy, sizeof(info.copy), remote(data[i]));
53     target.push_back(std::move(info));
54   }
55   ::operator delete(data);
56 }
57 namespace simgrid {
58 namespace mc {
59
60 void RemoteClient::refresh_simix()
61 {
62   if (this->cache_flags_ & RemoteClient::cache_simix_processes)
63     return;
64
65   // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global`
66
67   static_assert(std::is_same<
68       std::unique_ptr<simgrid::simix::Global>,
69       decltype(simix_global)
70     >::value, "Unexpected type for simix_global");
71   static_assert(sizeof(simix_global) == sizeof(simgrid::simix::Global*),
72     "Bad size for simix_global");
73
74   RemotePtr<simgrid::simix::Global> simix_global_p{this->read_variable<simgrid::simix::Global*>("simix_global")};
75
76   // simix_global = REMOTE(*simix_global)
77   Remote<simgrid::simix::Global> simix_global =
78     this->read<simgrid::simix::Global>(simix_global_p);
79
80   MC_process_refresh_simix_actor_dynar(this, this->smx_actors_infos, remote(simix_global.getBuffer()->actors_vector));
81   MC_process_refresh_simix_actor_dynar(this, this->smx_dead_actors_infos,
82                                        remote(simix_global.getBuffer()->dead_actors_vector));
83
84   this->cache_flags_ |= RemoteClient::cache_simix_processes;
85 }
86
87 }
88 }
89
90 /** Get the issuer of a simcall (`req->issuer`)
91  *
92  *  In split-process mode, it does the black magic necessary to get an address
93  *  of a (shallow) copy of the data structure the issuer SIMIX actor in the local
94  *  address space.
95  *
96  *  @param process the MCed process
97  *  @param req     the simcall (copied in the local process)
98  */
99 smx_actor_t MC_smx_simcall_get_issuer(s_smx_simcall const* req)
100 {
101   xbt_assert(mc_model_checker != nullptr);
102
103   // This is the address of the smx_actor in the MCed process:
104   auto address = simgrid::mc::remote(req->issuer);
105
106   // Lookup by address:
107   for (auto& actor : mc_model_checker->process().actors())
108     if (actor.address == address)
109       return actor.copy.getBuffer();
110   for (auto& actor : mc_model_checker->process().dead_actors())
111     if (actor.address == address)
112       return actor.copy.getBuffer();
113
114   xbt_die("Issuer not found");
115 }
116
117 const char* MC_smx_actor_get_host_name(smx_actor_t actor)
118 {
119   if (mc_model_checker == nullptr)
120     return actor->get_host()->get_cname();
121
122   simgrid::mc::RemoteClient* process = &mc_model_checker->process();
123
124   /* HACK, Horrible hack to find the offset of the id in the simgrid::s4u::Host.
125
126      Offsetof is not supported for non-POD types but this should
127      work in practice for the targets currently supported by the MC
128      as long as we do not add funny features to the Host class
129      (such as virtual base).
130
131      We are using a (C++11) unrestricted union in order to avoid
132      any construction/destruction of the simgrid::s4u::Host.
133   */
134   union fake_host {
135     simgrid::s4u::Host host;
136     fake_host() { /* Nothing to do*/}
137     ~fake_host() { /* Nothing to do*/}
138   };
139   fake_host foo;
140   const size_t offset = (char*)&foo.host.get_name() - (char*)&foo.host;
141
142   // Read the simgrid::xbt::string in the MCed process:
143   simgrid::mc::ActorInformation* info     = actor_info_cast(actor);
144   auto remote_string_address              = remote((simgrid::xbt::string_data*)((char*)actor->get_host() + offset));
145   simgrid::xbt::string_data remote_string = process->read(remote_string_address);
146   char hostname[remote_string.len];
147   process->read_bytes(hostname, remote_string.len + 1, remote(remote_string.data));
148   info->hostname = mc_model_checker->get_host_name(hostname).c_str();
149   return info->hostname;
150 }
151
152 const char* MC_smx_actor_get_name(smx_actor_t actor)
153 {
154   simgrid::mc::RemoteClient* process = &mc_model_checker->process();
155   if (mc_model_checker == nullptr)
156     return actor->get_cname();
157
158   simgrid::mc::ActorInformation* info = actor_info_cast(actor);
159   if (info->name.empty()) {
160     simgrid::xbt::string_data string_data = simgrid::xbt::string::to_string_data(actor->name_);
161     info->name = process->read_string(remote(string_data.data), string_data.len);
162   }
163   return info->name.c_str();
164 }
165
166 #if HAVE_SMPI
167 int MC_smpi_process_count()
168 {
169   if (mc_model_checker == nullptr)
170     return smpi_process_count();
171   int res;
172   mc_model_checker->process().read_variable("process_count",
173     &res, sizeof(res));
174   return res;
175 }
176 #endif
177
178 unsigned long MC_smx_get_maxpid()
179 {
180   unsigned long maxpid;
181   mc_model_checker->process().read_variable("simix_process_maxpid",
182     &maxpid, sizeof(maxpid));
183   return maxpid;
184 }