Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a straightforward implementation of start_time and kill_time. This change the...
[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
269         MSG_error_t rv = MSG_process_sleep(time);
270   jxbt_check_res("MSG_process_sleep()", rv, MSG_OK,
271                  bprintf("unexpected error , please report this bug"));
272 }
273 JNIEXPORT void JNICALL
274 Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess,
275                                      jdouble jseconds)
276 {
277   m_process_t process = jprocess_to_native_process(jprocess, env);
278
279   if (!process) {
280     jxbt_throw_notbound(env, "process", jprocess);
281     return;
282   }
283   MSG_error_t rv = MSG_process_sleep((double)jseconds);
284   if (rv != MSG_OK) {
285 //      smx_ctx_java_stop(smx_ctx_java_self());
286   }
287 }
288
289 JNIEXPORT void JNICALL
290 Java_org_simgrid_msg_Process_kill(JNIEnv * env,
291                                   jobject jprocess)
292 {
293         /* get the native instances from the java ones */
294   m_process_t process = jprocess_to_native_process(jprocess, env);
295   if (!process) {
296     jxbt_throw_notbound(env, "process", jprocess);
297     return;
298   }
299   /* Sets the "killed" flag to kill the process on the next unschedule */
300   smx_ctx_java_t context = (smx_ctx_java_t)MSG_process_get_smx_ctx(process);
301         context->killed = 1;
302
303         MSG_process_kill(process);
304 }
305 JNIEXPORT void JNICALL
306 Java_org_simgrid_msg_Process_migrate(JNIEnv * env,
307                                      jobject jprocess, jobject jhost)
308 {
309   m_process_t process = jprocess_to_native_process(jprocess, env);
310
311   if (!process) {
312     jxbt_throw_notbound(env, "process", jprocess);
313     return;
314   }
315
316   m_host_t host = jhost_get_native(env, jhost);
317
318   if (!host) {
319     jxbt_throw_notbound(env, "host", jhost);
320     return;
321   }
322
323   /* try to change the host of the process */
324   MSG_error_t rv = MSG_process_migrate(process, host);
325   jxbt_check_res("MSG_process_migrate()", rv, MSG_OK,
326                  bprintf("unexpected error , please report this bug"));
327   /* change the host java side */
328   (*env)->SetObjectField(env, jprocess, jprocess_field_Process_host, jhost);
329 }