- path: simgrid.jar
name: jarfile
-# notifications:
-# - irc: "irc.debian.org#simgrid" # Not implemented by AppVeyor yet :(
-
-
-
+# IRC notifications, even if https://github.com/appveyor/ci/issues/88 is not closed yet
+on_failure:
+ - "python tools/appveyor-irc-notify.py simgrid [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}"
+#on_success:
+# - "python tools/appveyor-irc-notify.py simgrid [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}"
on_success: change
on_failure: always
irc:
+ on_success: change
+ on_failure: always
channels:
- "irc.debian.org#simgrid"
template:
SimGrid (3.21) NOT RELEASED (Release Target: September 23. 2018, 1:54 UTC)
+Fixed bugs:
+ - #271: Dynamic and manual replay of SMPI traces
+ - #279: Breakpoints option uses time deltas instead of absolute time
-
+----------------------------------------------------------------------------
SimGrid (3.20) Released June 24. 2018
- #258: daemonized actors hang after all non-daemonized actors have completed
- #267: Linker error on unit_tmgr
- #269: SMPI: tracing of MPI_Wait/all/any broken
- - SMPI: Fix various crashes with combined use of MPI_PROC_NULL and MPI_IGNORE_STATUS
+ - SMPI: Fix various crashes with combined use of MPI_PROC_NULL and MPI_IGNORE_STATUS
----------------------------------------------------------------------------
@CMAKE_HOME_DIRECTORY@/doc/doxygen/module-trace.doc \
@CMAKE_BINARY_DIR@/doc/doxygen/logcategories.doc \
@CMAKE_HOME_DIRECTORY@/include/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/jedule/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/kernel/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/kernel/resource/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/kernel/routing/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/plugins/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/s4u/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/simix/ \
+ @CMAKE_HOME_DIRECTORY@/include/simgrid/smpi/ \
@CMAKE_HOME_DIRECTORY@/include/xbt \
- @CMAKE_HOME_DIRECTORY@/include/simgrid \
- @CMAKE_HOME_DIRECTORY@/include/simgrid/s4u \
+ @CMAKE_HOME_DIRECTORY@/src/include/simgrid/ \
@CMAKE_HOME_DIRECTORY@/src/include/surf \
@CMAKE_HOME_DIRECTORY@/src/include/xbt \
- @CMAKE_HOME_DIRECTORY@/src/msg/ \
+ @CMAKE_HOME_DIRECTORY@/src/instr/ \
+ @CMAKE_HOME_DIRECTORY@/src/instr/jedule/ \
@CMAKE_HOME_DIRECTORY@/src/kernel/ \
@CMAKE_HOME_DIRECTORY@/src/kernel/activity/ \
@CMAKE_HOME_DIRECTORY@/src/kernel/context/ \
+ @CMAKE_HOME_DIRECTORY@/src/kernel/lmm/ \
+ @CMAKE_HOME_DIRECTORY@/src/kernel/resource/ \
@CMAKE_HOME_DIRECTORY@/src/kernel/routing/ \
- @CMAKE_HOME_DIRECTORY@/src/instr/ \
- @CMAKE_HOME_DIRECTORY@/src/surf/ \
- @CMAKE_HOME_DIRECTORY@/src/surf/plugins/ \
+ @CMAKE_HOME_DIRECTORY@/src/msg/ \
+ @CMAKE_HOME_DIRECTORY@/src/plugins/ \
+ @CMAKE_HOME_DIRECTORY@/src/plugins/file_system/ \
+ @CMAKE_HOME_DIRECTORY@/src/plugins/vm/ \
@CMAKE_HOME_DIRECTORY@/src/s4u/ \
+ @CMAKE_HOME_DIRECTORY@/src/simdag/ \
+ @CMAKE_HOME_DIRECTORY@/src/simgrid/ \
+ @CMAKE_HOME_DIRECTORY@/src/simix/ \
@CMAKE_HOME_DIRECTORY@/src/smpi/ \
- @CMAKE_HOME_DIRECTORY@/src/simdag \
- @CMAKE_HOME_DIRECTORY@/src/simix \
+ @CMAKE_HOME_DIRECTORY@/src/surf/ \
@CMAKE_HOME_DIRECTORY@/src/xbt/ \
@CMAKE_BINARY_DIR@/include \
@CMAKE_BINARY_DIR@/src \
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = XBT_PUBLIC= \
+PREDEFINED = __cplusplus \
+ XBT_PUBLIC= \
XBT_EXPORT_NO_IMPORT= \
XBT_IMPORT_NO_EXPORT= \
XBT_PUBLIC_DATA=extern \
#surf_host_model_init_current_default() or #surf_host_model_init_ptask_L07()
to create the platform.
- Then you can access the hosts with the global variables \ref host_list.
+ Then you can access the hosts with the \ref simgrid::s4u::Engine::get_all_hosts.
Some functions of the \ref SURF_host_interface and similar can give
you some information about:
- a host: get_speed(), get_available_speed();
@Override
public boolean equals(Object x) {
- return (x == null) ? false : x.equals(id) ;
+ return x != null && x.equals(id);
}
@Override
return "Contact [id=" + id + ", distance=" + distance + "]";
}
-}
\ No newline at end of file
+}
#include <mpi.h>
#include <smpi/smpi.h>
+#include <simgrid/host.h>
+#include <simgrid/plugins/energy.h>
+
int main(int argc, char *argv[])
{
int rank;
exit(EXIT_FAILURE);
}
- int pstates = smpi_get_host_nb_pstates();
+ int pstates = sg_host_get_nb_pstates(sg_host_self());
char *s = buf;
size_t sz = sizeof buf;
size_t x = snprintf(s, sz,
"[%.6f] [rank %d] Pstates: %d; Powers: %.0f",
- MPI_Wtime(), rank, pstates, smpi_get_host_power_peak_at(0));
+ MPI_Wtime(), rank, pstates, sg_host_get_pstate_speed(sg_host_self(), 0));
if (x < sz) {
s += x;
sz -= x;
} else
sz = 0;
for (i = 1; i < pstates; i++) {
- x = snprintf(s, sz, ", %.0f", smpi_get_host_power_peak_at(i));
+ x = snprintf(s, sz, ", %.0f", sg_host_get_pstate_speed(sg_host_self(), i));
if (x < sz) {
s += x;
sz -= x;
fprintf(stderr, "%s%s\n", buf, (sz ? "" : " [...]"));
for (i = 0; i < pstates; i++) {
- smpi_set_host_pstate(i);
+ sg_host_set_pstate(sg_host_self(), i);
fprintf(stderr, "[%.6f] [rank %d] Current pstate: %d; Current power: %.0f\n",
- MPI_Wtime(), rank, i, smpi_get_host_current_power_peak());
+ MPI_Wtime(), rank, i, sg_host_speed(sg_host_self()));
SMPI_SAMPLE_FLOPS(1e9) {
/* imagine here some code running for 1e9 flops... */
}
fprintf(stderr, "[%.6f] [rank %d] Energy consumed: %g Joules.\n",
- MPI_Wtime(), rank, smpi_get_host_consumed_energy());
+ MPI_Wtime(), rank, sg_host_get_consumed_energy(sg_host_self()));
}
err = MPI_Finalize();
void yield();
/** Returns true if the actor is suspended. */
- int is_suspended();
+ bool is_suspended();
/** If set to true, the actor will automatically restart when its host reboots */
void set_auto_restart(bool autorestart);
/** Turns that host off. All actors are forcefully stopped. */
void turn_off();
/** Returns if that host is currently up and running */
- bool is_on();
+ bool is_on() const;
/** Returns if that host is currently down and offline */
- bool is_off() { return not is_on(); }
+ bool is_off() const { return not is_on(); }
- const char* get_property(const char* key);
+ const char* get_property(const char* key) const;
void set_property(std::string key, std::string value);
std::unordered_map<std::string, std::string>* get_properties();
XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_properties()") std::map<std::string, std::string>* getProperties()
return res;
}
- double get_speed();
- double get_available_speed();
- int get_core_count();
- double get_load();
+ double get_speed() const;
+ double get_available_speed() const;
+ int get_core_count() const;
+ double get_load() const;
- double get_pstate_speed(int pstate_index);
+ double get_pstate_speed(int pstate_index) const;
int get_pstate_count() const;
void set_pstate(int pstate_index);
- int get_pstate();
+ int get_pstate() const;
XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_speed() instead.") double getSpeed() { return get_speed(); }
XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_pstate_speed() instead.") double getPstateSpeed(int pstate_index)
return get_pstate_speed(pstate_index);
}
- std::vector<const char*> get_attached_storages();
+ std::vector<const char*> get_attached_storages() const;
XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_attached_storages() instead.") void getAttachedStorages(
std::vector<const char*>* storages);
}
private:
- simgrid::xbt::string name_{"noname"};
+ simgrid::xbt::string name_ {"noname"};
std::unordered_map<std::string, Storage*>* mounts_ = nullptr; // caching
public:
* std::map<std::string, std::string>* props: properties
*/
typedef smx_actor_t (*smx_creation_func_t)(
- /* name */ const char*, std::function<void()> code,
+ /* name */ const char*, simgrid::simix::ActorCode code,
/* userdata */ void*,
/* hostname */ sg_host_t,
/* props */ std::unordered_map<std::string, std::string>*,
XBT_PUBLIC void SIMIX_function_register_process_create(smx_creation_func_t function);
-XBT_PUBLIC smx_actor_t simcall_process_create(const char* name, std::function<void()> code, void* data, sg_host_t host,
+XBT_PUBLIC smx_actor_t simcall_process_create(const char* name, simgrid::simix::ActorCode code, void* data, sg_host_t host,
std::unordered_map<std::string, std::string>* properties);
XBT_PUBLIC smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback);
/**
* Base class for all ReplayActions.
* Note that this class actually implements the behavior of each action
- * while the parsing of the replay arguments is done in the @ActionArgParser class.
+ * while the parsing of the replay arguments is done in the @ref ActionArgParser class.
* In other words: The logic goes here, the setup is done by the ActionArgParser.
*/
template <class T> class ReplayAction {
XBT_PUBLIC void smpi_execute(double duration);
XBT_PUBLIC void smpi_execute_benched(double duration);
-XBT_PUBLIC double smpi_get_host_power_peak_at(int pstate_index);
-XBT_PUBLIC double smpi_get_host_current_power_peak();
-XBT_PUBLIC int smpi_get_host_nb_pstates();
-XBT_PUBLIC void smpi_set_host_pstate(int pstate_index);
-XBT_PUBLIC int smpi_get_host_pstate();
-
-XBT_PUBLIC double smpi_get_host_consumed_energy();
+// PLEASE NOTE: If you remove these functions, the entire smpi_dvfs.cpp file can be removed as well!!
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_get_pstate_speed(sg_host_self(), pstate_index) instead") XBT_PUBLIC double smpi_get_host_power_peak_at(int pstate_index);
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_speed(sg_host_self()) instead") XBT_PUBLIC double smpi_get_host_current_power_peak();
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_get_nb_pstates(sg_host_self()) instead") XBT_PUBLIC int smpi_get_host_nb_pstates();
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_set_pstate(sg_host_self(), pstate_index) instead") XBT_PUBLIC void smpi_set_host_pstate(int pstate_index);
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_get_pstate(sg_host_self()) instead") XBT_PUBLIC int smpi_get_host_pstate();
+
+XBT_ATTRIB_DEPRECATED_v324("Please use sg_host_get_consumed_energy(sg_host_self()) instead") XBT_PUBLIC double smpi_get_host_consumed_energy();
XBT_PUBLIC unsigned long long smpi_rastro_resolution();
# define XBT_ATTRIB_DESTRUCTOR(prio) __attribute__((__destructor__))
#endif
-#if defined(__GNUC__)
-# define XBT_ALWAYS_INLINE inline __attribute__ ((always_inline))
-#else
-# define XBT_ALWAYS_INLINE inline
+#ifndef XBT_ALWAYS_INLINE /* defined also in libsosp */
+# if defined(__GNUC__)
+# define XBT_ALWAYS_INLINE inline __attribute__ ((always_inline))
+# else
+# define XBT_ALWAYS_INLINE inline
+# endif
#endif
#if defined(__GNUC__)
void JavaContextFactory::run_all()
{
for (smx_actor_t const& process : simgrid::simix::process_get_runnable()) {
- static_cast<JavaContext*>(process->context)->resume();
+ static_cast<JavaContext*>(process->context_)->resume();
}
}
jobject jprocess_from_native(msg_process_t process)
{
- simgrid::kernel::context::JavaContext* context = (simgrid::kernel::context::JavaContext*)process->get_impl()->context;
+ simgrid::kernel::context::JavaContext* context =
+ (simgrid::kernel::context::JavaContext*)process->get_impl()->context_;
return context->jprocess;
}
#include "src/kernel/activity/CommImpl.hpp"
#include "simgrid/kernel/resource/Action.hpp"
-
#include "simgrid/modelchecker.h"
+#include "src/kernel/activity/MailboxImpl.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/simix/smx_network_private.hpp"
#include "src/surf/surf_interface.hpp"
mutex->unlock(issuer);
}
- synchro = SIMIX_synchro_wait(issuer->host, timeout);
+ synchro = SIMIX_synchro_wait(issuer->host_, timeout);
synchro->simcalls_.push_front(simcall);
issuer->waiting_synchro = synchro;
cond->sleeping.push_back(*simcall->issuer);
if (this->locked) {
/* FIXME: check if the host is active ? */
/* Somebody using the mutex, use a synchronization to get host failures */
- synchro = SIMIX_synchro_wait(issuer->host, -1);
+ synchro = SIMIX_synchro_wait(issuer->host_, -1);
synchro->simcalls_.push_back(&issuer->simcall);
issuer->waiting_synchro = synchro;
this->sleeping.push_back(*issuer);
/* If the mutex is not owned by the issuer, that's not good */
if (issuer != this->owner)
THROWF(mismatch_error, 0, "Cannot release that mutex: it was locked by %s (pid:%ld), not by you.",
- this->owner->get_cname(), this->owner->pid);
+ this->owner->get_cname(), this->owner->pid_);
if (not this->sleeping.empty()) {
/*process to wake up */
e_smx_state_t result;
switch (surf_sleep->get_state()) {
case simgrid::kernel::resource::Action::State::FAILED:
- simcall->issuer->context->iwannadie = 1;
+ simcall->issuer->context_->iwannadie = 1;
result = SIMIX_SRC_HOST_FAILURE;
break;
THROW_IMPOSSIBLE;
break;
}
- if (simcall->issuer->host->is_off()) {
- simcall->issuer->context->iwannadie = 1;
+ if (simcall->issuer->host_->is_off()) {
+ simcall->issuer->context_->iwannadie = 1;
}
simcall_process_sleep__set__result(simcall, result);
simcall->issuer->waiting_synchro = nullptr;
- if (simcall->issuer->suspended) {
+ if (simcall->issuer->suspended_) {
XBT_DEBUG("Wait! This process is suspended and can't wake up now.");
- simcall->issuer->suspended = 0;
+ simcall->issuer->suspended_ = 0;
simcall_HANDLER_process_suspend(simcall, simcall->issuer);
} else {
SIMIX_simcall_answer(simcall);
{
if (this->cleanup_func_)
this->cleanup_func_(this->process_);
- this->process_->suspended = 0;
+ this->process_->suspended_ = 0;
this->iwannadie = false;
simgrid::simix::simcall([this] { SIMIX_process_cleanup(this->process_); });
if (i < simix_global->process_to_run.size()) {
/* execute the next process */
XBT_DEBUG("Run next process");
- next_context = static_cast<SerialBoostContext*>(simix_global->process_to_run[i]->context);
+ next_context = static_cast<SerialBoostContext*>(simix_global->process_to_run[i]->context_);
} else {
/* all processes were run, return to maestro */
XBT_DEBUG("No more process to run");
smx_actor_t first_process = simix_global->process_to_run.front();
process_index_ = 1;
/* execute the first process */
- static_cast<SerialBoostContext*>(first_process->context)->resume();
+ static_cast<SerialBoostContext*>(first_process->context_)->resume();
}
// ParallelBoostContext
parmap_ = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
parmap_->apply(
[](smx_actor_t process) {
- ParallelBoostContext* context = static_cast<ParallelBoostContext*>(process->context);
+ ParallelBoostContext* context = static_cast<ParallelBoostContext*>(process->context_);
context->resume();
},
simix_global->process_to_run);
ParallelBoostContext* next_context;
if (next_work) {
XBT_DEBUG("Run next process");
- next_context = static_cast<ParallelBoostContext*>(next_work.get()->context);
+ next_context = static_cast<ParallelBoostContext*>(next_work.get()->context_);
} else {
XBT_DEBUG("No more processes to run");
uintptr_t worker_id = reinterpret_cast<uintptr_t>(xbt_os_thread_get_specific(worker_id_key_));
if (i < simix_global->process_to_run.size()) {
/* execute the next process */
XBT_DEBUG("Run next process");
- next_context = static_cast<SerialRawContext*>(simix_global->process_to_run[i]->context);
+ next_context = static_cast<SerialRawContext*>(simix_global->process_to_run[i]->context_);
} else {
/* all processes were run, return to maestro */
XBT_DEBUG("No more process to run");
return;
smx_actor_t first_process = simix_global->process_to_run.front();
process_index_ = 1;
- static_cast<SerialRawContext*>(first_process->context)->resume();
+ static_cast<SerialRawContext*>(first_process->context_)->resume();
}
// ParallelRawContext
parmap_ = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
parmap_->apply(
[](smx_actor_t process) {
- ParallelRawContext* context = static_cast<ParallelRawContext*>(process->context);
+ ParallelRawContext* context = static_cast<ParallelRawContext*>(process->context_);
context->resume();
},
simix_global->process_to_run);
if (next_work) {
/* there is a next process to resume */
XBT_DEBUG("Run next process");
- next_context = static_cast<ParallelRawContext*>(next_work.get()->context);
+ next_context = static_cast<ParallelRawContext*>(next_work.get()->context_);
} else {
/* all processes were run, go to the barrier */
XBT_DEBUG("No more processes to run");
void ThreadContext::attach_start()
{
// We're breaking the layers here by depending on the upper layer:
- ThreadContext* maestro = (ThreadContext*) simix_global->maestro_process->context;
+ ThreadContext* maestro = (ThreadContext*)simix_global->maestro_process->context_;
xbt_os_sem_release(maestro->begin_);
xbt_assert(not this->isMaestro());
this->start();
xbt_assert(not this->isMaestro());
this->yield();
- ThreadContext* maestro = (ThreadContext*) simix_global->maestro_process->context;
+ ThreadContext* maestro = (ThreadContext*)simix_global->maestro_process->context_;
xbt_os_sem_acquire(maestro->end_);
xbt_os_thread_set_extra_data(nullptr);
{
for (smx_actor_t const& process : simix_global->process_to_run) {
XBT_DEBUG("Handling %p", process);
- ThreadContext* context = static_cast<ThreadContext*>(process->context);
+ ThreadContext* context = static_cast<ThreadContext*>(process->context_);
context->release();
context->wait();
}
void ParallelThreadContext::run_all()
{
for (smx_actor_t const& process : simix_global->process_to_run)
- static_cast<ThreadContext*>(process->context)->release();
+ static_cast<ThreadContext*>(process->context_)->release();
for (smx_actor_t const& process : simix_global->process_to_run)
- static_cast<ThreadContext*>(process->context)->wait();
+ static_cast<ThreadContext*>(process->context_)->wait();
}
void ParallelThreadContext::start_hook()
if (i < simix_global->process_to_run.size()) {
/* execute the next process */
XBT_DEBUG("Run next process");
- next_context = static_cast<SerialUContext*>(simix_global->process_to_run[i]->context);
+ next_context = static_cast<SerialUContext*>(simix_global->process_to_run[i]->context_);
} else {
/* all processes were run, return to maestro */
XBT_DEBUG("No more process to run");
return;
smx_actor_t first_process = simix_global->process_to_run.front();
process_index_ = 1;
- static_cast<SerialUContext*>(first_process->context)->resume();
+ static_cast<SerialUContext*>(first_process->context_)->resume();
}
// ParallelUContext
parmap_ = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
parmap_->apply(
[](smx_actor_t process) {
- ParallelUContext* context = static_cast<ParallelUContext*>(process->context);
+ ParallelUContext* context = static_cast<ParallelUContext*>(process->context_);
context->resume();
},
simix_global->process_to_run);
if (next_work) {
// There is a next soul to embody (ie, a next process to resume)
XBT_DEBUG("Run next process");
- next_context = static_cast<ParallelUContext*>(next_work.get()->context);
+ next_context = static_cast<ParallelUContext*>(next_work.get()->context_);
} else {
// All processes were run, go to the barrier
XBT_DEBUG("No more processes to run");
+++ /dev/null
-/* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include <cstddef>
-#include <cstdint>
-
-#include <vector>
-
-#include "xbt/asserts.h"
-#include "xbt/misc.h"
-
-#include "src/mc/AddressSpace.hpp"
-#include "src/mc/ChunkedData.hpp"
-#include "src/mc/PageStore.hpp"
-
-namespace simgrid {
-namespace mc {
-
-/** Take a per-page snapshot of a region
- *
- * @param addr The start of the region (must be at the beginning of a page)
- * @param page_count Number of pages of the region
- * @return Snapshot page numbers of this new snapshot
- */
-ChunkedData::ChunkedData(PageStore& store, AddressSpace& as,
- RemotePtr<void> addr, std::size_t page_count)
-{
- store_ = &store;
- this->pagenos_.resize(page_count);
- std::vector<char> buffer(xbt_pagesize);
-
- for (size_t i = 0; i != page_count; ++i) {
-
- RemotePtr<void> page = remote((void*)
- simgrid::mc::mmu::join(i, addr.address()));
- xbt_assert(simgrid::mc::mmu::split(page.address()).second == 0,
- "Not at the beginning of a page");
-
- /* Adding another copy (and a syscall) will probably slow things a lot.
- TODO, optimize this somehow (at least by grouping the syscalls)
- if needed. Either:
- - reduce the number of syscalls
- - let the application snapshot itself
- - move the segments in shared memory (this will break `fork` however)
- */
-
- as.read_bytes(buffer.data(), xbt_pagesize, page, simgrid::mc::ProcessIndexDisabled);
-
- pagenos_[i] = store_->store_page(buffer.data());
-
- }
-}
-
-}
-}
-/* Copyright (c) 2008-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2008-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/sg_config.hpp"
#include "src/mc/ModelChecker.hpp"
-#include "src/mc/PageStore.hpp"
#include "src/mc/Transition.hpp"
#include "src/mc/checker/Checker.hpp"
#include "src/mc/mc_exit.hpp"
#include "src/mc/mc_record.hpp"
#include "src/mc/remote/RemoteClient.hpp"
#include "src/mc/remote/mc_protocol.h"
+#include "src/mc/sosp/PageStore.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ModelChecker, mc, "ModelChecker");
#include <sys/types.h>
-#include "src/mc/PageStore.hpp"
#include "src/mc/mc_forward.hpp"
#include "src/mc/remote/mc_protocol.h"
+#include "src/mc/sosp/PageStore.hpp"
namespace simgrid {
namespace mc {
+++ /dev/null
-/* Copyright (c) 2007-2018. The SimGrid Team.
- * All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include <cstdlib>
-
-#include <sys/mman.h>
-#ifdef __FreeBSD__
-# define MAP_POPULATE MAP_PREFAULT_READ
-#endif
-
-#include "mc/mc.h"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_snapshot.hpp"
-
-#include "src/mc/ChunkedData.hpp"
-#include "src/mc/RegionSnapshot.hpp"
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_RegionSnaphot, mc,
- "Logging specific to region snapshots");
-
-namespace simgrid {
-namespace mc {
-
-static inline
-const char* to_cstr(RegionType region)
-{
- switch (region) {
- case RegionType::Unknown:
- return "unknown";
- case RegionType::Heap:
- return "Heap";
- case RegionType::Data:
- return "Data";
- default:
- return "?";
- }
-}
-
-Buffer::Buffer(std::size_t size, Type type) : size_(size), type_(type)
-{
- switch(type_) {
- case Type::Malloc:
- data_ = ::operator new(size_);
- break;
- case Type::Mmap:
- data_ = ::mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0);
- if (data_ == MAP_FAILED) {
- data_ = nullptr;
- size_ = 0;
- type_ = Type::Malloc;
- throw std::bad_alloc();
- }
- break;
- default:
- abort();
- }
-}
-
-void Buffer::clear() noexcept
-{
- switch(type_) {
- case Type::Malloc:
- ::operator delete(data_);
- break;
- case Type::Mmap:
- if (munmap(data_, size_) != 0)
- abort();
- break;
- default:
- abort();
- }
- data_ = nullptr;
- size_ = 0;
- type_ = Type::Malloc;
-}
-
-RegionSnapshot dense_region(
- RegionType region_type,
- void *start_addr, void* permanent_addr, size_t size)
-{
- // When KSM support is enables, we allocate memory using mmap:
- // * we don't want to advise bits of the heap as mergable
- // * mmap gives data aligned on page boundaries which is merge friendly
- simgrid::mc::Buffer data;
- if (_sg_mc_ksm)
- data = Buffer::mmap(size);
- else
- data = Buffer::malloc(size);
-
- mc_model_checker->process().read_bytes(data.get(), size,
- remote(permanent_addr),
- simgrid::mc::ProcessIndexDisabled);
-
-#ifdef __linux__
- if (_sg_mc_ksm)
- // Mark the region as mergeable *after* we have written into it.
- // Trying to merge them before is useless/counterproductive.
- madvise(data.get(), size, MADV_MERGEABLE);
-#endif
-
- simgrid::mc::RegionSnapshot region(
- region_type, start_addr, permanent_addr, size);
- region.flat_data(std::move(data));
-
- XBT_DEBUG("New region : type : %s, data : %p (real addr %p), size : %zu",
- to_cstr(region_type), region.flat_data().get(), permanent_addr, size);
- return region;
-}
-
-/** @brief Take a snapshot of a given region
- *
- * @param type
- * @param start_addr Address of the region in the simulated process
- * @param permanent_addr Permanent address of this data (for privatized variables, this is the virtual address of the privatized mapping)
- * @param size Size of the data*
- */
-RegionSnapshot region(
- RegionType type, void *start_addr, void* permanent_addr, size_t size)
-{
- if (_sg_mc_sparse_checkpoint)
- return sparse_region(type, start_addr, permanent_addr, size);
- else
- return dense_region(type, start_addr, permanent_addr, size);
-}
-
-RegionSnapshot sparse_region(RegionType region_type,
- void *start_addr, void* permanent_addr, size_t size)
-{
- simgrid::mc::RemoteClient* process = &mc_model_checker->process();
- assert(process != nullptr);
-
- xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize-1)) == 0,
- "Not at the beginning of a page");
- xbt_assert((((uintptr_t)permanent_addr) & (xbt_pagesize-1)) == 0,
- "Not at the beginning of a page");
- size_t page_count = simgrid::mc::mmu::chunkCount(size);
-
- simgrid::mc::ChunkedData page_data(mc_model_checker->page_store(), *process, RemotePtr<void>(permanent_addr),
- page_count);
-
- simgrid::mc::RegionSnapshot region(
- region_type, start_addr, permanent_addr, size);
- region.page_data(std::move(page_data));
- return region;
-}
-
-}
-}
-/* Copyright (c) 2007-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#ifndef SIMGRID_MC_VISITED_STATE_HPP
#define SIMGRID_MC_VISITED_STATE_HPP
-#include <cstddef>
+#include "src/mc/mc_state.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
+#include <cstddef>
#include <memory>
-#include "src/mc/mc_snapshot.hpp"
-#include "src/mc/mc_state.hpp"
-
namespace simgrid {
namespace mc {
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <cstdint>
-
-#include <xbt/dynar.h>
-#include <xbt/log.h>
-#include <xbt/sysdep.h>
-
-#include "src/mc/VisitedState.hpp"
#include "src/mc/checker/CommunicationDeterminismChecker.hpp"
+#include "src/kernel/activity/MailboxImpl.hpp"
+#include "src/mc/VisitedState.hpp"
#include "src/mc/mc_exit.hpp"
#include "src/mc/mc_private.hpp"
#include "src/mc/mc_record.hpp"
#include "smpi_request.hpp"
+#include <cstdint>
+
using simgrid::mc::remote;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc, "Logging specific to MC communication determinism detection");
smx_actor_t src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->src_proc));
smx_actor_t dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->dst_proc));
- comm_pattern->src_proc = src_proc->pid;
- comm_pattern->dst_proc = dst_proc->pid;
+ comm_pattern->src_proc = src_proc->pid_;
+ comm_pattern->dst_proc = dst_proc->pid_;
comm_pattern->src_host = MC_smx_actor_get_host_name(src_proc);
comm_pattern->dst_host = MC_smx_actor_get_host_name(dst_proc);
if (comm_pattern->data.size() == 0 && comm->src_buff != nullptr) {
{
const smx_actor_t issuer = MC_smx_simcall_get_issuer(request);
simgrid::mc::PatternCommunicationList* initial_pattern =
- xbt_dynar_get_as(initial_communications_pattern, issuer->pid, simgrid::mc::PatternCommunicationList*);
- xbt_dynar_t incomplete_pattern = xbt_dynar_get_as(incomplete_communications_pattern, issuer->pid, xbt_dynar_t);
+ xbt_dynar_get_as(initial_communications_pattern, issuer->pid_, simgrid::mc::PatternCommunicationList*);
+ xbt_dynar_t incomplete_pattern = xbt_dynar_get_as(incomplete_communications_pattern, issuer->pid_, xbt_dynar_t);
std::unique_ptr<simgrid::mc::PatternCommunication> pattern =
std::unique_ptr<simgrid::mc::PatternCommunication>(new simgrid::mc::PatternCommunication());
char* remote_name = mc_model_checker->process().read<char*>(
RemotePtr<char*>((uint64_t)(synchro->mbox ? &synchro->mbox->name_ : &synchro->mbox_cpy->name_)));
pattern->rdv = mc_model_checker->process().read_string(RemotePtr<char>(remote_name));
- pattern->src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(synchro->src_proc))->pid;
+ pattern->src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(synchro->src_proc))->pid_;
pattern->src_host = MC_smx_actor_get_host_name(issuer);
simgrid::smpi::Request mpi_request = mc_model_checker->process().read<simgrid::smpi::Request>(
&remote_name, remote(comm->mbox ? &simgrid::xbt::string::to_string_data(comm->mbox->name_).data
: &simgrid::xbt::string::to_string_data(comm->mbox_cpy->name_).data));
pattern->rdv = mc_model_checker->process().read_string(RemotePtr<char>(remote_name));
- pattern->dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->dst_proc))->pid;
+ pattern->dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->dst_proc))->pid_;
pattern->dst_host = MC_smx_actor_get_host_name(issuer);
} else
xbt_die("Unexpected call_type %i", (int) call_type);
- XBT_DEBUG("Insert incomplete comm pattern %p for process %ld", pattern.get(), issuer->pid);
- xbt_dynar_t dynar = xbt_dynar_get_as(incomplete_communications_pattern, issuer->pid, xbt_dynar_t);
+ XBT_DEBUG("Insert incomplete comm pattern %p for process %ld", pattern.get(), issuer->pid_);
+ xbt_dynar_t dynar = xbt_dynar_get_as(incomplete_communications_pattern, issuer->pid_, xbt_dynar_t);
simgrid::mc::PatternCommunication* pattern2 = pattern.release();
xbt_dynar_push(dynar, &pattern2);
}
state->num);
}
- if (not prev_state->actorStates[issuer->pid].isDone())
+ if (not prev_state->actorStates[issuer->pid_].isDone())
prev_state->addInterleavingSet(issuer);
else
XBT_DEBUG("Process %p is in done set", req->issuer);
const smx_actor_t previous_issuer = MC_smx_simcall_get_issuer(&prev_state->internal_req);
XBT_DEBUG("Simcall %d, process %ld (state %d) and simcall %d, process %ld (state %d) are independent",
- req->call, issuer->pid, state->num,
- prev_state->internal_req.call,
- previous_issuer->pid,
+ req->call, issuer->pid_, state->num, prev_state->internal_req.call, previous_issuer->pid_,
prev_state->num);
-
}
}
}
#include "src/mc/mc_forward.hpp"
#include "src/mc/mc_private.hpp"
#include "src/mc/mc_smx.hpp"
-#include "src/mc/mc_snapshot.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, xbt, "Logging specific to mc_compare in mc");
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <simgrid/config.h>
-
-#include "mc/mc.h"
#include "src/mc/mc_base.h"
+#include "mc/mc.h"
+#include "simgrid/config.h"
+#include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/activity/MutexImpl.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_forward.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/simix/smx_private.hpp"
-#include "src/kernel/activity/MutexImpl.hpp"
-
#if SIMGRID_HAVE_MC
#include "src/mc/ModelChecker.hpp"
#include "src/mc/remote/RemoteClient.hpp"
#if SIMGRID_HAVE_MC
// If in the MCer, ask the client app since it has all the data
if (mc_model_checker != nullptr) {
- return mc_model_checker->process().actor_is_enabled(actor->pid);
+ return mc_model_checker->process().actor_is_enabled(actor->pid_);
}
#endif
if (mutex->owner == nullptr)
return true;
- return mutex->owner->pid == req->issuer->pid;
+ return mutex->owner->pid_ == req->issuer->pid_;
}
case SIMCALL_SEM_ACQUIRE: {
simgrid::mc::Client::get()->ignoreMemory(addr, size);
}
-void MC_automaton_new_propositional_symbol(const char* id, int (*fct)())
+void MC_automaton_new_propositional_symbol(const char* /*id*/, int (*/*fct*/)())
{
xbt_assert(mc_model_checker == nullptr);
if (not MC_is_active())
simgrid::mc::Client::get()->declareStack(stack, size, actor, context);
}
-void MC_ignore_global_variable(const char *name)
+void MC_ignore_global_variable(const char* /*name*/)
{
xbt_assert(mc_model_checker == nullptr);
if (not MC_is_active())
value, sizeof(comm_addr));
comm_addr = remote(addr);
}
- checker->complete_comm_pattern(pattern, comm_addr,
- MC_smx_simcall_get_issuer(req)->pid, backtracking);
+ checker->complete_comm_pattern(pattern, comm_addr, MC_smx_simcall_get_issuer(req)->pid_, backtracking);
}
break;
default:
* \param unit DIE of the compilation unit containing the type DIE
* \param type the type
*/
-static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
- Dwarf_Die * unit, simgrid::mc::Type* type)
+static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* /*info*/, Dwarf_Die* die, Dwarf_Die* /*unit*/,
+ simgrid::mc::Type* type)
{
int res;
Dwarf_Die child;
static int mc_anonymous_variable_index = 0;
-static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(
- simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
- Dwarf_Die * unit, simgrid::mc::Frame* frame,
- const char *ns)
+static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(simgrid::mc::ObjectInformation* info, Dwarf_Die* die,
+ Dwarf_Die* /*unit*/, simgrid::mc::Frame* frame,
+ const char* ns)
{
// Skip declarations:
if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
#include "src/mc/mc_request.hpp"
#include "src/mc/mc_safety.hpp"
#include "src/mc/mc_smx.hpp"
-#include "src/mc/mc_snapshot.hpp"
#include "src/mc/mc_unw.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
#include <libunwind.h>
#endif
if (simgrid::mc::processes_time.empty())
return 0;
if (process != nullptr)
- return simgrid::mc::processes_time[process->pid];
+ return simgrid::mc::processes_time[process->pid_];
return -1;
}
void MC_process_clock_add(smx_actor_t process, double amount)
{
- simgrid::mc::processes_time[process->pid] += amount;
+ simgrid::mc::processes_time[process->pid_] += amount;
}
-/* Copyright (c) 2014-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2014-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "mc/datatypes.h"
#include "src/mc/mc_hash.hpp"
#include "src/mc/mc_private.hpp"
-#include "src/mc/mc_snapshot.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
#include <mc/mc.h>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_hash, mc, "Logging specific to mc_hash");
* @param snapshot Snapshot (or nullptr)
* @return Process address of the given member of the 'object' struct/class
*/
-void *resolve_member(
- const void *base, simgrid::mc::Type* type, simgrid::mc::Member* member,
- simgrid::mc::AddressSpace* address_space, int process_index)
+void* resolve_member(const void* base, simgrid::mc::Type* /*type*/, simgrid::mc::Member* member,
+ simgrid::mc::AddressSpace* address_space, int process_index)
{
ExpressionContext state;
state.frame_base = nullptr;
#ifndef SIMGRID_MC_MMU_HPP
#define SIMGRID_MC_MMU_HPP
-#include "xbt/misc.h" // xbt_pagesize...
#include <cstdint>
#include <utility>
+#ifndef XBT_ALWAYS_INLINE
+#define XBT_ALWAYS_INLINE inline __attribute__((always_inline))
+#endif
+
+/** Cache the size of a memory page for the current system. */
+extern "C" int xbt_pagesize;
+/** Cache the number of bits of addresses inside a given page, log2(xbt_pagesize). */
+extern "C" int xbt_pagebits;
+
namespace simgrid {
namespace mc {
// TODO, do not depend on xbt_pagesize/xbt_pagebits but our own chunk size
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <cstring>
-#include <cstdio>
-#include <cstdlib>
-
-#include <stdexcept>
-#include <sstream>
-#include <string>
-
-#include "xbt/log.h"
-#include "xbt/sysdep.h"
-
-#include "simgrid/simix.h"
-
-#include "src/kernel/context/Context.hpp"
#include "src/mc/mc_record.hpp"
+#include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/context/Context.hpp"
+#include "src/mc/Transition.hpp"
+#include "src/mc/mc_base.h"
#include "src/mc/mc_replay.hpp"
#include "src/simix/ActorImpl.hpp"
-#include "src/simix/smx_private.hpp"
-
-#include "src/mc/mc_base.h"
-#include "src/mc/Transition.hpp"
#if SIMGRID_HAVE_MC
#include "src/mc/checker/Checker.hpp"
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <cassert>
-
+#include "src/mc/mc_request.hpp"
#include "src/include/mc/mc.h"
+#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/activity/MutexImpl.hpp"
#include "src/mc/ModelChecker.hpp"
-#include "src/mc/mc_request.hpp"
#include "src/mc/mc_smx.hpp"
#include "src/mc/mc_xbt.hpp"
type = "iSend";
char* p = pointer_to_string(simcall_comm_isend__get__src_buff(req));
char* bs = buff_size_to_string(simcall_comm_isend__get__src_buff_size(req));
- if (issuer->host)
- args = bprintf("src=(%ld)%s (%s), buff=%s, size=%s", issuer->pid, MC_smx_actor_get_host_name(issuer),
+ if (issuer->host_)
+ args = bprintf("src=(%ld)%s (%s), buff=%s, size=%s", issuer->pid_, MC_smx_actor_get_host_name(issuer),
MC_smx_actor_get_name(issuer), p, bs);
else
- args = bprintf("src=(%ld)%s, buff=%s, size=%s", issuer->pid, MC_smx_actor_get_name(issuer), p, bs);
+ args = bprintf("src=(%ld)%s, buff=%s, size=%s", issuer->pid_, MC_smx_actor_get_name(issuer), p, bs);
xbt_free(bs);
xbt_free(p);
break;
type = "iRecv";
char* p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req));
char* bs = buff_size_to_string(size);
- if (issuer->host)
- args = bprintf("dst=(%ld)%s (%s), buff=%s, size=%s", issuer->pid, MC_smx_actor_get_host_name(issuer),
+ if (issuer->host_)
+ args = bprintf("dst=(%ld)%s (%s), buff=%s, size=%s", issuer->pid_, MC_smx_actor_get_host_name(issuer),
MC_smx_actor_get_name(issuer), p, bs);
else
- args = bprintf("dst=(%ld)%s, buff=%s, size=%s", issuer->pid, MC_smx_actor_get_name(issuer), p, bs);
+ args = bprintf("dst=(%ld)%s, buff=%s, size=%s", issuer->pid_, MC_smx_actor_get_name(issuer), p, bs);
xbt_free(bs);
xbt_free(p);
break;
smx_actor_t src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(act->src_proc));
smx_actor_t dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(act->dst_proc));
args =
- bprintf("comm=%s [(%ld)%s (%s)-> (%ld)%s (%s)]", p, src_proc ? src_proc->pid : 0,
+ bprintf("comm=%s [(%ld)%s (%s)-> (%ld)%s (%s)]", p, src_proc ? src_proc->pid_ : 0,
src_proc ? MC_smx_actor_get_host_name(src_proc) : "", src_proc ? MC_smx_actor_get_name(src_proc) : "",
- dst_proc ? dst_proc->pid : 0, dst_proc ? MC_smx_actor_get_host_name(dst_proc) : "",
+ dst_proc ? dst_proc->pid_ : 0, dst_proc ? MC_smx_actor_get_host_name(dst_proc) : "",
dst_proc ? MC_smx_actor_get_name(dst_proc) : "");
}
xbt_free(p);
smx_actor_t src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(act->src_proc));
smx_actor_t dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(act->dst_proc));
- args = bprintf("comm=%s [(%ld)%s (%s) -> (%ld)%s (%s)]", p, src_proc->pid, MC_smx_actor_get_name(src_proc),
- MC_smx_actor_get_host_name(src_proc), dst_proc->pid, MC_smx_actor_get_name(dst_proc),
+ args = bprintf("comm=%s [(%ld)%s (%s) -> (%ld)%s (%s)]", p, src_proc->pid_, MC_smx_actor_get_name(src_proc),
+ MC_smx_actor_get_host_name(src_proc), dst_proc->pid_, MC_smx_actor_get_name(dst_proc),
MC_smx_actor_get_host_name(dst_proc));
}
xbt_free(p);
args =
bprintf("locked = %d, owner = %d, sleeping = n/a", mutex.getBuffer()->locked,
mutex.getBuffer()->owner != nullptr
- ? (int)mc_model_checker->process().resolveActor(simgrid::mc::remote(mutex.getBuffer()->owner))->pid
+ ? (int)mc_model_checker->process().resolveActor(simgrid::mc::remote(mutex.getBuffer()->owner))->pid_
: -1);
break;
}
std::string str;
if (args != nullptr)
- str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s(%s)", issuer->pid, MC_smx_actor_get_host_name(issuer),
+ str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s(%s)", issuer->pid_, MC_smx_actor_get_host_name(issuer),
MC_smx_actor_get_name(issuer), type, args);
else
- str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s ", issuer->pid, MC_smx_actor_get_host_name(issuer),
+ str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s ", issuer->pid_, MC_smx_actor_get_host_name(issuer),
MC_smx_actor_get_name(issuer), type);
xbt_free(args);
return str;
switch (req->call) {
case SIMCALL_COMM_ISEND:
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] iSend", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] iSend", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = bprintf("[(%ld)] iSend", issuer->pid);
+ label = bprintf("[(%ld)] iSend", issuer->pid_);
break;
case SIMCALL_COMM_IRECV:
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] iRecv", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] iRecv", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = simgrid::xbt::string_printf("[(%ld)] iRecv", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] iRecv", issuer->pid_);
break;
case SIMCALL_COMM_WAIT:
if (value == -1) {
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] WaitTimeout", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] WaitTimeout", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = simgrid::xbt::string_printf("[(%ld)] WaitTimeout", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] WaitTimeout", issuer->pid_);
} else {
simgrid::kernel::activity::ActivityImpl* remote_act = simcall_comm_wait__getraw__comm(req);
simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_comm;
smx_actor_t src_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->src_proc));
smx_actor_t dst_proc = mc_model_checker->process().resolveActor(simgrid::mc::remote(comm->dst_proc));
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] Wait [(%ld)->(%ld)]", issuer->pid,
- MC_smx_actor_get_host_name(issuer), src_proc ? src_proc->pid : 0,
- dst_proc ? dst_proc->pid : 0);
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] Wait [(%ld)->(%ld)]", issuer->pid_,
+ MC_smx_actor_get_host_name(issuer), src_proc ? src_proc->pid_ : 0,
+ dst_proc ? dst_proc->pid_ : 0);
else
- label = simgrid::xbt::string_printf("[(%ld)] Wait [(%ld)->(%ld)]",
- issuer->pid,
- src_proc ? src_proc->pid : 0,
- dst_proc ? dst_proc->pid : 0);
+ label = simgrid::xbt::string_printf("[(%ld)] Wait [(%ld)->(%ld)]", issuer->pid_, src_proc ? src_proc->pid_ : 0,
+ dst_proc ? dst_proc->pid_ : 0);
}
break;
mc_model_checker->process().read(temp_comm, remote(static_cast<simgrid::kernel::activity::CommImpl*>(remote_act)));
simgrid::kernel::activity::CommImpl* comm = temp_comm.getBuffer();
if (comm->src_proc == nullptr || comm->dst_proc == nullptr) {
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] Test FALSE", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] Test FALSE", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = bprintf("[(%ld)] Test FALSE", issuer->pid);
+ label = bprintf("[(%ld)] Test FALSE", issuer->pid_);
} else {
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] Test TRUE", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] Test TRUE", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = simgrid::xbt::string_printf("[(%ld)] Test TRUE", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] Test TRUE", issuer->pid_);
}
break;
}
case SIMCALL_COMM_WAITANY: {
unsigned long comms_size = read_length(
mc_model_checker->process(), remote(simcall_comm_waitany__get__comms(req)));
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] WaitAny [%d of %lu]", issuer->pid,
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] WaitAny [%d of %lu]", issuer->pid_,
MC_smx_actor_get_host_name(issuer), value + 1, comms_size);
else
- label = simgrid::xbt::string_printf("[(%ld)] WaitAny [%d of %lu]",
- issuer->pid, value + 1, comms_size);
+ label = simgrid::xbt::string_printf("[(%ld)] WaitAny [%d of %lu]", issuer->pid_, value + 1, comms_size);
break;
}
case SIMCALL_COMM_TESTANY:
if (value == -1) {
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] TestAny FALSE", issuer->pid, MC_smx_actor_get_host_name(issuer));
+ if (issuer->host_)
+ label =
+ simgrid::xbt::string_printf("[(%ld)%s] TestAny FALSE", issuer->pid_, MC_smx_actor_get_host_name(issuer));
else
- label = simgrid::xbt::string_printf("[(%ld)] TestAny FALSE", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] TestAny FALSE", issuer->pid_);
} else {
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] TestAny TRUE [%d of %lu]", issuer->pid,
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] TestAny TRUE [%d of %lu]", issuer->pid_,
MC_smx_actor_get_host_name(issuer), value + 1,
simcall_comm_testany__get__count(req));
else
- label = simgrid::xbt::string_printf("[(%ld)] TestAny TRUE [%d of %lu]",
- issuer->pid,
- value + 1,
- simcall_comm_testany__get__count(req));
+ label = simgrid::xbt::string_printf("[(%ld)] TestAny TRUE [%d of %lu]", issuer->pid_, value + 1,
+ simcall_comm_testany__get__count(req));
}
break;
case SIMCALL_MUTEX_TRYLOCK:
- label = simgrid::xbt::string_printf("[(%ld)] Mutex TRYLOCK", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] Mutex TRYLOCK", issuer->pid_);
break;
case SIMCALL_MUTEX_LOCK:
- label = simgrid::xbt::string_printf("[(%ld)] Mutex LOCK", issuer->pid);
+ label = simgrid::xbt::string_printf("[(%ld)] Mutex LOCK", issuer->pid_);
break;
case SIMCALL_MC_RANDOM:
- if (issuer->host)
- label = simgrid::xbt::string_printf("[(%ld)%s] MC_RANDOM (%d)", issuer->pid, MC_smx_actor_get_host_name(issuer),
+ if (issuer->host_)
+ label = simgrid::xbt::string_printf("[(%ld)%s] MC_RANDOM (%d)", issuer->pid_, MC_smx_actor_get_host_name(issuer),
value);
else
- label = simgrid::xbt::string_printf("[(%ld)] MC_RANDOM (%d)", issuer->pid, value);
+ label = simgrid::xbt::string_printf("[(%ld)] MC_RANDOM (%d)", issuer->pid_, value);
break;
default:
THROW_UNIMPLEMENTED;
}
- const char* color = get_color(issuer->pid - 1);
+ const char* color = get_color(issuer->pid_ - 1);
return simgrid::xbt::string_printf(
"label = \"%s\", color = %s, fontcolor = %s", label.c_str(),
color, color);
const char* MC_smx_actor_get_host_name(smx_actor_t actor)
{
if (mc_model_checker == nullptr)
- return actor->host->get_cname();
+ return actor->host_->get_cname();
simgrid::mc::RemoteClient* process = &mc_model_checker->process();
// Read the simgrid::xbt::string in the MCed process:
simgrid::mc::ActorInformation* info = actor_info_cast(actor);
- auto remote_string_address = remote((simgrid::xbt::string_data*)((char*)actor->host + offset));
+ auto remote_string_address = remote((simgrid::xbt::string_data*)((char*)actor->host_ + offset));
simgrid::xbt::string_data remote_string = process->read(remote_string_address);
char hostname[remote_string.len];
process->read_bytes(hostname, remote_string.len + 1, remote(remote_string.data));
{
simgrid::mc::RemoteClient* process = &mc_model_checker->process();
if (mc_model_checker == nullptr)
- return actor->name.c_str();
+ return actor->get_cname();
simgrid::mc::ActorInformation* info = actor_info_cast(actor);
if (info->name.empty()) {
- simgrid::xbt::string_data string_data = simgrid::xbt::string::to_string_data(actor->name);
+ simgrid::xbt::string_data string_data = simgrid::xbt::string::to_string_data(actor->name_);
info->name = process->read_string(remote(string_data.data), string_data.len);
}
return info->name.c_str();
+++ /dev/null
-/* Copyright (c) 2014-2018. The SimGrid Team.
- * All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include <cstddef>
-
-#include <memory>
-#include <utility>
-
-#include "xbt/asserts.h"
-#include "xbt/sysdep.h"
-
-#include "src/internal_config.h"
-#include "src/smpi/include/private.hpp"
-
-#include "src/mc/PageStore.hpp"
-#include "src/mc/mc_mmu.hpp"
-#include "src/mc/mc_private.hpp"
-#include "src/mc/mc_snapshot.hpp"
-
-/** @brief Find the snapshoted region from a pointer
- *
- * @param addr Pointer
- * @param snapshot Snapshot
- * @param Snapshot region in the snapshot this pointer belongs to
- * (or nullptr if it does not belong to any snapshot region)
- * */
-mc_mem_region_t mc_get_snapshot_region(
- const void* addr, const simgrid::mc::Snapshot* snapshot, int process_index)
-{
- size_t n = snapshot->snapshot_regions.size();
- for (size_t i = 0; i != n; ++i) {
- mc_mem_region_t region = snapshot->snapshot_regions[i].get();
- if (not(region && region->contain(simgrid::mc::remote(addr))))
- continue;
-
- if (region->storage_type() == simgrid::mc::StorageType::Privatized) {
-#if HAVE_SMPI
- // Use the current process index of the snapshot:
- if (process_index == simgrid::mc::ProcessIndexDisabled)
- process_index = snapshot->privatization_index;
- if (process_index < 0)
- xbt_die("Missing process index");
- if (process_index >= (int) region->privatized_data().size())
- xbt_die("Invalid process index");
- simgrid::mc::RegionSnapshot& priv_region = region->privatized_data()[process_index];
- xbt_assert(priv_region.contain(simgrid::mc::remote(addr)));
- return &priv_region;
-#else
- xbt_die("Privatized region in a non SMPI build (this should not happen)");
-#endif
- }
-
- return region;
- }
-
- return nullptr;
-}
-
-/** @brief Read memory from a snapshot region broken across fragmented pages
- *
- * @param addr Process (non-snapshot) address of the data
- * @param region Snapshot memory region where the data is located
- * @param target Buffer to store the value
- * @param size Size of the data to read in bytes
- * @return Pointer where the data is located (target buffer of original location)
- */
-const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size)
-{
- // Last byte of the memory area:
- void* end = (char*) addr + size - 1;
-
- // TODO, we assume the chunks are aligned to natural chunk boundaries.
- // We should remove this assumption.
-
- // Page of the last byte of the memory area:
- size_t page_end = simgrid::mc::mmu::split((std::uintptr_t) end).first;
-
- void* dest = target;
-
- if (dest==nullptr)
- xbt_die("Missing destination buffer for fragmented memory access");
-
- // Read each page:
- while (simgrid::mc::mmu::split((std::uintptr_t) addr).first != page_end) {
- void* snapshot_addr = mc_translate_address_region_chunked((uintptr_t) addr, region);
- void* next_page = (void*) simgrid::mc::mmu::join(
- simgrid::mc::mmu::split((std::uintptr_t) addr).first + 1,
- 0);
- size_t readable = (char*) next_page - (char*) addr;
- memcpy(dest, snapshot_addr, readable);
- addr = (char*) addr + readable;
- dest = (char*) dest + readable;
- size -= readable;
- }
-
- // Read the end:
- void* snapshot_addr = mc_translate_address_region_chunked((uintptr_t)addr, region);
- memcpy(dest, snapshot_addr, size);
-
- return target;
-}
-
-/** Compare memory between snapshots (with known regions)
- *
- * @param addr1 Address in the first snapshot
- * @param snapshot2 Region of the address in the first snapshot
- * @param addr2 Address in the second snapshot
- * @param snapshot2 Region of the address in the second snapshot
- * @return same as memcmp
- * */
-int MC_snapshot_region_memcmp(
- const void* addr1, mc_mem_region_t region1,
- const void* addr2, mc_mem_region_t region2,
- size_t size)
-{
- // Using alloca() for large allocations may trigger stack overflow:
- // use malloc if the buffer is too big.
- bool stack_alloc = size < 64;
- void* buffer1a = nullptr;
- void* buffer2a = nullptr;
- if (region1 != nullptr && region1->storage_type() != simgrid::mc::StorageType::Flat)
- buffer1a = stack_alloc ? alloca(size) : ::operator new(size);
- if (region2 != nullptr && region2->storage_type() != simgrid::mc::StorageType::Flat)
- buffer2a = stack_alloc ? alloca(size) : ::operator new(size);
- const void* buffer1 = MC_region_read(region1, buffer1a, addr1, size);
- const void* buffer2 = MC_region_read(region2, buffer2a, addr2, size);
- int res;
- if (buffer1 == buffer2)
- res = 0;
- else
- res = memcmp(buffer1, buffer2, size);
- if (not stack_alloc) {
- ::operator delete(buffer1a);
- ::operator delete(buffer2a);
- }
- return res;
-}
-
-namespace simgrid {
-namespace mc {
-
-Snapshot::Snapshot(RemoteClient* process, int _num_state)
- : AddressSpace(process)
- , num_state(_num_state)
- , heap_bytes_used(0)
- , enabled_processes()
- , privatization_index(0)
- , hash(0)
-{
-
-}
-
-const void* Snapshot::read_bytes(void* buffer, std::size_t size,
- RemotePtr<void> address, int process_index,
- ReadOptions options) const
-{
- mc_mem_region_t region = mc_get_snapshot_region((void*)address.address(), this, process_index);
- if (region) {
- const void* res = MC_region_read(region, buffer, (void*)address.address(), size);
- if (buffer == res || options & ReadOptions::lazy())
- return res;
- else {
- memcpy(buffer, res, size);
- return buffer;
- }
- }
- else
- return this->process()->read_bytes(
- buffer, size, address, process_index, options);
-}
-
-}
-}
-
-#ifdef SIMGRID_TEST
-
-#include <cstdlib>
-#include <cstring>
-
-#include <sys/mman.h>
-
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_mmu.hpp"
-#include "src/mc/mc_private.hpp"
-#include "src/mc/mc_snapshot.hpp"
-
-XBT_TEST_SUITE("mc_snapshot", "Snapshots");
-
-static inline void init_memory(void* mem, size_t size)
-{
- char* dest = (char*) mem;
- for (size_t i = 0; i < size; ++i) {
- dest[i] = rand() & 255;
- }
-}
-
-static void test_snapshot(bool sparse_checkpoint);
-
-XBT_TEST_UNIT("flat_snapshot", test_flat_snapshots, "Test flat snapshots")
-{
- test_snapshot(0);
-}
-
-XBT_TEST_UNIT("page_snapshots", test_per_snpashots, "Test per-page snapshots")
-{
- test_snapshot(1);
-}
-
-static void test_snapshot(bool sparse_checkpoint) {
-
- xbt_test_add("Initialization");
- _sg_mc_sparse_checkpoint = sparse_checkpoint;
- xbt_assert(xbt_pagesize == getpagesize());
- xbt_assert(1 << xbt_pagebits == xbt_pagesize);
-
- std::unique_ptr<simgrid::mc::RemoteClient> process(new simgrid::mc::RemoteClient(getpid(), -1));
- process->init();
- mc_model_checker = new ::simgrid::mc::ModelChecker(std::move(process));
-
- for(int n=1; n!=256; ++n) {
-
- // Store region page(s):
- size_t byte_size = n * xbt_pagesize;
- void* source = mmap(nullptr, byte_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- xbt_assert(source!=MAP_FAILED, "Could not allocate source memory");
-
- // Init memory and take snapshots:
- init_memory(source, byte_size);
- simgrid::mc::RegionSnapshot region0 = simgrid::mc::sparse_region(
- simgrid::mc::RegionType::Unknown, source, source, byte_size);
- for(int i=0; i<n; i+=2) {
- init_memory((char*) source + i*xbt_pagesize, xbt_pagesize);
- }
- simgrid::mc::RegionSnapshot region = simgrid::mc::sparse_region(
- simgrid::mc::RegionType::Unknown, source, source, byte_size);
-
- void* destination = mmap(nullptr, byte_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- xbt_assert(source!=MAP_FAILED, "Could not allocate destination memory");
-
- xbt_test_add("Reading whole region data for %i page(s)", n);
- const void* read = MC_region_read(®ion, destination, source, byte_size);
- xbt_test_assert(not memcmp(source, read, byte_size), "Mismatch in MC_region_read()");
-
- xbt_test_add("Reading parts of region data for %i page(s)", n);
- for(int j=0; j!=100; ++j) {
- size_t offset = rand() % byte_size;
- size_t size = rand() % (byte_size - offset);
- const void* read = MC_region_read(®ion, destination, (const char*) source+offset, size);
- xbt_test_assert(not memcmp((char*)source + offset, read, size), "Mismatch in MC_region_read()");
- }
-
- xbt_test_add("Compare whole region data for %i page(s)", n);
-
- xbt_test_assert(MC_snapshot_region_memcmp(source, ®ion0, source, ®ion, byte_size),
- "Unexpected match in MC_snapshot_region_memcmp() with previous snapshot");
-
- xbt_test_add("Compare parts of region data for %i page(s) with itself", n);
- for(int j=0; j!=100; ++j) {
- size_t offset = rand() % byte_size;
- size_t size = rand() % (byte_size - offset);
- xbt_test_assert(
- not MC_snapshot_region_memcmp((char*)source + offset, ®ion, (char*)source + offset, ®ion, size),
- "Mismatch in MC_snapshot_region_memcmp()");
- }
-
- if (n==1) {
- xbt_test_add("Read pointer for %i page(s)", n);
- memcpy(source, &mc_model_checker, sizeof(void*));
- simgrid::mc::RegionSnapshot region2 = simgrid::mc::sparse_region(
- simgrid::mc::RegionType::Unknown, source, source, byte_size);
- xbt_test_assert(MC_region_read_pointer(®ion2, source) == mc_model_checker,
- "Mismtach in MC_region_read_pointer()");
- }
-
- munmap(destination, byte_size);
- munmap(source, byte_size);
- }
-
- delete mc_model_checker;
- mc_model_checker = nullptr;
-}
-
-#endif /* SIMGRID_TEST */
-
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <cassert>
-
-#include <boost/range/algorithm.hpp>
-
-#include "xbt/log.h"
-#include "xbt/sysdep.h"
-
#include "src/mc/mc_comm_pattern.hpp"
-#include "src/mc/mc_private.hpp"
#include "src/mc/mc_request.hpp"
#include "src/mc/mc_smx.hpp"
#include "src/mc/mc_state.hpp"
#include "src/mc/mc_xbt.hpp"
-#include "src/simix/smx_private.hpp"
+
+#include <boost/range/algorithm.hpp>
using simgrid::mc::remote;
static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
{
/* reset the outgoing transition */
- simgrid::mc::ProcessState* procstate = &state->actorStates[actor->pid];
+ simgrid::mc::ProcessState* procstate = &state->actorStates[actor->pid_];
state->transition.pid = -1;
state->transition.argument = -1;
state->executed_req.call = SIMCALL_NONE;
if (not req)
return nullptr;
- state->transition.pid = actor->pid;
+ state->transition.pid = actor->pid_;
state->executed_req = *req;
// Fetch the data of the request and translate it:
state->internal_req = *req;
{
for (auto& actor : mc_model_checker->process().actors()) {
/* Only consider the actors that were marked as interleaving by the checker algorithm */
- if (not state->actorStates[actor.copy.getBuffer()->pid].isTodo())
+ if (not state->actorStates[actor.copy.getBuffer()->pid_].isTodo())
continue;
smx_simcall_t res = MC_state_get_request_for_process(state, actor.copy.getBuffer());
#include <memory>
#include "src/mc/mc_record.hpp"
-#include "src/mc/mc_snapshot.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
+#include "src/kernel/activity/CommImpl.hpp"
#include "src/mc/Transition.hpp"
namespace simgrid {
explicit State(unsigned long state_number);
std::size_t interleaveSize() const;
- void addInterleavingSet(smx_actor_t actor) { this->actorStates[actor->pid].consider(); }
+ void addInterleavingSet(smx_actor_t actor) { this->actorStates[actor->pid_].consider(); }
Transition getTransition() const;
};
}
return unw_create_addr_space(&accessors, BYTE_ORDER);
}
-void* create_context(unw_addr_space_t as, pid_t pid)
+void* create_context(unw_addr_space_t /*as*/, pid_t pid)
{
return _UPT_create(pid);
}
region.block = ((char*)stack - (char*)heap->heapbase) / BLOCKSIZE + 1;
#if HAVE_SMPI
if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP && process)
- region.process_index = process->pid - 1;
+ region.process_index = process->pid_ - 1;
else
#endif
region.process_index = -1;
#include <xbt/mmalloc.h>
#include "src/mc/mc_smx.hpp"
-#include "src/mc/mc_snapshot.hpp"
#include "src/mc/mc_unw.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
#include "src/mc/AddressSpace.hpp"
#include "src/mc/ObjectInformation.hpp"
-/* Copyright (c) 2015-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2015-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <memory>
-#include "src/mc/PageStore.hpp"
+#include "src/mc/sosp/PageStore.hpp"
using simgrid::mc::PageStore;
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_mmu.hpp"
#include "src/mc/mc_private.hpp"
-#include "src/mc/mc_snapshot.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
/**************** Class BOOST_tests *************************/
using simgrid::mc::RegionSnapshot;
--- /dev/null
+/* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <cstddef>
+#include <cstdint>
+
+#include <vector>
+
+#include "xbt/asserts.h"
+#include "xbt/misc.h"
+
+#include "src/mc/AddressSpace.hpp"
+#include "src/mc/sosp/ChunkedData.hpp"
+#include "src/mc/sosp/PageStore.hpp"
+
+namespace simgrid {
+namespace mc {
+
+/** Take a per-page snapshot of a region
+ *
+ * @param addr The start of the region (must be at the beginning of a page)
+ * @param page_count Number of pages of the region
+ * @return Snapshot page numbers of this new snapshot
+ */
+ChunkedData::ChunkedData(PageStore& store, AddressSpace& as, RemotePtr<void> addr, std::size_t page_count)
+{
+ store_ = &store;
+ this->pagenos_.resize(page_count);
+ std::vector<char> buffer(xbt_pagesize);
+
+ for (size_t i = 0; i != page_count; ++i) {
+
+ RemotePtr<void> page = remote((void*)simgrid::mc::mmu::join(i, addr.address()));
+ xbt_assert(simgrid::mc::mmu::split(page.address()).second == 0, "Not at the beginning of a page");
+
+ /* Adding another copy (and a syscall) will probably slow things a lot.
+ TODO, optimize this somehow (at least by grouping the syscalls)
+ if needed. Either:
+ - reduce the number of syscalls
+ - let the application snapshot itself
+ - move the segments in shared memory (this will break `fork` however)
+ */
+
+ as.read_bytes(buffer.data(), xbt_pagesize, page, simgrid::mc::ProcessIndexDisabled);
+
+ pagenos_[i] = store_->store_page(buffer.data());
+ }
+}
+
+} // namespace mc
+} // namespace simgrid
#include <vector>
#include "src/mc/mc_forward.hpp"
-#include "src/mc/PageStore.hpp"
+#include "src/mc/sosp/PageStore.hpp"
namespace simgrid {
namespace mc {
PageStore* store_ = nullptr;
/** Indices of the chunks in the `PageStore` */
std::vector<std::size_t> pagenos_;
-public:
+public:
ChunkedData() = default;
void clear()
{
store_->unref_page(pageno);
pagenos_.clear();
}
- ~ChunkedData()
- {
- clear();
- }
+ ~ChunkedData() { clear(); }
// Copy and move
- ChunkedData(ChunkedData const& that)
- : store_ (that.store_)
- , pagenos_(that.pagenos_)
+ ChunkedData(ChunkedData const& that) : store_(that.store_), pagenos_(that.pagenos_)
{
for (std::size_t const& pageno : pagenos_)
store_->ref_page(pageno);
}
- ChunkedData(ChunkedData&& that)
- : store_(that.store_)
- , pagenos_(std::move(that.pagenos_))
+ ChunkedData(ChunkedData&& that) : store_(that.store_), pagenos_(std::move(that.pagenos_))
{
that.store_ = nullptr;
that.pagenos_.clear();
ChunkedData& operator=(ChunkedData const& that)
{
this->clear();
- store_ = that.store_;
+ store_ = that.store_;
pagenos_ = that.pagenos_;
for (std::size_t const& pageno : pagenos_)
store_->ref_page(pageno);
return *this;
}
- ChunkedData& operator=(ChunkedData && that)
+ ChunkedData& operator=(ChunkedData&& that)
{
this->clear();
- store_ = that.store_;
+ store_ = that.store_;
that.store_ = nullptr;
- pagenos_ = std::move(that.pagenos_);
+ pagenos_ = std::move(that.pagenos_);
that.pagenos_.clear();
return *this;
}
/** How many pages are used */
- std::size_t page_count() const { return pagenos_.size(); }
+ std::size_t page_count() const { return pagenos_.size(); }
/** Get a chunk index */
std::size_t pageno(std::size_t i) const { return pagenos_[i]; }
/** Get a view of the chunk indices */
- const std::size_t* pagenos() const { return pagenos_.data(); }
+ const std::size_t* pagenos() const { return pagenos_.data(); }
/** Get a a pointer to a chunk */
- const void* page(std::size_t i) const
- {
- return store_->get_page(pagenos_[i]);
- }
+ const void* page(std::size_t i) const { return store_->get_page(pagenos_[i]); }
- ChunkedData(PageStore& store, AddressSpace& as,
- RemotePtr<void> addr, std::size_t page_count);
+ ChunkedData(PageStore& store, AddressSpace& as, RemotePtr<void> addr, std::size_t page_count);
};
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
#include <sys/mman.h>
#ifdef __FreeBSD__
-# define MAP_POPULATE MAP_PREFAULT_READ
+#define MAP_POPULATE MAP_PREFAULT_READ
#endif
#include "xbt/base.h"
#include "src/internal_config.h"
-#include "src/mc/PageStore.hpp"
+#include "src/mc/sosp/PageStore.hpp"
#include "src/mc/mc_mmu.hpp"
*/
static XBT_ALWAYS_INLINE PageStore::hash_type mc_hash_page(const void* data)
{
- const std::uint64_t* values = (const uint64_t*) data;
- std::size_t n = xbt_pagesize / sizeof(uint64_t);
+ const std::uint64_t* values = (const uint64_t*)data;
+ std::size_t n = xbt_pagesize / sizeof(uint64_t);
// This djb2:
std::uint64_t hash = 5381;
PageStore::PageStore(size_t size) : memory_(nullptr), capacity_(size), top_index_(0)
{
// Using mmap in order to be able to expand the region by relocating it somewhere else in the virtual memory space:
- void* memory = ::mmap(nullptr, size << xbt_pagebits, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0);
+ void* memory =
+ ::mmap(nullptr, size << xbt_pagebits, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
if (memory == MAP_FAILED)
xbt_die("Could not mmap initial snapshot pages.");
this->top_index_ = 0;
- this->memory_ = memory;
+ this->memory_ = memory;
this->page_counts_.resize(size);
}
{
size_t old_bytesize = this->capacity_ << xbt_pagebits;
size_t new_bytesize = size << xbt_pagebits;
- void *new_memory;
+ void* new_memory;
// Expand the memory region by moving it into another
// virtual memory address if necessary:
#else
if (new_bytesize > old_bytesize) {
// Grow: first try to add new space after current map
- new_memory = mmap((char *)this->memory_ + old_bytesize,
- new_bytesize-old_bytesize,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE,
- -1, 0);
+ new_memory = mmap((char*)this->memory_ + old_bytesize, new_bytesize - old_bytesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
if (new_memory == MAP_FAILED)
xbt_die("Could not mremap snapshot pages.");
// Check if expanding worked
- if (new_memory != (char *)this->memory_ + old_bytesize) {
+ if (new_memory != (char*)this->memory_ + old_bytesize) {
// New memory segment could not be put at the end of this->memory_,
// so cancel this one and try to rellocate everything and copy data
- munmap(new_memory, new_bytesize-old_bytesize);
- new_memory = mmap(nullptr,
- new_bytesize,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE,
- -1, 0);
+ munmap(new_memory, new_bytesize - old_bytesize);
+ new_memory =
+ mmap(nullptr, new_bytesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
if (new_memory == MAP_FAILED)
xbt_die("Could not mremap snapshot pages.");
memcpy(new_memory, this->memory_, old_bytesize);
munmap(this->memory_, old_bytesize);
}
- }
- else {
+ } else {
// We don't have functions to shrink a mapping, so leave memory as
// it is for now
new_memory = this->memory_;
#endif
this->capacity_ = size;
- this->memory_ = new_memory;
+ this->memory_ = new_memory;
this->page_counts_.resize(size, 0);
}
{
this->free_pages_.push_back(pageno);
const void* page = this->get_page(pageno);
- hash_type hash = mc_hash_page(page);
+ hash_type hash = mc_hash_page(page);
this->hash_index_[hash].erase(pageno);
}
// If a page with the same content is already in the page store it's reused and its refcount is incremented.
page_counts_[pageno]++;
return pageno;
-
}
}
// Otherwise, a new page is allocated in the page store and the content of the page is `memcpy()`-ed to this new page.
std::size_t pageno = alloc_page();
- xbt_assert(this->page_counts_[pageno]==0, "Allocated page is already used");
- void* snapshot_page = (void*) this->get_page(pageno);
+ xbt_assert(this->page_counts_[pageno] == 0, "Allocated page is already used");
+ void* snapshot_page = (void*)this->get_page(pageno);
memcpy(snapshot_page, page, xbt_pagesize);
page_set.insert(pageno);
page_counts_[pageno]++;
return pageno;
}
-}
-}
-
-#ifdef SIMGRID_TEST
-
-#include <cstring>
-#include <cstdint>
-
-#include <unistd.h>
-#include <sys/mman.h>
-
-#include <memory>
-
-#include "src/mc/PageStore.hpp"
-
-static int value = 0;
-
-static void new_content(void* data, std::size_t size)
-{
- ::memset(data, ++value, size);
-}
-
-static void* getpage()
-{
- return mmap(nullptr, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-}
-
-XBT_TEST_SUITE("mc_page_store", "Page store");
-
-XBT_TEST_UNIT("base", test_mc_page_store, "Test adding/removing pages in the store")
-{
- using simgrid::mc::PageStore;
-
- xbt_test_add("Init");
- std::size_t pagesize = (size_t) getpagesize();
- std::unique_ptr<PageStore> store = std::unique_ptr<PageStore>(new simgrid::mc::PageStore(500));
- void* data = getpage();
- xbt_test_assert(store->size()==0, "Bad size");
-
- xbt_test_add("Store the page once");
- new_content(data, pagesize);
- size_t pageno1 = store->store_page(data);
- xbt_test_assert(store->get_ref(pageno1)==1, "Bad refcount");
- const void* copy = store->get_page(pageno1);
- xbt_test_assert(::memcmp(data, copy, pagesize)==0, "Page data should be the same");
- xbt_test_assert(store->size()==1, "Bad size");
-
- xbt_test_add("Store the same page again");
- size_t pageno2 = store->store_page(data);
- xbt_test_assert(pageno1==pageno2, "Page should be the same");
- xbt_test_assert(store->get_ref(pageno1)==2, "Bad refcount");
- xbt_test_assert(store->size()==1, "Bad size");
-
- xbt_test_add("Store a new page");
- new_content(data, pagesize);
- size_t pageno3 = store->store_page(data);
- xbt_test_assert(pageno1 != pageno3, "New page should be different");
- xbt_test_assert(store->size()==2, "Bad size");
-
- xbt_test_add("Unref pages");
- store->unref_page(pageno1);
- xbt_assert(store->get_ref(pageno1)==1, "Bad refcount");
- xbt_assert(store->size()==2, "Bad size");
- store->unref_page(pageno2);
- xbt_test_assert(store->size()==1, "Bad size");
-
- xbt_test_add("Reallocate page");
- new_content(data, pagesize);
- size_t pageno4 = store->store_page(data);
- xbt_test_assert(pageno1 == pageno4, "Page was not reused");
- xbt_test_assert(store->get_ref(pageno4)==1, "Bad refcount");
- xbt_test_assert(store->size()==2, "Bad size");
-}
-
-#endif /* SIMGRID_TEST */
+} // namespace mc
+} // namespace simgrid
-/* Copyright (c) 2015-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2015-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <unordered_map>
#include <unordered_set>
-#include "xbt/base.h"
-
#include "src/mc/mc_forward.hpp"
#include "src/mc/mc_mmu.hpp"
+#ifndef XBT_ALWAYS_INLINE
+#define XBT_ALWAYS_INLINE inline __attribute__((always_inline))
+#endif
+
namespace simgrid {
namespace mc {
* The capacity is expanded by a system call (mremap).
* */
std::size_t capacity();
-
};
XBT_ALWAYS_INLINE void PageStore::unref_page(std::size_t pageno)
XBT_ALWAYS_INLINE const void* PageStore::get_page(std::size_t pageno) const
{
- return (void*) simgrid::mc::mmu::join(pageno, (std::uintptr_t) this->memory_);
+ return (void*)simgrid::mc::mmu::join(pageno, (std::uintptr_t)this->memory_);
}
XBT_ALWAYS_INLINE std::size_t PageStore::get_ref(std::size_t pageno)
return this->capacity_;
}
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
--- /dev/null
+/* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <cstdlib>
+
+#include <sys/mman.h>
+#ifdef __FreeBSD__
+#define MAP_POPULATE MAP_PREFAULT_READ
+#endif
+
+#include "mc/mc.h"
+#include "src/mc/mc_config.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
+
+#include "src/mc/sosp/ChunkedData.hpp"
+#include "src/mc/sosp/RegionSnapshot.hpp"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_RegionSnaphot, mc, "Logging specific to region snapshots");
+
+namespace simgrid {
+namespace mc {
+
+static inline const char* to_cstr(RegionType region)
+{
+ switch (region) {
+ case RegionType::Unknown:
+ return "unknown";
+ case RegionType::Heap:
+ return "Heap";
+ case RegionType::Data:
+ return "Data";
+ default:
+ return "?";
+ }
+}
+
+Buffer::Buffer(std::size_t size, Type type) : size_(size), type_(type)
+{
+ switch (type_) {
+ case Type::Malloc:
+ data_ = ::operator new(size_);
+ break;
+ case Type::Mmap:
+ data_ = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
+ if (data_ == MAP_FAILED) {
+ data_ = nullptr;
+ size_ = 0;
+ type_ = Type::Malloc;
+ throw std::bad_alloc();
+ }
+ break;
+ default:
+ abort();
+ }
+}
+
+void Buffer::clear() noexcept
+{
+ switch (type_) {
+ case Type::Malloc:
+ ::operator delete(data_);
+ break;
+ case Type::Mmap:
+ if (munmap(data_, size_) != 0)
+ abort();
+ break;
+ default:
+ abort();
+ }
+ data_ = nullptr;
+ size_ = 0;
+ type_ = Type::Malloc;
+}
+
+RegionSnapshot dense_region(RegionType region_type, void* start_addr, void* permanent_addr, size_t size)
+{
+ // When KSM support is enables, we allocate memory using mmap:
+ // * we don't want to advise bits of the heap as mergable
+ // * mmap gives data aligned on page boundaries which is merge friendly
+ simgrid::mc::Buffer data;
+ if (_sg_mc_ksm)
+ data = Buffer::mmap(size);
+ else
+ data = Buffer::malloc(size);
+
+ mc_model_checker->process().read_bytes(data.get(), size, remote(permanent_addr), simgrid::mc::ProcessIndexDisabled);
+
+#ifdef __linux__
+ if (_sg_mc_ksm)
+ // Mark the region as mergeable *after* we have written into it.
+ // Trying to merge them before is useless/counterproductive.
+ madvise(data.get(), size, MADV_MERGEABLE);
+#endif
+
+ simgrid::mc::RegionSnapshot region(region_type, start_addr, permanent_addr, size);
+ region.flat_data(std::move(data));
+
+ XBT_DEBUG("New region : type : %s, data : %p (real addr %p), size : %zu", to_cstr(region_type),
+ region.flat_data().get(), permanent_addr, size);
+ return region;
+}
+
+/** @brief Take a snapshot of a given region
+ *
+ * @param type
+ * @param start_addr Address of the region in the simulated process
+ * @param permanent_addr Permanent address of this data (for privatized variables, this is the virtual address of the
+ * privatized mapping)
+ * @param size Size of the data*
+ */
+RegionSnapshot region(RegionType type, void* start_addr, void* permanent_addr, size_t size)
+{
+ if (_sg_mc_sparse_checkpoint)
+ return sparse_region(type, start_addr, permanent_addr, size);
+ else
+ return dense_region(type, start_addr, permanent_addr, size);
+}
+
+RegionSnapshot sparse_region(RegionType region_type, void* start_addr, void* permanent_addr, size_t size)
+{
+ simgrid::mc::RemoteClient* process = &mc_model_checker->process();
+ assert(process != nullptr);
+
+ xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page");
+ xbt_assert((((uintptr_t)permanent_addr) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page");
+ size_t page_count = simgrid::mc::mmu::chunkCount(size);
+
+ simgrid::mc::ChunkedData page_data(mc_model_checker->page_store(), *process, RemotePtr<void>(permanent_addr),
+ page_count);
+
+ simgrid::mc::RegionSnapshot region(region_type, start_addr, permanent_addr, size);
+ region.page_data(std::move(page_data));
+ return region;
+}
+
+} // namespace mc
+} // namespace simgrid
#include "xbt/base.h"
#include "src/mc/AddressSpace.hpp"
-#include "src/mc/ChunkedData.hpp"
-#include "src/mc/PageStore.hpp"
#include "src/mc/remote/RemotePtr.hpp"
+#include "src/mc/sosp/ChunkedData.hpp"
+#include "src/mc/sosp/PageStore.hpp"
namespace simgrid {
namespace mc {
-enum class RegionType {
- Unknown = 0,
- Heap = 1,
- Data = 2
-};
+enum class RegionType { Unknown = 0, Heap = 1, Data = 2 };
-enum class StorageType {
- NoData = 0,
- Flat = 1,
- Chunked = 2,
- Privatized = 3
-};
+enum class StorageType { NoData = 0, Flat = 1, Chunked = 2, Privatized = 3 };
class Buffer {
private:
- enum class Type {
- Malloc,
- Mmap
- };
+ enum class Type { Malloc, Mmap };
void* data_ = nullptr;
std::size_t size_;
Type type_ = Type::Malloc;
Buffer(std::size_t size, Type type = Type::Malloc);
- Buffer(void* data, std::size_t size, Type type = Type::Malloc) :
- data_(data), size_(size), type_(type) {}
+ Buffer(void* data, std::size_t size, Type type = Type::Malloc) : data_(data), size_(size), type_(type) {}
+
public:
Buffer() = default;
void clear() noexcept;
~Buffer() noexcept { clear(); }
- static Buffer malloc(std::size_t size)
- {
- return Buffer(size, Type::Malloc);
- }
- static Buffer mmap(std::size_t size)
- {
- return Buffer(size, Type::Mmap);
- }
+ static Buffer malloc(std::size_t size) { return Buffer(size, Type::Malloc); }
+ static Buffer mmap(std::size_t size) { return Buffer(size, Type::Mmap); }
// No copy
Buffer(Buffer const& buffer) = delete;
Buffer& operator=(Buffer const& buffer) = delete;
// Move
- Buffer(Buffer&& that) noexcept
- : data_(that.data_), size_(that.size_), type_(that.type_)
+ Buffer(Buffer&& that) noexcept : data_(that.data_), size_(that.size_), type_(that.type_)
{
that.data_ = nullptr;
that.size_ = 0;
Buffer& operator=(Buffer&& that) noexcept
{
clear();
- data_ = that.data_;
- size_ = that.size_;
- type_ = that.type_;
+ data_ = that.data_;
+ size_ = that.size_;
+ type_ = that.type_;
that.data_ = nullptr;
that.size_ = 0;
that.type_ = Type::Malloc;
return *this;
}
- void* get() { return data_; }
- const void* get() const { return data_; }
+ void* get() { return data_; }
+ const void* get() const { return data_; }
std::size_t size() const { return size_; }
};
class RegionSnapshot {
public:
static const RegionType UnknownRegion = RegionType::Unknown;
- static const RegionType HeapRegion = RegionType::Heap;
- static const RegionType DataRegion = RegionType::Data;
+ static const RegionType HeapRegion = RegionType::Heap;
+ static const RegionType DataRegion = RegionType::Data;
+
private:
RegionType region_type_;
StorageType storage_type_;
simgrid::mc::ObjectInformation* object_info_;
/** @brief Virtual address of the region in the simulated process */
- void *start_addr_;
+ void* start_addr_;
/** @brief Size of the data region in bytes */
std::size_t size_;
* on the region of the global variables.
*
* */
- void *permanent_addr_;
+ void* permanent_addr_;
Buffer flat_data_;
ChunkedData page_numbers_;
std::vector<RegionSnapshot> privatized_regions_;
+
public:
- RegionSnapshot() :
- region_type_(UnknownRegion),
- storage_type_(StorageType::NoData),
- object_info_(nullptr),
- start_addr_(nullptr),
- size_(0),
- permanent_addr_(nullptr)
- {}
- RegionSnapshot(RegionType type, void *start_addr, void* permanent_addr, size_t size) :
- region_type_(type),
- storage_type_(StorageType::NoData),
- object_info_(nullptr),
- start_addr_(start_addr),
- size_(size),
- permanent_addr_(permanent_addr)
- {}
+ RegionSnapshot()
+ : region_type_(UnknownRegion)
+ , storage_type_(StorageType::NoData)
+ , object_info_(nullptr)
+ , start_addr_(nullptr)
+ , size_(0)
+ , permanent_addr_(nullptr)
+ {
+ }
+ RegionSnapshot(RegionType type, void* start_addr, void* permanent_addr, size_t size)
+ : region_type_(type)
+ , storage_type_(StorageType::NoData)
+ , object_info_(nullptr)
+ , start_addr_(start_addr)
+ , size_(size)
+ , permanent_addr_(permanent_addr)
+ {
+ }
~RegionSnapshot() = default;
RegionSnapshot(RegionSnapshot const&) = default;
RegionSnapshot& operator=(RegionSnapshot const&) = default;
}
RegionSnapshot& operator=(RegionSnapshot&& that)
{
- region_type_ = that.region_type_;
- storage_type_ = that.storage_type_;
- object_info_ = that.object_info_;
- start_addr_ = that.start_addr_;
- size_ = that.size_;
- permanent_addr_ = that.permanent_addr_;
- flat_data_ = std::move(that.flat_data_);
- page_numbers_ = std::move(that.page_numbers_);
+ region_type_ = that.region_type_;
+ storage_type_ = that.storage_type_;
+ object_info_ = that.object_info_;
+ start_addr_ = that.start_addr_;
+ size_ = that.size_;
+ permanent_addr_ = that.permanent_addr_;
+ flat_data_ = std::move(that.flat_data_);
+ page_numbers_ = std::move(that.page_numbers_);
privatized_regions_ = std::move(that.privatized_regions_);
that.clear();
return *this;
void clear()
{
- region_type_ = UnknownRegion;
+ region_type_ = UnknownRegion;
storage_type_ = StorageType::NoData;
privatized_regions_.clear();
page_numbers_.clear();
flat_data_.clear();
- object_info_ = nullptr;
- start_addr_ = nullptr;
- size_ = 0;
+ object_info_ = nullptr;
+ start_addr_ = nullptr;
+ size_ = 0;
permanent_addr_ = nullptr;
}
void flat_data(Buffer data)
{
storage_type_ = StorageType::Flat;
- flat_data_ = std::move(data);
+ flat_data_ = std::move(data);
page_numbers_.clear();
privatized_regions_.clear();
}
const Buffer& flat_data() const { return flat_data_; }
- Buffer& flat_data() { return flat_data_; }
+ Buffer& flat_data() { return flat_data_; }
void page_data(ChunkedData page_data)
{
page_numbers_.clear();
privatized_regions_ = std::move(data);
}
- std::vector<RegionSnapshot> const& privatized_data() const
- {
- return privatized_regions_;
- }
- std::vector<RegionSnapshot>& privatized_data()
- {
- return privatized_regions_;
- }
+ std::vector<RegionSnapshot> const& privatized_data() const { return privatized_regions_; }
+ std::vector<RegionSnapshot>& privatized_data() { return privatized_regions_; }
simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
StorageType storage_type() const { return storage_type_; }
RegionType region_type() const { return region_type_; }
- bool contain(RemotePtr<void> p) const
- {
- return p >= start() && p < end();
- }
+ bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
};
-RegionSnapshot privatized_region(
- RegionType region_type, void *start_addr, void* permanent_addr,
- std::size_t size);
-RegionSnapshot dense_region(
- RegionType type, void *start_addr, void* data_addr, std::size_t size);
-simgrid::mc::RegionSnapshot sparse_region(
- RegionType type, void *start_addr, void* data_addr, std::size_t size);
-simgrid::mc::RegionSnapshot region(
- RegionType type, void *start_addr, void* data_addr, std::size_t size);
-
-}
-}
+RegionSnapshot privatized_region(RegionType region_type, void* start_addr, void* permanent_addr, std::size_t size);
+RegionSnapshot dense_region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
+simgrid::mc::RegionSnapshot sparse_region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
+simgrid::mc::RegionSnapshot region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
+
+} // namespace mc
+} // namespace simgrid
typedef simgrid::mc::RegionSnapshot s_mc_mem_region_t;
typedef s_mc_mem_region_t* mc_mem_region_t;
-/* Copyright (c) 2008-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2008-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/simix/smx_private.hpp"
-#include <libunwind.h>
#include <libelf.h>
+#include <libunwind.h>
#include "src/mc/mc_private.hpp"
#include <mc/mc.h>
#include "src/mc/mc_hash.hpp"
#include "src/mc/mc_mmu.hpp"
#include "src/mc/mc_smx.hpp"
-#include "src/mc/mc_snapshot.hpp"
#include "src/mc/mc_unw.hpp"
#include "src/mc/remote/mc_protocol.h"
+#include "src/mc/sosp/mc_snapshot.hpp"
-#include "src/mc/RegionSnapshot.hpp"
-#include "src/mc/ObjectInformation.hpp"
#include "src/mc/Frame.hpp"
+#include "src/mc/ObjectInformation.hpp"
#include "src/mc/Variable.hpp"
+#include "src/mc/sosp/RegionSnapshot.hpp"
using simgrid::mc::remote;
*/
static void restore(mc_mem_region_t region)
{
- switch(region->storage_type()) {
- case simgrid::mc::StorageType::Flat:
- mc_model_checker->process().write_bytes(region->flat_data().get(),
- region->size(), region->permanent_address());
- break;
-
- case simgrid::mc::StorageType::Chunked:
- mc_region_restore_sparse(&mc_model_checker->process(), region);
- break;
-
- case simgrid::mc::StorageType::Privatized:
- for (auto& p : region->privatized_data())
- restore(&p);
- break;
-
- default: // includes StorageType::NoData
- xbt_die("Storage type not supported");
- break;
+ switch (region->storage_type()) {
+ case simgrid::mc::StorageType::Flat:
+ mc_model_checker->process().write_bytes(region->flat_data().get(), region->size(), region->permanent_address());
+ break;
+
+ case simgrid::mc::StorageType::Chunked:
+ mc_region_restore_sparse(&mc_model_checker->process(), region);
+ break;
+
+ case simgrid::mc::StorageType::Privatized:
+ for (auto& p : region->privatized_data())
+ restore(&p);
+ break;
+
+ default: // includes StorageType::NoData
+ xbt_die("Storage type not supported");
+ break;
}
}
#if HAVE_SMPI
-RegionSnapshot privatized_region(
- RegionType region_type, void *start_addr, void* permanent_addr,
- std::size_t size
- )
+RegionSnapshot privatized_region(RegionType region_type, void* start_addr, void* permanent_addr, std::size_t size)
{
size_t process_count = MC_smpi_process_count();
// Read smpi_privatization_regions from MCed:
smpi_privatization_region_t remote_smpi_privatization_regions;
- mc_model_checker->process().read_variable(
- "smpi_privatization_regions",
- &remote_smpi_privatization_regions, sizeof(remote_smpi_privatization_regions));
+ mc_model_checker->process().read_variable("smpi_privatization_regions", &remote_smpi_privatization_regions,
+ sizeof(remote_smpi_privatization_regions));
s_smpi_privatization_region_t privatization_regions[process_count];
- mc_model_checker->process().read_bytes(
- &privatization_regions, sizeof(privatization_regions),
- remote(remote_smpi_privatization_regions));
+ mc_model_checker->process().read_bytes(&privatization_regions, sizeof(privatization_regions),
+ remote(remote_smpi_privatization_regions));
std::vector<simgrid::mc::RegionSnapshot> data;
data.reserve(process_count);
for (size_t i = 0; i < process_count; i++)
- data.push_back(simgrid::mc::region(region_type, start_addr,
- privatization_regions[i].address, size));
+ data.push_back(simgrid::mc::region(region_type, start_addr, privatization_regions[i].address, size));
- simgrid::mc::RegionSnapshot region = simgrid::mc::RegionSnapshot(
- region_type, start_addr, permanent_addr, size);
+ simgrid::mc::RegionSnapshot region = simgrid::mc::RegionSnapshot(region_type, start_addr, permanent_addr, size);
region.privatized_data(std::move(data));
return region;
}
#endif
-static
-void add_region(int index, simgrid::mc::Snapshot* snapshot,
- simgrid::mc::RegionType type,
- simgrid::mc::ObjectInformation* object_info,
- void *start_addr, void* permanent_addr,
- std::size_t size)
+static void add_region(int index, simgrid::mc::Snapshot* snapshot, simgrid::mc::RegionType type,
+ simgrid::mc::ObjectInformation* object_info, void* start_addr, void* permanent_addr,
+ std::size_t size)
{
if (type == simgrid::mc::RegionType::Data)
xbt_assert(object_info, "Missing object info for object.");
simgrid::mc::RegionSnapshot region;
#if HAVE_SMPI
- const bool privatization_aware = object_info
- && mc_model_checker->process().privatized(*object_info);
+ const bool privatization_aware = object_info && mc_model_checker->process().privatized(*object_info);
if (privatization_aware && MC_smpi_process_count())
- region = simgrid::mc::privatized_region(
- type, start_addr, permanent_addr, size);
+ region = simgrid::mc::privatized_region(type, start_addr, permanent_addr, size);
else
#endif
region = simgrid::mc::region(type, start_addr, permanent_addr, size);
region.object_info(object_info);
- snapshot->snapshot_regions[index]
- = std::unique_ptr<simgrid::mc::RegionSnapshot>(
- new simgrid::mc::RegionSnapshot(std::move(region)));
+ snapshot->snapshot_regions[index] =
+ std::unique_ptr<simgrid::mc::RegionSnapshot>(new simgrid::mc::RegionSnapshot(std::move(region)));
}
static void get_memory_regions(simgrid::mc::RemoteClient* process, simgrid::mc::Snapshot* snapshot)
snapshot->snapshot_regions.resize(n + 1);
int i = 0;
for (auto const& object_info : process->object_infos)
- add_region(i++, snapshot, simgrid::mc::RegionType::Data,
- object_info.get(),
- object_info->start_rw, object_info->start_rw,
- object_info->end_rw - object_info->start_rw);
+ add_region(i++, snapshot, simgrid::mc::RegionType::Data, object_info.get(), object_info->start_rw,
+ object_info->start_rw, object_info->end_rw - object_info->start_rw);
xbt_mheap_t heap = process->get_heap();
- void *start_heap = heap->base;
- void *end_heap = heap->breakval;
+ void* start_heap = heap->base;
+ void* end_heap = heap->breakval;
- add_region(n, snapshot, simgrid::mc::RegionType::Heap, nullptr,
- start_heap, start_heap,
- (char *) end_heap - (char *) start_heap);
- snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote(
- heap->heaplimit,
- process->get_malloc_info());
+ add_region(n, snapshot, simgrid::mc::RegionType::Heap, nullptr, start_heap, start_heap,
+ (char*)end_heap - (char*)start_heap);
+ snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote(heap->heaplimit, process->get_malloc_info());
#if HAVE_SMPI
if (mc_model_checker->process().privatized() && MC_smpi_process_count())
// snapshot->privatization_index = smpi_loaded_page
- mc_model_checker->process().read_variable(
- "smpi_loaded_page", &snapshot->privatization_index,
- sizeof(snapshot->privatization_index));
+ mc_model_checker->process().read_variable("smpi_loaded_page", &snapshot->privatization_index,
+ sizeof(snapshot->privatization_index));
else
#endif
snapshot->privatization_index = simgrid::mc::ProcessIndexMissing;
/** \brief Fills the position of the segments (executable, read-only, read/write).
* */
// TODO, use the ELF segment information for more robustness
-void find_object_address(
- std::vector<simgrid::xbt::VmMap> const& maps,
- simgrid::mc::ObjectInformation* result)
+void find_object_address(std::vector<simgrid::xbt::VmMap> const& maps, simgrid::mc::ObjectInformation* result)
{
std::string name = simgrid::xbt::Path(result->file_name).get_base_name();
// This is the non-GNU_RELRO-part of the data segment:
if (reg.prot == PROT_RW) {
xbt_assert(not result->start_rw, "Multiple read-write segments for %s, not supported", maps[i].pathname.c_str());
- result->start_rw = (char*) reg.start_addr;
- result->end_rw = (char*) reg.end_addr;
+ result->start_rw = (char*)reg.start_addr;
+ result->end_rw = (char*)reg.end_addr;
// The next VMA might be end of the data segment:
- if (i + 1 < maps.size()
- && maps[i + 1].pathname.empty()
- && maps[i + 1].prot == PROT_RW
- && maps[i + 1].start_addr == reg.end_addr)
- result->end_rw = (char*) maps[i + 1].end_addr;
+ if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW &&
+ maps[i + 1].start_addr == reg.end_addr)
+ result->end_rw = (char*)maps[i + 1].end_addr;
}
// This is the text segment:
else if (reg.prot == PROT_RX) {
xbt_assert(not result->start_exec, "Multiple executable segments for %s, not supported",
maps[i].pathname.c_str());
- result->start_exec = (char*) reg.start_addr;
- result->end_exec = (char*) reg.end_addr;
+ result->start_exec = (char*)reg.start_addr;
+ result->end_exec = (char*)reg.end_addr;
// The next VMA might be end of the data segment:
- if (i + 1 < maps.size()
- && maps[i + 1].pathname.empty()
- && maps[i + 1].prot == PROT_RW
- && maps[i + 1].start_addr == reg.end_addr) {
- result->start_rw = (char*) maps[i + 1].start_addr;
- result->end_rw = (char*) maps[i + 1].end_addr;
+ if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW &&
+ maps[i + 1].start_addr == reg.end_addr) {
+ result->start_rw = (char*)maps[i + 1].start_addr;
+ result->end_rw = (char*)maps[i + 1].end_addr;
}
}
// This is the GNU_RELRO-part of the data segment:
else if (reg.prot == PROT_READ) {
xbt_assert(not result->start_ro, "Multiple read only segments for %s, not supported", maps[i].pathname.c_str());
- result->start_ro = (char*) reg.start_addr;
- result->end_ro = (char*) reg.end_addr;
+ result->start_ro = (char*)reg.start_addr;
+ result->end_ro = (char*)reg.end_addr;
}
}
result->start = result->start_rw;
- if ((const void*) result->start_ro < result->start)
+ if ((const void*)result->start_ro < result->start)
result->start = result->start_ro;
- if ((const void*) result->start_exec < result->start)
+ if ((const void*)result->start_exec < result->start)
result->start = result->start_exec;
result->end = result->end_rw;
- if (result->end_ro && (const void*) result->end_ro > result->end)
+ if (result->end_ro && (const void*)result->end_ro > result->end)
result->end = result->end_ro;
- if (result->end_exec && (const void*) result->end_exec > result->end)
+ if (result->end_exec && (const void*)result->end_exec > result->end)
result->end = result->end_exec;
xbt_assert(result->start_exec || result->start_rw || result->start_ro);
* \param ip Instruction pointer
* \return true if the variable is valid
* */
-static bool valid_variable(simgrid::mc::Variable* var,
- simgrid::mc::Frame* scope,
- const void *ip)
+static bool valid_variable(simgrid::mc::Variable* var, simgrid::mc::Frame* scope, const void* ip)
{
// The variable is not yet valid:
- if (scope->range.begin() + var->start_scope > (std::uint64_t) ip)
+ if (scope->range.begin() + var->start_scope > (std::uint64_t)ip)
return false;
else
return true;
int region_type;
// FIXME, get rid of `region_type`
- if ((long) stack_frame->ip > (long) process->libsimgrid_info->start_exec)
+ if ((long)stack_frame->ip > (long)process->libsimgrid_info->start_exec)
region_type = 1;
else
region_type = 2;
s_local_variable_t new_var;
new_var.subprogram = stack_frame->frame;
- new_var.ip = stack_frame->ip;
- new_var.name = current_variable.name;
- new_var.type = current_variable.type;
- new_var.region = region_type;
- new_var.address = nullptr;
+ new_var.ip = stack_frame->ip;
+ new_var.name = current_variable.name;
+ new_var.type = current_variable.type;
+ new_var.region = region_type;
+ new_var.address = nullptr;
if (current_variable.address != nullptr)
new_var.address = current_variable.address;
else if (not current_variable.location_list.empty()) {
- simgrid::dwarf::Location location =
- simgrid::dwarf::resolve(
- current_variable.location_list,
- current_variable.object_info,
- &(stack_frame->unw_cursor),
- (void *) stack_frame->frame_base,
- &mc_model_checker->process(), process_index);
+ simgrid::dwarf::Location location = simgrid::dwarf::resolve(
+ current_variable.location_list, current_variable.object_info, &(stack_frame->unw_cursor),
+ (void*)stack_frame->frame_base, &mc_model_checker->process(), process_index);
if (not location.in_memory())
xbt_die("Cannot handle non-address variable");
// Recursive processing of nested scopes:
for (simgrid::mc::Frame& nested_scope : scope->scopes)
- fill_local_variables_values(
- stack_frame, &nested_scope, process_index, result);
+ fill_local_variables_values(stack_frame, &nested_scope, process_index, result);
}
static std::vector<s_local_variable_t> get_local_variables_values(std::vector<s_mc_stack_frame_t>& stack_frames,
// TODO, check condition check (unw_init_local==0 means end of frame)
- while (1) {
+ while (1) {
- s_mc_stack_frame_t stack_frame;
+ s_mc_stack_frame_t stack_frame;
- stack_frame.unw_cursor = c;
+ stack_frame.unw_cursor = c;
- unw_word_t ip;
- unw_word_t sp;
+ unw_word_t ip;
+ unw_word_t sp;
- unw_get_reg(&c, UNW_REG_IP, &ip);
- unw_get_reg(&c, UNW_REG_SP, &sp);
+ unw_get_reg(&c, UNW_REG_IP, &ip);
+ unw_get_reg(&c, UNW_REG_SP, &sp);
- stack_frame.ip = ip;
- stack_frame.sp = sp;
+ stack_frame.ip = ip;
+ stack_frame.sp = sp;
- // TODO, use real addresses in frame_t instead of fixing it here
+ // TODO, use real addresses in frame_t instead of fixing it here
- simgrid::mc::Frame* frame = process->find_function(remote(ip));
- stack_frame.frame = frame;
+ simgrid::mc::Frame* frame = process->find_function(remote(ip));
+ stack_frame.frame = frame;
- if (frame) {
- stack_frame.frame_name = frame->name;
- stack_frame.frame_base =
- (unw_word_t) frame->frame_base(c);
- } else {
- stack_frame.frame_base = 0;
- stack_frame.frame_name = std::string();
- }
+ if (frame) {
+ stack_frame.frame_name = frame->name;
+ stack_frame.frame_base = (unw_word_t)frame->frame_base(c);
+ } else {
+ stack_frame.frame_base = 0;
+ stack_frame.frame_name = std::string();
+ }
- result.push_back(std::move(stack_frame));
+ result.push_back(std::move(stack_frame));
- /* Stop before context switch with maestro */
- if (frame != nullptr &&
- frame->name == "smx_ctx_sysv_wrapper")
- break;
+ /* Stop before context switch with maestro */
+ if (frame != nullptr && frame->name == "smx_ctx_sysv_wrapper")
+ break;
- int ret = unw_step(&c);
- if (ret == 0)
- xbt_die("Unexpected end of stack.");
- else if (ret < 0)
- xbt_die("Error while unwinding stack");
- }
+ int ret = unw_step(&c);
+ if (ret == 0)
+ xbt_die("Unexpected end of stack.");
+ else if (ret < 0)
+ xbt_die("Error while unwinding stack");
+ }
if (result.empty()) {
XBT_INFO("unw_init_local failed");
// Read the context from remote process:
unw_context_t context;
- mc_model_checker->process().read_bytes(
- &context, sizeof(context), remote(stack.context));
+ mc_model_checker->process().read_bytes(&context, sizeof(context), remote(stack.context));
st.context.initialize(&mc_model_checker->process(), &context);
- st.stack_frames = unwind_stack_frames(&st.context);
+ st.stack_frames = unwind_stack_frames(&st.context);
st.local_variables = get_local_variables_values(st.stack_frames, stack.process_index);
- st.process_index = stack.process_index;
+ st.process_index = stack.process_index;
unw_word_t sp = st.stack_frames[0].sp;
res.push_back(std::move(st));
- size_t stack_size =
- (char*) stack.address + stack.size - (char*) sp;
+ size_t stack_size = (char*)stack.address + stack.size - (char*)sp;
snapshot->stack_sizes.push_back(stack_size);
}
return res;
-
}
static void snapshot_handle_ignore(simgrid::mc::Snapshot* snapshot)
ignored_data.start = (void*)region.addr;
ignored_data.data.resize(region.size);
// TODO, we should do this once per privatization segment:
- snapshot->process()->read_bytes(
- ignored_data.data.data(), region.size, remote(region.addr),
- simgrid::mc::ProcessIndexDisabled);
+ snapshot->process()->read_bytes(ignored_data.data.data(), region.size, remote(region.addr),
+ simgrid::mc::ProcessIndexDisabled);
snapshot->ignored_data.push_back(std::move(ignored_data));
}
// Zero the memory:
for (auto const& region : mc_model_checker->process().ignored_regions())
snapshot->process()->clear_bytes(remote(region.addr), region.size);
-
}
static void snapshot_ignore_restore(simgrid::mc::Snapshot* snapshot)
{
for (auto const& ignored_data : snapshot->ignored_data)
- snapshot->process()->write_bytes(
- ignored_data.data.data(), ignored_data.data.size(),
- remote(ignored_data.start));
+ snapshot->process()->write_bytes(ignored_data.data.data(), ignored_data.data.size(), remote(ignored_data.start));
}
static std::vector<s_fd_infos_t> get_current_fds(pid_t pid)
{
const size_t fd_dir_path_size = 20;
char fd_dir_path[fd_dir_path_size];
- int res = snprintf(fd_dir_path, fd_dir_path_size,
- "/proc/%lli/fd", (long long int) pid);
+ int res = snprintf(fd_dir_path, fd_dir_path_size, "/proc/%lli/fd", (long long int)pid);
xbt_assert(res >= 0);
- if ((size_t) res > fd_dir_path_size)
+ if ((size_t)res > fd_dir_path_size)
xbt_die("Unexpected buffer is too small for fd_dir_path");
DIR* fd_dir = opendir(fd_dir_path);
int fd_value = xbt_str_parse_int(fd_number->d_name, "Found a non-numerical FD: %s. Freaking out!");
- if(fd_value < 3)
+ if (fd_value < 3)
continue;
const size_t source_size = 25;
char source[25];
- int res = snprintf(source, source_size, "/proc/%lli/fd/%s",
- (long long int) pid, fd_number->d_name);
+ int res = snprintf(source, source_size, "/proc/%lli/fd/%s", (long long int)pid, fd_number->d_name);
xbt_assert(res >= 0);
- if ((size_t) res > source_size)
+ if ((size_t)res > source_size)
xbt_die("Unexpected buffer is too small for fd %s", fd_number->d_name);
const size_t link_size = 200;
char link[200];
res = readlink(source, link, link_size);
- if (res<0)
+ if (res < 0)
xbt_die("Could not read link for %s", source);
- if (res==200)
+ if (res == 200)
xbt_die("Buffer to small for link of %s", source);
link[res] = '\0';
#if HAVE_SMPI
- if(smpi_is_privatization_file(link))
+ if (smpi_is_privatization_file(link))
continue;
#endif
// This is (probably) the DIR* we are reading:
// TODO, read all the file entries at once and close the DIR.*
- if(strcmp(fd_dir_path, link) == 0)
+ if (strcmp(fd_dir_path, link) == 0)
continue;
// We don't handle them.
}
// This is probably a shared memory used by lttng-ust:
- if(strncmp("/dev/shm/ust-shm-tmp-", link, std::strlen("/dev/shm/ust-shm-tmp-"))==0)
+ if (strncmp("/dev/shm/ust-shm-tmp-", link, std::strlen("/dev/shm/ust-shm-tmp-")) == 0)
continue;
// Add an entry for this FD in the snapshot:
s_fd_infos_t fd;
- fd.filename = std::string(link);
- fd.number = fd_value;
- fd.flags = fcntl(fd_value, F_GETFL) | fcntl(fd_value, F_GETFD) ;
+ fd.filename = std::string(link);
+ fd.number = fd_value;
+ fd.flags = fcntl(fd_value, F_GETFL) | fcntl(fd_value, F_GETFD);
fd.current_position = lseek(fd_value, 0, SEEK_CUR);
fds.push_back(std::move(fd));
}
- closedir (fd_dir);
+ closedir(fd_dir);
return fds;
}
std::shared_ptr<simgrid::mc::Snapshot> snapshot = std::make_shared<simgrid::mc::Snapshot>(mc_process, num_state);
for (auto const& p : mc_model_checker->process().actors())
- snapshot->enabled_processes.insert(p.copy.getBuffer()->pid);
+ snapshot->enabled_processes.insert(p.copy.getBuffer()->pid_);
snapshot_handle_ignore(snapshot.get());
return snapshot;
}
-static inline
-void restore_snapshot_regions(simgrid::mc::Snapshot* snapshot)
+static inline void restore_snapshot_regions(simgrid::mc::Snapshot* snapshot)
{
for (std::unique_ptr<s_mc_mem_region_t> const& region : snapshot->snapshot_regions) {
// For privatized, variables we decided it was not necessary to take the snapshot:
}
#if HAVE_SMPI
- if(snapshot->privatization_index >= 0) {
+ if (snapshot->privatization_index >= 0) {
// Fix the privatization mmap:
s_mc_message_restore_t message{MC_MESSAGE_RESTORE, snapshot->privatization_index};
mc_model_checker->process().getChannel().send(message);
#endif
}
-static inline
-void restore_snapshot_fds(simgrid::mc::Snapshot* snapshot)
+static inline void restore_snapshot_fds(simgrid::mc::Snapshot* snapshot)
{
xbt_die("FD snapshot not implemented in client/server mode.");
mc_model_checker->process().clear_cache();
}
-}
-}
-
+} // namespace mc
+} // namespace simgrid
-/* Copyright (c) 2014-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2014-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
/* MC interface: definitions that non-MC modules must see, but not the user */
-
#include <unistd.h> // pread, pwrite
-#include "src/mc/PageStore.hpp"
#include "src/mc/mc_mmu.hpp"
#include "src/mc/mc_private.hpp"
-#include "src/mc/mc_snapshot.hpp"
+#include "src/mc/sosp/PageStore.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
+#include "src/mc/sosp/ChunkedData.hpp"
#include <xbt/mmalloc.h>
-#include "src/mc/ChunkedData.hpp"
using simgrid::mc::remote;
{
for (size_t i = 0; i != pages_copy.page_count(); ++i) {
// Otherwise, copy the page:
- void* target_page = (void*) simgrid::mc::mmu::join(i, (std::uintptr_t) start_addr);
+ void* target_page = (void*)simgrid::mc::mmu::join(i, (std::uintptr_t)start_addr);
const void* source_page = pages_copy.page(i);
process->write_bytes(source_page, xbt_pagesize, remote(target_page));
}
void mc_region_restore_sparse(simgrid::mc::RemoteClient* process, mc_mem_region_t reg)
{
- xbt_assert(((reg->permanent_address().address()) & (xbt_pagesize-1)) == 0,
- "Not at the beginning of a page");
+ xbt_assert(((reg->permanent_address().address()) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page");
xbt_assert(simgrid::mc::mmu::chunkCount(reg->size()) == reg->page_data().page_count());
- mc_restore_page_snapshot_region(process,
- (void*) reg->permanent_address().address(), reg->page_data());
+ mc_restore_page_snapshot_region(process, (void*)reg->permanent_address().address(), reg->page_data());
}
--- /dev/null
+/* Copyright (c) 2014-2018. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <cstddef>
+
+#include <memory>
+#include <utility>
+
+#include "xbt/asserts.h"
+#include "xbt/sysdep.h"
+
+#include "src/internal_config.h"
+#include "src/smpi/include/private.hpp"
+
+#include "src/mc/mc_mmu.hpp"
+#include "src/mc/mc_private.hpp"
+#include "src/mc/sosp/PageStore.hpp"
+#include "src/mc/sosp/mc_snapshot.hpp"
+
+/** @brief Find the snapshoted region from a pointer
+ *
+ * @param addr Pointer
+ * @param snapshot Snapshot
+ * @param Snapshot region in the snapshot this pointer belongs to
+ * (or nullptr if it does not belong to any snapshot region)
+ * */
+mc_mem_region_t mc_get_snapshot_region(const void* addr, const simgrid::mc::Snapshot* snapshot, int process_index)
+{
+ size_t n = snapshot->snapshot_regions.size();
+ for (size_t i = 0; i != n; ++i) {
+ mc_mem_region_t region = snapshot->snapshot_regions[i].get();
+ if (not(region && region->contain(simgrid::mc::remote(addr))))
+ continue;
+
+ if (region->storage_type() == simgrid::mc::StorageType::Privatized) {
+#if HAVE_SMPI
+ // Use the current process index of the snapshot:
+ if (process_index == simgrid::mc::ProcessIndexDisabled)
+ process_index = snapshot->privatization_index;
+ if (process_index < 0)
+ xbt_die("Missing process index");
+ if (process_index >= (int)region->privatized_data().size())
+ xbt_die("Invalid process index");
+ simgrid::mc::RegionSnapshot& priv_region = region->privatized_data()[process_index];
+ xbt_assert(priv_region.contain(simgrid::mc::remote(addr)));
+ return &priv_region;
+#else
+ xbt_die("Privatized region in a non SMPI build (this should not happen)");
+#endif
+ }
+
+ return region;
+ }
+
+ return nullptr;
+}
+
+/** @brief Read memory from a snapshot region broken across fragmented pages
+ *
+ * @param addr Process (non-snapshot) address of the data
+ * @param region Snapshot memory region where the data is located
+ * @param target Buffer to store the value
+ * @param size Size of the data to read in bytes
+ * @return Pointer where the data is located (target buffer of original location)
+ */
+const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size)
+{
+ // Last byte of the memory area:
+ void* end = (char*)addr + size - 1;
+
+ // TODO, we assume the chunks are aligned to natural chunk boundaries.
+ // We should remove this assumption.
+
+ // Page of the last byte of the memory area:
+ size_t page_end = simgrid::mc::mmu::split((std::uintptr_t)end).first;
+
+ void* dest = target;
+
+ if (dest == nullptr)
+ xbt_die("Missing destination buffer for fragmented memory access");
+
+ // Read each page:
+ while (simgrid::mc::mmu::split((std::uintptr_t)addr).first != page_end) {
+ void* snapshot_addr = mc_translate_address_region_chunked((uintptr_t)addr, region);
+ void* next_page = (void*)simgrid::mc::mmu::join(simgrid::mc::mmu::split((std::uintptr_t)addr).first + 1, 0);
+ size_t readable = (char*)next_page - (char*)addr;
+ memcpy(dest, snapshot_addr, readable);
+ addr = (char*)addr + readable;
+ dest = (char*)dest + readable;
+ size -= readable;
+ }
+
+ // Read the end:
+ void* snapshot_addr = mc_translate_address_region_chunked((uintptr_t)addr, region);
+ memcpy(dest, snapshot_addr, size);
+
+ return target;
+}
+
+/** Compare memory between snapshots (with known regions)
+ *
+ * @param addr1 Address in the first snapshot
+ * @param snapshot2 Region of the address in the first snapshot
+ * @param addr2 Address in the second snapshot
+ * @param snapshot2 Region of the address in the second snapshot
+ * @return same as memcmp
+ * */
+int MC_snapshot_region_memcmp(const void* addr1, mc_mem_region_t region1, const void* addr2, mc_mem_region_t region2,
+ size_t size)
+{
+ // Using alloca() for large allocations may trigger stack overflow:
+ // use malloc if the buffer is too big.
+ bool stack_alloc = size < 64;
+ void* buffer1a = nullptr;
+ void* buffer2a = nullptr;
+ if (region1 != nullptr && region1->storage_type() != simgrid::mc::StorageType::Flat)
+ buffer1a = stack_alloc ? alloca(size) : ::operator new(size);
+ if (region2 != nullptr && region2->storage_type() != simgrid::mc::StorageType::Flat)
+ buffer2a = stack_alloc ? alloca(size) : ::operator new(size);
+ const void* buffer1 = MC_region_read(region1, buffer1a, addr1, size);
+ const void* buffer2 = MC_region_read(region2, buffer2a, addr2, size);
+ int res;
+ if (buffer1 == buffer2)
+ res = 0;
+ else
+ res = memcmp(buffer1, buffer2, size);
+ if (not stack_alloc) {
+ ::operator delete(buffer1a);
+ ::operator delete(buffer2a);
+ }
+ return res;
+}
+
+namespace simgrid {
+namespace mc {
+
+Snapshot::Snapshot(RemoteClient* process, int _num_state)
+ : AddressSpace(process)
+ , num_state(_num_state)
+ , heap_bytes_used(0)
+ , enabled_processes()
+ , privatization_index(0)
+ , hash(0)
+{
+}
+
+const void* Snapshot::read_bytes(void* buffer, std::size_t size, RemotePtr<void> address, int process_index,
+ ReadOptions options) const
+{
+ mc_mem_region_t region = mc_get_snapshot_region((void*)address.address(), this, process_index);
+ if (region) {
+ const void* res = MC_region_read(region, buffer, (void*)address.address(), size);
+ if (buffer == res || options & ReadOptions::lazy())
+ return res;
+ else {
+ memcpy(buffer, res, size);
+ return buffer;
+ }
+ } else
+ return this->process()->read_bytes(buffer, size, address, process_index, options);
+}
+
+} // namespace mc
+} // namespace simgrid
#define SIMGRID_MC_SNAPSHOT_HPP
#include "src/mc/ModelChecker.hpp"
-#include "src/mc/RegionSnapshot.hpp"
#include "src/mc/mc_unw.hpp"
#include "src/mc/remote/RemoteClient.hpp"
+#include "src/mc/sosp/RegionSnapshot.hpp"
// ***** Snapshot region
std::vector<s_mc_snapshot_ignored_data_t> ignored_data;
std::vector<s_fd_infos_t> current_fds;
};
-}
-}
+} // namespace mc
+} // namespace simgrid
static XBT_ALWAYS_INLINE mc_mem_region_t mc_get_region_hinted(void* addr, simgrid::mc::Snapshot* snapshot,
int process_index, mc_mem_region_t region)
XBT_PRIVATE std::shared_ptr<simgrid::mc::Snapshot> take_snapshot(int num_state);
XBT_PRIVATE void restore_snapshot(std::shared_ptr<simgrid::mc::Snapshot> snapshot);
-}
-}
+} // namespace mc
+} // namespace simgrid
XBT_PRIVATE void mc_restore_page_snapshot_region(simgrid::mc::RemoteClient* process, void* start_addr,
simgrid::mc::ChunkedData const& pagenos);
#include <xbt/ex.hpp>
+#include "simgrid/s4u/Mailbox.hpp"
#include "src/instr/instr_private.hpp"
#include "src/kernel/activity/ExecImpl.hpp"
#include "src/msg/msg_private.hpp"
/*************************************************************/
XBT_PRIVATE void MSG_process_cleanup_from_SIMIX(smx_actor_t smx_proc);
-XBT_PRIVATE smx_actor_t MSG_process_create_from_SIMIX(const char* name, std::function<void()> code, void* data,
+XBT_PRIVATE smx_actor_t MSG_process_create_from_SIMIX(const char* name, simgrid::simix::ActorCode code, void* data,
sg_host_t host,
std::unordered_map<std::string, std::string>* properties,
smx_actor_t parent_process);
msg_actor = (simgrid::msg::ActorExt*)SIMIX_process_self_get_data();
SIMIX_process_self_set_data(nullptr);
} else {
- msg_actor = (simgrid::msg::ActorExt*)smx_actor->getUserData();
+ msg_actor = (simgrid::msg::ActorExt*)smx_actor->get_user_data();
simcall_process_set_data(smx_actor, nullptr);
}
}
/* This function creates a MSG process. It has the prototype enforced by SIMIX_function_register_process_create */
-smx_actor_t MSG_process_create_from_SIMIX(const char* name, std::function<void()> code, void* data, sg_host_t host,
+smx_actor_t MSG_process_create_from_SIMIX(const char* name, simgrid::simix::ActorCode code, void* data, sg_host_t host,
std::unordered_map<std::string, std::string>* properties,
smx_actor_t /*parent_process*/)
{
msg_process_t MSG_process_create_with_environment(const char *name, xbt_main_func_t code, void *data, msg_host_t host,
int argc, char **argv, xbt_dict_t properties)
{
- std::function<void()> function;
+ simgrid::simix::ActorCode function;
if (code)
function = simgrid::xbt::wrap_main(code, argc, static_cast<const char* const*>(argv));
return res;
}
-msg_process_t MSG_process_create_from_stdfunc(const char* name, std::function<void()> code, void* data, msg_host_t host,
+msg_process_t MSG_process_create_from_stdfunc(const char* name, simgrid::simix::ActorCode code, void* data, msg_host_t host,
std::unordered_map<std::string, std::string>* properties)
{
xbt_assert(code != nullptr && host != nullptr, "Invalid parameters: host and code params must not be nullptr");
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
/* get from SIMIX the MSG process data, and then the user data */
- simgrid::msg::ActorExt* msgExt = (simgrid::msg::ActorExt*)process->get_impl()->getUserData();
+ simgrid::msg::ActorExt* msgExt = (simgrid::msg::ActorExt*)process->get_impl()->get_user_data();
if (msgExt)
return msgExt->data;
else
{
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
- static_cast<simgrid::msg::ActorExt*>(process->get_impl()->getUserData())->data = data;
+ static_cast<simgrid::msg::ActorExt*>(process->get_impl()->get_user_data())->data = data;
return MSG_OK;
}
int MSG_process_self_PID()
{
smx_actor_t self = SIMIX_process_self();
- return self == nullptr ? 0 : self->pid;
+ return self == nullptr ? 0 : self->pid_;
}
/** \ingroup m_process_management
}
smx_context_t MSG_process_get_smx_ctx(msg_process_t process) { // deprecated -- smx_context_t should die afterward
- return process->get_impl()->context;
+ return process->get_impl()->context_;
}
/**
* \ingroup m_process_management
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/plugins/live_migration.h"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
namespace simgrid {
/** \brief Write into a file (local or remote)
*
* \param size of the file to write
- * \param fd is a the file descriptor
* \return the number of bytes successfully write or -1 if an error occurred
*/
sg_size_t File::write(sg_size_t size)
#include "simgrid/plugins/energy.h"
#include "simgrid/plugins/load.h"
#include "simgrid/s4u/Engine.hpp"
+#include "src/include/surf/surf.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/surf/cpu_interface.hpp"
double power_slope = 0;
if (cpu_load > 0) { /* Something is going on, the machine is not idle */
- double min_power = range.min_;
- double max_power = range.max_;
+ min_power = range.min_;
+ max_power = range.max_;
/**
* The min_power states how much we consume when only one single
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <simgrid/s4u.hpp>
#include "simgrid/plugins/load.h"
+#include "src/include/surf/surf.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include <simgrid/s4u.hpp>
/** @addtogroup plugin_load
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include "src/include/surf/surf.hpp"
#include "src/simix/ActorImpl.hpp"
#include "src/simix/smx_host_private.hpp"
-
-#include <xbt/asserts.h> // xbt_log_no_loc
+#include "xbt/asserts.h" // xbt_log_no_loc
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_vm, surf, "Logging specific to the SURF VM module");
{
if (get_state() != s4u::VirtualMachine::state::RUNNING)
THROWF(vm_error, 0, "Cannot suspend VM %s: it is not running.", piface_->get_cname());
- if (issuer->host == piface_)
+ if (issuer->host_ == piface_)
THROWF(vm_error, 0, "Actor %s cannot suspend the VM %s in which it runs", issuer->get_cname(),
piface_->get_cname());
- auto& process_list = piface_->extension<simgrid::simix::Host>()->process_list;
- XBT_DEBUG("suspend VM(%s), where %zu processes exist", piface_->get_cname(), process_list.size());
+ XBT_DEBUG("suspend VM(%s), where %zu processes exist", piface_->get_cname(), process_list_.size());
action_->suspend();
- for (auto& smx_process : process_list) {
- XBT_DEBUG("suspend %s", smx_process.name.c_str());
+ for (auto& smx_process : process_list_) {
+ XBT_DEBUG("suspend %s", smx_process.get_cname());
smx_process.suspend(issuer);
}
if (get_state() != s4u::VirtualMachine::state::SUSPENDED)
THROWF(vm_error, 0, "Cannot resume VM %s: it was not suspended", piface_->get_cname());
- auto& process_list = piface_->extension<simgrid::simix::Host>()->process_list;
- XBT_DEBUG("Resume VM %s, containing %zu processes.", piface_->get_cname(), process_list.size());
+ XBT_DEBUG("Resume VM %s, containing %zu processes.", piface_->get_cname(), process_list_.size());
action_->resume();
- for (auto& smx_process : process_list) {
+ for (auto& smx_process : process_list_) {
XBT_DEBUG("resume %s", smx_process.get_cname());
smx_process.resume();
}
XBT_VERB("Shutting down the VM %s even if it's not running but %s", piface_->get_cname(), stateName);
}
- auto& process_list = piface_->extension<simgrid::simix::Host>()->process_list;
- XBT_DEBUG("shutdown VM %s, that contains %zu processes", piface_->get_cname(), process_list.size());
+ XBT_DEBUG("shutdown VM %s, that contains %zu processes", piface_->get_cname(), process_list_.size());
- for (auto& smx_process : process_list) {
+ for (auto& smx_process : process_list_) {
XBT_DEBUG("kill %s@%s on behalf of %s which shutdown that VM.", smx_process.get_cname(),
- smx_process.host->get_cname(), issuer->get_cname());
+ smx_process.host_->get_cname(), issuer->get_cname());
SIMIX_process_kill(&smx_process, issuer);
}
#include "simgrid/s4u/Actor.hpp"
#include "simgrid/vm.h"
+#include "src/include/surf/surf.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/plugins/vm/VmHostExt.hpp"
#include "src/simix/smx_host_private.hpp"
surf_cpu_model_vm->create_cpu(this, &speeds, physical_host->get_core_count());
if (physical_host->get_pstate() != 0)
set_pstate(physical_host->get_pstate());
-
- /* Make a process container */
- extension_set<simgrid::simix::Host>(new simgrid::simix::Host());
}
VirtualMachine::~VirtualMachine()
XBT_DEBUG("destroy %s", get_cname());
- /* FIXME: this is really strange that everything fails if the next line is removed.
- * This is as if we shared these data with the PM, which definitely should not be the case...
- *
- * We need to test that suspending a VM does not suspends the processes running on its PM, for example.
- * Or we need to simplify this code enough to make it actually readable (but this sounds harder than testing)
- */
- extension_set<simgrid::simix::Host>(nullptr);
-
/* Don't free these things twice: they are the ones of my physical host */
pimpl_netpoint = nullptr;
}
#include "simgrid/s4u/Actor.hpp"
#include "simgrid/s4u/Exec.hpp"
#include "simgrid/s4u/Host.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/simix/smx_private.hpp"
+
#include <sstream>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors");
void Actor::set_auto_restart(bool autorestart)
{
- simgrid::simix::simcall([this, autorestart]() { pimpl_->auto_restart = autorestart; });
+ simgrid::simix::simcall([this, autorestart]() { pimpl_->set_auto_restart(autorestart); });
}
void Actor::on_exit(int_f_pvoid_pvoid_t fun, void* data) /* deprecated */
s4u::Host* Actor::get_host()
{
- return this->pimpl_->host;
+ return this->pimpl_->host_;
}
void Actor::daemonize()
bool Actor::is_daemon() const
{
- return this->pimpl_->isDaemon();
+ return this->pimpl_->is_daemon();
}
const simgrid::xbt::string& Actor::get_name() const
aid_t Actor::get_pid() const
{
- return this->pimpl_->pid;
+ return this->pimpl_->pid_;
}
aid_t Actor::get_ppid() const
{
- return this->pimpl_->ppid;
+ return this->pimpl_->ppid_;
}
void Actor::suspend()
s4u::Actor::on_resume(this);
}
-int Actor::is_suspended()
+bool Actor::is_suspended()
{
- return simgrid::simix::simcall([this] { return pimpl_->suspended; });
+ return simgrid::simix::simcall([this] { return pimpl_->suspended_; });
}
void Actor::set_kill_time(double time)
aid_t get_pid()
{
- return SIMIX_process_self()->pid;
+ return SIMIX_process_self()->pid_;
}
aid_t get_ppid()
{
- return SIMIX_process_self()->ppid;
+ return SIMIX_process_self()->ppid_;
}
std::string get_name()
Host* get_host()
{
- return SIMIX_process_self()->host;
+ return SIMIX_process_self()->host_;
}
void suspend()
bool is_suspended()
{
smx_actor_t process = SIMIX_process_self();
- return simgrid::simix::simcall([process] { return process->suspended; });
+ return simgrid::simix::simcall([process] { return process->suspended_; });
}
void kill()
smx_actor_t smx_proc = SIMIX_process_self();
if (smx_proc == nullptr)
xbt_die("Cannot call Host::current() from the maestro context");
- return smx_proc->host;
+ return smx_proc->host_;
}
void Host::turn_on()
{
if (is_off()) {
simgrid::simix::simcall([this] {
- this->extension<simgrid::simix::Host>()->turnOn();
+ this->pimpl_->turn_on();
this->pimpl_cpu->turn_on();
on_state_change(*this);
});
void Host::turn_off()
{
if (is_on()) {
- smx_actor_t self = SIMIX_process_self();
- simgrid::simix::simcall([this, self] {
- simgrid::simix::Host* host = this->extension<simgrid::simix::Host>();
-
- xbt_assert((host != nullptr), "Invalid parameters");
-
+ simgrid::simix::simcall([this] {
this->pimpl_cpu->turn_off();
-
- /* Clean Simulator data */
- if (not host->process_list.empty()) {
- for (auto& process : host->process_list) {
- SIMIX_process_kill(&process, self);
- XBT_DEBUG("Killing %s@%s on behalf of %s which turned off that host.", process.get_cname(),
- process.host->get_cname(), self->get_cname());
- }
- }
+ this->pimpl_->turn_off();
on_state_change(*this);
});
}
}
-bool Host::is_on()
+bool Host::is_on() const
{
return this->pimpl_cpu->is_on();
}
*/
std::vector<ActorPtr> Host::get_all_actors()
{
- std::vector<ActorPtr> res;
- for (auto& actor : this->extension<simgrid::simix::Host>()->process_list)
- res.push_back(actor.ciface());
- return res;
+ return pimpl_->get_all_actors();
}
/** @brief Returns how many actors (daemonized or not) have been launched on this host */
int Host::get_actor_count()
{
- return this->extension<simgrid::simix::Host>()->process_list.size();
+ return pimpl_->get_actor_count();
}
/** @deprecated */
void Host::getProcesses(std::vector<ActorPtr>* list)
{
- for (auto& actor : this->extension<simgrid::simix::Host>()->process_list) {
- list->push_back(actor.iface());
- }
+ auto actors = get_all_actors();
+ for (auto& actor : actors)
+ list->push_back(actor);
}
/** @deprecated */
void Host::actorList(std::vector<ActorPtr>* whereto)
{
- for (auto& actor : this->extension<simgrid::simix::Host>()->process_list) {
- whereto->push_back(actor.ciface());
- }
+ auto actors = get_all_actors();
+ for (auto& actor : actors)
+ whereto->push_back(actor);
}
/**
}
/** Retrieve the property value (or nullptr if not set) */
-const char* Host::get_property(const char* key)
+const char* Host::get_property(const char* key) const
{
return this->pimpl_->get_property(key);
}
}
/** @brief Get the peak processor speed (in flops/s), at the specified pstate */
-double Host::get_pstate_speed(int pstate_index)
+double Host::get_pstate_speed(int pstate_index) const
{
return simgrid::simix::simcall([this, pstate_index] { return this->pimpl_cpu->get_pstate_peak_speed(pstate_index); });
}
* The amount of flops per second available for computing depends on several things:
* - The current pstate determines the maximal peak computing speed (use @ref get_pstate_speed() to retrieve the
* computing speed you would get at another pstate)
- * - If you declared an external load, then this reduces the available computing speed (see @ref set_speed_trace())
+ * - If you declared an external load, then this reduces the available computing speed
+ * (see @ref simgrid::surf::Cpu::set_speed_trace())
*
* The remaining speed is then shared between the executions located on this host.
* You can retrieve the amount of tasks currently running on this host with @ref get_load().
*
* Finally, executions of priority 2 get twice the amount of flops than executions of priority 1.
*/
-double Host::get_speed()
+double Host::get_speed() const
{
return this->pimpl_cpu->get_speed(1.0);
}
/** @brief Returns the current computation load (in flops per second)
* The external load (coming from an availability trace) is not taken in account.
*/
-double Host::get_load()
+double Host::get_load() const
{
return this->pimpl_cpu->get_load();
}
/** @brief Get the available speed ratio, between 0 and 1.
*
- * This accounts for external load (see @ref set_speed_trace()).
+ * This accounts for external load (see @ref simgrid::surf::Cpu::set_speed_trace()).
*/
-double Host::get_available_speed()
+double Host::get_available_speed() const
{
return this->pimpl_cpu->get_speed_ratio();
}
/** @brief Returns the number of core of the processor. */
-int Host::get_core_count()
+int Host::get_core_count() const
{
return this->pimpl_cpu->get_core_count();
}
simgrid::simix::simcall([this, pstate_index] { this->pimpl_cpu->set_pstate(pstate_index); });
}
/** @brief Retrieve the pstate at which the host is currently running */
-int Host::get_pstate()
+int Host::get_pstate() const
{
return this->pimpl_cpu->get_pstate();
}
* \brief Returns the list of storages attached to an host.
* \return a vector containing all storages attached to the host
*/
-std::vector<const char*> Host::get_attached_storages()
+std::vector<const char*> Host::get_attached_storages() const
{
return simgrid::simix::simcall([this] { return this->pimpl_->get_attached_storages(); });
}
*/
void sg_host_get_actor_list(sg_host_t host, xbt_dynar_t whereto)
{
- for (auto& actor : host->extension<simgrid::simix::Host>()->process_list) {
- s4u_Actor* p = actor.ciface();
- xbt_dynar_push(whereto, &p);
- }
+ auto actors = host->get_all_actors();
+ for (auto& actor : actors)
+ xbt_dynar_push(whereto, &actor);
}
sg_host_t sg_host_self()
{
smx_actor_t process = SIMIX_process_self();
- return (process == nullptr) ? nullptr : process->host;
+ return (process == nullptr) ? nullptr : process->host_;
}
#include "simgrid/s4u/Comm.hpp"
#include "simgrid/s4u/Mailbox.hpp"
-#include "src/msg/msg_private.hpp"
-#include "src/simix/ActorImpl.hpp"
-#include "src/simix/smx_network_private.hpp"
-#include "xbt/log.h"
+#include "src/kernel/activity/MailboxImpl.hpp"
+#include <simgrid/mailbox.h>
XBT_LOG_EXTERNAL_CATEGORY(s4u);
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_channel, s4u, "S4U Communication Mailboxes");
#include "mc/mc.h"
#include "smx_private.hpp"
+#include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/kernel/activity/IoImpl.hpp"
#include "src/kernel/activity/SleepImpl.hpp"
#include "src/kernel/activity/SynchroRaw.hpp"
#include "src/simix/smx_host_private.hpp"
#include "src/simix/smx_io_private.hpp"
#include "src/simix/smx_synchro_private.hpp"
+#include "src/surf/HostImpl.hpp"
#include "src/surf/cpu_interface.hpp"
#include "xbt/ex.hpp"
*/
void SIMIX_process_cleanup(smx_actor_t process)
{
- XBT_DEBUG("Cleanup process %s (%p), waiting synchro %p", process->name.c_str(), process,
+ XBT_DEBUG("Cleanup process %s (%p), waiting synchro %p", process->get_cname(), process,
process->waiting_synchro.get());
- process->finished = true;
+ process->finished_ = true;
SIMIX_process_on_exit_runall(process);
/* Unregister from the kill timer if any */
}
XBT_DEBUG("%p should not be run anymore",process);
- simix_global->process_list.erase(process->pid);
- if (process->host && process->host_process_list_hook.is_linked())
- simgrid::xbt::intrusive_erase(process->host->extension<simgrid::simix::Host>()->process_list, *process);
+ simix_global->process_list.erase(process->pid_);
+ if (process->host_ && process->host_process_list_hook.is_linked())
+ simgrid::xbt::intrusive_erase(process->host_->pimpl_->process_list_, *process);
if (not process->smx_destroy_list_hook.is_linked()) {
#if SIMGRID_HAVE_MC
xbt_dynar_push_as(simix_global->dead_actors_vector, smx_actor_t, process);
#endif
simix_global->process_to_destroy.push_back(*process);
}
- process->context->iwannadie = 0;
+ process->context_->iwannadie = 0;
xbt_os_mutex_release(simix_global->mutex);
}
ActorImpl::~ActorImpl()
{
- delete this->context;
+ delete this->context_;
}
static void dying_daemon(int /*exit_status*/, void* data)
/** This process will be terminated automatically when the last non-daemon process finishes */
void ActorImpl::daemonize()
{
- if (not daemon) {
- daemon = true;
+ if (not daemon_) {
+ daemon_ = true;
simix_global->daemons.push_back(this);
SIMIX_process_on_exit(this, dying_daemon, this);
}
simgrid::s4u::Actor* ActorImpl::restart()
{
- XBT_DEBUG("Restarting process %s on %s", get_cname(), host->get_cname());
+ XBT_DEBUG("Restarting process %s on %s", get_cname(), host_->get_cname());
// retrieve the arguments of the old process
- // FIXME: Factorize this with SIMIX_host_add_auto_restart_process ?
- simgrid::kernel::actor::ProcessArg arg;
- arg.name = name;
- arg.code = code;
- arg.host = host;
- arg.kill_time = SIMIX_timer_get_date(kill_timer);
- arg.data = userdata;
- arg.properties = nullptr;
- arg.auto_restart = auto_restart;
+ simgrid::kernel::actor::ProcessArg arg = ProcessArg(host_, this);
// kill the old process
SIMIX_process_kill(this, (this == simix_global->maestro_process) ? this : SIMIX_process_self());
// start the new process
ActorImpl* actor = simix_global->create_process_function(arg.name.c_str(), std::move(arg.code), arg.data, arg.host,
arg.properties.get(), nullptr);
- if (arg.kill_time >= 0)
- simcall_process_set_kill_time(actor, arg.kill_time);
- if (arg.auto_restart)
- actor->auto_restart = arg.auto_restart;
+ simcall_process_set_kill_time(actor, arg.kill_time);
+ actor->set_auto_restart(arg.auto_restart);
return actor->ciface();
}
smx_activity_t ActorImpl::suspend(ActorImpl* issuer)
{
- if (suspended) {
- XBT_DEBUG("Actor '%s' is already suspended", name.c_str());
+ if (suspended_) {
+ XBT_DEBUG("Actor '%s' is already suspended", get_cname());
return nullptr;
}
- suspended = 1;
+ suspended_ = 1;
/* If we are suspending another actor that is waiting on a sync, suspend its synchronization. */
if (this != issuer) {
return nullptr;
} else {
- return SIMIX_execution_start("suspend", 0.0, 1.0, 0.0, this->host);
+ return SIMIX_execution_start("suspend", 0.0, 1.0, 0.0, this->host_);
}
}
{
XBT_IN("process = %p", this);
- if (context->iwannadie) {
+ if (context_->iwannadie) {
XBT_VERB("Ignoring request to suspend an actor that is currently dying.");
return;
}
- if (not suspended)
+ if (not suspended_)
return;
- suspended = 0;
+ suspended_ = 0;
/* resume the synchronization that was blocking the resumed actor. */
if (waiting_synchro)
smx_activity_t ActorImpl::sleep(double duration)
{
- if (host->is_off())
- THROWF(host_error, 0, "Host %s failed, you cannot sleep there.", host->get_cname());
+ if (host_->is_off())
+ THROWF(host_error, 0, "Host %s failed, you cannot sleep there.", host_->get_cname());
simgrid::kernel::activity::SleepImpl* synchro = new simgrid::kernel::activity::SleepImpl();
- synchro->host = host;
- synchro->surf_sleep = host->pimpl_cpu->sleep(duration);
+ synchro->host = host_;
+ synchro->surf_sleep = host_->pimpl_cpu->sleep(duration);
synchro->surf_sleep->set_data(synchro);
XBT_DEBUG("Create sleep synchronization %p", synchro);
return synchro;
}
-void create_maestro(std::function<void()> code)
+void create_maestro(simgrid::simix::ActorCode code)
{
smx_actor_t maestro = nullptr;
/* Create maestro process and initialize it */
maestro = new simgrid::kernel::actor::ActorImpl();
- maestro->pid = simix_process_maxpid++;
- maestro->name = "";
- maestro->setUserData(nullptr);
+ maestro->pid_ = simix_process_maxpid++;
+ maestro->name_ = "";
+ maestro->set_user_data(nullptr);
if (not code) {
- maestro->context = SIMIX_context_new(std::function<void()>(), nullptr, maestro);
+ maestro->context_ = SIMIX_context_new(simgrid::simix::ActorCode(), nullptr, maestro);
} else {
if (not simix_global)
xbt_die("simix is not initialized, please call MSG_init first");
- maestro->context = simix_global->context_factory->create_maestro(code, maestro);
+ maestro->context_ = simix_global->context_factory->create_maestro(code, maestro);
}
maestro->simcall.issuer = maestro;
*
* \return the process created
*/
-smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, void* data, simgrid::s4u::Host* host,
+smx_actor_t SIMIX_process_create(const char* name, simgrid::simix::ActorCode code, void* data, simgrid::s4u::Host* host,
std::unordered_map<std::string, std::string>* properties, smx_actor_t parent_process)
{
xbt_assert(code && host != nullptr, "Invalid parameters");
/* Process data */
- process->pid = simix_process_maxpid++;
- process->name = simgrid::xbt::string(name);
- process->host = host;
- process->setUserData(data);
+ process->pid_ = simix_process_maxpid++;
+ process->name_ = simgrid::xbt::string(name);
+ process->host_ = host;
+ process->set_user_data(data);
process->simcall.issuer = process;
if (parent_process != nullptr) {
- process->ppid = parent_process->pid;
+ process->ppid_ = parent_process->pid_;
}
process->code = code;
- XBT_VERB("Create context %s", process->name.c_str());
- process->context = SIMIX_context_new(std::move(code), simix_global->cleanup_process_function, process);
+ XBT_VERB("Create context %s", process->get_cname());
+ process->context_ = SIMIX_context_new(std::move(code), simix_global->cleanup_process_function, process);
/* Add properties */
if (properties != nullptr)
for (auto const& kv : *properties)
process->set_property(kv.first, kv.second);
- /* Make sure that the process is initialized for simix, in case we are called from the Host::onCreation signal */
- if (host->extension<simgrid::simix::Host>() == nullptr)
- host->extension_set<simgrid::simix::Host>(new simgrid::simix::Host());
-
/* Add the process to its host's process list */
- host->extension<simgrid::simix::Host>()->process_list.push_back(*process);
+ host->pimpl_->process_list_.push_back(*process);
- XBT_DEBUG("Start context '%s'", process->name.c_str());
+ XBT_DEBUG("Start context '%s'", process->get_cname());
/* Now insert it in the global process list and in the process to run list */
- simix_global->process_list[process->pid] = process;
+ simix_global->process_list[process->pid_] = process;
XBT_DEBUG("Inserting %s(%s) in the to_run list", process->get_cname(), host->get_cname());
simix_global->process_to_run.push_back(process);
intrusive_ptr_add_ref(process);
smx_actor_t process = new simgrid::kernel::actor::ActorImpl();
/* Process data */
- process->pid = simix_process_maxpid++;
- process->name = std::string(name);
- process->host = host;
- process->setUserData(data);
+ process->pid_ = simix_process_maxpid++;
+ process->name_ = std::string(name);
+ process->host_ = host;
+ process->set_user_data(data);
process->simcall.issuer = process;
if (parent_process != nullptr) {
- process->ppid = parent_process->pid;
+ process->ppid_ = parent_process->pid_;
}
/* Process data for auto-restart */
process->code = nullptr;
- XBT_VERB("Create context %s", process->name.c_str());
+ XBT_VERB("Create context %s", process->get_cname());
if (not simix_global)
xbt_die("simix is not initialized, please call MSG_init first");
- process->context = simix_global->context_factory->attach(simix_global->cleanup_process_function, process);
+ process->context_ = simix_global->context_factory->attach(simix_global->cleanup_process_function, process);
/* Add properties */
if (properties != nullptr)
process->set_property(kv.first, kv.second);
/* Add the process to it's host process list */
- host->extension<simgrid::simix::Host>()->process_list.push_back(*process);
+ host->pimpl_->process_list_.push_back(*process);
/* Now insert it in the global process list and in the process to run list */
- simix_global->process_list[process->pid] = process;
+ simix_global->process_list[process->pid_] = process;
XBT_DEBUG("Inserting %s(%s) in the to_run list", process->get_cname(), host->get_cname());
simix_global->process_to_run.push_back(process);
intrusive_ptr_add_ref(process);
-
- auto* context = dynamic_cast<simgrid::kernel::context::AttachContext*>(process->context);
+ auto* context = dynamic_cast<simgrid::kernel::context::AttachContext*>(process->context_);
if (not context)
xbt_die("Not a suitable context");
*/
void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer) {
- if (process->finished) {
+ if (process->finished_) {
XBT_DEBUG("Ignoring request to kill process %s@%s that is already dead", process->get_cname(),
- process->host->get_cname());
+ process->host_->get_cname());
return;
}
- XBT_DEBUG("Actor '%s'@%s is killing actor '%s'@%s", issuer->get_cname(), issuer->host->get_cname(),
- process->get_cname(), process->host->get_cname());
+ XBT_DEBUG("Actor '%s'@%s is killing actor '%s'@%s", issuer->get_cname(),
+ (issuer->host_ == nullptr ? "(null)" : issuer->host_->get_cname()), process->get_cname(),
+ process->host_->get_cname());
- process->context->iwannadie = 1;
- process->blocked = 0;
- process->suspended = 0;
+ process->context_->iwannadie = 1;
+ process->blocked_ = 0;
+ process->suspended_ = 0;
process->exception = nullptr;
/* destroy the blocking synchro if any */
if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
end(simix_global->process_to_run) &&
process != issuer) {
- XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
+ XBT_DEBUG("Inserting %s in the to_run list", process->get_cname());
simix_global->process_to_run.push_back(process);
}
}
void SIMIX_process_throw(smx_actor_t process, xbt_errcat_t cat, int value, const char *msg) {
SMX_EXCEPTION(process, cat, value, msg);
- if (process->suspended)
+ if (process->suspended_)
process->resume();
/* cancel the blocking synchro if any */
if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
end(simix_global->process_to_run) &&
process != SIMIX_process_self()) {
- XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
+ XBT_DEBUG("Inserting %s in the to_run list", process->get_cname());
simix_global->process_to_run.push_back(process);
}
}
void SIMIX_process_change_host(smx_actor_t actor, sg_host_t dest)
{
xbt_assert((actor != nullptr), "Invalid parameters");
- simgrid::xbt::intrusive_erase(actor->host->extension<simgrid::simix::Host>()->process_list, *actor);
- actor->host = dest;
- dest->extension<simgrid::simix::Host>()->process_list.push_back(*actor);
+ simgrid::xbt::intrusive_erase(actor->host_->pimpl_->process_list_, *actor);
+ actor->host_ = dest;
+ dest->pimpl_->process_list_.push_back(*actor);
}
void simcall_HANDLER_process_suspend(smx_simcall_t simcall, smx_actor_t process)
if (not self) {
return nullptr;
}
- return self->getUserData();
+ return self->get_user_data();
}
void SIMIX_process_self_set_data(void *data)
{
- SIMIX_process_self()->setUserData(data);
+ SIMIX_process_self()->set_user_data(data);
}
if (process == nullptr || process == simix_global->maestro_process)
return "maestro";
- return process->name.c_str();
+ return process->get_cname();
}
void simcall_HANDLER_process_join(smx_simcall_t simcall, smx_actor_t process, double timeout)
{
- if (process->finished) {
+ if (process->finished_) {
// The joined process is already finished, just wake up the issuer process right away
simcall_process_sleep__set__result(simcall, SIMIX_DONE);
SIMIX_simcall_answer(simcall);
XBT_DEBUG("Yield actor '%s'", self->get_cname());
/* Go into sleep and return control to maestro */
- self->context->suspend();
+ self->context_->suspend();
/* Ok, maestro returned control to us */
- XBT_DEBUG("Control returned to me: '%s'", self->name.c_str());
+ XBT_DEBUG("Control returned to me: '%s'", self->get_cname());
- if (self->context->iwannadie){
+ if (self->context_->iwannadie) {
XBT_DEBUG("I wanna die!");
- self->finished = true;
+ self->finished_ = true;
/* execute the on_exit functions */
SIMIX_process_on_exit_runall(self);
/* Add the process to the list of process to restart, only if the host is down */
- if (self->auto_restart && self->host->is_off()) {
- SIMIX_host_add_auto_restart_process(self->host, self->get_cname(), self->code, self->getUserData(),
- SIMIX_timer_get_date(self->kill_timer), self->get_properties(),
- self->auto_restart);
+ if (self->auto_restart_ && self->host_->is_off()) {
+ SIMIX_host_add_auto_restart_process(self->host_, self);
}
- XBT_DEBUG("Process %s@%s is dead", self->get_cname(), self->host->get_cname());
- self->context->stop();
+ XBT_DEBUG("Process %s@%s is dead", self->get_cname(), self->host_->get_cname());
+ self->context_->stop();
}
- if (self->suspended) {
+ if (self->suspended_) {
XBT_DEBUG("Hey! I'm suspended.");
xbt_assert(self->exception != nullptr, "Gasp! This exception may be lost by subsequent calls.");
- self->suspended = 0;
+ self->suspended_ = 0;
self->suspend(self);
}
std::rethrow_exception(std::move(exception));
}
- if (SMPI_switch_data_segment && not self->finished) {
+ if (SMPI_switch_data_segment && not self->finished_) {
SMPI_switch_data_segment(self->iface());
}
}
void SIMIX_process_on_exit_runall(smx_actor_t process) {
simgrid::s4u::Actor::on_destruction(process->iface());
- smx_process_exit_status_t exit_status = (process->context->iwannadie) ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
+ smx_process_exit_status_t exit_status = (process->context_->iwannadie) ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
while (not process->on_exit.empty()) {
s_smx_process_exit_fun_t exit_fun = process->on_exit.back();
process->on_exit.pop_back();
process->on_exit.emplace_back(s_smx_process_exit_fun_t{fun, data});
}
-/**
- * \brief Sets the auto-restart status of the process.
- * If set to 1, the process will be automatically restarted when its host comes back.
- */
-void SIMIX_process_auto_restart_set(smx_actor_t process, int auto_restart) {
- process->auto_restart = auto_restart;
-}
-
/** @brief Restart a process, starting it again from the beginning. */
/**
* \ingroup simix_process_management
return res;
}
-smx_actor_t simcall_process_create(const char* name, std::function<void()> code, void* data, sg_host_t host,
+smx_actor_t simcall_process_create(const char* name, simgrid::simix::ActorCode code, void* data, sg_host_t host,
std::unordered_map<std::string, std::string>* properties)
{
if (name == nullptr)
namespace kernel {
namespace actor {
-class ProcessArg {
-public:
- std::string name;
- std::function<void()> code;
- void* data = nullptr;
- s4u::Host* host = nullptr;
- double kill_time = 0.0;
- std::shared_ptr<std::unordered_map<std::string, std::string>> properties;
- bool auto_restart = false;
- ProcessArg() = default;
- explicit ProcessArg(std::string name, std::function<void()> code, void* data, s4u::Host* host, double kill_time,
- std::shared_ptr<std::unordered_map<std::string, std::string>> properties, bool auto_restart)
- : name(name)
- , code(std::move(code))
- , data(data)
- , host(host)
- , kill_time(kill_time)
- , properties(properties)
- , auto_restart(auto_restart)
- {
- }
-};
-
class ActorImpl : public simgrid::surf::PropertyHolder {
public:
ActorImpl() : piface_(this) {}
~ActorImpl();
+ void set_auto_restart(bool autorestart) { auto_restart_ = autorestart; }
+
boost::intrusive::list_member_hook<> host_process_list_hook; /* simgrid::simix::Host::process_list */
boost::intrusive::list_member_hook<> smx_destroy_list_hook; /* simix_global->process_to_destroy */
boost::intrusive::list_member_hook<> smx_synchro_hook; /* {mutex,cond,sem}->sleeping */
- aid_t pid = 0;
- aid_t ppid = -1;
- simgrid::xbt::string name;
- const simgrid::xbt::string& get_name() const { return name; }
- const char* get_cname() const { return name.c_str(); }
- s4u::Host* host = nullptr; /* the host on which the process is running */
- smx_context_t context = nullptr; /* the context (uctx/raw/thread) that executes the user function */
+ aid_t pid_ = 0;
+ aid_t ppid_ = -1;
+ simgrid::xbt::string name_;
+ const simgrid::xbt::string& get_name() const { return name_; }
+ const char* get_cname() const { return name_.c_str(); }
+ s4u::Host* host_ = nullptr; /* the host on which the process is running */
+ smx_context_t context_ = nullptr; /* the context (uctx/raw/thread) that executes the user function */
std::exception_ptr exception;
- bool finished = false;
- bool blocked = false;
- bool suspended = false;
- bool auto_restart = false;
+ bool finished_ = false;
+ bool blocked_ = false;
+ bool suspended_ = false;
+ bool auto_restart_ = false;
smx_activity_t waiting_synchro = nullptr; /* the current blocking synchro if any */
std::list<smx_activity_t> comms; /* the current non-blocking communication synchros */
smx_timer_t kill_timer = nullptr;
private:
- void* userdata = nullptr; /* kept for compatibility, it should be replaced with moddata */
+ void* userdata_ = nullptr; /* kept for compatibility, it should be replaced with moddata */
/* Refcounting */
std::atomic_int_fast32_t refcount_{0};
/* Daemon actors are automatically killed when the last non-daemon leaves */
private:
- bool daemon = false;
+ bool daemon_ = false;
public:
void daemonize();
- bool isDaemon() { return daemon; } /** Whether this actor has been daemonized */
- bool isSuspended() { return suspended; }
+ bool is_daemon() { return daemon_; } /** Whether this actor has been daemonized */
+ bool is_suspended() { return suspended_; }
simgrid::s4u::Actor* restart();
smx_activity_t suspend(ActorImpl* issuer);
void resume();
smx_activity_t sleep(double duration);
- void setUserData(void* data) { userdata = data; }
- void* getUserData() { return userdata; }
+ void set_user_data(void* data) { userdata_ = data; }
+ void* get_user_data() { return userdata_; }
+};
+
+class ProcessArg {
+public:
+ std::string name;
+ std::function<void()> code;
+ void* data = nullptr;
+ s4u::Host* host = nullptr;
+ double kill_time = 0.0;
+ std::shared_ptr<std::unordered_map<std::string, std::string>> properties = nullptr;
+ bool auto_restart = false;
+ ProcessArg() = default;
+
+ explicit ProcessArg(std::string name, std::function<void()> code, void* data, s4u::Host* host, double kill_time,
+ std::shared_ptr<std::unordered_map<std::string, std::string>> properties, bool auto_restart)
+ : name(name)
+ , code(std::move(code))
+ , data(data)
+ , host(host)
+ , kill_time(kill_time)
+ , properties(properties)
+ , auto_restart(auto_restart)
+ {
+ }
+
+ explicit ProcessArg(s4u::Host* host, ActorImpl* actor)
+ : name(actor->get_name())
+ , code(std::move(actor->code))
+ , data(actor->get_user_data())
+ , host(host)
+ , kill_time(SIMIX_timer_get_date(actor->kill_timer))
+ , auto_restart(actor->auto_restart_)
+ {
+ properties.reset(actor->get_properties(), [](decltype(actor->get_properties())) {});
+ }
};
/* Used to keep the list of actors blocked on a synchro */
XBT_PRIVATE void SIMIX_process_yield(smx_actor_t self);
XBT_PRIVATE void SIMIX_process_change_host(smx_actor_t process, sg_host_t dest);
-XBT_PRIVATE void SIMIX_process_auto_restart_set(smx_actor_t process, int auto_restart);
-
extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor);
XBT_PRIVATE void SIMIX_process_sleep_destroy(smx_activity_t synchro);
/* */
/* This is somehow the "libc" of SimGrid */
-/* Copyright (c) 2010-2018. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2010-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <cmath> /* std::isfinite() */
-
-#include <functional>
-
#include "mc/mc.h"
-#include "simgrid/s4u/VirtualMachine.hpp"
-#include "simgrid/simix.hpp"
#include "simgrid/simix/blocking_simcall.hpp"
-#include "smx_private.hpp"
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/activity/ConditionVariableImpl.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/kernel/activity/MutexImpl.hpp"
-#include "src/mc/mc_forward.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/simix/smx_host_private.hpp"
-#include "xbt/ex.h"
-#include "xbt/functional.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
*/
void simcall_process_set_data(smx_actor_t process, void *data)
{
- simgrid::simix::simcall([process, data] { process->setUserData(data); });
+ simgrid::simix::simcall([process, data] { process->set_user_data(data); });
}
/**
if (kill_time <= SIMIX_get_clock() || simix_global->kill_process_function == nullptr)
return;
- XBT_DEBUG("Set kill time %f for process %s@%s", kill_time, process->get_cname(), process->host->get_cname());
+ XBT_DEBUG("Set kill time %f for process %s@%s", kill_time, process->get_cname(), process->host_->get_cname());
process->kill_timer = SIMIX_timer_set(kill_time, [process] {
simix_global->kill_process_function(process);
process->kill_timer=nullptr;
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "smx_private.hpp"
-#include "xbt/xbt_os_thread.h"
-#if SIMGRID_HAVE_MC
-#include "src/mc/mc_private.hpp"
-#endif
-
-#include "src/kernel/activity/CommImpl.hpp"
-#include "src/kernel/activity/ExecImpl.hpp"
-#include "src/kernel/activity/IoImpl.hpp"
-#include "src/kernel/activity/SleepImpl.hpp"
-#include "src/kernel/activity/SynchroRaw.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_popping, simix,
"Popping part of SIMIX (transmuting from user request into kernel handlers)");
{
if (simcall->issuer != simix_global->maestro_process){
XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall->call), (int)simcall->call,
- simcall->issuer->name.c_str(), simcall->issuer);
+ simcall->issuer->get_cname(), simcall->issuer);
simcall->issuer->simcall.call = SIMCALL_NONE;
#if 0
/* This check should be useless and slows everyone. Reactivate if you see something weird in process scheduling. */
smx_actor_t self = SIMIX_process_self();
simgrid::simix::marshal(&self->simcall, call, t...);
if (self != simix_global->maestro_process) {
- XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name.c_str(),
- SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
+ XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->get_cname(), SIMIX_simcall_name(self->simcall.call),
+ (int)self->simcall.call);
SIMIX_process_yield(self);
} else {
SIMIX_simcall_handle(&self->simcall, 0);
void SIMIX_simcall_handle(smx_simcall_t simcall, int value) {
XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));
SIMCALL_SET_MC_VALUE(simcall, value);
- if (simcall->issuer->context->iwannadie)
+ if (simcall->issuer->context_->iwannadie)
return;
switch (simcall->call) {
case SIMCALL_PROCESS_SUSPEND:
case NUM_SIMCALLS:
break;
case SIMCALL_NONE:
- THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s",
- simcall->issuer->name.c_str(),
- sg_host_get_name(simcall->issuer->host)
- );
+ THROWF(arg_error, 0, "Asked to do the noop syscall on %s@%s", simcall->issuer->get_cname(),
+ sg_host_get_name(simcall->issuer->host_));
break;
default:
THROW_IMPOSSIBLE;
#ifndef SG_POPPING_PRIVATE_HPP
#define SG_POPPING_PRIVATE_HPP
-#include <simgrid/simix.h>
-#include <xbt/base.h>
-
-#include <src/kernel/activity/ActivityImpl.hpp>
-#include <src/kernel/activity/CommImpl.hpp>
-#include <src/kernel/activity/ExecImpl.hpp>
+#include "simgrid/forward.h"
+#include "src/kernel/activity/ActivityImpl.hpp"
#include <boost/intrusive_ptr.hpp>
' XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));\n')
fd.write(' SIMCALL_SET_MC_VALUE(simcall, value);\n')
fd.write(
- ' if (simcall->issuer->context->iwannadie)\n')
+ ' if (simcall->issuer->context_->iwannadie)\n')
fd.write(' return;\n')
fd.write(' switch (simcall->call) {\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(' simcall->issuer->name.c_str(),\n')
- fd.write(' sg_host_get_name(simcall->issuer->host)\n')
+ fd.write(' simcall->issuer->get_cname(),\n')
+ fd.write(' sg_host_get_name(simcall->issuer->host_)\n')
fd.write(' );\n')
fd.write(' break;\n')
fd.write(' default:\n')
smx_actor_t self = SIMIX_process_self();
simgrid::simix::marshal(&self->simcall, call, t...);
if (self != simix_global->maestro_process) {
- XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name.c_str(),
+ XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->get_cname(),
SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
SIMIX_process_yield(self);
} else {
-/* Copyright (c) 2007-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "smx_private.hpp"
-#include "xbt/config.hpp"
-#include "xbt/log.h"
-#include "xbt/sysdep.h"
+#include "src/include/surf/surf.hpp"
#include "xbt/xbt_os_time.h"
#include <xbt/ex.hpp>
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Host.hpp"
-#include "../kernel/activity/IoImpl.hpp"
#include "simgrid/sg_config.hpp"
-#include "smx_private.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
+#include "src/kernel/activity/IoImpl.hpp"
+#include "src/kernel/activity/MailboxImpl.hpp"
#include "src/kernel/activity/SleepImpl.hpp"
#include "src/kernel/activity/SynchroRaw.hpp"
#include "src/mc/mc_record.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/simix/smx_host_private.hpp"
+#include "src/simix/smx_private.hpp"
#include "src/smpi/include/smpi_process.hpp"
#include "src/surf/StorageImpl.hpp"
#include "src/surf/xml/platf.hpp"
#if SIMGRID_HAVE_MC
-#include "src/mc/mc_private.hpp"
#include "src/mc/remote/Client.hpp"
-#include "src/mc/remote/mc_protocol.h"
-#endif
-
-#if HAVE_SMPI
-#include "src/smpi/include/private.hpp"
#endif
#include <boost/heap/fibonacci_heap.hpp>
-#include <csignal>
XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)");
}
}
-static std::function<void()> maestro_code;
+static simgrid::simix::ActorCode maestro_code;
void SIMIX_set_maestro(void (*code)(void*), void* data)
{
#ifdef _WIN32
/* register a function to be called by SURF after the environment creation */
sg_platf_init();
simgrid::s4u::on_platform_created.connect(SIMIX_post_create_environment);
- simgrid::s4u::Host::on_creation.connect([](simgrid::s4u::Host& host) {
- if (host.extension<simgrid::simix::Host>() == nullptr) // another callback to the same signal may have created it
- host.extension_set<simgrid::simix::Host>(new simgrid::simix::Host());
- });
simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage& storage) {
sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_cname());
#endif
/* Let's free maestro now */
- delete simix_global->maestro_process->context;
- simix_global->maestro_process->context = nullptr;
+ delete simix_global->maestro_process->context_;
+ simix_global->maestro_process->context_ = nullptr;
delete simix_global->maestro_process;
simix_global->maestro_process = nullptr;
do {
XBT_DEBUG("New Schedule Round; size(queue)=%zu", simix_global->process_to_run.size());
- if (simgrid::simix::breakpoint >= 0.0 && time >= simgrid::simix::breakpoint) {
+ if (simgrid::simix::breakpoint >= 0.0 && surf_get_clock() >= simgrid::simix::breakpoint) {
XBT_DEBUG("Breakpoint reached (%g)", simgrid::simix::breakpoint.get());
simgrid::simix::breakpoint = -1.0;
#ifdef SIGTRAP
if (boost::dynamic_pointer_cast<simgrid::kernel::activity::IoImpl>(process->waiting_synchro) != nullptr)
synchro_description = "I/O";
- XBT_INFO("Process %ld (%s@%s): waiting for %s synchro %p (%s) in state %d to finish", process->pid,
- process->get_cname(), process->host->get_cname(), synchro_description, process->waiting_synchro.get(),
+ XBT_INFO("Process %ld (%s@%s): waiting for %s synchro %p (%s) in state %d to finish", process->pid_,
+ process->get_cname(), process->host_->get_cname(), synchro_description, process->waiting_synchro.get(),
process->waiting_synchro->name_.c_str(), (int)process->waiting_synchro->state_);
}
else {
- XBT_INFO("Process %ld (%s@%s)", process->pid, process->get_cname(), process->host->get_cname());
+ XBT_INFO("Process %ld (%s@%s)", process->pid_, process->get_cname(), process->host_->get_cname());
}
}
}
#include "mc/mc.h"
#include "smx_private.hpp"
+#include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/simix/smx_host_private.hpp"
-#include "src/surf/surf_interface.hpp"
#include "xbt/ex.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_host, simix, "SIMIX hosts");
-namespace simgrid {
- namespace simix {
- simgrid::xbt::Extension<simgrid::s4u::Host, Host> Host::EXTENSION_ID;
-
- Host::Host()
- {
- if (not Host::EXTENSION_ID.valid())
- Host::EXTENSION_ID = s4u::Host::extension_create<simix::Host>();
- }
-
- Host::~Host()
- {
- /* All processes should be gone when the host is turned off (by the end of the simulation). */
- if (not process_list.empty()) {
- std::string msg = std::string("Shutting down host, but it's not empty:");
- for (auto const& process : process_list)
- msg += "\n\t" + std::string(process.get_name());
-
- SIMIX_display_process_status();
- THROWF(arg_error, 0, "%s", msg.c_str());
- }
- for (auto const& arg : auto_restart_processes)
- delete arg;
- auto_restart_processes.clear();
- for (auto const& arg : boot_processes)
- delete arg;
- boot_processes.clear();
- }
-
- /** Re-starts all the actors that are marked as restartable.
- *
- * Weird things will happen if you turn on an host that is already on. S4U is fool-proof, not this.
- */
- void Host::turnOn()
- {
- for (auto const& arg : boot_processes) {
- XBT_DEBUG("Booting Process %s(%s) right now", arg->name.c_str(), arg->host->get_cname());
- smx_actor_t actor = simix_global->create_process_function(arg->name.c_str(), arg->code, nullptr, arg->host,
- arg->properties.get(), nullptr);
- if (arg->kill_time >= 0)
- simcall_process_set_kill_time(actor, arg->kill_time);
- if (arg->auto_restart)
- actor->auto_restart = arg->auto_restart;
- }
- }
-
-}} // namespaces
-
/* needs to be public and without simcall for exceptions and logging events */
const char* sg_host_self_get_name()
{
* The processes will only be restarted once, meaning that you will have to register the process
* again to restart the process again.
*/
-void SIMIX_host_add_auto_restart_process(sg_host_t host, const char* name, std::function<void()> code, void* data,
- double kill_time, std::unordered_map<std::string, std::string>* properties,
- int auto_restart)
+void SIMIX_host_add_auto_restart_process(sg_host_t host, simgrid::kernel::actor::ActorImpl* actor)
{
- simgrid::kernel::actor::ProcessArg* arg =
- new simgrid::kernel::actor::ProcessArg(name, code, data, host, kill_time, nullptr, auto_restart);
- arg->properties.reset(properties, [](decltype(properties)) {});
+ simgrid::kernel::actor::ProcessArg* arg = new simgrid::kernel::actor::ProcessArg(host, actor);
if (host->is_off() && watched_hosts.find(host->get_cname()) == watched_hosts.end()) {
watched_hosts.insert(host->get_cname());
XBT_DEBUG("Push host %s to watched_hosts because state == SURF_RESOURCE_OFF", host->get_cname());
}
XBT_DEBUG("Adding Process %s to the auto-restart list of Host %s", arg->name.c_str(), arg->host->get_cname());
- host->extension<simgrid::simix::Host>()->auto_restart_processes.push_back(arg);
+ host->pimpl_->auto_restart_processes_.push_back(arg);
}
/** @brief Restart the list of processes that have been registered to the host */
void SIMIX_host_autorestart(sg_host_t host)
{
- std::vector<simgrid::kernel::actor::ProcessArg*> process_list =
- host->extension<simgrid::simix::Host>()->auto_restart_processes;
+ std::vector<simgrid::kernel::actor::ProcessArg*> process_list = host->pimpl_->auto_restart_processes_;
for (auto const& arg : process_list) {
XBT_DEBUG("Restarting Process %s@%s right now", arg->name.c_str(), arg->host->get_cname());
if (arg->kill_time >= 0)
simcall_process_set_kill_time(actor, arg->kill_time);
if (arg->auto_restart)
- actor->auto_restart = arg->auto_restart;
+ actor->auto_restart_ = arg->auto_restart;
}
process_list.clear();
}
break;
case SIMIX_FAILED:
- XBT_DEBUG("SIMIX_execution_finished: host '%s' failed", simcall->issuer->host->get_cname());
- simcall->issuer->context->iwannadie = 1;
+ XBT_DEBUG("SIMIX_execution_finished: host '%s' failed", simcall->issuer->host_->get_cname());
+ simcall->issuer->context_->iwannadie = 1;
SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
break;
xbt_die("Internal error in SIMIX_execution_finish: unexpected synchro state %d", (int)exec->state_);
}
/* Fail the process if the host is down */
- if (simcall->issuer->host->is_off())
- simcall->issuer->context->iwannadie = 1;
+ if (simcall->issuer->host_->is_off())
+ simcall->issuer->context_->iwannadie = 1;
simcall->issuer->waiting_synchro = nullptr;
simcall_execution_wait__set__result(simcall, exec->state_);
#ifndef SIMIX_HOST_PRIVATE_HPP
#define SIMIX_HOST_PRIVATE_HPP
-#include <boost/intrusive/list.hpp>
-#include <functional>
-#include <unordered_map>
-#include <vector>
-
#include "src/simix/ActorImpl.hpp"
-#include "src/simix/popping_private.hpp"
-#include "xbt/Extendable.hpp"
-
-/** @brief Host datatype from SIMIX POV */
-namespace simgrid {
-namespace simix {
-
-class Host {
-public:
- static simgrid::xbt::Extension<simgrid::s4u::Host, Host> EXTENSION_ID;
- explicit Host();
- virtual ~Host();
-
- boost::intrusive::list<kernel::actor::ActorImpl,
- boost::intrusive::member_hook<kernel::actor::ActorImpl, boost::intrusive::list_member_hook<>,
- &kernel::actor::ActorImpl::host_process_list_hook>>
- process_list;
- std::vector<kernel::actor::ProcessArg*> auto_restart_processes;
- std::vector<kernel::actor::ProcessArg*> boot_processes;
-
- void turnOn();
-};
-}
-}
-
-XBT_PRIVATE void SIMIX_host_add_auto_restart_process(sg_host_t host, const char* name, std::function<void()> code,
- void* data, double kill_time,
- std::unordered_map<std::string, std::string>* properties,
- int auto_restart);
+#include <boost/intrusive/list.hpp>
+XBT_PRIVATE void SIMIX_host_add_auto_restart_process(sg_host_t host, simgrid::kernel::actor::ActorImpl* actor);
XBT_PRIVATE void SIMIX_host_autorestart(sg_host_t host);
XBT_PRIVATE void SIMIX_execution_finish(smx_activity_t synchro);
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <xbt/ex.hpp>
-#include <xbt/sysdep.h>
-#include <xbt/log.h>
-
#include "simgrid/s4u/Host.hpp"
-#include "simgrid/s4u/Storage.hpp"
+#include "xbt/ex.hpp"
#include "smx_private.hpp"
#include "src/kernel/activity/IoImpl.hpp"
#include "src/simix/smx_io_private.hpp"
-#include "src/surf/HostImpl.hpp"
#include "src/surf/StorageImpl.hpp"
-#include "src/surf/surf_interface.hpp"
-#include "surf/surf.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix, "Logging specific to SIMIX (io)");
xbt_die("Internal error in SIMIX_io_finish: unexpected synchro state %d", static_cast<int>(synchro->state_));
}
- if (simcall->issuer->host->is_off()) {
- simcall->issuer->context->iwannadie = 1;
+ if (simcall->issuer->host_->is_off()) {
+ simcall->issuer->context_->iwannadie = 1;
}
simcall->issuer->waiting_synchro = nullptr;
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include <algorithm>
-
-#include <boost/range/algorithm.hpp>
-
-#include "src/kernel/activity/CommImpl.hpp"
-#include <xbt/ex.hpp>
-
-#include "simgrid/s4u/Host.hpp"
-
#include "mc/mc.h"
-#include "simgrid/s4u/Activity.hpp"
-#include "simgrid/s4u/Mailbox.hpp"
+#include "src/kernel/activity/MailboxImpl.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/simix/smx_private.hpp"
#include "src/surf/cpu_interface.hpp"
-#include "src/surf/surf_interface.hpp"
-
#include "src/surf/network_interface.hpp"
+#include "xbt/ex.hpp"
+
+#include <boost/circular_buffer.hpp>
+#include <boost/range/algorithm.hpp>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_network, simix, "SIMIX network-related synchronization");
SIMIX_comm_finish(synchro);
} else { /* we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host
fails */
- simgrid::kernel::resource::Action* sleep = simcall->issuer->host->pimpl_cpu->sleep(timeout);
+ simgrid::kernel::resource::Action* sleep = simcall->issuer->host_->pimpl_cpu->sleep(timeout);
sleep->set_data(synchro.get());
simgrid::kernel::activity::CommImplPtr comm =
/* If both the sender and the receiver are already there, start the communication */
if (comm->state_ == SIMIX_READY) {
- simgrid::s4u::Host* sender = comm->src_proc->host;
- simgrid::s4u::Host* receiver = comm->dst_proc->host;
+ simgrid::s4u::Host* sender = comm->src_proc->host_;
+ simgrid::s4u::Host* receiver = comm->dst_proc->host_;
comm->surfAction_ = surf_network_model->communicate(sender, receiver, comm->task_size, comm->rate);
comm->surfAction_->set_data(comm.get());
/* If any of the process is suspended, create the synchro but stop its execution,
it will be restarted when the sender process resume */
- if (comm->src_proc->isSuspended() || comm->dst_proc->isSuspended()) {
- if (comm->src_proc->isSuspended())
+ if (comm->src_proc->is_suspended() || comm->dst_proc->is_suspended()) {
+ if (comm->src_proc->is_suspended())
XBT_DEBUG("The communication is suspended on startup because src (%s@%s) was suspended since it initiated the "
"communication",
- comm->src_proc->get_cname(), comm->src_proc->host->get_cname());
+ comm->src_proc->get_cname(), comm->src_proc->host_->get_cname());
else
XBT_DEBUG("The communication is suspended on startup because dst (%s@%s) was suspended since it initiated the "
"communication",
- comm->dst_proc->get_cname(), comm->dst_proc->host->get_cname());
+ comm->dst_proc->get_cname(), comm->dst_proc->host_->get_cname());
comm->surfAction_->suspend();
}
/* Check out for errors */
- if (simcall->issuer->host->is_off()) {
- simcall->issuer->context->iwannadie = 1;
+ if (simcall->issuer->host_->is_off()) {
+ simcall->issuer->context_->iwannadie = 1;
SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
} else {
switch (comm->state_) {
case SIMIX_SRC_HOST_FAILURE:
if (simcall->issuer == comm->src_proc)
- simcall->issuer->context->iwannadie = 1;
+ simcall->issuer->context_->iwannadie = 1;
else
SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
break;
case SIMIX_DST_HOST_FAILURE:
if (simcall->issuer == comm->dst_proc)
- simcall->issuer->context->iwannadie = 1;
+ simcall->issuer->context_->iwannadie = 1;
else
SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
break;
case SIMIX_LINK_FAILURE:
XBT_DEBUG("Link failure in synchro %p between '%s' and '%s': posting an exception to the issuer: %s (%p) "
"detached:%d",
- synchro.get(), comm->src_proc ? comm->src_proc->host->get_cname() : nullptr,
- comm->dst_proc ? comm->dst_proc->host->get_cname() : nullptr, simcall->issuer->get_cname(),
+ synchro.get(), comm->src_proc ? comm->src_proc->host_->get_cname() : nullptr,
+ comm->dst_proc ? comm->dst_proc->host_->get_cname() : nullptr, simcall->issuer->get_cname(),
simcall->issuer, comm->detached);
if (comm->src_proc == simcall->issuer) {
XBT_DEBUG("I'm source");
}
}
- if (simcall->issuer->host->is_off()) {
- simcall->issuer->context->iwannadie = 1;
+ if (simcall->issuer->host_->is_off()) {
+ simcall->issuer->context_->iwannadie = 1;
}
simcall->issuer->waiting_synchro = nullptr;
return;
XBT_DEBUG("Copying comm %p data from %s (%p) -> %s (%p) (%zu bytes)", comm.get(),
- comm->src_proc ? comm->src_proc->host->get_cname() : "a finished process", comm->src_buff,
- comm->dst_proc ? comm->dst_proc->host->get_cname() : "a finished process", comm->dst_buff, buff_size);
+ comm->src_proc ? comm->src_proc->host_->get_cname() : "a finished process", comm->src_buff,
+ comm->dst_proc ? comm->dst_proc->host_->get_cname() : "a finished process", comm->dst_buff, buff_size);
/* Copy at most dst_buff_size bytes of the message to receiver's buffer */
if (comm->dst_buff_size)
#ifndef SIMIX_NETWORK_PRIVATE_HPP
#define SIMIX_NETWORK_PRIVATE_HPP
-#include "simgrid/s4u/Mailbox.hpp"
-#include "src/kernel/activity/MailboxImpl.hpp"
-#include "src/simix/ActorImpl.hpp"
+#include "simgrid/forward.h"
+#include "src/simix/popping_private.hpp"
XBT_PRIVATE smx_activity_t SIMIX_comm_irecv(smx_actor_t dst_proc, smx_mailbox_t mbox, void* dst_buff,
size_t* dst_buff_size,
#include "simgrid/s4u/Actor.hpp"
#include "src/kernel/context/Context.hpp"
+#include "src/simix/ActorImpl.hpp"
#include <xbt/xbt_os_thread.h>
+#include <boost/intrusive/list.hpp>
#include <unordered_map>
#include <vector>
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include "smx_private.hpp"
#include "src/kernel/activity/ConditionVariableImpl.hpp"
#include "src/kernel/activity/MutexImpl.hpp"
#include "src/kernel/activity/SynchroRaw.hpp"
+#include "src/kernel/context/Context.hpp"
#include "src/simix/smx_synchro_private.hpp"
#include "src/surf/cpu_interface.hpp"
-#include <xbt/ex.hpp>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_synchro, simix, "SIMIX Synchronization (mutex, semaphores and conditions)");
if (synchro->state_ != SIMIX_SRC_TIMEOUT) {
if (synchro->state_ == SIMIX_FAILED)
- simcall->issuer->context->iwannadie = 1;
+ simcall->issuer->context_->iwannadie = 1;
else
THROW_IMPOSSIBLE;
}
XBT_DEBUG("Wait semaphore %p (timeout:%f)", sem, timeout);
if (sem->value <= 0) {
- synchro = SIMIX_synchro_wait(issuer->host, timeout);
+ synchro = SIMIX_synchro_wait(issuer->host_, timeout);
synchro->simcalls_.push_front(simcall);
issuer->waiting_synchro = synchro;
sem->sleeping.push_back(*issuer);
#ifndef SIMIX_SYNCHRO_PRIVATE_H
#define SIMIX_SYNCHRO_PRIVATE_H
-#include "simgrid/s4u/ConditionVariable.hpp"
#include "src/simix/ActorImpl.hpp"
-#include <boost/intrusive/list.hpp>
smx_activity_t SIMIX_synchro_wait(sg_host_t smx_host, double timeout);
int min_coll = -1, global_coll = -1; \
int i; \
double buf_in, buf_out, max_min = DBL_MAX; \
- for (i = 0; Colls::mpi_coll_##cat##_description[i].name; i++) { \
- if (not strcmp(Colls::mpi_coll_##cat##_description[i].name, "automatic")) \
+ for (i = 0; not Colls::mpi_coll_##cat##_description[i].name.empty(); i++) { \
+ if (Colls::mpi_coll_##cat##_description[i].name == "automatic") \
continue; \
- if (not strcmp(Colls::mpi_coll_##cat##_description[i].name, "default")) \
+ if (Colls::mpi_coll_##cat##_description[i].name == "default") \
continue; \
Coll_barrier_default::barrier(comm); \
TRACE_AUTO_COLL(cat) \
} \
if (comm->rank() == 0) { \
XBT_WARN("For rank 0, the quickest was %s : %f , but global was %s : %f at max", \
- Colls::mpi_coll_##cat##_description[min_coll].name, time_min, \
- Colls::mpi_coll_##cat##_description[global_coll].name, max_min); \
+ Colls::mpi_coll_##cat##_description[min_coll].name.c_str(), time_min, \
+ Colls::mpi_coll_##cat##_description[global_coll].name.c_str(), max_min); \
} else \
XBT_WARN("The quickest %s was %s on rank %d and took %f", #cat, \
- Colls::mpi_coll_##cat##_description[min_coll].name, comm->rank(), time_min); \
+ Colls::mpi_coll_##cat##_description[min_coll].name.c_str(), comm->rank(), time_min); \
return (min_coll != -1) ? MPI_SUCCESS : MPI_ERR_INTERN; \
}
xbt_die("Collective " #cat " set to nullptr!"); \
}
-#define SET_COLL(coll) \
- name = simgrid::config::get_value<std::string>("smpi/" #coll); \
- if (name.empty()) \
- name = selector_name; \
- set_##coll(name);
-
namespace simgrid{
namespace smpi{
/* these arrays must be nullptr terminated */
s_mpi_coll_description_t Colls::mpi_coll_gather_description[] = {
- COLL_GATHERS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_GATHERS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_allgather_description[] = {
- COLL_ALLGATHERS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_ALLGATHERS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_allgatherv_description[] = {
- COLL_ALLGATHERVS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_ALLGATHERVS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_allreduce_description[] ={
- COLL_ALLREDUCES(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_ALLREDUCES(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_reduce_scatter_description[] = {
- COLL_REDUCE_SCATTERS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_REDUCE_SCATTERS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_scatter_description[] ={
- COLL_SCATTERS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_SCATTERS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_barrier_description[] ={
- COLL_BARRIERS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_BARRIERS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_alltoall_description[] = {
- COLL_ALLTOALLS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_ALLTOALLS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_alltoallv_description[] = {
- COLL_ALLTOALLVS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_ALLTOALLVS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_bcast_description[] = {
- COLL_BCASTS(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_BCASTS(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
s_mpi_coll_description_t Colls::mpi_coll_reduce_description[] = {
- COLL_REDUCES(COLL_DESCRIPTION, COLL_COMMA), {nullptr, nullptr, nullptr} };
+ COLL_REDUCES(COLL_DESCRIPTION, COLL_COMMA), {"", "", nullptr} };
/** Displays the long description of all registered models, and quit */
void Colls::coll_help(const char *category, s_mpi_coll_description_t * table)
{
XBT_WARN("Long description of the %s models accepted by this simulator:\n", category);
- for (int i = 0; table[i].name; i++)
- XBT_WARN(" %s: %s\n", table[i].name, table[i].description);
+ for (int i = 0; not table[i].name.empty(); i++)
+ XBT_WARN(" %s: %s\n", table[i].name.c_str(), table[i].description.c_str());
}
int Colls::find_coll_description(s_mpi_coll_description_t* table, std::string name, const char* desc)
{
- for (int i = 0; table[i].name; i++)
+ for (int i = 0; not table[i].name.empty(); i++)
if (name == table[i].name) {
- if (strcmp(table[i].name,"default"))
- XBT_INFO("Switch to algorithm %s for collective %s",table[i].name,desc);
+ if (table[i].name != "default")
+ XBT_INFO("Switch to algorithm %s for collective %s",table[i].name.c_str(),desc);
return i;
}
- if (not table[0].name)
+ if (table[0].name.empty())
xbt_die("No collective is valid for '%s'! This is a bug.", name.c_str());
- std::string name_list = std::string(table[0].name);
- for (int i = 1; table[i].name; i++)
+ std::string name_list = table[0].name;
+ for (int i = 1; not table[i].name.empty(); i++)
name_list = name_list + ", " + table[i].name;
xbt_die("Collective '%s' is invalid! Valid collectives are: %s.", name.c_str(), name_list.c_str());
COLL_APPLY(COLL_SETTER,COLL_ALLTOALL_SIG,"");
COLL_APPLY(COLL_SETTER,COLL_ALLTOALLV_SIG,"");
-
void Colls::set_collectives(){
std::string selector_name = simgrid::config::get_value<std::string>("smpi/coll-selector");
if (selector_name.empty())
selector_name = "default";
- std::string name;
-
- SET_COLL(gather);
- SET_COLL(allgather);
- SET_COLL(allgatherv);
- SET_COLL(allreduce);
- SET_COLL(alltoall);
- SET_COLL(alltoallv);
- SET_COLL(reduce);
- SET_COLL(reduce_scatter);
- SET_COLL(scatter);
- SET_COLL(bcast);
- SET_COLL(barrier);
+ std::pair<std::string, std::function<void(std::string)>> setter_callbacks[] = {
+ {"gather", &Colls::set_gather}, {"allgather", &Colls::set_allgather},
+ {"allgatherv", &Colls::set_allgatherv}, {"allreduce", &Colls::set_allreduce},
+ {"alltoall", &Colls::set_alltoall}, {"alltoallv", &Colls::set_alltoallv},
+ {"reduce", &Colls::set_reduce}, {"reduce_scatter", &Colls::set_reduce_scatter},
+ {"scatter", &Colls::set_scatter}, {"bcast", &Colls::set_bcast},
+ {"barrier", &Colls::set_barrier}};
+
+ for (auto& elem : setter_callbacks) {
+ std::string name = simgrid::config::get_value<std::string>(("smpi/" + elem.first).c_str());
+ if (name.empty())
+ name = selector_name;
+
+ (elem.second)(name);
+ }
}
namespace smpi{
struct s_mpi_coll_description_t {
- const char *name;
- const char *description;
+ std::string name;
+ std::string description;
void *coll;
};
/** \ingroup smpi_simulation
* \brief Registers a running instance of a MPI program.
*
- * FIXME : remove MSG from the loop at some point.
* \param name the reference name of the function.
* \param code the main mpi function (must have a int ..(int argc, char *argv[])) prototype
* \param num_processes the size of the instance we want to deploy
void smpi_deployment_register_process(const std::string instance_id, int rank, simgrid::s4u::ActorPtr actor)
{
- if (smpi_instances.empty()) // no instance registered, we probably used smpirun.
- return;
-
Instance& instance = smpi_instances.at(instance_id);
instance.present_processes++;
extern "C" XBT_PUBLIC doublereal smpi_get_host_power_peak_at_(integer* pstate_index);
doublereal smpi_get_host_power_peak_at_(integer *pstate_index)
{
- return static_cast<doublereal>(smpi_get_host_power_peak_at((int)*pstate_index));
+ return static_cast<doublereal>(sg_host_self()->get_pstate_speed((int)*pstate_index));
}
extern "C" XBT_PUBLIC doublereal smpi_get_host_current_power_peak_();
doublereal smpi_get_host_current_power_peak_()
{
- return smpi_get_host_current_power_peak();
+ return sg_host_self()->get_speed();
}
extern "C" XBT_PUBLIC integer smpi_get_host_nb_pstates_();
integer smpi_get_host_nb_pstates_()
{
- return static_cast<integer>(smpi_get_host_nb_pstates());
+ return static_cast<integer>(sg_host_self()->get_pstate_count());
}
extern "C" XBT_PUBLIC void smpi_set_host_pstate_(integer* pstate_index);
void smpi_set_host_pstate_(integer *pstate_index)
{
- smpi_set_host_pstate(static_cast<int>(*pstate_index));
+ sg_host_set_pstate(sg_host_self(), (static_cast<int>(*pstate_index)));
}
extern "C" XBT_PUBLIC doublereal smpi_get_host_consumed_energy_();
doublereal smpi_get_host_consumed_energy_()
{
- return static_cast<doublereal>(smpi_get_host_consumed_energy());
+ return static_cast<doublereal>(sg_host_get_consumed_energy(sg_host_self()));
}
#endif
#include <cfloat> /* DBL_MAX */
#include <dlfcn.h>
#include <fcntl.h>
+#include <fstream>
+
#if not defined(__APPLE__)
#include <link.h>
#endif
-#include <fstream>
+
+#if defined(__APPLE__)
+# include <AvailabilityMacros.h>
+# ifndef MAC_OS_X_VERSION_10_12
+# define MAC_OS_X_VERSION_10_12 101200
+# endif
+# define HAVE_WORKING_MMAP (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12)
+#elif defined(__FreeBSD__)
+# define HAVE_WORKING_MMAP 0
+#else
+# define HAVE_WORKING_MMAP 1
+#endif
#if HAVE_SENDFILE
#include <sys/sendfile.h>
ActorPtr me = Actor::self();
if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
return nullptr;
- simgrid::msg::ActorExt* msgExt = static_cast<simgrid::msg::ActorExt*>(me->get_impl()->getUserData());
+ simgrid::msg::ActorExt* msgExt = static_cast<simgrid::msg::ActorExt*>(me->get_impl()->get_user_data());
return static_cast<simgrid::smpi::Process*>(msgExt->data);
}
XBT_DEBUG("Running without smpi_main(); disable smpi/privatization.");
smpi_privatize_global_variables = SmpiPrivStrategies::NONE;
}
-#if defined(__FreeBSD__)
+#if !HAVE_WORKING_MMAP
if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
- XBT_INFO("mmap privatization is broken on FreeBSD, switching to dlopen privatization instead.");
+ XBT_INFO("mmap privatization is broken on this platform, switching to dlopen privatization instead.");
smpi_privatize_global_variables = SmpiPrivStrategies::DLOPEN;
}
#endif
}
#endif
-static void smpi_init_privatization_dlopen(const char* executable)
+static void smpi_init_privatization_dlopen(std::string executable)
{
- std::string executable_copy = executable;
-
// Prepare the copy of the binary (get its size)
struct stat fdin_stat;
- stat(executable_copy.c_str(), &fdin_stat);
+ stat(executable.c_str(), &fdin_stat);
off_t fdin_size = fdin_stat.st_size;
static std::size_t rank = 0;
}
}
- simix_global->default_function = [executable_copy, fdin_size](std::vector<std::string> args) {
- return std::function<void()>([executable_copy, fdin_size, args] {
+ simix_global->default_function = [executable, fdin_size](std::vector<std::string> args) {
+ return std::function<void()>([executable, fdin_size, args] {
// Copy the dynamic library:
std::string target_executable =
- executable_copy + "_" + std::to_string(getpid()) + "_" + std::to_string(rank) + ".so";
+ executable + "_" + std::to_string(getpid()) + "_" + std::to_string(rank) + ".so";
- smpi_copy_file(executable_copy, target_executable, fdin_size);
+ smpi_copy_file(executable, target_executable, fdin_size);
// if smpi/privatize-libs is set, duplicate pointed lib and link each executable copy to a different one.
std::string target_lib;
for (auto const& libpath : privatize_libs_paths) {
};
}
-static void smpi_init_privatization_no_dlopen(const char* executable)
+static void smpi_init_privatization_no_dlopen(std::string executable)
{
if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP)
smpi_prepare_global_memory_segment();
// Load the dynamic library and resolve the entry point:
- void* handle = dlopen(executable, RTLD_LAZY | RTLD_LOCAL);
+ void* handle = dlopen(executable.c_str(), RTLD_LAZY | RTLD_LOCAL);
if (handle == nullptr)
- xbt_die("dlopen failed for %s: %s (errno: %d -- %s)", executable, dlerror(), errno, strerror(errno));
+ xbt_die("dlopen failed for %s: %s (errno: %d -- %s)", executable.c_str(), dlerror(), errno, strerror(errno));
smpi_entry_point_type entry_point = smpi_resolve_function(handle);
if (not entry_point)
- xbt_die("main not found in %s", executable);
+ xbt_die("main not found in %s", executable.c_str());
if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP)
smpi_backup_global_memory_segment();
TRACE_global_init();
SIMIX_global_init(&argc, argv);
- MSG_init(&argc, argv);
+ MSG_init(&argc, argv); // FIXME Remove this MSG call. Once it's removed, we can remove the msg header include as well
SMPI_switch_data_segment = &smpi_switch_data_segment;
finalization_barrier_ = barrier;
actor_ = simgrid::s4u::Actor::self();
- static_cast<simgrid::msg::ActorExt*>(actor_->get_impl()->getUserData())->data = this;
+ static_cast<simgrid::msg::ActorExt*>(actor_->get_impl()->get_user_data())->data = this;
if (*argc > 3) {
memmove(&(*argv)[0], &(*argv)[2], sizeof(char*) * (*argc - 2));
}
if (argc != nullptr && argv != nullptr) {
simgrid::s4u::ActorPtr proc = simgrid::s4u::Actor::self();
- proc->get_impl()->context->set_cleanup(&MSG_process_cleanup_from_SIMIX);
+ proc->get_impl()->context_->set_cleanup(&MSG_process_cleanup_from_SIMIX);
char* instance_id = (*argv)[1];
try {
} // Replay Namespace
}} // namespace simgrid::smpi
-static std::vector<simgrid::smpi::replay::RequestStorage> storage;
+static std::unordered_map<aid_t, simgrid::smpi::replay::RequestStorage> storage;
/** @brief Only initialize the replay, don't do it for real */
void smpi_replay_init(int* argc, char*** argv)
{
smpi_process()->set_replaying(true);
int my_proc_id = simgrid::s4u::this_actor::get_pid();
- storage.resize(smpi_process_count());
TRACE_smpi_init(my_proc_id);
TRACE_smpi_computing_init(my_proc_id);
xbt_replay_action_register("comm_size", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
xbt_replay_action_register("comm_split",[](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
xbt_replay_action_register("comm_dup", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
- xbt_replay_action_register("send", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("send", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("isend", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("isend", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("recv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("recv", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("irecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("irecv", storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("test", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::TestAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("wait", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
- xbt_replay_action_register("waitall", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAllAction(storage[simgrid::s4u::this_actor::get_pid()-1]).execute(action); });
+ xbt_replay_action_register("send", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("send", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("isend", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendAction("isend", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("recv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("recv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("irecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("irecv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("test", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::TestAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("wait", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
+ xbt_replay_action_register("waitall", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAllAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); });
xbt_replay_action_register("barrier", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::BarrierAction().execute(action); });
xbt_replay_action_register("bcast", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::BcastAction().execute(action); });
xbt_replay_action_register("reduce", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::ReduceAction().execute(action); });
{
static int active_processes = 0;
active_processes++;
+ storage[simgrid::s4u::this_actor::get_pid()] = simgrid::smpi::replay::RequestStorage();
simgrid::xbt::replay_runner(*argc, *argv);
/* and now, finalize everything */
/* One active process will stop. Decrease the counter*/
- unsigned int count_requests = storage[simgrid::s4u::this_actor::get_pid() - 1].size();
+ unsigned int count_requests = storage[simgrid::s4u::this_actor::get_pid()].size();
XBT_DEBUG("There are %ud elements in reqq[*]", count_requests);
if (count_requests > 0) {
MPI_Request requests[count_requests];
MPI_Status status[count_requests];
unsigned int i=0;
- for (auto const& pair : storage[simgrid::s4u::this_actor::get_pid() - 1].get_store()) {
+ for (auto const& pair : storage[simgrid::s4u::this_actor::get_pid()].get_store()) {
requests[i] = pair.second;
i++;
}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "smpi_comm.hpp"
-#include "private.hpp"
-#include "simgrid/s4u/Host.hpp"
#include "smpi_coll.hpp"
#include "smpi_datatype.hpp"
#include "smpi_process.hpp"
#include "smpi_request.hpp"
-#include "smpi_status.hpp"
#include "smpi_win.hpp"
-#include "src/simix/smx_host_private.hpp"
-#include "src/simix/smx_private.hpp"
+#include "src/surf/HostImpl.hpp"
-#include <algorithm>
#include <climits>
-#include <vector>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_comm, smpi, "Logging specific to SMPI (comm)");
}
//identify neighbours in comm
//get the indices of all processes sharing the same simix host
- auto& process_list = sg_host_self()->extension<simgrid::simix::Host>()->process_list;
+ auto& process_list = sg_host_self()->pimpl_->process_list_;
int intra_comm_size = 0;
int min_index = INT_MAX; // the minimum index will be the leader
for (auto& actor : process_list) {
- int index = actor.pid;
+ int index = actor.pid_;
if (this->group()->rank(actor.iface()) != MPI_UNDEFINED) { // Is this process in the current group?
intra_comm_size++;
if (index < min_index)
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include "src/simix/smx_private.hpp"
+
#include <string>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_host, surf, "Logging specific to the SURF host module");
delete piface_->pimpl_;
piface_->pimpl_ = this;
}
+HostImpl::~HostImpl()
+{
+ /* All processes should be gone when the host is turned off (by the end of the simulation). */
+ if (not process_list_.empty()) {
+ std::string msg = std::string("Shutting down host, but it's not empty:");
+ for (auto const& process : process_list_)
+ msg += "\n\t" + std::string(process.get_name());
+
+ SIMIX_display_process_status();
+ THROWF(arg_error, 0, "%s", msg.c_str());
+ }
+ for (auto const& arg : auto_restart_processes_)
+ delete arg;
+ auto_restart_processes_.clear();
+ for (auto const& arg : boot_processes_)
+ delete arg;
+ boot_processes_.clear();
+}
+
+/** Re-starts all the actors that are marked as restartable.
+ *
+ * Weird things will happen if you turn on an host that is already on. S4U is fool-proof, not this.
+ */
+void HostImpl::turn_on()
+{
+ for (auto const& arg : boot_processes_) {
+ XBT_DEBUG("Booting Process %s(%s) right now", arg->name.c_str(), arg->host->get_cname());
+ smx_actor_t actor = simix_global->create_process_function(arg->name.c_str(), arg->code, nullptr, arg->host,
+ arg->properties.get(), nullptr);
+ if (arg->kill_time >= 0)
+ simcall_process_set_kill_time(actor, arg->kill_time);
+ if (arg->auto_restart)
+ actor->auto_restart_ = arg->auto_restart;
+ }
+}
+/** Kill all actors hosted here */
+void HostImpl::turn_off()
+{
+ if (not process_list_.empty()) {
+ for (auto& actor : process_list_) {
+ SIMIX_process_kill(&actor, SIMIX_process_self());
+ XBT_DEBUG("Killing %s@%s on behalf of %s which turned off that host.", actor.get_cname(),
+ actor.host_->get_cname(), SIMIX_process_self()->get_cname());
+ }
+ }
+}
+std::vector<s4u::ActorPtr> HostImpl::get_all_actors()
+{
+ std::vector<s4u::ActorPtr> res;
+ for (auto& actor : process_list_)
+ res.push_back(actor.ciface());
+ return res;
+}
+int HostImpl::get_actor_count()
+{
+ return process_list_.size();
+}
std::vector<const char*> HostImpl::get_attached_storages()
{
std::vector<const char*> storages;
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+#ifndef SURF_HOST_INTERFACE_HPP_
+#define SURF_HOST_INTERFACE_HPP_
+
+#include "StorageImpl.hpp"
#include "cpu_interface.hpp"
#include "network_interface.hpp"
+#include "src/simix/ActorImpl.hpp"
#include "src/surf/PropertyHolder.hpp"
-#include "StorageImpl.hpp"
+#include <vector>
-#ifndef SURF_HOST_INTERFACE_HPP_
-#define SURF_HOST_INTERFACE_HPP_
+namespace simgrid {
+namespace surf {
/*********
* Model *
*********/
-namespace simgrid {
-namespace surf {
-
/** @ingroup SURF_host_interface
* @brief SURF Host model interface class
* @details A model is an object which handle the interactions between its Resources and its Actions
public:
explicit HostImpl(s4u::Host* host);
- virtual ~HostImpl() = default;
+ virtual ~HostImpl();
/** @brief Get the vector of storages (by names) attached to the Host */
virtual std::vector<const char*> get_attached_storages();
std::map<std::string, simgrid::surf::StorageImpl*> storage_;
simgrid::s4u::Host* piface_ = nullptr;
+
+ void turn_on();
+ void turn_off();
+ std::vector<s4u::ActorPtr> get_all_actors();
+ int get_actor_count();
+
+ typedef boost::intrusive::list<
+ kernel::actor::ActorImpl,
+ boost::intrusive::member_hook<kernel::actor::ActorImpl, boost::intrusive::list_member_hook<>,
+ &kernel::actor::ActorImpl::host_process_list_hook>>
+ ActorList;
+
+ // FIXME: make these private
+ ActorList process_list_;
+ std::vector<kernel::actor::ProcessArg*> auto_restart_processes_;
+ std::vector<kernel::actor::ProcessArg*> boot_processes_;
};
}
}
* @brief Create a Cpu
*
* @param host The host that will have this CPU
- * @param speedPerPstate Processor speed (in Flops) of each pstate. This ignores any potential external load coming from a trace.
+ * @param speed_per_pstate Processor speed (in Flops) of each pstate.
+ * This ignores any potential external load coming from a trace.
* @param core The number of core of this Cpu
*/
virtual Cpu* create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core) = 0;
* @brief Execute some quantity of computation on more than one core
*
* @param size The value of the processing amount (in flop) needed to process
- * @param requestedCores The desired amount of cores. Must be >= 1
+ * @param requested_cores The desired amount of cores. Must be >= 1
* @return The CpuAction corresponding to the processing
*/
virtual simgrid::kernel::resource::Action* execution_start(double size, int requested_cores) = 0;
#include "simgrid/kernel/routing/VivaldiZone.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "src/include/simgrid/sg_config.hpp"
+#include "src/include/surf/surf.hpp"
#include "src/kernel/EngineImpl.hpp"
#include "src/simix/smx_host_private.hpp"
#include "src/simix/smx_private.hpp"
bool auto_restart = actor->on_failure != simgrid::kernel::routing::ActorOnFailure::DIE;
std::string actor_name = actor->args[0];
- std::function<void()> code = factory(std::move(actor->args));
+ simgrid::simix::ActorCode code = factory(std::move(actor->args));
std::shared_ptr<std::unordered_map<std::string, std::string>> properties(actor->properties);
simgrid::kernel::actor::ProcessArg* arg =
new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, properties, auto_restart);
- host->extension<simgrid::simix::Host>()->boot_processes.push_back(arg);
+ host->pimpl_->boot_processes_.push_back(arg);
if (start_time > SIMIX_get_clock()) {
if (arg->kill_time >= 0)
simcall_process_set_kill_time(actor, arg->kill_time);
if (auto_restart)
- SIMIX_process_auto_restart_set(actor, auto_restart);
+ actor->set_auto_restart(auto_restart);
delete arg;
});
} else { // start_time <= SIMIX_get_clock()
if (arg->kill_time >= 0)
simcall_process_set_kill_time(actor, arg->kill_time);
if (auto_restart)
- SIMIX_process_auto_restart_set(actor, auto_restart);
+ actor->set_auto_restart(auto_restart);
}
}
}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/s4u/Engine.hpp"
+#include "src/include/surf/surf.hpp"
#include "src/instr/instr_private.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
+
#include <algorithm>
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
* \brief Outputs the content of the structure (debugging purpose)
*
* \param dict the exibitionist
- * \param output a function to dump each data in the tree (check @ref xbt_dict_dump_output_string)
+ * \param output a function to dump each data in the tree
*
- * Outputs the content of the structure. (for debugging purpose). \a output is a function to output the data. If nullptr,
- * data won't be displayed.
+ * Outputs the content of the structure. (for debugging purpose).
+ * \a output is a function to output the data. If nullptr, data won't be displayed.
*/
void xbt_dict_dump(xbt_dict_t dict, void_f_pvoid_t output)
{
/* log - a generic logging facility in the spirit of log4j */
-/* Copyright (c) 2004-2018. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2004-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-foreach(x actor
+foreach(x actor actor-autorestart
comm-pt2pt
cloud-interrupt-migration
concurrent_rw storage_client_server host_on_off_wait listen_async pid )
## Add the tests.
## Some need to be run with all factories, some need not tesh to run
-foreach(x actor cloud-interrupt-migration concurrent_rw)
+foreach(x actor actor-autorestart cloud-interrupt-migration concurrent_rw)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh)
ADD_TESH_FACTORIES(tesh-s4u-${x} "thread;ucontext;raw;boost" --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x}/${x}.tesh)
endforeach()
--- /dev/null
+/* Copyright (c) 2017-2018. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+
+static void dummy()
+{
+ XBT_INFO("I start");
+ simgrid::s4u::this_actor::sleep_for(200);
+ XBT_INFO("I stop");
+}
+
+static void autostart()
+{
+ simgrid::s4u::Host* host = simgrid::s4u::Host::by_name("Fafard");
+ XBT_INFO("starting a dummy process on %s ", host->get_cname());
+
+ simgrid::s4u::ActorPtr dummy_actor = simgrid::s4u::Actor::create("Dummy", host, dummy);
+ dummy_actor->set_auto_restart(true);
+
+ simgrid::s4u::this_actor::sleep_for(50);
+
+ XBT_INFO("powering off %s", host->get_cname());
+ host->turn_off();
+
+ simgrid::s4u::this_actor::sleep_for(10);
+
+ XBT_INFO("powering on %s", host->get_cname());
+ host->turn_on();
+ simgrid::s4u::this_actor::sleep_for(200);
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ e.load_platform(argv[1]);
+
+ simgrid::s4u::Actor::create("Autostart", simgrid::s4u::Host::by_name("Tremblay"), autostart);
+
+ e.run();
+ XBT_INFO("Simulation time %g", e.get_clock());
+
+ return 0;
+}
--- /dev/null
+$ ./actor-autorestart ${platfdir}/small_platform.xml
+> [Tremblay:Autostart:(1) 0.000000] [s4u_test/INFO] starting a dummy process on Fafard
+> [Fafard:Dummy:(2) 0.000000] [s4u_test/INFO] I start
+> [Tremblay:Autostart:(1) 50.000000] [s4u_test/INFO] powering off Fafard
+> [Tremblay:Autostart:(1) 60.000000] [s4u_test/INFO] powering on Fafard
+> [Fafard:Dummy:(2) 60.000000] [s4u_test/INFO] I start
+> [Fafard:Dummy:(2) 260.000000] [s4u_test/INFO] I stop
+> [260.000000] [s4u_test/INFO] Simulation time 260
double min_func = func(min);
double max_func = func(max);
- if ((min_func > 0 && max_func > 0))
+ if (min_func > 0 && max_func > 0)
return min - 1.0;
- if ((min_func < 0 && max_func < 0))
+ if (min_func < 0 && max_func < 0)
return max + 1.0;
- if ((min_func > 0 && max_func < 0))
+ if (min_func > 0 && max_func < 0)
abort();
SHOW_EXPR(min_error);
--- /dev/null
+"""
+From: https://raw.githubusercontent.com/wesnoth/wesnoth/b28d8d469af047cbbb20b18757c07b1bfc6afa31/utils/appveyor/irc-notify.py
+which is from: https://raw.githubusercontent.com/nexB/scancode-toolkit/48aeaf76ce9f53d02223c41c1b2ad1d1ad73b851/etc/scripts/irc-notify.py
+
+Copyright (C) 2015-2016 Christopher R. Wood
+
+This program is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this
+program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301 USA.
+
+Simple AppVeyor IRC notification script.
+
+Modified by nexB on October 2016:
+ - rework the handling of environment variables.
+ - made the script use functions
+ - support only Appveyor loading its environment variable to craft IRC notices.
+
+Modified by Jyrki Vesterinen on November 2016:
+
+ - join the channel instead of sending an external message.
+
+The first argument is a Freenode channel. Other arguments passed to the script will be
+sent as notice messages content and any {var}-formatted environment variables will be
+expanded automatically, replaced with a corresponding Appveyor environment variable
+value. se commas to delineate multiple messages.
+
+Modified by Martin Quinson on June 2018:
+
+ - Use OFTC instead of Freenode
+
+Example:
+export APPVEYOR_URL=https://ci.appveyor.com
+export APPVEYOR_PROJECT_NAME=attributecode
+export APPVEYOR_REPO_COMMIT_AUTHOR=pombredanne
+export APPVEYOR_REPO_COMMIT_TIMESTAMP=2016-10-31
+export APPVEYOR_REPO_PROVIDER=gihub
+export APPVEYOR_REPO_BRANCH=repo_branch
+export APPVEYOR_PULL_REQUEST_TITLE=pull_request_title
+export APPVEYOR_BUILD_VERSION=1
+export APPVEYOR_REPO_COMMIT=22c95b72e29248dc4de9b85e590ee18f6f587de8
+export APPVEYOR_REPO_COMMIT_MESSAGE="some IRC test"
+export APPVEYOR_ACCOUNT_NAME=nexB
+export APPVEYOR_PULL_REQUEST_NUMBER=pull_request_number
+export APPVEYOR_REPO_NAME=nexB/attributecode
+python etc/scripts/irc-notify.py aboutcode '[{project_name}:{branch}] {short_commit}: "{message}" ({author}) {color_red}Succeeded','Details: {build_url} | Commit: {commit_url}'
+
+See also https://github.com/gridsync/gridsync/blob/master/appveyor.yml for examples
+in Appveyor's YAML:
+
+ on_success:
+ - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}"
+ on_failure:
+ - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}"
+
+"""
+
+import random, socket, ssl, sys, time
+
+
+def appveyor_vars():
+ """
+ Return a dict of key value crafted from appveyor environment variables.
+ """
+ from os import environ
+
+ appveyor_url = environ.get('APPVEYOR_URL')
+ message_extended = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED')
+ configuration_name = environ.get('CONFIGURATION')
+ branch = environ.get('APPVEYOR_REPO_BRANCH')
+ author = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR')
+ author_email = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL')
+ timestamp = environ.get('APPVEYOR_REPO_COMMIT_TIMESTAMP')
+ repo_provider = environ.get('APPVEYOR_REPO_PROVIDER')
+ project_name = environ.get('APPVEYOR_PROJECT_NAME')
+ project_slug = environ.get('APPVEYOR_PROJECT_SLUG')
+ pull_request_title = environ.get('APPVEYOR_PULL_REQUEST_TITLE')
+ build_version = environ.get('APPVEYOR_BUILD_VERSION')
+ commit = environ.get('APPVEYOR_REPO_COMMIT')
+ message = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE')
+ account_name = environ.get('APPVEYOR_ACCOUNT_NAME')
+ pull_request_number = environ.get('APPVEYOR_PULL_REQUEST_NUMBER')
+ repo_name = environ.get('APPVEYOR_REPO_NAME')
+
+ short_commit = commit[:7]
+ build_url = '{appveyor_url}/project/{account_name}/{project_slug}/build/{build_version}'.format(**locals())
+ commit_url = 'https://{repo_provider}.com/{repo_name}/commit/{commit}'.format(**locals())
+
+ apvy_vars = dict(
+ appveyor_url=appveyor_url,
+ account_name=account_name,
+ project_name=project_name,
+ project_slug=project_slug,
+ build_version=build_version,
+
+ build_url=build_url,
+
+ repo_provider=repo_provider,
+ repo_name=repo_name,
+ branch=branch,
+ configuration_name=configuration_name,
+ author=author,
+ author_email=author_email,
+ timestamp=timestamp,
+ commit=commit,
+ short_commit=short_commit,
+ message=message,
+ message_extended=message_extended,
+
+ pull_request_title=pull_request_title,
+ pull_request_number=pull_request_number,
+
+ commit_url=commit_url,
+
+ color_green='\x033',
+ color_red='\x034',
+ bold='\x02',
+ underline='\x1f',
+ plain='\x0f',
+ )
+ return apvy_vars
+
+
+if __name__ == '__main__':
+ apvy_vars = appveyor_vars()
+
+ channel = sys.argv[1]
+ messages = sys.argv[2:]
+ messages = ' '.join(messages)
+ messages = messages.split(',')
+ messages = [msg.format(**apvy_vars).strip() for msg in messages]
+
+ irc_username = 'Appveyor'
+ irc_nick = irc_username + str(random.randint(1, 9999))
+
+ try:
+ # establish connection
+ irc_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+ irc_sock.connect((socket.gethostbyname('irc.oftc.net'), 6697))
+ irc_sock.send('NICK {0}\r\nUSER {0} * 0 :{0}\r\n'.format(irc_username).encode('utf_8'))
+ irc_file = irc_sock.makefile()
+
+ while irc_file:
+ line = irc_file.readline()
+ print(line.rstrip())
+ response = line.split()
+
+ if response[0] == 'PING':
+ irc_file.send('PONG {}\r\n'.format(reponse[1]).encode('utf_8'))
+
+ elif response[1] == '433':
+ irc_sock.send('NICK {}\r\n'.format(irc_nick).encode('utf_8'))
+
+ elif response[1] == '001':
+ time.sleep(5)
+ # join the channel
+ irc_sock.send('JOIN #{}\r\n'.format(channel).encode('utf_8'))
+ # send messages
+ for msg in messages:
+ print('PRIVMSG #{} :{}'.format(channel, msg))
+ irc_sock.send('PRIVMSG #{} :{}\r\n'.format(channel, msg).encode('utf_8'))
+ time.sleep(5)
+ # leave the channel
+ irc_sock.send('PART #{}\r\n'.format(channel).encode('utf_8'))
+ sys.exit()
+ except:
+ e = sys.exc_info()[0]
+ print(e)
+ sys.exit()
src/mc/remote/mc_protocol.h
src/mc/remote/mc_protocol.cpp
+ src/mc/sosp/PageStore.hpp
+ src/mc/sosp/PageStore.cpp
+ src/mc/sosp/ChunkedData.hpp
+ src/mc/sosp/ChunkedData.cpp
+ src/mc/sosp/RegionSnapshot.cpp
+ src/mc/sosp/RegionSnapshot.hpp
+ src/mc/sosp/mc_checkpoint.cpp
+ src/mc/sosp/mc_snapshot.hpp
+ src/mc/sosp/mc_snapshot.cpp
+ src/mc/sosp/mc_page_snapshot.cpp
+
src/mc/AddressSpace.hpp
src/mc/Frame.hpp
src/mc/Frame.cpp
src/mc/ModelChecker.cpp
src/mc/ObjectInformation.hpp
src/mc/ObjectInformation.cpp
- src/mc/PageStore.hpp
- src/mc/PageStore.cpp
- src/mc/ChunkedData.hpp
- src/mc/ChunkedData.cpp
- src/mc/RegionSnapshot.cpp
- src/mc/RegionSnapshot.hpp
src/mc/Type.hpp
src/mc/Variable.hpp
src/mc/mc_forward.hpp
src/mc/mc_unw.hpp
src/mc/mc_unw.cpp
src/mc/mc_unw_vmread.cpp
- src/mc/mc_checkpoint.cpp
- src/mc/mc_snapshot.hpp
- src/mc/mc_snapshot.cpp
- src/mc/mc_page_snapshot.cpp
src/mc/mc_comm_pattern.cpp
src/mc/mc_comm_pattern.hpp
src/mc/compare.cpp
### Simgrid Lib sources
set(simgrid_sources
- ${PLUGINS_SRC}
- ${BINDINGS_SRC}
- ${MC_SRC_BASE}
- ${MSG_SRC}
${S4U_SRC}
- ${SIMDAG_SRC}
${SIMGRID_SRC}
+ ${MC_SRC_BASE}
${SIMIX_SRC}
${SURF_SRC}
${TRACING_SRC}
${XBT_SRC}
+ ${PLUGINS_SRC}
+ ${BINDINGS_SRC}
+ ${MSG_SRC}
+ ${SIMDAG_SRC}
)
if(${SIMGRID_HAVE_JEDULE})
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc
)
-### Fill in the "make gforge-gforge" target ###
+### Fill in the "make gforge-sync" target ###
set(RSYNC_CMD rsync --verbose --cvs-exclude --compress --delete --delete-excluded --rsh=ssh --ignore-times --recursive --links --times --omit-dir-times --perms --chmod=a+rX,ug+w,o-w,Dg+s)
COMMAND ${RSYNC_CMD} doc/html/ scm.gforge.inria.fr:/home/groups/simgrid/htdocs/simgrid/${release_version}/doc/ || true
- COMMAND ${RSYNC_CMD} doc/html/simgrid_modules2.png doc/html/simgrid_modules.png doc/webcruft/simgrid_logo_2011.png
- doc/webcruft/simgrid_logo_2011_small.png scm.gforge.inria.fr:/home/groups/simgrid/htdocs/simgrid/${release_version}/
+ COMMAND ${RSYNC_CMD} doc/html/simgrid_modules2.png doc/html/simgrid_modules.png /${CMAKE_HOME_DIRECTORY}/doc/webcruft/simgrid_logo_2011.png
+ /${CMAKE_HOME_DIRECTORY}/doc/webcruft/simgrid_logo_2011_small.png scm.gforge.inria.fr:/home/groups/simgrid/htdocs/simgrid/${release_version}/
COMMAND ${RSYNC_CMD} ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid.dtd scm.gforge.inria.fr:/home/groups/simgrid/htdocs/simgrid/
COMMAND ${RSYNC_CMD} ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid.dtd scm.gforge.inria.fr:/home/groups/simgrid/htdocs/simgrid/${release_version}/simgrid.dtd
src/xbt/config.cpp
)
-if(SIMGRID_HAVE_MC)
- set(FILES_CONTAINING_UNITTESTS ${FILES_CONTAINING_UNITTESTS}
- src/mc/PageStore.cpp
- src/mc/mc_snapshot.cpp
- )
-endif()
-
#### Nothing to change below this line to add a new tested file
################################################################