Logo AND Algorithmique Numérique Distribuée

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