3 /* Copyright (c) 2002,2003,2004 Arnaud Legrand. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
9 #include "xbt/sysdep.h"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
12 "Logging specific to SIMIX (process)");
13 /** \defgroup m_process_management Management Functions of Agents
14 * \brief This section describes the agent structure of MSG
15 * (#m_process_t) and the functions for managing it.
16 * \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Agents" --> \endhtmlonly
18 * We need to simulate many independent scheduling decisions, so
19 * the concept of <em>process</em> is at the heart of the
20 * simulator. A process may be defined as a <em>code</em>, with
21 * some <em>private data</em>, executing in a <em>location</em>.
25 /******************************** Process ************************************/
26 /** \ingroup m_process_management
27 * \brief Creates and runs a new #m_process_t.
29 * Does exactly the same as #MSG_process_create_with_arguments but without
30 providing standard arguments (\a argc, \a argv, \a start_time, \a kill_time).
31 * \sa MSG_process_create_with_arguments
33 smx_process_t SIMIX_process_create(const char *name,
34 smx_process_code_t code, void *data,
35 const char * hostname, void * clean_process_function)
37 return SIMIX_process_create_with_arguments(name, code, data, hostname, -1, NULL, clean_process_function);
40 void SIMIX_process_cleanup(void *arg)
42 xbt_swag_remove(arg, simix_global->process_list);
43 xbt_swag_remove(arg, simix_global->process_to_run);
44 xbt_swag_remove(arg, ((smx_process_t) arg)->simdata->host->simdata->process_list);
45 free(((smx_process_t) arg)->name);
46 ((smx_process_t) arg)->name = NULL;
47 free(((smx_process_t) arg)->simdata);
48 ((smx_process_t) arg)->simdata = NULL;
52 /** \ingroup m_process_management
53 * \brief Creates and runs a new #m_process_t.
55 * A constructor for #m_process_t taking four arguments and returning the
56 * corresponding object. The structure (and the corresponding thread) is
57 * created, and put in the list of ready process.
58 * \param name a name for the object. It is for user-level information
60 * \param code is a function describing the behavior of the agent. It
61 should then only use functions described in \ref
62 m_process_management (to create a new #m_process_t for example),
63 in \ref m_host_management (only the read-only functions i.e. whose
64 name contains the word get), in \ref m_task_management (to create
65 or destroy some #m_task_t for example) and in \ref
66 msg_gos_functions (to handle file transfers and task processing).
67 * \param data a pointer to any data one may want to attach to the new
68 object. It is for user-level information and can be NULL. It can
69 be retrieved with the function \ref MSG_process_get_data.
70 * \param host the location where the new agent is executed.
71 * \param argc first argument passed to \a code
72 * \param argv second argument passed to \a code
74 * \return The new corresponding object.
76 smx_process_t SIMIX_process_create_with_arguments(const char *name,
77 smx_process_code_t code, void *data,
78 const char * hostname, int argc, char **argv, void * clean_process_function)
80 smx_simdata_process_t simdata = xbt_new0(s_smx_simdata_process_t,1);
81 smx_process_t process = xbt_new0(s_smx_process_t,1);
82 smx_process_t self = NULL;
83 smx_host_t host = SIMIX_host_get_by_name(hostname);
85 xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
91 if (clean_process_function) {
92 simdata->context = xbt_context_new(code, NULL, NULL,
93 clean_process_function, process,
94 simdata->argc, simdata->argv);
97 simdata->context = xbt_context_new(code, NULL, NULL,
98 SIMIX_process_cleanup, process,
99 simdata->argc, simdata->argv);
101 //simdata->last_errno=SIMIX_OK;
104 /* Process structure */
105 process->name = xbt_strdup(name);
106 process->simdata = simdata;
107 process->data = data;
109 xbt_swag_insert(process, host->simdata->process_list);
111 /* *************** FIX du current_process !!! *************** */
112 self = simix_global->current_process;
113 xbt_context_start(process->simdata->context);
114 simix_global->current_process = self;
116 xbt_swag_insert(process,simix_global->process_list);
117 DEBUG2("Inserting %s(%s) in the to_run list",process->name,
119 xbt_swag_insert(process,simix_global->process_to_run);
127 /** \ingroup m_process_management
128 * \param process poor victim
130 * This function simply kills a \a process... scarry isn't it ? :)
132 void SIMIX_process_kill(smx_process_t process)
135 smx_simdata_process_t p_simdata = process->simdata;
136 //simdata_host_t h_simdata= p_simdata->host->simdata;
138 //smx_process_t proc = NULL;
140 DEBUG2("Killing %s on %s",process->name, p_simdata->host->name);
142 if (p_simdata->mutex) {
143 xbt_swag_remove(process,p_simdata->mutex->sleeping);
145 if (p_simdata->cond) {
146 xbt_swag_remove(process,p_simdata->cond->sleeping);
150 if(p_simdata->waiting_task) {
151 xbt_dynar_foreach(p_simdata->waiting_task->simdata->sleeping,_cursor,proc) {
153 xbt_dynar_remove_at(p_simdata->waiting_task->simdata->sleeping,_cursor,&proc);
155 if(p_simdata->waiting_task->simdata->compute)
156 surf_workstation_resource->common_public->
157 action_free(p_simdata->waiting_task->simdata->compute);
158 else if (p_simdata->waiting_task->simdata->comm) {
159 surf_workstation_resource->common_public->
160 action_change_state(p_simdata->waiting_task->simdata->comm,SURF_ACTION_FAILED);
161 surf_workstation_resource->common_public->
162 action_free(p_simdata->waiting_task->simdata->comm);
164 xbt_die("UNKNOWN STATUS. Please report this bug.");
168 if ((i==msg_global->max_channel) && (process!=MSG_process_self()) &&
169 (!p_simdata->waiting_task)) {
170 xbt_die("UNKNOWN STATUS. Please report this bug.");
173 xbt_swag_remove(process,simix_global->process_to_run);
174 xbt_swag_remove(process,simix_global->process_list);
175 xbt_context_kill(process->simdata->context);
177 if(process==SIMIX_process_self()) {
178 /* I just killed myself */
183 /** \ingroup m_process_management
184 * \brief Return the user data of a #m_process_t.
186 * This functions checks whether \a process is a valid pointer or not
187 and return the user data associated to \a process if it is possible.
189 void *SIMIX_process_get_data(smx_process_t process)
191 xbt_assert0((process != NULL), "Invalid parameters");
193 return (process->data);
196 /** \ingroup m_process_management
197 * \brief Set the user data of a #m_process_t.
199 * This functions checks whether \a process is a valid pointer or not
200 and set the user data associated to \a process if it is possible.
202 void SIMIX_process_set_data(smx_process_t process,void *data)
204 xbt_assert0((process != NULL), "Invalid parameters");
205 xbt_assert0((process->data == NULL), "Data already set");
207 process->data = data;
212 /** \ingroup m_process_management
213 * \brief Return the location on which an agent is running.
215 * This functions checks whether \a process is a valid pointer or not
216 and return the m_host_t corresponding to the location on which \a
219 smx_host_t SIMIX_process_get_host(smx_process_t process)
221 xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
223 return (process->simdata->host);
226 /** \ingroup m_process_management
227 * \brief Return the name of an agent.
229 * This functions checks whether \a process is a valid pointer or not
232 const char *SIMIX_process_get_name(smx_process_t process)
234 xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
236 return (process->name);
239 /** \ingroup m_process_management
240 * \brief Return the current agent.
242 * This functions returns the currently running #m_process_t.
244 smx_process_t SIMIX_process_self(void)
246 return simix_global ? simix_global->current_process : NULL;
249 /** \ingroup m_process_management
250 * \brief Suspend the process.
252 * This functions suspend the process by suspending the task on which
253 * it was waiting for the completion.
255 void SIMIX_process_suspend(smx_process_t process)
257 smx_simdata_process_t simdata = NULL;
259 xbt_assert0(((process) && (process->simdata)), "Invalid parameters");
261 if(process!=SIMIX_process_self()) {
262 simdata = process->simdata;
264 if (simdata->mutex) {
265 /* process blocked on a mutex, only set suspend=1 */
266 simdata->suspended = 1;
268 else if (simdata->cond){
269 /* process blocked cond, suspend all actions */
271 /* temporaries variables */
276 simdata->suspended = 1;
278 xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
279 surf_workstation_resource->common_public->suspend(act->simdata->surf_action);
283 simdata->suspended = 1;
287 /* process executing, I can create an action and suspend it */
288 process->simdata->suspended = 1;
291 char name[] = "dummy";
293 cond = SIMIX_cond_init();
294 dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
295 surf_workstation_resource->common_public->set_priority(dummy->simdata->surf_action,0.0);
296 SIMIX_register_condition_to_action(dummy,cond);
297 SIMIX_register_action_to_condition(dummy,cond);
298 __SIMIX_cond_wait(cond);
299 //SIMIX_action_destroy(dummy);
300 //SIMIX_cond_destroy(cond);
305 /** \ingroup m_process_management
306 * \brief Resume a suspended process.
308 * This functions resume a suspended process by resuming the task on
309 * which it was waiting for the completion.
311 void SIMIX_process_resume(smx_process_t process)
313 smx_simdata_process_t simdata = NULL;
315 xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
318 if(process == SIMIX_process_self()) {
322 simdata = process->simdata;
324 DEBUG0("Resume process blocked on a mutex");
325 simdata->suspended = 0; /* He'll wake up by itself */
328 else if (simdata->cond) {
329 DEBUG0("Resume process blocked on a conditional");
330 /* temporaries variables */
334 simdata->suspended = 0;
336 xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
337 surf_workstation_resource->common_public->resume(act->simdata->surf_action);
342 simdata->suspended = 0;
343 xbt_swag_insert(process,simix_global->process_to_run);
348 /** \ingroup m_process_management
349 * \brief Returns true if the process is suspended .
351 * This checks whether a process is suspended or not by inspecting the
352 * task on which it was waiting for the completion.
354 int SIMIX_process_is_suspended(smx_process_t process)
356 xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
358 return (process->simdata->suspended);