Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
The file containing the new implementation of the switch context mechanism.
[simgrid.git] / src / xbt / xbt_jcontext.c
1 \r
2 \r
3 #include "xbt/function_types.h"\r
4 #include "xbt/ex_interface.h"\r
5 \r
6 XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg,"MSG for Java(TM)");\r
7 \r
8 #include "java/jmsg.c"\r
9 #include "java/jmsg_channel.c"\r
10 #include "java/jmsg_host.c"\r
11 #include "java/jmsg_parallel_task.c"\r
12 #include "java/jmsg_task.c"\r
13 #include "java/jxbt_utilities.c"\r
14 #include "java/jmsg_process.c"\r
15 \r
16 \r
17 /* callback: context fetching */\r
18 static ex_ctx_t*\r
19 xbt_jcontext_ex_ctx(void);\r
20 \r
21 /* callback: termination */\r
22 static void \r
23 xbt_jcontext_ex_terminate(xbt_ex_t *e);\r
24 \r
25 static xbt_context_t \r
26 xbt_jcontext_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv);\r
27 \r
28 static int \r
29 xbt_jcontext_factory_create_maestro_context(xbt_context_t* maestro);\r
30 \r
31 static int\r
32 xbt_jcontext_factory_finalize(xbt_context_factory_t* factory);\r
33 \r
34 static void \r
35 xbt_jcontext_free(xbt_context_t context);\r
36 \r
37 static void \r
38 xbt_jcontext_kill(xbt_context_t context);\r
39 \r
40 static void \r
41 xbt_jcontext_schedule(xbt_context_t context);\r
42 \r
43 static void \r
44 xbt_jcontext_yield(void);\r
45 \r
46 static void \r
47 xbt_jcontext_start(xbt_context_t context);\r
48 \r
49 static void \r
50 xbt_jcontext_stop(int exit_code);\r
51 \r
52 static void \r
53 xbt_jcontext_swap(xbt_context_t context);\r
54 \r
55 static void\r
56 xbt_jcontext_schedule(xbt_context_t context);\r
57 \r
58 static void\r
59 xbt_jcontext_yield(void);\r
60 \r
61 static void\r
62 xbt_jcontext_suspend(xbt_context_t context);\r
63 \r
64 static void\r
65 xbt_jcontext_resume(xbt_context_t context);\r
66 \r
67 \r
68 /* callback: context fetching */\r
69 static ex_ctx_t*\r
70 xbt_jcontext_ex_ctx(void) \r
71 {\r
72         return current_context->exception;\r
73 }\r
74 \r
75 /* callback: termination */\r
76 static void \r
77 xbt_jcontext_ex_terminate(xbt_ex_t *e) \r
78 {\r
79         xbt_ex_display(e);\r
80         abort();\r
81 }\r
82 \r
83 int\r
84 xbt_jcontext_factory_init(xbt_context_factory_t* factory)\r
85 {\r
86         /* context exception handlers */\r
87     __xbt_ex_ctx       = xbt_jcontext_ex_ctx;\r
88     __xbt_ex_terminate = xbt_jcontext_ex_terminate;     \r
89     \r
90     /* instantiate the context factory */\r
91         *factory = xbt_new0(s_xbt_context_factory_t,1);\r
92         \r
93         (*factory)->create_context = xbt_jcontext_factory_create_context;\r
94         (*factory)->finalize = xbt_jcontext_factory_finalize;\r
95         (*factory)->create_maestro_context = xbt_jcontext_factory_create_maestro_context;\r
96         (*factory)->name = "jcontext_factory";\r
97         \r
98         return 0;\r
99 }\r
100 \r
101 static int \r
102 xbt_jcontext_factory_create_maestro_context(xbt_context_t* maestro)\r
103 {\r
104         xbt_jcontext_t context = xbt_new0(s_xbt_jcontext_t, 1);\r
105         \r
106         context->exception = xbt_new(ex_ctx_t,1);\r
107     XBT_CTX_INITIALIZE(context->exception);\r
108     \r
109     *maestro = (xbt_context_t)context;\r
110     \r
111     return 0;\r
112 }\r
113 \r
114 static int\r
115 xbt_jcontext_factory_finalize(xbt_context_factory_t* factory)\r
116 {\r
117         free(maestro_context->exception);\r
118         free(*factory);\r
119         *factory = NULL;\r
120 \r
121         return 0;\r
122 }\r
123 \r
124 static xbt_context_t \r
125 xbt_jcontext_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv)\r
126 {\r
127         xbt_jcontext_t context = xbt_new0(s_xbt_jcontext_t,1);\r
128 \r
129         context->name = xbt_strdup(name);\r
130 \r
131         context->cleanup_func = cleanup_func;\r
132         context->cleanup_arg = cleanup_arg;\r
133 \r
134         context->exception = xbt_new(ex_ctx_t,1);\r
135         XBT_CTX_INITIALIZE(context->exception);\r
136 \r
137         context->free = xbt_jcontext_free;                      \r
138         context->kill = xbt_jcontext_kill;                      \r
139         context->schedule = xbt_jcontext_schedule;\r
140         context->yield = xbt_jcontext_yield;                    \r
141         context->start = xbt_jcontext_start;                    \r
142         context->stop = xbt_jcontext_stop;      \r
143         context->jprocess = (jobject)startup_arg;\r
144         context->jenv = get_current_thread_env();\r
145 \r
146         return (xbt_context_t)context;\r
147 }\r
148 \r
149 static void \r
150 xbt_jcontext_free(xbt_context_t context)\r
151 {\r
152         if(context) \r
153         {\r
154                 xbt_jcontext_t jcontext = (xbt_jcontext_t)context;\r
155                 \r
156                 free(jcontext->name);\r
157                 \r
158                 if(jcontext->jprocess) \r
159                 {\r
160                         jobject jprocess = jcontext->jprocess;\r
161                         jcontext->jprocess = NULL;\r
162 \r
163                         /* if the java process is alive join it */\r
164                         if(jprocess_is_alive(jprocess,get_current_thread_env())) \r
165                                 jprocess_join(jprocess,get_current_thread_env());\r
166                 }\r
167 \r
168                 if(jcontext->exception) \r
169                         free(jcontext->exception);\r
170 \r
171                 free(context);\r
172                 context = NULL;\r
173         }\r
174 }\r
175 \r
176 static void \r
177 xbt_jcontext_kill(xbt_context_t context)\r
178 {\r
179         context->iwannadie = 1;\r
180         xbt_jcontext_swap(context);\r
181 }\r
182 \r
183 /** \r
184  * \param context the winner\r
185  *\r
186  * Calling this function blocks the current context and schedule \a context.  \r
187  * When \a context will call xbt_context_yield, it will return\r
188  * to this function as if nothing had happened.\r
189  * \r
190  * Only the maestro can call this function to run a given process.\r
191  */\r
192 static void \r
193 xbt_jcontext_schedule(xbt_context_t context)\r
194 {\r
195         xbt_assert0((current_context == maestro_context),"You are not supposed to run this function here!");\r
196         xbt_jcontext_swap(context);\r
197 }\r
198 \r
199 /** \r
200  * Calling this function makes the current context yield. The context\r
201  * that scheduled it returns from xbt_context_schedule as if nothing\r
202  * had happened.\r
203  * \r
204  * Only the processes can call this function, giving back the control\r
205  * to the maestro\r
206  */\r
207 static void \r
208 xbt_jcontext_yield(void)\r
209 {\r
210         xbt_assert0((current_context != maestro_context),"You are not supposed to run this function here!");\r
211         jprocess_unschedule(current_context);\r
212 }\r
213 \r
214 static void \r
215 xbt_jcontext_start(xbt_context_t context)\r
216 {\r
217         jprocess_start(((xbt_jcontext_t)context)->jprocess,get_current_thread_env());\r
218 }\r
219 \r
220 static void \r
221 xbt_jcontext_stop(int exit_code)\r
222 {\r
223         jobject jprocess = NULL;\r
224         xbt_jcontext_t jcontext;\r
225 \r
226         if(current_context->cleanup_func)\r
227                 (*(current_context->cleanup_func))(current_context->cleanup_arg);\r
228 \r
229         xbt_swag_remove(current_context, context_living);\r
230         xbt_swag_insert(current_context, context_to_destroy);\r
231         \r
232         jcontext = (xbt_jcontext_t)current_context;\r
233         \r
234         if(jcontext->iwannadie)\r
235         {\r
236                 /* The maestro call xbt_context_stop() with an exit code set to one */\r
237                 if(jcontext->jprocess) \r
238                 {\r
239                         /* if the java process is alive schedule it */\r
240                         if(jprocess_is_alive(jcontext->jprocess,get_current_thread_env())) \r
241                         {\r
242                                 jprocess_schedule(current_context);\r
243                                 jprocess = jcontext->jprocess;\r
244                                 jcontext->jprocess = NULL;\r
245                                 \r
246                                 /* interrupt the java process */\r
247                                 jprocess_exit(jprocess,get_current_thread_env());\r
248 \r
249                         }\r
250                 }\r
251         }\r
252         else\r
253         {\r
254                 /* the java process exits */\r
255                 jprocess = jcontext->jprocess;\r
256                 jcontext->jprocess = NULL;\r
257         }\r
258 \r
259         /* delete the global reference associated with the java process */\r
260         jprocess_delete_global_ref(jprocess,get_current_thread_env());  \r
261 }\r
262 \r
263 static void \r
264 xbt_jcontext_swap(xbt_context_t context)\r
265 {\r
266         if(context) \r
267         {\r
268                 xbt_context_t self = current_context;\r
269                 \r
270                 current_context = context;\r
271                 \r
272                 jprocess_schedule(context);\r
273                 \r
274                 current_context = self;\r
275         }\r
276         \r
277         if(current_context->iwannadie)\r
278                 xbt_jcontext_stop(1);\r
279 }\r