Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
make the category setting function public
[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 (empty) VMs.
14  *  @ingroup msg_VMs
15  *
16  *  @bug it is expected that in the future, the coreAmount parameter will be used
17  *  to add extra constraints on the execution, but the argument is ignored for now.
18  */
19
20 msg_vm_t MSG_vm_start(msg_host_t location, const char *name, int coreAmount) {
21   msg_vm_t res = xbt_new0(s_msg_vm_t,1);
22   res->all_vms_hookup.prev = NULL;
23   res->host_vms_hookup.prev = NULL;
24   res->state = msg_vm_state_running;
25   res->location = location;
26   res->coreAmount = coreAmount;
27   res->name = xbt_strdup(name);
28   res->processes = xbt_dynar_new(sizeof(msg_process_t),NULL);
29
30   xbt_swag_insert(res,msg_global->vms);
31   xbt_swag_insert(res, MSG_host_priv(location)->vms);
32
33   #ifdef HAVE_TRACING
34   TRACE_msg_vm_create(name, location);
35   #endif
36
37
38   return res;
39 }
40 /** @brief Returns a newly constructed dynar containing all existing VMs in the system.
41  *  @ingroup msg_VMs
42  *
43  * Don't forget to free the dynar after use.
44  */
45 xbt_dynar_t MSG_vms_as_dynar(void) {
46   xbt_dynar_t res = xbt_dynar_new(sizeof(msg_vm_t),NULL);
47   msg_vm_t vm;
48   xbt_swag_foreach(vm,msg_global->vms) {
49     xbt_dynar_push(res,&vm);
50   }
51   return res;
52 }
53
54 /** @brief Returns whether the given VM is currently suspended
55  *  @ingroup msg_VMs
56  */
57 int MSG_vm_is_suspended(msg_vm_t vm) {
58   return vm->state == msg_vm_state_suspended;
59 }
60 /** @brief Returns whether the given VM is currently running
61  *  @ingroup msg_VMs
62  */
63 int MSG_vm_is_running(msg_vm_t vm) {
64   return vm->state == msg_vm_state_running;
65 }
66 /** @brief Add the given process into the VM.
67  *  @ingroup msg_VMs
68  *
69  * Afterward, when the VM is migrated or suspended or whatever, the process will have the corresponding handling, too.
70  *
71  */
72 void MSG_vm_bind(msg_vm_t vm, msg_process_t process) {
73   /* check if the process is already in a VM */
74   simdata_process_t simdata = simcall_process_get_data(process);
75   if (simdata->vm) {
76     msg_vm_t old_vm = simdata->vm;
77     int pos = xbt_dynar_search(old_vm->processes,&process);
78     xbt_dynar_remove_at(old_vm->processes,pos, NULL);
79   }
80   /* check if the host is in the right host */
81   if (simdata->m_host != vm->location) {
82     MSG_process_migrate(process,vm->location);
83   }
84   simdata->vm = vm;
85
86   XBT_DEBUG("binding Process %s to %p",MSG_process_get_name(process),vm);
87
88   xbt_dynar_push_as(vm->processes,msg_process_t,process);
89 }
90 /** @brief Removes the given process from the given VM, and kill it
91  *  @ingroup msg_VMs
92  *
93  *  Will raise a not_found exception if the process were not binded to that VM
94  */
95 void MSG_vm_unbind(msg_vm_t vm, msg_process_t process) {
96   int pos = xbt_dynar_search(vm->processes,process);
97   xbt_dynar_remove_at(vm->processes,pos, NULL);
98   MSG_process_kill(process);
99 }
100
101 /** @brief Immediately change the host on which all processes are running.
102  *  @ingroup msg_VMs
103  *
104  * No migration cost occurs. If you want to simulate this too, you want to use a
105  * MSG_task_send() before or after, depending on whether you want to do cold or hot
106  * migration.
107  */
108 void MSG_vm_migrate(msg_vm_t vm, msg_host_t destination) {
109   unsigned int cpt;
110   msg_process_t process;
111   xbt_dynar_foreach(vm->processes,cpt,process) {
112     MSG_process_migrate(process,destination);
113   }
114   xbt_swag_remove(vm, MSG_host_priv(vm->location)->vms);
115   xbt_swag_insert_at_tail(vm, MSG_host_priv(destination)->vms);
116   
117   #ifdef HAVE_TRACING
118   TRACE_msg_vm_change_host(vm,vm->location,destination);
119   #endif
120
121   vm->location = destination;
122 }
123
124 /** @brief Immediately suspend the execution of all processes within the given VM.
125  *  @ingroup msg_VMs
126  *
127  * No suspension cost occurs. If you want to simulate this too, you want to
128  * use a \ref MSG_file_write() before or after, depending on the exact semantic
129  * of VM suspend to you.
130  */
131 void MSG_vm_suspend(msg_vm_t vm) {
132   unsigned int cpt;
133   msg_process_t process;
134   xbt_dynar_foreach(vm->processes,cpt,process) {
135     XBT_DEBUG("suspend process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
136     MSG_process_suspend(process);
137   }
138
139   #ifdef HAVE_TRACING
140   TRACE_msg_vm_suspend(vm);
141   #endif
142 }
143
144 /** @brief Immediately resumes the execution of all processes within the given VM.
145  *  @ingroup msg_VMs
146  *
147  * No resume cost occurs. If you want to simulate this too, you want to
148  * use a \ref MSG_file_read() before or after, depending on the exact semantic
149  * of VM resume to you.
150  */
151 void MSG_vm_resume(msg_vm_t vm) {
152   unsigned int cpt;
153   msg_process_t process;
154   xbt_dynar_foreach(vm->processes,cpt,process) {
155     XBT_DEBUG("resume process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
156     MSG_process_resume(process);
157   }
158
159   #ifdef HAVE_TRACING
160   TRACE_msg_vm_resume(vm);
161   #endif
162 }
163
164 /** @brief Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
165  *  @ingroup msg_VMs
166  *
167  * No extra delay occurs. If you want to simulate this too, you want to
168  * use a #MSG_process_sleep() or something. I'm not quite sure.
169  */
170 void MSG_vm_shutdown(msg_vm_t vm)
171 {
172   msg_process_t process;
173   XBT_DEBUG("%lu processes in the VM", xbt_dynar_length(vm->processes));
174   while (xbt_dynar_length(vm->processes) > 0) {
175     process = xbt_dynar_get_as(vm->processes,0,msg_process_t);
176     MSG_process_kill(process);
177   }
178
179   #ifdef HAVE_TRACING
180   TRACE_msg_vm_kill(vm);
181   #endif
182
183 }
184 /**
185  * \ingroup msg_VMs
186  * \brief Reboot the VM, restarting all the processes in it.
187  */
188 void MSG_vm_reboot(msg_vm_t vm)
189 {
190   xbt_dynar_t new_processes = xbt_dynar_new(sizeof(msg_process_t),NULL);
191
192   msg_process_t process;
193   unsigned int cpt;
194
195   xbt_dynar_foreach(vm->processes,cpt,process) {
196     msg_process_t new_process = MSG_process_restart(process);
197     xbt_dynar_push_as(new_processes,msg_process_t,new_process);
198
199   }
200
201   xbt_dynar_foreach(new_processes, cpt, process) {
202     MSG_vm_bind(vm,process);
203   }
204
205   xbt_dynar_free(&new_processes);
206 }
207 /** @brief Destroy a msg_vm_t.
208  *  @ingroup msg_VMs
209  */
210 void MSG_vm_destroy(msg_vm_t vm) {
211   unsigned int cpt;
212   msg_process_t process;
213   xbt_dynar_foreach(vm->processes,cpt,process) {
214     //FIXME: Slow ?
215     simdata_process_t simdata = simcall_process_get_data(process);
216     simdata->vm = NULL;
217   }
218
219   #ifdef HAVE_TRACING
220   TRACE_msg_vm_end(vm);
221   #endif
222
223
224   xbt_dynar_free(&vm->processes);
225   xbt_free(vm);
226 }