Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
9b3bb96d5562945ee7d5654bff402ab0f6a80bb5
[simgrid.git] / src / jmsg_process.c
1 /* Functions related to the java process instances.                         */
2
3 /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7   * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "jmsg_process.h"
9
10 #include "jmsg.h"
11 #include "jmsg_host.h"
12 #include "jxbt_utilities.h"
13 #include "smx_context_java.h"
14
15 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(jmsg);
16
17 static jfieldID jprocess_field_Process_bind;
18 static jfieldID jprocess_field_Process_name;
19 static jfieldID jprocess_field_Process_host;
20 static jfieldID jprocess_field_Process_id;
21 static jfieldID jprocess_field_Process_pid;
22 static jfieldID jprocess_field_Process_ppid;
23
24 jobject native_to_java_process(m_process_t process)
25 {
26   return ((smx_ctx_java_t)MSG_process_get_smx_ctx(process))->jprocess;
27 }
28
29 jobject jprocess_new_global_ref(jobject jprocess, JNIEnv * env)
30 {
31   return (*env)->NewGlobalRef(env, jprocess);
32 }
33
34 void jprocess_delete_global_ref(jobject jprocess, JNIEnv * env)
35 {
36   (*env)->DeleteGlobalRef(env, jprocess);
37 }
38
39 void jprocess_join(jobject jprocess, JNIEnv * env)
40 {
41         m_process_t process = jprocess_to_native_process(jprocess,env);
42         smx_ctx_java_t context = (smx_ctx_java_t)MSG_process_get_smx_ctx(process);
43         xbt_os_thread_join(context->thread,NULL);
44 }
45
46 m_process_t jprocess_to_native_process(jobject jprocess, JNIEnv * env)
47 {
48   return (m_process_t) (long) (*env)->GetLongField(env, jprocess, jprocess_field_Process_bind);
49 }
50
51 void jprocess_bind(jobject jprocess, m_process_t process, JNIEnv * env)
52 {
53   (*env)->SetLongField(env, jprocess, jprocess_field_Process_bind, (jlong) (long) (process));
54 }
55
56 jlong jprocess_get_id(jobject jprocess, JNIEnv * env)
57 {
58   return (*env)->GetLongField(env, jprocess, jprocess_field_Process_id);
59 }
60
61 jstring jprocess_get_name(jobject jprocess, JNIEnv * env)
62 {
63   jstring jname = (jstring) (*env)->GetObjectField(env, jprocess, jprocess_field_Process_name);
64   return (*env)->NewGlobalRef(env, jname);
65
66 }
67
68 jboolean jprocess_is_valid(jobject jprocess, JNIEnv * env)
69 {
70   jfieldID id = jxbt_get_sfield(env, "org/simgrid/msg/Process", "bind", "J");
71
72   if (!id)
73     return JNI_FALSE;
74
75   return (*env)->GetLongField(env, jprocess, id) ? JNI_TRUE : JNI_FALSE;
76 }
77 JNIEXPORT void JNICALL
78 Java_org_simgrid_msg_Process_nativeInit(JNIEnv *env, jclass cls) {
79         jclass jprocess_class_Process = (*env)->FindClass(env, "org/simgrid/msg/Process");
80
81         jprocess_field_Process_name = jxbt_get_jfield(env, jprocess_class_Process, "name", "Ljava/lang/String;");
82         jprocess_field_Process_bind = jxbt_get_jfield(env, jprocess_class_Process, "bind", "J");
83         jprocess_field_Process_id = jxbt_get_jfield(env, jprocess_class_Process, "id", "J");
84         jprocess_field_Process_pid = jxbt_get_jfield(env, jprocess_class_Process, "pid", "I");
85         jprocess_field_Process_ppid = jxbt_get_jfield(env, jprocess_class_Process, "ppid", "I");
86         jprocess_field_Process_host = jxbt_get_jfield(env, jprocess_class_Process, "host", "Lorg/simgrid/msg/Host;");
87
88         if (!jprocess_class_Process || !jprocess_field_Process_id || !jprocess_field_Process_name || !jprocess_field_Process_pid ||
89                         !jprocess_field_Process_ppid || !jprocess_field_Process_host) {
90         jxbt_throw_native(env,bprintf("Can't find some fields in Java class. You should report this bug."));
91         }
92 }
93 JNIEXPORT void JNICALL
94 Java_org_simgrid_msg_Process_create(JNIEnv * env,
95                                     jobject jprocess_arg,
96                                     jobject jhostname, jdouble jstartTime, jdouble jkillTime)
97 {
98
99
100   jobject jprocess;             /* the global reference to the java process instance    */
101   jstring jname;                /* the name of the java process instance                */
102   const char *name;             /* the C name of the process                            */
103   const char *hostname;
104   m_process_t process;          /* the native process to create                         */
105   m_host_t host;                /* Where that process lives */
106
107   hostname = (*env)->GetStringUTFChars(env, jhostname, 0);
108
109   XBT_DEBUG("Java_org_simgrid_msg_MsgNative_processCreate(env=%p,jproc=%p,host=%s)",
110          env, jprocess_arg, hostname);
111
112
113   /* get the name of the java process */
114   jname = jprocess_get_name(jprocess_arg, env);
115   if (!jname) {
116     jxbt_throw_null(env,
117             xbt_strdup("Internal error: Process name cannot be NULL"));
118     return;
119   }
120
121   /* bind/retrieve the msg host */
122   host = MSG_get_host_by_name(hostname);
123
124   if (!(host)) {    /* not binded */
125     jxbt_throw_host_not_found(env, hostname);
126     return;
127   }
128
129   /* create a global java process instance */
130   jprocess = jprocess_new_global_ref(jprocess_arg, env);
131   if (!jprocess) {
132     jxbt_throw_jni(env, "Can't get a global ref to the java process");
133     return;
134   }
135
136   /* build the C name of the process */
137   name = (*env)->GetStringUTFChars(env, jname, 0);
138   name = xbt_strdup(name);
139
140   /* Actually build the MSG process */
141   process = MSG_process_create_with_environment(name,
142                                                 (xbt_main_func_t) jprocess,
143                                                 /*data*/ NULL,
144                                                 host,
145                                                 (double)jkillTime, /* kill time */
146                                                 /*argc, argv, properties*/
147                                                 0,NULL,NULL);
148
149   MSG_process_set_data(process,&process);
150   /* bind the java process instance to the native process */
151   jprocess_bind(jprocess, process, env);
152
153   /* release our reference to the process name (variable name becomes invalid) */
154   //FIXME : This line should be uncommented but with mac it doesn't work. BIG WARNING
155   //(*env)->ReleaseStringUTFChars(env, jname, name);
156   (*env)->ReleaseStringUTFChars(env, jhostname, hostname);
157
158   /* sets the PID and the PPID of the process */
159   (*env)->SetIntField(env, jprocess, jprocess_field_Process_pid,(jint) MSG_process_get_PID(process));
160   (*env)->SetIntField(env, jprocess, jprocess_field_Process_ppid, (jint) MSG_process_get_PPID(process));
161   /* sets the Host of the process */
162   jobject jhost = Java_org_simgrid_msg_Host_getByName(env,NULL,jhostname);
163
164   (*env)->SetObjectField(env, jprocess, jprocess_field_Process_host, jhost);
165 }
166
167 JNIEXPORT jint JNICALL
168 Java_org_simgrid_msg_Process_killAll(JNIEnv * env, jclass cls,
169                                      jint jresetPID)
170 {
171   return (jint) MSG_process_killall((int) jresetPID);
172 }
173
174 JNIEXPORT jobject JNICALL
175 Java_org_simgrid_msg_Process_fromPID(JNIEnv * env, jclass cls,
176                                      jint PID)
177 {
178   m_process_t process = MSG_process_from_PID(PID);
179
180   if (!process) {
181     jxbt_throw_process_not_found(env, bprintf("PID = %d",(int) PID));
182     return NULL;
183   }
184
185   jobject jprocess = native_to_java_process(process);
186
187   if (!jprocess) {
188     jxbt_throw_jni(env, "SIMIX_process_get_jprocess() failed");
189     return NULL;
190   }
191
192   return jprocess;
193 }
194
195 JNIEXPORT jobject JNICALL
196 Java_org_simgrid_msg_Process_currentProcess(JNIEnv * env, jclass cls)
197 {
198   m_process_t process = MSG_process_self();
199   jobject jprocess;
200
201   if (!process) {
202     jxbt_throw_jni(env, xbt_strdup("MSG_process_self() failed"));
203     return NULL;
204   }
205
206   jprocess = native_to_java_process(process);
207
208   if (!jprocess)
209     jxbt_throw_jni(env, xbt_strdup("SIMIX_process_get_jprocess() failed"));
210
211   return jprocess;
212 }
213
214 JNIEXPORT void JNICALL
215 Java_org_simgrid_msg_Process_pause(JNIEnv * env,
216                                    jobject jprocess)
217 {
218   m_process_t process = jprocess_to_native_process(jprocess, env);
219
220   if (!process) {
221     jxbt_throw_notbound(env, "process", jprocess);
222     return;
223   }
224
225   /* try to suspend the process */
226   MSG_error_t rv = MSG_process_suspend(process);
227
228   jxbt_check_res("MSG_process_suspend()", rv, MSG_OK,
229                  bprintf("unexpected error , please report this bug"));
230
231 }
232 JNIEXPORT void JNICALL
233 Java_org_simgrid_msg_Process_restart(JNIEnv * env,
234                                      jobject jprocess)
235 {
236   m_process_t process = jprocess_to_native_process(jprocess, env);
237
238   if (!process) {
239     jxbt_throw_notbound(env, "process", jprocess);
240     return;
241   }
242
243   /* try to resume the process */
244   MSG_error_t rv = MSG_process_resume(process);
245
246   jxbt_check_res("MSG_process_resume()", rv, MSG_OK,
247                  bprintf("unexpected error , please report this bug"));
248 }
249 JNIEXPORT jboolean JNICALL
250 Java_org_simgrid_msg_Process_isSuspended(JNIEnv * env,
251                                          jobject jprocess)
252 {
253   m_process_t process = jprocess_to_native_process(jprocess, env);
254
255   if (!process) {
256     jxbt_throw_notbound(env, "process", jprocess);
257     return 0;
258   }
259
260   /* true is the process is suspended, false otherwise */
261   return (jboolean) MSG_process_is_suspended(process);
262 }
263
264 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep
265         (JNIEnv *env, jclass cls, jlong jmillis, jint jnanos) {
266
267         double time =  jmillis / 1000 + jnanos / 1000;
268         MSG_error_t rv;
269         TRY {
270                 rv = MSG_process_sleep(time);
271         }
272         CATCH_ANONYMOUS {
273                 return;
274         }
275         jxbt_check_res("MSG_process_sleep()", rv, MSG_OK,
276                  bprintf("unexpected error , please report this bug"));
277 }
278 JNIEXPORT void JNICALL
279 Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess,
280                                      jdouble jseconds)
281 {
282   m_process_t process = jprocess_to_native_process(jprocess, env);
283
284   if (!process) {
285     jxbt_throw_notbound(env, "process", jprocess);
286     return;
287   }
288   MSG_error_t rv;
289   TRY {
290          rv = MSG_process_sleep((double)jseconds);
291   }
292   CATCH_ANONYMOUS {
293         return;
294   }
295   if (rv != MSG_OK) {
296 //      smx_ctx_java_stop(smx_ctx_java_self());
297   }
298 }
299
300 JNIEXPORT void JNICALL
301 Java_org_simgrid_msg_Process_kill(JNIEnv * env,
302                                   jobject jprocess)
303 {
304         /* get the native instances from the java ones */
305   m_process_t process = jprocess_to_native_process(jprocess, env);
306   if (!process) {
307     jxbt_throw_notbound(env, "process", jprocess);
308     return;
309   }
310
311         MSG_process_kill(process);
312 }
313 JNIEXPORT void JNICALL
314 Java_org_simgrid_msg_Process_migrate(JNIEnv * env,
315                                      jobject jprocess, jobject jhost)
316 {
317   m_process_t process = jprocess_to_native_process(jprocess, env);
318
319   if (!process) {
320     jxbt_throw_notbound(env, "process", jprocess);
321     return;
322   }
323
324   m_host_t host = jhost_get_native(env, jhost);
325
326   if (!host) {
327     jxbt_throw_notbound(env, "host", jhost);
328     return;
329   }
330
331   /* try to change the host of the process */
332   MSG_error_t rv = MSG_process_migrate(process, host);
333   jxbt_check_res("MSG_process_migrate()", rv, MSG_OK,
334                  bprintf("unexpected error , please report this bug"));
335   /* change the host java side */
336   (*env)->SetObjectField(env, jprocess, jprocess_field_Process_host, jhost);
337 }