Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Don't read a comm after completion since it is auto-destroyed now.
[simgrid.git] / src / simix / private.h
1 /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #ifndef _SIMIX_PRIVATE_H
8 #define _SIMIX_PRIVATE_H
9
10 #include "simix/simix.h"
11 #include "surf/surf.h"
12 #include "xbt/fifo.h"
13 #include "xbt/swag.h"
14 #include "xbt/dict.h"
15 #include "xbt/config.h"
16 #include "xbt/function_types.h"
17 #include "xbt/ex_interface.h"
18 #include "instr/instr_private.h"
19 #include "process_private.h"
20 #include "host_private.h"
21 #include "network_private.h"
22 #include "smurf_private.h"
23 #include "synchro_private.h"
24 #include "simix/context.h"
25
26 /********************************** Simix Global ******************************/
27
28
29 typedef struct s_smx_global {
30   smx_context_factory_t context_factory;
31   xbt_dict_t host;
32   xbt_dynar_t process_to_run;
33   xbt_swag_t process_list;
34   xbt_swag_t process_to_destroy;
35   smx_process_t maestro_process;
36   xbt_dict_t registered_functions;
37   smx_creation_func_t create_process_function;
38   void_f_pvoid_t kill_process_function;
39   void_pfn_smxprocess_t cleanup_process_function;
40 } s_smx_global_t, *smx_global_t;
41
42 extern smx_global_t simix_global;
43 extern unsigned long simix_process_maxpid;
44
45 /*********************************** Time ************************************/
46
47 /** @brief Timer datatype */
48 typedef struct s_smx_timer {
49   double date;
50   void* func;
51   void* args;
52 } s_smx_timer_t;
53
54 /********************************* Action *************************************/
55
56 typedef enum {
57   SIMIX_ACTION_EXECUTE,
58   SIMIX_ACTION_PARALLEL_EXECUTE,
59   SIMIX_ACTION_COMMUNICATE,
60   SIMIX_ACTION_SLEEP,
61   SIMIX_ACTION_SYNCHRO,
62   SIMIX_ACTION_IO
63 } e_smx_action_type_t;
64
65 typedef enum {
66   SIMIX_COMM_SEND,
67   SIMIX_COMM_RECEIVE,
68   SIMIX_COMM_READY,
69   SIMIX_COMM_DONE
70 } e_smx_comm_type_t;
71
72 /** @brief Action datatype */
73 typedef struct s_smx_action {
74
75   e_smx_action_type_t type;          /* Type of SIMIX action*/
76   e_smx_state_t state;               /* State of the action */
77   char *name;                        /* Action name if any */
78   xbt_fifo_t request_list;           /* List of requests on this action */
79
80   /* Data specific to each action type */
81   union {
82
83     struct {
84       smx_host_t host;                /* The host where the execution takes place */
85       surf_action_t surf_exec;        /* The Surf execution action encapsulated */
86     } execution; /* Possibly parallel execution */
87
88     struct {
89       e_smx_comm_type_t type;         /* Type of the communication (SIMIX_COMM_SEND or SIMIX_COMM_RECEIVE) */
90       smx_rdv_t rdv;                  /* Rendez-vous where the comm is queued */
91       int refcount;                   /* Number of processes involved in the cond */
92       int detached;                   /* If detached or not */
93
94       /* Surf action data */
95       surf_action_t surf_comm;        /* The Surf communication action encapsulated */
96       surf_action_t src_timeout;      /* Surf's actions to instrument the timeouts */
97       surf_action_t dst_timeout;      /* Surf's actions to instrument the timeouts */
98       smx_process_t src_proc;
99       smx_process_t dst_proc;
100       double rate;
101       double task_size;
102
103       /* Data to be transfered */
104       void *src_buff;
105       void *dst_buff;
106       size_t src_buff_size;
107       size_t *dst_buff_size;
108       char copied;
109
110       void* src_data;                     /* User data associated to communication */
111       void* dst_data;
112     } comm;    
113
114     struct {
115       smx_host_t host;                /* The host that is sleeping */
116       surf_action_t surf_sleep;       /* The Surf sleeping action encapsulated */
117     } sleep;
118
119     struct {
120       surf_action_t sleep;
121     } synchro;
122
123   };
124
125 #ifdef HAVE_LATENCY_BOUND_TRACKING
126   int latency_limited;
127 #endif
128
129 #ifdef HAVE_TRACING
130   char *category;                     /* simix action category for instrumentation */
131 #endif
132 } s_smx_action_t;
133
134 /* FIXME: check if we can delete this function */
135 static XBT_INLINE e_smx_state_t SIMIX_action_map_state(e_surf_action_state_t state)
136 {
137   switch (state) {
138     case SURF_ACTION_READY:
139       return SIMIX_READY;
140     case SURF_ACTION_RUNNING:
141       return SIMIX_RUNNING;
142     case SURF_ACTION_FAILED:
143       return SIMIX_FAILED;
144     case SURF_ACTION_DONE:
145       return SIMIX_DONE;
146     default:
147       xbt_die("Unexpected SURF action state");
148   }
149 }
150
151
152
153 void SIMIX_context_mod_init(void);
154 void SIMIX_context_mod_exit(void);
155
156
157 /* All factories init */
158 void SIMIX_ctx_thread_factory_init(smx_context_factory_t *factory);
159 void SIMIX_ctx_sysv_factory_init(smx_context_factory_t *factory);
160 void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory);
161
162 /* ****************************** */
163 /* context manipulation functions */
164 /* ****************************** */
165
166 /* Scenario for the end of a context:
167  *
168  * CASE 1: death after end of the main function
169  *   the context_wrapper, called internally by the context module, calls 
170  *   SIMIX_context_stop after user code stops, smx_context_stop calls user 
171  *   cleanup_func if any (in context settings), add current process to trashbin
172  *   and yields back to maestro.
173  *   From time to time, maestro calls SIMIX_context_empty_trash, which destroy
174  *   all the process and context data structures, and frees the memory 
175  *
176  * CASE 2: brutal death
177  *   SIMIX_process_kill (from any process) set process->iwannadie = 1 and then
178  *   schedules the process. Then the process is awaken in the middle of the
179  *   SIMIX_process_yield function, and at the end of it, it checks that
180  *   iwannadie == 1, and call SIMIX_context_stop(same than first case afterward)
181  */
182
183 /**
184  * \brief creates a new context for a user level process
185  * \param code a main function
186  * \param argc the number of arguments of the main function
187  * \param argv the vector of arguments of the main function
188  * \param cleanup_func the function to call when the context stops
189  * \param cleanup_arg the argument of the cleanup_func function
190  */
191 static XBT_INLINE smx_context_t SIMIX_context_new(xbt_main_func_t code,
192                                                   int argc, char **argv,
193                                                   void_pfn_smxprocess_t cleanup_func,
194                                                   smx_process_t simix_process)
195 {
196
197   return (*(simix_global->context_factory->create_context))
198       (code, argc, argv, cleanup_func, simix_process);
199 }
200
201 /**
202  * \brief destroy a context 
203  * \param context the context to destroy
204  * Argument must be stopped first -- runs in maestro context
205  */
206 static XBT_INLINE void SIMIX_context_free(smx_context_t context)
207 {
208   (*(simix_global->context_factory->free)) (context);
209 }
210
211 /**
212  * \brief stops the execution of a context
213  * \param context to stop
214  */
215 static XBT_INLINE void SIMIX_context_stop(smx_context_t context)
216 {
217   (*(simix_global->context_factory->stop)) (context);
218 }
219
220 /**
221  \brief suspends a context and return the control back to the one which
222         scheduled it
223  \param context the context to be suspended (it must be the running one)
224  */
225 static XBT_INLINE void SIMIX_context_suspend(smx_context_t context)
226 {
227   (*(simix_global->context_factory->suspend)) (context);
228 }
229
230 /**
231  \brief executes all the processes (in parallel if possible)
232  \param processes the dynar of processes to execute
233  */
234 static XBT_INLINE void SIMIX_context_runall(xbt_dynar_t processes)
235 {
236   (*(simix_global->context_factory->runall)) (processes);
237 }
238
239 /**
240  \brief returns the current running context 
241  */
242 static XBT_INLINE smx_context_t SIMIX_context_self(void)
243 {
244   if (simix_global && simix_global->context_factory != NULL) {
245     return (*(simix_global->context_factory->self))();
246   }
247
248   return NULL;
249 }
250
251 /**
252  \brief returns the data associated to a context
253  \param context The context
254  \return The data
255  */
256 static XBT_INLINE void* SIMIX_context_get_data(smx_context_t context)
257 {
258   return (*(simix_global->context_factory->get_data))(context);
259 }
260
261 /**
262  \brief returns the thread's pid running the current context
263  \return The pid
264  */
265 static XBT_INLINE int SIMIX_context_get_thread_id(void)
266 {
267   return (*(simix_global->context_factory->get_thread_id))();
268 }
269
270 XBT_PUBLIC(int) SIMIX_process_get_maxpid(void);
271 #endif