examples/msg/simulation.trace
examples/msg/toto.txt
examples/msg/z_gtnets.trace
+examples/msg/cloud/masterslave_virtual_machines
examples/msg/tracing/link_srcdst_user_variables
examples/msg/tracing/link_user_variables
examples/msg/tracing/simple
SimGrid (3.8) NOT RELEASED; urgency=low
+ The "SimGrid makes psssshiiiit and jumps into the cloud" release.
+
+ MSG:
+ * Add an experimental interface to manipulate VMs. They are mainly
+ process groups with very few intrinsic semantic, but they should
+ allow you to build the semantic you want easily.
+
SimDag:
* New type of typed tasks SD_TASK_COMP_PAR_AMDAHL that represents a
parallel task whose initial work is distributed among host according
ADD_TEST(msg-masterslave-mailbox-thread ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/masterslave/masterslave_mailbox_crosstraffic.tesh)
ADD_TEST(msg-masterslave-cpu-ti-thread ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/masterslave --cd ${CMAKE_HOME_DIRECTORY}/examples/msg masterslave/masterslave_cpu_ti_crosstraffic.tesh)
+ADD_TEST(msg-masterslave-virtual-machines
+ ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}
+ --cfg contexts/factory:thread
+ --setenvbindir=${CMAKE_BINARY_DIR}/examples/msg/cloud
+ --cd ${CMAKE_HOME_DIRECTORY}/examples/msg cloud/masterslave_virtual_machines.tesh)
+
if(HAVE_UCONTEXT_H)
ADD_TEST(msg-sendrecv-CLM03-ucontext ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/sendrecv/sendrecv_CLM03.tesh)
ADD_TEST(msg-sendrecv-Vegas-ucontext ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/sendrecv/sendrecv_Vegas.tesh)
src/msg/msg_deployment.c
src/msg/msg_mailbox.c
src/msg/msg_actions.c
+ src/msg/msg_vm.c
)
set(SIMDAG_SRC
add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/start_kill_time)\r
\r
add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/io)\r
+add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/cloud)\r
\r
add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/gpu)\r
\r
- \ref m_task_management
- \ref msg_file_management
- \ref msg_task_usage
+ - \ref msg_VMs
- \ref msg_trace_driven
- \ref msg_deprecated_functions
* by a process to execute, communicate or otherwise handle some task.
*/
+/** @defgroup msg_VMs VMs
+ * @ingroup MSG_API
+ * @brief This section describes the interface created to mimick IaaS clouds.
+ *
+ * With it, you can create virtual machines to put your processes
+ * into, and interact directly with the VMs to manage groups of
+ * processes.
+ *
+ * This interface is highly experimental at this point. Testing is
+ * welcomed, but do not expect too much of it right now. Even the
+ * interfaces may be changed in future releases of SimGrid (although
+ * things are expected to stabilize nicely before SimGrid v3.8).
+ * There is no guaranty on the rest of SimGrid, and there is less
+ * than that on this part.
+ *
+ */
+
/** @defgroup msg_file_management File Management Functions
* @ingroup MSG_API
* @brief This section describes the file structure of MSG
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+
+set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(masterslave_virtual_machines "masterslave_virtual_machines.c")
+
+### Add definitions for compile
+if(WIN32)
+ target_link_libraries(masterslave_virtual_machines simgrid )
+else(WIN32)
+ target_link_libraries(masterslave_virtual_machines simgrid m )
+endif(WIN32)
--- /dev/null
+/* Copyright (c) 2007-2012. 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 <stdio.h>
+#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */
+#include "xbt/sysdep.h" /* calloc, printf */
+
+/* Create a log channel to have nice outputs. */
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
+ "Messages specific for this msg example");
+
+/** @addtogroup MSG_examples
+ *
+ * - <b>cloud/masterslave_virtual_machines.c: Master/slaves
+ * example, à la cloud</b>. The classical example revisited to demonstrate the use of virtual machines.
+ */
+
+double task_comp_size = 10000000;
+double task_comm_size = 10000000;
+
+
+int master(int argc, char *argv[]);
+int slave_fun(int argc, char *argv[]);
+
+static void work_batch(int slaves_count) {
+ int i;
+ for (i = 0; i < slaves_count; i++) {
+ char taskname_buffer[64];
+ char mailbox_buffer[64];
+
+ sprintf(taskname_buffer, "Task_%d", i);
+ sprintf(mailbox_buffer,"Slave_%d",i);
+
+ XBT_INFO("Sending \"%s\" to \"%s\"",taskname_buffer,mailbox_buffer);
+ MSG_task_send(MSG_task_create(taskname_buffer, task_comp_size, task_comm_size,NULL),
+ mailbox_buffer);
+ }
+}
+
+int master(int argc, char *argv[]) {
+ int slaves_count = 10;
+ m_host_t *slaves = xbt_new(m_host_t,10);
+
+ int i;
+
+ /* Retrive the hostnames constituting our playground today */
+ for (i = 1; i < argc; i++) {
+ slaves[i - 1] = MSG_get_host_by_name(argv[i]);
+ xbt_assert(slaves[i - 1] != NULL, "Cannot use inexistent host %s", argv[i]);
+ }
+
+ /* Launch the sub processes: one VM per host, with one process inside each */
+
+ for (i=0;i<slaves_count;i++) {
+ char slavename[64];
+ sprintf(slavename,"Slave %d",i);
+ char**argv=xbt_new(char*,3);
+ argv[0] = xbt_strdup(slavename);
+ argv[1] = bprintf("%d",i);
+ argv[2] = NULL;
+ msg_vm_t vm = MSG_vm_start(slaves[i],2);
+ MSG_vm_bind(vm, MSG_process_create_with_arguments(slavename,slave_fun,NULL,slaves[i],2,argv));
+ }
+
+ xbt_dynar_t vms = MSG_vms_as_dynar();
+ XBT_INFO("Launched %ld VMs", xbt_dynar_length(vms));
+
+ /* Send a bunch of work to every one */
+ XBT_INFO("Send a first batch of work to every one");
+ work_batch(slaves_count);
+
+ XBT_INFO("Now suspend all VMs, just for fun");
+ for (i=0;i<xbt_dynar_length(vms);i++)
+ MSG_vm_suspend(xbt_dynar_get_as(vms,i,msg_vm_t));
+
+ XBT_INFO("Wait a while");
+ MSG_process_sleep(2);
+
+ XBT_INFO("Enough. Let's resume everybody.");
+ for (i=0;i<xbt_dynar_length(vms);i++)
+ MSG_vm_resume(xbt_dynar_get_as(vms,i,msg_vm_t));
+
+ XBT_INFO("Sleep long enough for everyone to be done with previous batch of work");
+ MSG_process_sleep(1000-MSG_get_clock());
+
+ XBT_INFO("Add one more process per VM, and dispatch a batch of work to everyone");
+ for (i=0;i<xbt_dynar_length(vms);i++) {
+ msg_vm_t vm = xbt_dynar_get_as(vms,i,msg_vm_t);
+ char slavename[64];
+ sprintf(slavename,"Slave %ld",i+xbt_dynar_length(vms));
+ char**argv=xbt_new(char*,3);
+ argv[0] = xbt_strdup(slavename);
+ argv[1] = bprintf("%ld",i+xbt_dynar_length(vms));
+ argv[2] = NULL;
+ MSG_vm_bind(vm, MSG_process_create_with_arguments(slavename,slave_fun,NULL,slaves[i],2,argv));
+ }
+ work_batch(slaves_count*2);
+
+ XBT_INFO("Migrate everyone to the second host.");
+ for (i=0;i<xbt_dynar_length(vms);i++)
+ MSG_vm_migrate(xbt_dynar_get_as(vms,i,msg_vm_t),slaves[1]);
+
+ XBT_INFO("Suspend everyone, move them to the third host, and resume them.");
+ for (i=0;i<xbt_dynar_length(vms);i++) {
+ msg_vm_t vm = xbt_dynar_get_as(vms,i,msg_vm_t);
+ MSG_vm_suspend(vm);
+ MSG_vm_migrate(vm,slaves[2]);
+ MSG_vm_resume(vm);
+ }
+
+
+
+ XBT_INFO("Let's shut down the simulation. 10 first processes will be shut down cleanly while the second half will forcefully get killed");
+ for (i = 0; i < slaves_count; i++) {
+ char mailbox_buffer[64];
+ sprintf(mailbox_buffer,"Slave_%d",i);
+ m_task_t finalize = MSG_task_create("finalize", 0, 0, 0);
+ MSG_task_send(finalize, mailbox_buffer);
+ }
+
+ for (i=0;i<xbt_dynar_length(vms);i++) {
+ msg_vm_t vm = xbt_dynar_get_as(vms,i,msg_vm_t);
+ MSG_vm_shutdown(vm);
+ }
+
+ XBT_INFO("Goodbye now!");
+ free(slaves);
+ xbt_dynar_free(&vms);
+ return 0;
+} /* end_of_master */
+
+/** Receiver function */
+int slave_fun(int argc, char *argv[])
+{
+ char *mailbox_name;
+ m_task_t task = NULL;
+ _XBT_GNUC_UNUSED int res;
+
+ /* since the slaves will move around, use slave_%d as mailbox names instead of hostnames */
+ xbt_assert(argc>=2, "slave processes need to be given their rank as parameter");
+ mailbox_name=bprintf("Slave_%s",argv[1]);
+
+ while (1) {
+ res = MSG_task_receive(&(task),mailbox_name);
+ xbt_assert(res == MSG_OK, "MSG_task_get failed");
+
+ XBT_INFO("Received \"%s\" from mailbox %s", MSG_task_get_name(task),mailbox_name);
+ if (!strcmp(MSG_task_get_name(task), "finalize")) {
+ MSG_task_destroy(task);
+ break;
+ }
+
+ MSG_task_execute(task);
+ XBT_INFO("\"%s\" done", MSG_task_get_name(task));
+ MSG_task_destroy(task);
+ task = NULL;
+ }
+ free(mailbox_name);
+ return 0;
+} /* end_of_slave */
+
+/** Main function */
+int main(int argc, char *argv[])
+{
+ MSG_error_t res = MSG_OK;
+ xbt_dynar_t hosts_dynar;
+ m_host_t*hosts= xbt_new(m_host_t,10);
+ char**hostnames= xbt_new(char*,10);
+ char**masterargv=xbt_new(char*,12);
+ int i;
+
+ /* Get the arguments */
+ MSG_global_init(&argc, argv);
+ if (argc < 2) {
+ printf("Usage: %s platform_file\n", argv[0]);
+ printf("example: %s msg_platform.xml\n", argv[0]);
+ exit(1);
+ } if (argc>2) {
+ printf("Usage: %s platform_file\n", argv[0]);
+ printf("Other parameters (such as the deployment file) are ignored.");
+ }
+
+ /* load the platform file */
+ MSG_create_environment(argv[1]);
+ /* Retrieve the 10 first hosts of the platform file */
+ hosts_dynar = MSG_hosts_as_dynar();
+ xbt_assert(xbt_dynar_length(hosts_dynar)>10,
+ "I need at least 10 hosts in the platform file, but %s contains only %ld hosts_dynar.",
+ argv[1],xbt_dynar_length(hosts_dynar));
+ for (i=0;i<10;i++) {
+ hosts[i] = xbt_dynar_get_as(hosts_dynar,i,m_host_t);
+ hostnames[i] = xbt_strdup(MSG_host_get_name(hosts[i]));
+ }
+ masterargv[0]=xbt_strdup("master");
+ for (i=1;i<11;i++) {
+ masterargv[i] = xbt_strdup(MSG_host_get_name(hosts[i-1]));
+ }
+ masterargv[11]=NULL;
+ MSG_process_create_with_arguments("master",master,NULL,hosts[0],11,masterargv);
+ res = MSG_main();
+ XBT_INFO("Simulation time %g", MSG_get_clock());
+
+ MSG_clean();
+ free(hosts);
+ free(hostnames);
+ xbt_dynar_free(&hosts_dynar);
+
+ if (res == MSG_OK)
+ return 0;
+ else
+ return 1;
+} /* end_of_main */
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<platform version="3">
+ <!-- The master process (with some arguments) -->
+ <process host="Tremblay" function="master">
+ <argument value="20"/> <!-- Number of tasks -->
+ <argument value="50000000"/> <!-- Computation size of tasks -->
+ <argument value="1000000"/> <!-- Communication size of tasks -->
+ <argument value="Jupiter"/> <!-- First slave -->
+ <argument value="Fafard"/> <!-- Second slave -->
+ <argument value="Ginette"/> <!-- Third slave -->
+ <argument value="Bourassa"/> <!-- Last slave -->
+ </process>
+ <!-- The slave process (with no argument) -->
+ <process host="Tremblay" function="slave"/>
+ <process host="Jupiter" function="slave"/>
+ <process host="Fafard" function="slave"/>
+ <process host="Ginette" function="slave"/>
+ <process host="Bourassa" function="slave"/>
+</platform>
-/* Copyright (c) 2004, 2005, 2007, 2008, 2009, 2010. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2004-2012. 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. */
/* ******************************** Host ************************************ */
typedef struct m_host {
+ xbt_swag_t vms;
smx_host_t smx_host; /**< SIMIX representation of this host */
#ifdef MSG_USE_DEPRECATED
msg_mailbox_t *mailboxes; /**< the channels */
-/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2004-2012. 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 "instr/instr.h"
-/* Used only by the bindings */
+/** @brief Opaque type describing a Virtual Machine.
+ * @ingroup msg_VMs
+ *
+ * All this is highly experimental and the interface will probably change in the future.
+ * Please don't depend on this yet (although testing is welcomed if you feel so).
+ * Usual lack of guaranty of any kind applies here, and is even increased.
+ *
+ */
+typedef struct msg_vm *msg_vm_t;
+/* This function should not be called directly, but rather from MSG_vm_start_from_template that does not exist yet*/
+XBT_PUBLIC(msg_vm_t) MSG_vm_start(m_host_t location, int coreAmount);
+
+XBT_PUBLIC(int) MSG_vm_is_suspended(msg_vm_t);
+XBT_PUBLIC(int) MSG_vm_is_running(msg_vm_t);
+
+XBT_PUBLIC(void) MSG_vm_bind(msg_vm_t vm, m_process_t process);
+XBT_PUBLIC(void) MSG_vm_unbind(msg_vm_t vm, m_process_t process); // simple wrapper over process_kill
+
+XBT_PUBLIC(void) MSG_vm_migrate(msg_vm_t vm, m_host_t destination);
+
+XBT_PUBLIC(void) MSG_vm_suspend(msg_vm_t vm);
+ // \forall p in VM, MSG_process_suspend(p) // Freeze the processes
+
+XBT_PUBLIC(void) MSG_vm_resume(msg_vm_t vm); // Simulate the fact of reading the processes from disk and resuming them
+ // \forall p in VM, MSG_process_resume(p) // unfreeze them
+
+XBT_PUBLIC(void) MSG_vm_shutdown(msg_vm_t vm); // killall
+
+XBT_PUBLIC(xbt_dynar_t) MSG_vms_as_dynar(void);
+
+/*
+void* MSG_process_get_property(msg_process_t, char* key)
+void MSG_process_set_property(msg_process_t, char* key, void* data)
+void MSG_vm_set_property(msg_vm_t, char* key, void* data)
+
+void MSG_vm_setMemoryUsed(msg_vm_t vm, double size);
+void MSG_vm_setCpuUsed(msg_vm_t vm, double inducedLoad);
+ // inducedLoad: un pourcentage (>100 si ca charge plus d'un coeur;
+ // <100 si c'est pas CPU intensive)
+ // Contraintes à poser:
+ // HOST_Power >= CpuUsedVm (\forall VM) + CpuUsedTask (\forall Task)
+ // VM_coreAmount >= Load de toutes les tasks
+*/
+
+ /*
+xbt_dynar_t<msg_vm_t> MSG_vm_get_list_from_host(msg_host_t)
+xbt_dynar_t<msg_vm_t> MSG_vm_get_list_from_hosts(msg_dynar_t<msg_host_t>)
++ des fonctions de filtrage sur les dynar
+*/
+
+
+/* ****************************************************************************************** */
+/* Used only by the bindings -- unclean pimple, please ignore if you're not writing a binding */
XBT_PUBLIC(smx_context_t) MSG_process_get_smx_ctx(m_process_t process);
SG_END_DECL()
xbt_getpid = MSG_process_self_PID;
if (!msg_global) {
+ s_msg_vm_t vm; // to compute the offset
+
SIMIX_global_init(argc, argv);
msg_global = xbt_new0(s_MSG_Global_t, 1);
msg_global->sent_msg = 0;
msg_global->task_copy_callback = NULL;
msg_global->process_data_cleanup = NULL;
+ msg_global->vms = xbt_swag_new(xbt_swag_offset(vm,all_vms_hookup));
/* initialization of the action module */
_MSG_action_init();
XBT_DEBUG("ADD MSG LEVELS");
MSG_HOST_LEVEL = xbt_lib_add_level(host_lib, (void_f_pvoid_t) __MSG_host_destroy);
+
}
#ifdef MSG_USE_DEPRECATED
SIMIX_clean();
+ xbt_swag_free(msg_global->vms);
free(msg_global);
msg_global = NULL;
#include "xbt/log.h"
#include "simgrid/simix.h"
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(msg);
+
/** @addtogroup m_host_management
* \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Hosts" --> \endhtmlonly
* (#m_host_t) and the functions for managing it.
{
const char *name = SIMIX_host_get_name(workstation);
m_host_t host = xbt_new0(s_m_host_t, 1);
+ s_msg_vm_t vm; // simply to compute the offset
host->smx_host = workstation;
+ host->vms = xbt_swag_new(xbt_swag_offset(vm,host_vms_hookup));
#ifdef MSG_USE_DEPRECATED
int i;
if (msg_global->max_channel > 0)
free(host->mailboxes);
#endif
-
+ if (xbt_swag_size(host->vms) > 0 ) {
+ XBT_VERB("Host %s shut down, but it still hosts %d VMs. They will be leaked.",
+ MSG_host_get_name(host),xbt_swag_size(host->vms));
+ }
+ xbt_swag_free(host->vms);
free(host);
}
MSG_error_t status; /* status of the communication once finished */
} s_msg_comm_t;
+typedef enum {
+ msg_vm_state_suspended, msg_vm_state_running, msg_vm_state_migrating
+} e_msg_vm_state_t;
+
+typedef struct msg_vm {
+ s_xbt_swag_hookup_t all_vms_hookup;
+ s_xbt_swag_hookup_t host_vms_hookup;
+ xbt_dynar_t processes;
+ e_msg_vm_state_t state;
+ m_host_t location;
+ int coreAmount;
+} s_msg_vm_t;
+
/************************** Global variables ********************************/
typedef struct MSG_Global {
xbt_fifo_t host;
unsigned long int sent_msg; /* Total amount of messages sent during the simulation */
void (*task_copy_callback) (m_task_t task, m_process_t src, m_process_t dst);
void_f_pvoid_t process_data_cleanup;
+ xbt_swag_t vms;
} s_MSG_Global_t, *MSG_Global_t;
/*extern MSG_Global_t msg_global;*/
--- /dev/null
+/* Copyright (c) 2012. 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 "msg_private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_vm, msg,
+ "Cloud-oriented parts of the MSG API");
+
+/** @brief Create a new (empty) VMs
+ * @ingroup msg_VMs
+ *
+ * @bug it is expected that in the future, the coreAmount parameter will be used
+ * to add extra constraints on the execution, but the argument is ignored for now.
+ */
+
+msg_vm_t MSG_vm_start(m_host_t location, int coreAmount) {
+ msg_vm_t res = xbt_new0(s_msg_vm_t,1);
+ res->all_vms_hookup.prev = NULL;
+ res->host_vms_hookup.prev = NULL;
+ res->state = msg_vm_state_running;
+ res->location = location;
+ res->coreAmount = coreAmount;
+ res->processes = xbt_dynar_new(sizeof(m_process_t),NULL);
+
+ xbt_swag_insert(res,msg_global->vms);
+ xbt_swag_insert(res,location->vms);
+
+ return res;
+}
+/** @brief Returns a newly constructed dynar containing all existing VMs in the system
+ * @ingroup msg_VMs
+ *
+ * Don't forget to free the dynar after use.
+ */
+xbt_dynar_t MSG_vms_as_dynar(void) {
+ xbt_dynar_t res = xbt_dynar_new(sizeof(msg_vm_t),NULL);
+ msg_vm_t vm;
+ xbt_swag_foreach(vm,msg_global->vms) {
+ xbt_dynar_push(res,&vm);
+ }
+ return res;
+}
+
+/** @brief Returns whether the given VM is currently suspended
+ * @ingroup msg_VMs
+ */
+int MSG_vm_is_suspended(msg_vm_t vm) {
+ return vm->state == msg_vm_state_suspended;
+}
+/** @brief Returns whether the given VM is currently running
+ * @ingroup msg_VMs
+ */
+int MSG_vm_is_running(msg_vm_t vm) {
+ return vm->state == msg_vm_state_running;
+}
+/** @brief Add the given process into the VM.
+ * @ingroup msg_VMs
+ *
+ * Afterward, when the VM is migrated or suspended or whatever, the process will have the corresponding handling, too.
+ *
+ * @bug for now, if a binded process terminates, every VM functions will segfault. Baaaad.
+ */
+void MSG_vm_bind(msg_vm_t vm, m_process_t process) {
+ xbt_dynar_push_as(vm->processes,m_process_t,process);
+}
+/** @brief Removes the given process from the given VM, and kill it
+ * @ingroup msg_VMs
+ *
+ * Will raise a not_found exception if the process were not binded to that VM
+ */
+void MSG_vm_unbind(msg_vm_t vm, m_process_t process) {
+ int pos = xbt_dynar_search(vm->processes,process);
+ xbt_dynar_remove_at(vm->processes,pos, NULL);
+ MSG_process_kill(process);
+}
+
+/** @brief Immediately change the host on which all processes are running
+ * @ingroup msg_VMs
+ *
+ * No migration cost occurs. If you want to simulate this too, you want to use a
+ * MSG_task_send() before or after, depending on whether you want to do cold or hot
+ * migration.
+ */
+void MSG_vm_migrate(msg_vm_t vm, m_host_t destination) {
+ unsigned int cpt;
+ m_process_t process;
+ xbt_dynar_foreach(vm->processes,cpt,process) {
+ MSG_process_migrate(process,destination);
+ }
+ xbt_swag_remove(vm,vm->location->vms);
+ xbt_swag_insert_at_tail(vm,destination->vms);
+ vm->location = destination;
+}
+
+/** @brief Immediately suspend the execution of all processes within the given VM
+ * @ingroup msg_VMs
+ *
+ * No suspension cost occurs. If you want to simulate this too, you want to
+ * use a \ref MSG_file_write() before or after, depending on the exact semantic
+ * of VM suspend to you.
+ */
+void MSG_vm_suspend(msg_vm_t vm) {
+ unsigned int cpt;
+ m_process_t process;
+ xbt_dynar_foreach(vm->processes,cpt,process) {
+ XBT_INFO("suspend process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
+ MSG_process_suspend(process);
+ }
+}
+
+/** @brief Immediately resumes the execution of all processes within the given VM
+ * @ingroup msg_VMs
+ *
+ * No resume cost occurs. If you want to simulate this too, you want to
+ * use a \ref MSG_file_read() before or after, depending on the exact semantic
+ * of VM resume to you.
+ */
+void MSG_vm_resume(msg_vm_t vm) {
+ unsigned int cpt;
+ m_process_t process;
+ xbt_dynar_foreach(vm->processes,cpt,process) {
+ XBT_INFO("resume process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
+ MSG_process_resume(process);
+ }
+}
+
+/** @brief Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
+ * @ingroup msg_VMs
+ *
+ * No extra delay occurs. If you want to simulate this too, you want to
+ * use a #MSG_process_sleep() or something. I'm not quite sure.
+ */
+void MSG_vm_shutdown(msg_vm_t vm) {
+ unsigned int cpt;
+ m_process_t process;
+ xbt_dynar_foreach(vm->processes,cpt,process) {
+ MSG_process_kill(process);
+ }
+}
XBT_LOG_CONNECT(msg_mailbox);
XBT_LOG_CONNECT(msg_process);
XBT_LOG_CONNECT(msg_task);
-
+ XBT_LOG_CONNECT(msg_vm);
+
/* simdag */
XBT_LOG_CONNECT(sd);
XBT_LOG_CONNECT(sd_daxparse);