-def handle(fd,func, simcalls, guarded_simcalls):
- def nonempty(e): return e != ''
- fd.write('\n'.join( filter(nonempty, (func(simcall) for simcall in simcalls))))
-
- for guard, list in guarded_simcalls.items():
- fd.write('\n#ifdef %s\n'%(guard))
- fd.write('\n'.join(func(simcall) for simcall in list))
- fd.write('\n#endif\n')
-
-if __name__=='__main__':
- import sys
- simcalls, simcalls_dict = parse('simcalls.in')
-
- ok = True
- ok &= all(map(Simcall.check, simcalls))
- for k,v in simcalls_dict.items():
- ok &= all(map(Simcall.check, v))
- # FIXME: we should not hide it
- #if not ok:
- # print ("Some checks fail!")
- # sys.exit(1)
-
- ###
- ### smx_popping_accessors.c
- ###
- fd = header('popping_accessors.h')
- handle(fd, Simcall.accessors, simcalls, simcalls_dict)
- fd.write("\n\n/* The prototype of all simcall handlers, automatically generated for you */\n\n")
- handle(fd, Simcall.handler_prototype, simcalls, simcalls_dict)
- fd.close()
-
- ###
- ### smx_popping_enum.c
- ###
- fd = header("popping_enum.h")
- fd.write('/**\n')
- fd.write(' * @brief All possible simcalls.\n')
- fd.write(' */\n')
- fd.write('typedef enum {\n')
- fd.write(' SIMCALL_NONE,\n')
-
- handle(fd, Simcall.enum, simcalls, simcalls_dict)
-
- fd.write(' NUM_SIMCALLS\n')
- fd.write('} e_smx_simcall_t;\n')
- fd.close()
-
- ###
- ### smx_popping_generated.c
- ###
-
- fd = header("popping_generated.c")
-
- fd.write('#include "smx_private.h"\n');
- fd.write('#ifdef HAVE_MC\n');
- fd.write('#include "mc/mc_process.h"\n');
- fd.write('#endif\n');
- fd.write('\n');
- fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n');
-
- fd.write('/** @brief Simcalls\' names (generated from src/simix/simcalls.in) */\n')
- fd.write('const char* simcall_names[] = {\n')
-
- handle(fd, Simcall.string, simcalls, simcalls_dict)
-
- fd.write('[SIMCALL_NONE] = "NONE"\n')
- fd.write('};\n\n')
-
-
- fd.write('/**\n');
- fd.write(' * @brief (in kernel mode) unpack the simcall and activate the handler\n');
- fd.write(' * \n')
- fd.write(' * This function is generated from src/simix/simcalls.in\n')
- fd.write(' */\n');
- fd.write('void SIMIX_simcall_handle(smx_simcall_t simcall, int value) {\n');
- fd.write(' XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));\n');
- fd.write(' #ifdef HAVE_MC\n');
- fd.write(' if (mc_model_checker) {\n');
- fd.write(' MC_invalidate_cache();\n');
- fd.write(' }\n');
- fd.write(' #endif\n');
- fd.write(' SIMCALL_SET_MC_VALUE(simcall, value);\n');
- fd.write(' if (simcall->issuer->context->iwannadie && simcall->call != SIMCALL_PROCESS_CLEANUP)\n');
- fd.write(' return;\n');
- fd.write(' switch (simcall->call) {\n');
-
- handle(fd, Simcall.case, simcalls, simcalls_dict)
-
- fd.write(' case NUM_SIMCALLS:\n');
- fd.write(' break;\n');
- fd.write(' case SIMCALL_NONE:\n');
- fd.write(' THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s",\n');
- fd.write(' SIMIX_process_get_name(simcall->issuer),\n');
- fd.write(' SIMIX_host_get_name(SIMIX_process_get_host(simcall->issuer))\n');
- fd.write(' );\n');
- fd.write(' break;\n');
- fd.write('\n');
- fd.write(' }\n');
- fd.write('}\n');
-
- fd.close()
-
- ###
- ### smx_popping_bodies.c
- ###
- fd = header('popping_bodies.c')
- fd.write('#include "smx_private.h"\n')
- fd.write('#include "mc/mc_forward.h"\n')
- fd.write('#include "xbt/ex.h"\n')
- handle(fd, Simcall.body, simcalls, simcalls_dict)
- fd.close()
+
+def handle(fd, func, simcalls, guarded_simcalls):
+ def nonempty(e):
+ return e != ''
+ fd.write('\n'.join(filter(nonempty, (func(simcall) for simcall in simcalls))))
+
+ for guard, ll in guarded_simcalls.items():
+ fd.write('\n#if %s\n' % (guard))
+ fd.write('\n'.join(func(simcall) for simcall in ll))
+ fd.write('\n#endif')
+
+ fd.write('\n')
+
+if __name__ == '__main__':
+ simcalls, simcalls_dict = parse('simcalls.in')
+
+ ok = True
+ ok &= all(map(Simcall.check, simcalls))
+ for k, v in simcalls_dict.items():
+ ok &= all(map(Simcall.check, v))
+ if not ok:
+ print ("Some checks fail!")
+ sys.exit(1)
+
+ #
+ # popping_accessors.hpp
+ #
+ fd = header('popping_accessors.hpp')
+ fd.write('#include "src/simix/popping_private.hpp"')
+ handle(fd, Simcall.accessors, simcalls, simcalls_dict)
+ fd.write(
+ "\n/* The prototype of all simcall handlers, automatically generated for you */\n\n")
+ handle(fd, Simcall.handler_prototype, simcalls, simcalls_dict)
+ fd.close()
+
+ #
+ # popping_enum.hpp
+ #
+ fd = header("popping_enum.hpp")
+ fd.write('namespace simgrid {\n')
+ fd.write('namespace simix {\n')
+ fd.write('/**\n')
+ fd.write(' * @brief All possible simcalls.\n')
+ fd.write(' */\n')
+ fd.write('enum class Simcall {\n')
+ fd.write(' NONE,\n')
+
+ handle(fd, Simcall.enum, simcalls, simcalls_dict)
+
+ fd.write('};\n')
+ fd.write('\n')
+ fd.write('constexpr int NUM_SIMCALLS = ' + str(1 + len(simcalls)) + ';\n')
+ fd.write('} // namespace simix\n')
+ fd.write('} // namespace simgrid\n')
+ fd.close()
+
+ #
+ # popping_generated.cpp
+ #
+
+ fd = header("popping_generated.cpp")
+
+ fd.write('#include <simgrid/config.h>\n')
+ fd.write('#include <simgrid/host.h>\n')
+ fd.write('#include <xbt/base.h>\n')
+ fd.write('#if SIMGRID_HAVE_MC\n')
+ fd.write('#include "src/mc/mc_forward.hpp"\n')
+ fd.write('#endif\n')
+ fd.write('#include "src/kernel/activity/ConditionVariableImpl.hpp"\n')
+ fd.write('#include "src/kernel/actor/SimcallObserver.hpp"\n')
+ fd.write('#include "src/kernel/context/Context.hpp"\n')
+
+ fd.write('\n')
+ fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n')
+
+ fd.write('using simgrid::simix::Simcall;')
+ fd.write('\n')
+ fd.write('/** @brief Simcalls\' names (generated from src/simix/simcalls.in) */\n')
+ fd.write('constexpr std::array<const char*, simgrid::simix::NUM_SIMCALLS> simcall_names{{\n')
+
+ fd.write(' "Simcall::NONE",\n')
+ handle(fd, Simcall.string, simcalls, simcalls_dict)
+
+ fd.write('}};\n\n')
+
+ fd.write('/** @private\n')
+ fd.write(' * @brief (in kernel mode) unpack the simcall and activate the handler\n')
+ fd.write(' *\n')
+ fd.write(' * This function is generated from src/simix/simcalls.in\n')
+ fd.write(' */\n')
+ fd.write('void simgrid::kernel::actor::ActorImpl::simcall_handle(int times_considered)\n')
+ fd.write('{\n')
+ fd.write(' XBT_DEBUG("Handling simcall %p: %s", &simcall_, SIMIX_simcall_name(simcall_));\n')
+ fd.write(' simcall_.mc_value_ = times_considered;\n')
+ fd.write(' if (simcall_.observer_ != nullptr)\n')
+ fd.write(' simcall_.observer_->prepare(times_considered);\n')
+
+ fd.write(' if (context_->wannadie())\n')
+ fd.write(' return;\n')
+ fd.write(' switch (simcall_.call_) {\n')
+
+ handle(fd, Simcall.case, simcalls, simcalls_dict)
+
+ fd.write(' case Simcall::NONE:\n')
+ fd.write(' throw std::invalid_argument(simgrid::xbt::string_printf("Asked to do the noop syscall on %s@%s",\n')
+ fd.write(' get_cname(),\n')
+ fd.write(' sg_host_get_name(get_host())));\n')
+ fd.write(' default:\n')
+ fd.write(' THROW_IMPOSSIBLE;\n')
+ fd.write(' }\n')
+ fd.write('}\n')
+
+ fd.close()
+
+ #
+ # popping_bodies.cpp
+ #
+ fd = header('popping_bodies.cpp')
+ fd.write('#include "src/kernel/EngineImpl.hpp"\n')
+ fd.write('#include "src/kernel/actor/ActorImpl.hpp"\n')
+ fd.write('#include "src/mc/mc_forward.hpp"\n')
+ fd.write('#include "xbt/ex.h"\n')
+ fd.write('#include <functional>\n')
+ fd.write('#include <simgrid/simix.hpp>\n')
+ fd.write('#include <xbt/log.h>\n')
+
+ fd.write("/** @cond */ // Please Doxygen, don't look at this\n")
+ fd.write('''
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
+
+using simgrid::simix::Simcall;
+
+template<class R, class... T>
+inline static R simcall(Simcall call, T const&... t)
+{
+ auto self = simgrid::kernel::actor::ActorImpl::self();
+ simgrid::simix::marshal(&self->simcall_, call, t...);
+ if (not simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) {
+ XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), SIMIX_simcall_name(self->simcall_));
+ self->yield();
+ } else {
+ self->simcall_handle(0);
+ }
+ return simgrid::simix::unmarshal<R>(self->simcall_.result_);
+}
+''')
+ handle(fd, Simcall.body, simcalls, simcalls_dict)
+ fd.write("/** @endcond */\n")
+ fd.close()