Logo AND Algorithmique Numérique Distribuée

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