Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
3e1faaee71407d0042938002754c0ea300266771
[simgrid.git] / src / bindings / java / jmsg_process.cpp
1 /* Functions related to the java process instances.                         */
2
3 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "jmsg_process.h"
9
10 #include "JavaContext.hpp"
11 #include "jmsg.hpp"
12 #include "jmsg_host.h"
13 #include "jxbt_utilities.hpp"
14 #include "simgrid/Exception.hpp"
15 #include "src/simix/ActorImpl.hpp"
16
17 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java);
18
19 jfieldID jprocess_field_Process_bind;
20 jfieldID jprocess_field_Process_host;
21 jfieldID jprocess_field_Process_killTime;
22 jfieldID jprocess_field_Process_name;
23 jfieldID jprocess_field_Process_pid;
24 jfieldID jprocess_field_Process_ppid;
25
26 jobject jprocess_from_native(msg_process_t process)
27 {
28   simgrid::kernel::context::JavaContext* context =
29       (simgrid::kernel::context::JavaContext*)process->get_impl()->context_;
30   return context->jprocess_;
31 }
32
33 jobject jprocess_ref(jobject jprocess, JNIEnv* env)
34 {
35   return env->NewGlobalRef(jprocess);
36 }
37
38 void jprocess_unref(jobject jprocess, JNIEnv* env)
39 {
40   env->DeleteGlobalRef(jprocess);
41 }
42
43 msg_process_t jprocess_to_native(jobject jprocess, JNIEnv* env)
44 {
45   return (msg_process_t)(intptr_t)env->GetLongField(jprocess, jprocess_field_Process_bind);
46 }
47
48 void jprocess_bind(jobject jprocess, msg_process_t process, JNIEnv * env)
49 {
50   env->SetLongField(jprocess, jprocess_field_Process_bind, (intptr_t)process);
51 }
52
53 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_nativeInit(JNIEnv *env, jclass cls) {
54   jclass jprocess_class_Process = env->FindClass("org/simgrid/msg/Process");
55   xbt_assert(jprocess_class_Process, "Native initialization of msg/Process failed. Please report that bug");
56
57   jprocess_field_Process_name = jxbt_get_jfield(env, jprocess_class_Process, "name", "Ljava/lang/String;");
58   jprocess_field_Process_bind = jxbt_get_jfield(env, jprocess_class_Process, "bind", "J");
59   jprocess_field_Process_pid = jxbt_get_jfield(env, jprocess_class_Process, "pid", "I");
60   jprocess_field_Process_ppid = jxbt_get_jfield(env, jprocess_class_Process, "ppid", "I");
61   jprocess_field_Process_host = jxbt_get_jfield(env, jprocess_class_Process, "host", "Lorg/simgrid/msg/Host;");
62   jprocess_field_Process_killTime = jxbt_get_jfield(env, jprocess_class_Process, "killTime", "D");
63   xbt_assert(jprocess_field_Process_name && jprocess_field_Process_pid && jprocess_field_Process_ppid &&
64                  jprocess_field_Process_host,
65              "Native initialization of msg/Process failed. Please report that bug");
66 }
67
68 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_create(JNIEnv* env, jobject jprocess_arg, jobject jhost)
69 {
70   /* create a global java process instance */
71   jobject jprocess = jprocess_ref(jprocess_arg, env);
72
73   /* Actually build the MSG process */
74   jstring jname         = (jstring)env->GetObjectField(jprocess, jprocess_field_Process_name);
75   const char* name      = env->GetStringUTFChars(jname, 0);
76   simgrid::simix::ActorCode function = [jprocess]() { simgrid::kernel::context::java_main_jprocess(jprocess); };
77   smx_actor_t actor =
78       simcall_process_create(name, function, /*data*/ nullptr, jhost_get_native(env, jhost), /* properties*/ nullptr);
79   MSG_process_yield();
80
81   env->ReleaseStringUTFChars(jname, name);
82
83   /* Retrieve the kill time from the process */
84   actor->ciface()->set_kill_time((double)env->GetDoubleField(jprocess, jprocess_field_Process_killTime));
85
86   /* sets the PID and the PPID of the process */
87   env->SetIntField(jprocess, jprocess_field_Process_pid, (jint)actor->ciface()->get_pid());
88   env->SetIntField(jprocess, jprocess_field_Process_ppid, (jint)actor->ciface()->get_ppid());
89 }
90
91 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_daemonize(JNIEnv* env, jobject jprocess)
92 {
93   msg_process_t process = jprocess_to_native(jprocess, env);
94
95   if (not process) {
96     jxbt_throw_notbound(env, "process", jprocess);
97     return;
98   }
99
100   process->daemonize();
101 }
102
103 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_killAll(JNIEnv* env, jclass cls)
104 {
105   MSG_process_killall();
106 }
107
108 JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_fromPID(JNIEnv * env, jclass cls, jint pid)
109 {
110   msg_process_t process = MSG_process_from_PID(pid);
111
112   if (not process) {
113     jxbt_throw_process_not_found(env, std::string("PID = ") + std::to_string(static_cast<int>(pid)));
114     return nullptr;
115   }
116
117   jobject jprocess = jprocess_from_native(process);
118
119   if (not jprocess) {
120     jxbt_throw_jni(env, "get process failed");
121     return nullptr;
122   }
123
124   return jprocess;
125 }
126
127 JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_nativeGetPID(JNIEnv* env, jobject jprocess)
128 {
129   msg_process_t process = jprocess_to_native(jprocess, env);
130   return MSG_process_get_PID(process);
131 }
132
133 JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv *env, jobject jprocess, jobject jname) {
134   msg_process_t process = jprocess_to_native(jprocess, env);
135
136   if (not process) {
137     jxbt_throw_notbound(env, "process", jprocess);
138     return nullptr;
139   }
140   const char *name = env->GetStringUTFChars((jstring)jname, 0);
141
142   const char *property = MSG_process_get_property_value(process, name);
143   if (not property)
144     return nullptr;
145
146   jobject jproperty = env->NewStringUTF(property);
147
148   env->ReleaseStringUTFChars((jstring)jname, name);
149
150   return jproperty;
151 }
152
153 JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getCurrentProcess(JNIEnv * env, jclass cls)
154 {
155   jobject jprocess = jprocess_from_native(MSG_process_self());
156   if (not jprocess)
157     jxbt_throw_jni(env, xbt_strdup("SIMIX_process_get_jprocess() failed"));
158
159   return jprocess;
160 }
161
162 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_suspend(JNIEnv * env, jobject jprocess)
163 {
164   msg_process_t process = jprocess_to_native(jprocess, env);
165
166   if (not process) {
167     jxbt_throw_notbound(env, "process", jprocess);
168     return;
169   }
170
171   /* suspend the process */
172   process->suspend();
173 }
174
175 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_resume(JNIEnv * env, jobject jprocess)
176 {
177   msg_process_t process = jprocess_to_native(jprocess, env);
178
179   if (not process) {
180     jxbt_throw_notbound(env, "process", jprocess);
181     return;
182   }
183
184   /* resume the process */
185   process->resume();
186 }
187
188 JNIEXPORT void
189 JNICALL Java_org_simgrid_msg_Process_setAutoRestart (JNIEnv *env, jobject jprocess, jboolean jauto_restart) {
190
191   msg_process_t process = jprocess_to_native(jprocess, env);
192   if (not process) {
193     jxbt_throw_notbound(env, "process", jprocess);
194     return;
195   }
196
197   process->set_auto_restart(jauto_restart == JNI_TRUE);
198 }
199
200 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_restart (JNIEnv *env, jobject jprocess) {
201   msg_process_t process = jprocess_to_native(jprocess, env);
202
203   if (not process) {
204     jxbt_throw_notbound(env, "process", jprocess);
205     return;
206   }
207
208   process->restart();
209 }
210
211 JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Process_isSuspended(JNIEnv * env, jobject jprocess)
212 {
213   msg_process_t process = jprocess_to_native(jprocess, env);
214
215   if (not process) {
216     jxbt_throw_notbound(env, "process", jprocess);
217     return 0;
218   }
219
220   /* true is the process is suspended, false otherwise */
221   return (jboolean)process->is_suspended();
222 }
223
224 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cls, jlong jmillis, jint jnanos)
225  {
226   double time =  ((double)jmillis) / 1000 + ((double)jnanos) / 1000000000;
227   msg_error_t rv;
228   try {
229     rv = MSG_process_sleep(time);
230   } catch (simgrid::kernel::context::Context::StopRequest const&) {
231     rv = MSG_HOST_FAILURE;
232   }
233   if (rv != MSG_OK) {
234     XBT_DEBUG("Something during the MSG_process_sleep invocation was wrong, trigger a HostFailureException");
235
236     jxbt_throw_host_failure(env, "");
237   }
238 }
239
240 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess, jdouble jseconds)
241 {
242   msg_error_t rv;
243   rv = MSG_process_sleep((double)jseconds);
244   if (env->ExceptionOccurred())
245     return;
246   if (rv != MSG_OK) {
247     XBT_DEBUG("Status NOK");
248     jmsg_throw_status(env,rv);
249   }
250 }
251
252 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_kill(JNIEnv * env, jobject jprocess)
253 {
254   /* get the native instances from the java ones */
255   msg_process_t process = jprocess_to_native(jprocess, env);
256   if (not process) {
257     jxbt_throw_notbound(env, "process", jprocess);
258     return;
259   }
260   try {
261     MSG_process_kill(process);
262   } catch (xbt_ex& ex) {
263     XBT_VERB("Process %s just committed a suicide", MSG_process_get_name(process));
264     xbt_assert(process == MSG_process_self(),
265                "Killing a process should not raise an exception if it's not a suicide. Please report that bug.");
266   }
267 }
268
269 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_migrate(JNIEnv * env, jobject jprocess, jobject jhost)
270 {
271   msg_process_t process = jprocess_to_native(jprocess, env);
272
273   if (not process) {
274     jxbt_throw_notbound(env, "process", jprocess);
275     return;
276   }
277
278   msg_host_t host = jhost_get_native(env, jhost);
279
280   if (not host) {
281     jxbt_throw_notbound(env, "host", jhost);
282     return;
283   }
284
285   /* change the host of the process */
286   process->migrate(host);
287
288   /* change the host java side */
289   env->SetObjectField(jprocess, jprocess_field_Process_host, jhost);
290 }
291
292 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_yield(JNIEnv* env, jclass cls)
293 {
294   MSG_process_yield();
295 }
296
297 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setKillTime (JNIEnv *env , jobject jprocess, jdouble jkilltime) {
298   msg_process_t process = jprocess_to_native(jprocess, env);
299   MSG_process_set_kill_time(process, (double)jkilltime);
300 }
301
302 JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_getCount(JNIEnv * env, jclass cls) {
303   return (jint) MSG_process_get_number();
304 }