Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix missing call to surf - Adrien
[simgrid.git] / src / msg / msg_vm.c
1 /* Copyright (c) 2012. The SimGrid Team. All rights reserved.               */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "msg_private.h"
7 #include "xbt/sysdep.h"
8 #include "xbt/log.h"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_vm, msg,
11                                 "Cloud-oriented parts of the MSG API");
12
13 /** @brief Create a new VM (the VM is just attached to the location but it is not started yet).
14  *  @ingroup msg_VMs
15  */
16
17 msg_vm_t MSG_vm_create(msg_host_t location, const char *name,
18                                              int core_nb, int mem_cap, int net_cap){
19
20   // Note new and vm_workstation refer to the same area (due to the lib/dict appraoch)
21   msg_vm_t new = NULL;
22   void *vm_workstation =  NULL;
23   // Ask simix to create the surf vm resource
24   vm_workstation = simcall_vm_create(name,location);
25   new = (msg_vm_t) __MSG_host_create(vm_workstation);
26
27
28   MSG_vm_set_property_value(new, "CORE_NB", bprintf("%d", core_nb), free);
29   MSG_vm_set_property_value(new, "MEM_CAP", bprintf("%d", core_nb), free);
30   MSG_vm_set_property_value(new, "NET_CAP", bprintf("%d", core_nb), free);
31
32   #ifdef HAVE_TRACING
33   TRACE_msg_vm_create(name, location);
34   #endif
35   return new;
36 }
37
38 /** \ingroup m_host_management
39  * \brief Returns the value of a given host property
40  *
41  * \param host a host
42  * \param name a property name
43  * \return value of a property (or NULL if property not set)
44  */
45 const char *MSG_host_get_property_value(msg_host_t host, const char *name)
46 {
47   return xbt_dict_get_or_null(MSG_host_get_properties(host), name);
48 }
49
50 /** \ingroup m_host_management
51  * \brief Returns a xbt_dict_t consisting of the list of properties assigned to this host
52  *
53  * \param host a host
54  * \return a dict containing the properties
55  */
56 xbt_dict_t MSG_host_get_properties(msg_host_t host)
57 {
58   xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
59
60   return (simcall_host_get_properties(host));
61 }
62
63 /** \ingroup m_host_management
64  * \brief Change the value of a given host property
65  *
66  * \param host a host
67  * \param name a property name
68  * \param value what to change the property to
69  * \param free_ctn the freeing function to use to kill the value on need
70  */
71 void MSG_vm_set_property_value(msg_vm_t vm, const char *name, void *value,void_f_pvoid_t free_ctn) {
72
73   xbt_dict_set(MSG_host_get_properties(vm), name, value,free_ctn);
74 }
75
76 /** @brief Immediately suspend the execution of all processes within the given VM.
77  *  @ingroup msg_VMs
78  *  return wheter the VM has been correctly started (0) or not (<0)
79  *
80  */
81 int MSG_vm_start(msg_vm_t vm) {
82  // TODO Please complete the code
83
84   #ifdef HAVE_TRACING
85   TRACE_msg_vm_start(vm);
86   #endif
87 }
88
89 /** @brief Returns a newly constructed dynar containing all existing VMs in the system.
90  *  @ingroup msg_VMs
91  *
92  * Don't forget to free the dynar after use.
93  */
94 xbt_dynar_t MSG_vms_as_dynar(void) {
95   xbt_dynar_t res = xbt_dynar_new(sizeof(msg_vm_t),NULL);
96   msg_vm_t vm;
97   xbt_swag_foreach(vm,msg_global->vms) {
98     xbt_dynar_push(res,&vm);
99   }
100   return res;
101 }
102
103 /** @brief Returns whether the given VM is currently suspended
104  *  @ingroup msg_VMs
105  */
106 int MSG_vm_is_suspended(msg_vm_t vm) {
107   return vm->state == msg_vm_state_suspended;
108 }
109 /** @brief Returns whether the given VM is currently running
110  *  @ingroup msg_VMs
111  */
112 int MSG_vm_is_running(msg_vm_t vm) {
113   return vm->state == msg_vm_state_running;
114 }
115 /** @brief Add the given process into the VM.
116  *  @ingroup msg_VMs
117  *
118  * Afterward, when the VM is migrated or suspended or whatever, the process will have the corresponding handling, too.
119  *
120  */
121 void MSG_vm_bind(msg_vm_t vm, msg_process_t process) {
122   /* check if the process is already in a VM */
123   simdata_process_t simdata = simcall_process_get_data(process);
124   if (simdata->vm) {
125     msg_vm_t old_vm = simdata->vm;
126     int pos = xbt_dynar_search(old_vm->processes,&process);
127     xbt_dynar_remove_at(old_vm->processes,pos, NULL);
128   }
129   /* check if the host is in the right host */
130   if (simdata->m_host != vm->location) {
131     MSG_process_migrate(process,vm->location);
132   }
133   simdata->vm = vm;
134
135   XBT_DEBUG("binding Process %s to %p",MSG_process_get_name(process),vm);
136
137   xbt_dynar_push_as(vm->processes,msg_process_t,process);
138 }
139 /** @brief Removes the given process from the given VM, and kill it
140  *  @ingroup msg_VMs
141  *
142  *  Will raise a not_found exception if the process were not binded to that VM
143  */
144 void MSG_vm_unbind(msg_vm_t vm, msg_process_t process) {
145   int pos = xbt_dynar_search(vm->processes,process);
146   xbt_dynar_remove_at(vm->processes,pos, NULL);
147   MSG_process_kill(process);
148 }
149
150 /** @brief Immediately change the host on which all processes are running.
151  *  @ingroup msg_VMs
152  *
153  * No migration cost occurs. If you want to simulate this too, you want to use a
154  * MSG_task_send() before or after, depending on whether you want to do cold or hot
155  * migration.
156  */
157 void MSG_vm_migrate(msg_vm_t vm, msg_host_t destination) {
158   unsigned int cpt;
159   msg_process_t process;
160   xbt_dynar_foreach(vm->processes,cpt,process) {
161     MSG_process_migrate(process,destination);
162   }
163   xbt_swag_remove(vm, MSG_host_priv(vm->location)->vms);
164   xbt_swag_insert_at_tail(vm, MSG_host_priv(destination)->vms);
165   
166   #ifdef HAVE_TRACING
167   TRACE_msg_vm_change_host(vm,vm->location,destination);
168   #endif
169
170   vm->location = destination;
171 }
172
173 /** @brief Immediately suspend the execution of all processes within the given VM.
174  *  @ingroup msg_VMs
175  *
176  * No suspension cost occurs. If you want to simulate this too, you want to
177  * use a \ref MSG_file_write() before or after, depending on the exact semantic
178  * of VM suspend to you.
179  */
180 void MSG_vm_suspend(msg_vm_t vm) {
181   unsigned int cpt;
182   msg_process_t process;
183   xbt_dynar_foreach(vm->processes,cpt,process) {
184     XBT_DEBUG("suspend process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
185     MSG_process_suspend(process);
186   }
187
188   #ifdef HAVE_TRACING
189   TRACE_msg_vm_suspend(vm);
190   #endif
191 }
192
193 /** @brief Immediately resumes the execution of all processes within the given VM.
194  *  @ingroup msg_VMs
195  *
196  * No resume cost occurs. If you want to simulate this too, you want to
197  * use a \ref MSG_file_read() before or after, depending on the exact semantic
198  * of VM resume to you.
199  */
200 void MSG_vm_resume(msg_vm_t vm) {
201   unsigned int cpt;
202   msg_process_t process;
203   xbt_dynar_foreach(vm->processes,cpt,process) {
204     XBT_DEBUG("resume process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
205     MSG_process_resume(process);
206   }
207
208   #ifdef HAVE_TRACING
209   TRACE_msg_vm_resume(vm);
210   #endif
211 }
212
213 /** @brief Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
214  *  @ingroup msg_VMs
215  *
216  * No extra delay occurs. If you want to simulate this too, you want to
217  * use a #MSG_process_sleep() or something. I'm not quite sure.
218  */
219 void MSG_vm_shutdown(msg_vm_t vm)
220 {
221   msg_process_t process;
222   XBT_DEBUG("%lu processes in the VM", xbt_dynar_length(vm->processes));
223   while (xbt_dynar_length(vm->processes) > 0) {
224     process = xbt_dynar_get_as(vm->processes,0,msg_process_t);
225     MSG_process_kill(process);
226   }
227
228   #ifdef HAVE_TRACING
229   TRACE_msg_vm_kill(vm);
230   #endif
231
232 }
233 /**
234  * \ingroup msg_VMs
235  * \brief Reboot the VM, restarting all the processes in it.
236  */
237 void MSG_vm_reboot(msg_vm_t vm)
238 {
239   xbt_dynar_t new_processes = xbt_dynar_new(sizeof(msg_process_t),NULL);
240
241   msg_process_t process;
242   unsigned int cpt;
243
244   xbt_dynar_foreach(vm->processes,cpt,process) {
245     msg_process_t new_process = MSG_process_restart(process);
246     xbt_dynar_push_as(new_processes,msg_process_t,new_process);
247
248   }
249
250   xbt_dynar_foreach(new_processes, cpt, process) {
251     MSG_vm_bind(vm,process);
252   }
253
254   xbt_dynar_free(&new_processes);
255 }
256 /** @brief Destroy a msg_vm_t.
257  *  @ingroup msg_VMs
258  */
259 void MSG_vm_destroy(msg_vm_t vm) {
260   unsigned int cpt;
261   msg_process_t process;
262   xbt_dynar_foreach(vm->processes,cpt,process) {
263     //FIXME: Slow ?
264     simdata_process_t simdata = simcall_process_get_data(process);
265     simdata->vm = NULL;
266   }
267
268   #ifdef HAVE_TRACING
269   TRACE_msg_vm_end(vm);
270   #endif
271
272
273   xbt_dynar_free(&vm->processes);
274   xbt_free(vm);
275 }