#include "smx_private.h"
#include "xbt/sysdep.h"
-#include "xbt/log.h"
-#include "xbt/dict.h"
#include "mc/mc.h"
#include "src/mc/mc_replay.h"
+#include "src/surf/virtual_machine.hpp"
+#include "src/surf/HostImpl.hpp"
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_host, simix,
- "SIMIX hosts");
+#include "src/simix/SynchroExec.hpp"
+#include "src/simix/SynchroComm.hpp"
-static void SIMIX_execution_finish(smx_synchro_t synchro);
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_host, simix, "SIMIX hosts");
/**
* \brief Internal function to create a SIMIX host.
void SIMIX_host_create(sg_host_t host) // FIXME: braindead prototype. Take sg_host as parameter
{
smx_host_priv_t smx_host = xbt_new0(s_smx_host_priv_t, 1);
- s_smx_process_t proc;
/* Host structure */
- smx_host->process_list =
- xbt_swag_new(xbt_swag_offset(proc, host_proc_hookup));
+ simgrid::simix::Process proc;
+ smx_host->process_list = xbt_swag_new(xbt_swag_offset(proc, host_proc_hookup));
/* Update global variables */
sg_host_simix_set(host, smx_host);
xbt_assert((host != NULL), "Invalid parameters");
- if (surf_host_get_state(surf_host_resource_priv(h))==SURF_RESOURCE_OFF) {
- surf_host_set_state(surf_host_resource_priv(h), SURF_RESOURCE_ON);
+ if (h->isOff()) {
+ simgrid::surf::HostImpl* surf_host = h->extension<simgrid::surf::HostImpl>();
+ surf_host->turnOn();
unsigned int cpt;
smx_process_arg_t arg;
}
}
-void simcall_HANDLER_host_off(smx_simcall_t simcall, sg_host_t h)
-{
- SIMIX_host_off(h, simcall->issuer);
-}
-
/**
* \brief Stop the host if it is on
*
xbt_assert((host != NULL), "Invalid parameters");
- if (surf_host_get_state(surf_host_resource_priv(h))==SURF_RESOURCE_ON) {
- surf_host_set_state(surf_host_resource_priv(h), SURF_RESOURCE_OFF);
+ if (h->isOn()) {
+ simgrid::surf::HostImpl* surf_host = h->extension<simgrid::surf::HostImpl>();
+ surf_host->turnOff();
/* Clean Simulator data */
if (xbt_swag_size(host->process_list) != 0) {
XBT_DEBUG("Killing %s on %s by %s", process->name, sg_host_get_name(process->host), issuer->name);
}
}
+ } else {
+ XBT_INFO("Host %s is already off",h->name().c_str());
}
}
if (host == NULL || SIMIX_process_self() == simix_global->maestro_process)
return "";
- return SIMIX_host_get_name(host);
-}
-
-xbt_dict_t SIMIX_host_get_properties(sg_host_t host){
- return surf_host_get_properties(surf_host_resource_priv(host));
-}
-
-
-xbt_swag_t SIMIX_host_get_process_list(sg_host_t host){
- smx_host_priv_t host_priv = sg_host_simix(host);
-
- return host_priv->process_list;
-}
-
-
-double SIMIX_host_get_current_power_peak(sg_host_t host) {
- return surf_host_get_current_power_peak(host);
-}
-
-double SIMIX_host_get_power_peak_at(sg_host_t host, int pstate_index) {
- return surf_host_get_power_peak_at(host, pstate_index);
-}
-
-void SIMIX_host_set_pstate(sg_host_t host, int pstate_index) {
- surf_host_set_pstate(host, pstate_index);
-}
-double SIMIX_host_get_wattmin_at(sg_host_t host,int pstate) {
- return surf_host_get_wattmin_at(host,pstate);
-}
-double SIMIX_host_get_wattmax_at(sg_host_t host,int pstate) {
- return surf_host_get_wattmax_at(host,pstate);
+ return sg_host_get_name(host);
}
void _SIMIX_host_free_process_arg(void *data)
{
smx_process_arg_t arg = *(smx_process_arg_t*)data;
- int i;
- for (i = 0; i < arg->argc; i++)
+ for (int i = 0; i < arg->argc; i++)
xbt_free(arg->argv[i]);
xbt_free(arg->argv);
- xbt_free(arg->name);
- xbt_free(arg);
+ delete arg;
}
/**
* \brief Add a process to the list of the processes that the host will restart when it comes back
if (!sg_host_simix(host)->auto_restart_processes) {
sg_host_simix(host)->auto_restart_processes = xbt_dynar_new(sizeof(smx_process_arg_t),_SIMIX_host_free_process_arg);
}
- smx_process_arg_t arg = xbt_new(s_smx_process_arg_t,1);
- arg->name = xbt_strdup(name);
+ smx_process_arg_t arg = new s_smx_process_arg_t();
+ arg->name = name;
arg->code = code;
arg->data = data;
arg->hostname = hostname;
arg->argv = xbt_new(char*,argc + 1);
- int i;
- for (i = 0; i < argc; i++) {
+ for (int i = 0; i < argc; i++)
arg->argv[i] = xbt_strdup(argv[i]);
- }
arg->argv[argc] = NULL;
arg->properties = properties;
arg->auto_restart = auto_restart;
- if( sg_host_get_state(host) == SURF_RESOURCE_OFF
- && !xbt_dict_get_or_null(watched_hosts_lib,sg_host_get_name(host))){
+ if( host->isOff() && !xbt_dict_get_or_null(watched_hosts_lib,sg_host_get_name(host))){
xbt_dict_set(watched_hosts_lib,sg_host_get_name(host),host,NULL);
- XBT_DEBUG("Have pushed host %s to watched_hosts_lib because state == SURF_RESOURCE_OFF",sg_host_get_name(host));
+ XBT_DEBUG("Push host %s to watched_hosts_lib because state == SURF_RESOURCE_OFF",sg_host_get_name(host));
}
xbt_dynar_push_as(sg_host_simix(host)->auto_restart_processes,smx_process_arg_t,arg);
}
/**
* \brief Restart the list of processes that have been registered to the host
*/
-void SIMIX_host_restart_processes(sg_host_t host)
+void SIMIX_host_autorestart(sg_host_t host)
{
unsigned int cpt;
smx_process_arg_t arg;
xbt_dynar_reset(process_list);
}
-void SIMIX_host_autorestart(sg_host_t host)
-{
- if(simix_global->autorestart)
- simix_global->autorestart(host);
- else
- xbt_die("No function for simix_global->autorestart");
+smx_synchro_t simcall_HANDLER_execution_start(smx_simcall_t simcall,
+ const char* name, double flops_amount, double priority, double bound, unsigned long affinity_mask) {
+ return SIMIX_execution_start(simcall->issuer, name,flops_amount,priority,bound,affinity_mask);
}
-smx_synchro_t simcall_HANDLER_process_execute(smx_simcall_t simcall,
- const char* name, double flops_amount, double priority, double bound, unsigned long affinity_mask) {
- return SIMIX_process_execute(simcall->issuer, name,flops_amount,priority,bound,affinity_mask);
-}
-smx_synchro_t SIMIX_process_execute(smx_process_t issuer, const char *name,
+smx_synchro_t SIMIX_execution_start(smx_process_t issuer, const char *name,
double flops_amount, double priority, double bound, unsigned long affinity_mask){
/* alloc structures and initialize */
- smx_synchro_t synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
- synchro->type = SIMIX_SYNC_EXECUTE;
- synchro->name = xbt_strdup(name);
- synchro->state = SIMIX_RUNNING;
- synchro->execution.host = issuer->host;
- synchro->category = NULL;
+ simgrid::simix::Exec *exec = new simgrid::simix::Exec();
+ exec->name = xbt_strdup(name);
+ exec->state = SIMIX_RUNNING;
+ exec->host = issuer->host;
/* set surf's action */
if (!MC_is_active() && !MC_record_replay_is_active()) {
- synchro->execution.surf_exec = surf_host_execute(issuer->host, flops_amount);
- surf_action_set_data(synchro->execution.surf_exec, synchro);
- surf_action_set_priority(synchro->execution.surf_exec, priority);
+ exec->surf_exec = issuer->host->pimpl_cpu->execution_start(flops_amount);
+ exec->surf_exec->setData(exec);
+ exec->surf_exec->setPriority(priority);
- /* Note (hypervisor): for multicore, the bound value being passed to the
- * surf layer should not be zero (i.e., unlimited). It should be the
- * capacity of a CPU core. */
- if (bound == 0)
- surf_cpu_action_set_bound(synchro->execution.surf_exec, sg_host_get_speed(issuer->host));
- else
- surf_cpu_action_set_bound(synchro->execution.surf_exec, bound);
+ if (bound != 0)
+ static_cast<simgrid::surf::CpuAction*>(exec->surf_exec)->setBound(bound);
if (affinity_mask != 0) {
/* just a double check to confirm that this host is the host where this task is running. */
- xbt_assert(synchro->execution.host == issuer->host);
- surf_cpu_action_set_affinity(synchro->execution.surf_exec, issuer->host, affinity_mask);
+ xbt_assert(exec->host == issuer->host);
+ static_cast<simgrid::surf::CpuAction*>(exec->surf_exec)
+ ->setAffinity(issuer->host->pimpl_cpu, affinity_mask);
}
}
- XBT_DEBUG("Create execute synchro %p: %s", synchro, synchro->name);
+ XBT_DEBUG("Create execute synchro %p: %s", exec, exec->name);
- return synchro;
+ return exec;
}
-smx_synchro_t SIMIX_process_parallel_execute(const char *name,
+smx_synchro_t SIMIX_execution_parallel_start(const char *name,
int host_nb, sg_host_t *host_list,
double *flops_amount, double *bytes_amount,
double amount, double rate){
- sg_host_t*host_list_cpy = NULL;
+ sg_host_t *host_list_cpy = NULL;
int i;
/* alloc structures and initialize */
- smx_synchro_t synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
- synchro->type = SIMIX_SYNC_PARALLEL_EXECUTE;
- synchro->name = xbt_strdup(name);
- synchro->state = SIMIX_RUNNING;
- synchro->execution.host = NULL; /* FIXME: do we need the list of hosts? */
- synchro->category = NULL;
+ simgrid::simix::Exec *exec = new simgrid::simix::Exec();
+ exec->name = xbt_strdup(name);
+ exec->state = SIMIX_RUNNING;
+ exec->host = nullptr; /* FIXME: do we need the list of hosts? */
/* set surf's synchro */
host_list_cpy = xbt_new0(sg_host_t, host_nb);
for (i = 0; i < host_nb; i++)
host_list_cpy[i] = host_list[i];
-
- /* FIXME: what happens if host_list contains VMs and PMs. If
- * execute_parallel_task() does not change the state of the model, we can mix
- * them. */
- surf_model_t ws_model = surf_resource_model(host_list[0], SURF_HOST_LEVEL);
+ /* Check that we are not mixing VMs and PMs in the parallel task */
+ simgrid::surf::HostImpl *host = host_list[0]->extension<simgrid::surf::HostImpl>();
+ bool is_a_vm = (nullptr != dynamic_cast<simgrid::surf::VirtualMachine*>(host));
for (i = 1; i < host_nb; i++) {
- surf_model_t ws_model_tmp = surf_resource_model(host_list[i], SURF_HOST_LEVEL);
- if (ws_model_tmp != ws_model) {
- XBT_CRITICAL("mixing VMs and PMs is not supported");
- DIE_IMPOSSIBLE;
- }
+ bool tmp_is_a_vm = (nullptr != dynamic_cast<simgrid::surf::VirtualMachine*>(host_list[i]->extension<simgrid::surf::HostImpl>()));
+ xbt_assert(is_a_vm == tmp_is_a_vm, "parallel_execute: mixing VMs and PMs is not supported (yet).");
}
/* set surf's synchro */
if (!MC_is_active() && !MC_record_replay_is_active()) {
- synchro->execution.surf_exec =
- surf_host_model_execute_parallel_task(surf_host_model,
- host_nb, host_list_cpy, flops_amount, bytes_amount, rate);
-
- surf_action_set_data(synchro->execution.surf_exec, synchro);
+ exec->surf_exec = surf_host_model->executeParallelTask(host_nb, host_list_cpy, flops_amount, bytes_amount, rate);
+ exec->surf_exec->setData(exec);
}
- XBT_DEBUG("Create parallel execute synchro %p", synchro);
-
- return synchro;
-}
+ XBT_DEBUG("Create parallel execute synchro %p", exec);
-void SIMIX_process_execution_destroy(smx_synchro_t synchro){
- XBT_DEBUG("Destroy synchro %p", synchro);
-
- if (synchro->execution.surf_exec) {
- surf_action_unref(synchro->execution.surf_exec);
- synchro->execution.surf_exec = NULL;
- }
- xbt_free(synchro->name);
- xbt_mallocator_release(simix_global->synchro_mallocator, synchro);
+ return exec;
}
-void SIMIX_process_execution_cancel(smx_synchro_t synchro){
+void SIMIX_execution_cancel(smx_synchro_t synchro)
+{
XBT_DEBUG("Cancel synchro %p", synchro);
+ simgrid::simix::Exec *exec = static_cast<simgrid::simix::Exec *>(synchro);
- if (synchro->execution.surf_exec)
- surf_action_cancel(synchro->execution.surf_exec);
-}
-
-double SIMIX_process_execution_get_remains(smx_synchro_t synchro){
- double result = 0.0;
-
- if (synchro->state == SIMIX_RUNNING)
- result = surf_action_get_remains(synchro->execution.surf_exec);
-
- return result;
+ if (exec->surf_exec)
+ exec->surf_exec->cancel();
}
-e_smx_state_t SIMIX_process_execution_get_state(smx_synchro_t synchro){
- return synchro->state;
-}
-
-void SIMIX_process_execution_set_priority(smx_synchro_t synchro, double priority){
-
- if(synchro->execution.surf_exec)
- surf_action_set_priority(synchro->execution.surf_exec, priority);
+void SIMIX_execution_set_priority(smx_synchro_t synchro, double priority)
+{
+ simgrid::simix::Exec *exec = static_cast<simgrid::simix::Exec *>(synchro);
+ if(exec->surf_exec)
+ exec->surf_exec->setPriority(priority);
}
-void SIMIX_process_execution_set_bound(smx_synchro_t synchro, double bound){
-
- if(synchro->execution.surf_exec)
- surf_cpu_action_set_bound(synchro->execution.surf_exec, bound);
+void SIMIX_execution_set_bound(smx_synchro_t synchro, double bound)
+{
+ simgrid::simix::Exec *exec = static_cast<simgrid::simix::Exec *>(synchro);
+ if(exec->surf_exec)
+ static_cast<simgrid::surf::CpuAction*>(exec->surf_exec)->setBound(bound);
}
-void SIMIX_process_execution_set_affinity(smx_synchro_t synchro, sg_host_t host, unsigned long mask){
- xbt_assert(synchro->type == SIMIX_SYNC_EXECUTE);
-
- if (synchro->execution.surf_exec) {
+void SIMIX_execution_set_affinity(smx_synchro_t synchro, sg_host_t host, unsigned long mask)
+{
+ simgrid::simix::Exec *exec = static_cast<simgrid::simix::Exec *>(synchro);
+ if(exec->surf_exec) {
/* just a double check to confirm that this host is the host where this task is running. */
- xbt_assert(synchro->execution.host == host);
- surf_cpu_action_set_affinity(synchro->execution.surf_exec, host, mask);
+ xbt_assert(exec->host == host);
+ static_cast<simgrid::surf::CpuAction*>(exec->surf_exec)->setAffinity(host->pimpl_cpu, mask);
}
}
-void simcall_HANDLER_process_execution_wait(smx_simcall_t simcall, smx_synchro_t synchro){
-
+void simcall_HANDLER_execution_wait(smx_simcall_t simcall, smx_synchro_t synchro)
+{
+ simgrid::simix::Exec *exec = static_cast<simgrid::simix::Exec *>(synchro);
XBT_DEBUG("Wait for execution of synchro %p, state %d", synchro, (int)synchro->state);
/* Associate this simcall to the synchro */
/* set surf's synchro */
if (MC_is_active() || MC_record_replay_is_active()) {
synchro->state = SIMIX_DONE;
- SIMIX_execution_finish(synchro);
+ SIMIX_execution_finish(exec);
return;
}
/* If the synchro is already finished then perform the error handling */
if (synchro->state != SIMIX_RUNNING)
- SIMIX_execution_finish(synchro);
-}
-
-void SIMIX_host_execution_suspend(smx_synchro_t synchro)
-{
- if(synchro->execution.surf_exec)
- surf_action_suspend(synchro->execution.surf_exec);
-}
-
-void SIMIX_host_execution_resume(smx_synchro_t synchro)
-{
- if(synchro->execution.surf_exec)
- surf_action_resume(synchro->execution.surf_exec);
+ SIMIX_execution_finish(exec);
}
-void SIMIX_execution_finish(smx_synchro_t synchro)
+void SIMIX_execution_finish(simgrid::simix::Exec *exec)
{
xbt_fifo_item_t item;
smx_simcall_t simcall;
- xbt_fifo_foreach(synchro->simcalls, item, simcall, smx_simcall_t) {
+ xbt_fifo_foreach(exec->simcalls, item, simcall, smx_simcall_t) {
- switch (synchro->state) {
+ switch (exec->state) {
case SIMIX_DONE:
/* do nothing, synchro done */
default:
xbt_die("Internal error in SIMIX_execution_finish: unexpected synchro state %d",
- (int)synchro->state);
+ (int)exec->state);
}
- /* check if the host is down */
- if (surf_host_get_state(surf_host_resource_priv(simcall->issuer->host)) != SURF_RESOURCE_ON) {
+ /* Fail the process if the host is down */
+ if (simcall->issuer->host->isOff())
simcall->issuer->context->iwannadie = 1;
- }
- simcall->issuer->waiting_synchro = NULL;
- simcall_process_execution_wait__set__result(simcall, synchro->state);
+ simcall->issuer->waiting_synchro = NULL;
+ simcall_execution_wait__set__result(simcall, exec->state);
SIMIX_simcall_answer(simcall);
}
/* We no longer need it */
- SIMIX_process_execution_destroy(synchro);
-}
-
-
-void SIMIX_post_host_execute(smx_synchro_t synchro)
-{
- if (synchro->type == SIMIX_SYNC_EXECUTE && /* FIMXE: handle resource failure
- * for parallel tasks too */
- surf_host_get_state(surf_host_resource_priv(synchro->execution.host)) == SURF_RESOURCE_OFF) {
- /* If the host running the synchro failed, notice it so that the asking
- * process can be killed if it runs on that host itself */
- synchro->state = SIMIX_FAILED;
- } else if (surf_action_get_state(synchro->execution.surf_exec) == SURF_ACTION_FAILED) {
- /* If the host running the synchro didn't fail, then the synchro was
- * canceled */
- synchro->state = SIMIX_CANCELED;
- } else {
- synchro->state = SIMIX_DONE;
- }
-
- if (synchro->execution.surf_exec) {
- surf_action_unref(synchro->execution.surf_exec);
- synchro->execution.surf_exec = NULL;
- }
-
- /* If there are simcalls associated with the synchro, then answer them */
- if (xbt_fifo_size(synchro->simcalls)) {
- SIMIX_execution_finish(synchro);
- }
+ exec->unref();
}
-
void SIMIX_set_category(smx_synchro_t synchro, const char *category)
{
if (synchro->state != SIMIX_RUNNING) return;
- if (synchro->type == SIMIX_SYNC_EXECUTE){
- surf_action_set_category(synchro->execution.surf_exec, category);
- }else if (synchro->type == SIMIX_SYNC_COMMUNICATE){
- surf_action_set_category(synchro->comm.surf_comm, category);
- }
-}
-
-/**
- * \brief Function to get the parameters of the given the SIMIX host.
- *
- * \param host the host to get_phys_host (a sg_host_t)
- * \param param the parameter object space to be overwritten (a ws_params_t)
- */
-void SIMIX_host_get_params(sg_host_t ind_vm, vm_params_t params)
-{
- /* jump to ws_get_params(). */
- surf_host_get_params(ind_vm, params);
-}
-void SIMIX_host_set_params(sg_host_t ind_vm, vm_params_t params)
-{
- /* jump to ws_set_params(). */
- surf_host_set_params(ind_vm, params);
-}
-
-xbt_dict_t SIMIX_host_get_mounted_storage_list(sg_host_t host){
- xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
-
- return surf_host_get_mounted_storage_list(host);
-}
-
-xbt_dynar_t SIMIX_host_get_attached_storage_list(sg_host_t host){
- xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+ simgrid::simix::Exec *exec = dynamic_cast<simgrid::simix::Exec *>(synchro);
+ if (exec != nullptr) {
+ exec->surf_exec->setCategory(category);
+ return;
+ }
- return surf_host_get_attached_storage_list(host);
+ simgrid::simix::Comm *comm = dynamic_cast<simgrid::simix::Comm *>(synchro);
+ if (comm != nullptr) {
+ comm->surf_comm->setCategory(category);
+ return;
+ }
}