Logo AND Algorithmique Numérique Distribuée

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