Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
work around issues by passing the hostname instead of the host to processCreate()
[simgrid.git] / src / jmsg.c
1 /* Java Wrappers to the MSG API.                                            */
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
9 #include <msg/msg.h>
10 #include <simgrid/simix.h>
11 #include <surf/surfxml_parse.h>
12
13 #include "smx_context_java.h"
14
15 #include "jmsg_process.h"
16 #include "jmsg_host.h"
17 #include "jmsg_task.h"
18 #include "jmsg_application_handler.h"
19 #include "jxbt_utilities.h"
20
21 #include "jmsg.h"
22
23 /* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */
24 #ifndef JNIEXPORT
25 #define JNIEXPORT
26 #endif
27 #ifndef JNICALL
28 #define JNICALL
29 #endif
30 /* end of eclipse-mandated pimple */
31
32 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(jmsg);
33
34 static JavaVM *__java_vm = NULL;
35
36 static jobject native_to_java_process(m_process_t process);
37
38 JavaVM *get_java_VM(void)
39 {
40   return __java_vm;
41 }
42
43 JNIEnv *get_current_thread_env(void)
44 {
45   JNIEnv *env;
46
47   (*__java_vm)->AttachCurrentThread(__java_vm, (void **) &env, NULL);
48
49   return env;
50 }
51
52 static jobject native_to_java_process(m_process_t process)
53 {
54   return ((smx_ctx_java_t)MSG_process_get_smx_ctx(process))->jprocess;
55 }
56
57 /*
58  * The MSG process connected functions implementation.                                 
59  */
60
61 JNIEXPORT void JNICALL
62 Java_org_simgrid_msg_MsgNative_processCreate(JNIEnv * env, jclass cls,
63                                          jobject jprocess_arg,
64                                          jobject jhostname)
65 {
66      
67    
68   jobject jprocess;             /* the global reference to the java process instance    */
69   jstring jname;                /* the name of the java process instance                */
70   const char *name;             /* the C name of the process                            */
71   const char *hostname;
72   m_process_t process;          /* the native process to create                         */
73   m_host_t host;                /* Where that process lives */
74    
75   hostname = (*env)->GetStringUTFChars(env, jhostname, 0);
76
77   XBT_DEBUG("Java_org_simgrid_msg_MsgNative_processCreate(env=%p,cls=%p,jproc=%p,host=%s)",
78          env, cls, jprocess_arg, hostname);
79    
80    
81   /* get the name of the java process */
82   jname = jprocess_get_name(jprocess_arg, env);
83   if (!jname) {
84     jxbt_throw_null(env,
85             xbt_strdup("Internal error: Process name cannot be NULL"));
86     return;
87   }
88
89   /* bind/retrieve the msg host */
90   host = MSG_get_host_by_name(hostname);
91
92   if (!(host)) {    /* not binded */
93     jxbt_throw_host_not_found(env, hostname);
94     return;
95   }
96
97   /* create a global java process instance */
98   jprocess = jprocess_new_global_ref(jprocess_arg, env);
99   if (!jprocess) {
100     jxbt_throw_jni(env, "Can't get a global ref to the java process");
101     return;
102   }
103
104   /* build the C name of the process */
105   name = (*env)->GetStringUTFChars(env, jname, 0);
106   name = xbt_strdup(name);
107   
108   /* Actually build the MSG process */
109   process = MSG_process_create_with_environment(name,
110                                                 (xbt_main_func_t) jprocess,
111                                                 /*data*/ NULL,
112                                                 host,
113                                                 /*kill_time*/0.,
114                                                 /*argc, argv, properties*/
115                                                 0,NULL,NULL);
116      
117   MSG_process_set_data(process,&process);
118    
119   /* release our reference to the process name (variable name becomes invalid) */
120   //FIXME : This line should be uncommented but with mac it doesn't work. BIG WARNING
121   //(*env)->ReleaseStringUTFChars(env, jname, name);
122   (*env)->ReleaseStringUTFChars(env, jhostname, hostname);
123    
124   /* bind the java process instance to the native process */
125   jprocess_bind(jprocess, process, env);
126
127 }
128
129 JNIEXPORT void JNICALL
130 Java_org_simgrid_msg_MsgNative_processSuspend(JNIEnv * env, jclass cls,
131                                           jobject jprocess)
132 {
133   m_process_t process = jprocess_to_native_process(jprocess, env);
134
135   if (!process) {
136     jxbt_throw_notbound(env, "process", jprocess);
137     return;
138   }
139
140   /* try to suspend the process */
141   MSG_error_t rv = MSG_process_suspend(process);
142
143   jxbt_check_res("MSG_process_suspend()", rv, MSG_OK,
144                  bprintf("unexpected error , please report this bug"));
145
146 }
147
148 JNIEXPORT void JNICALL
149 Java_org_simgrid_msg_Process_simulatedSleep(JNIEnv * env, jobject jprocess,
150                                            jdouble jseconds) {
151           m_process_t process = jprocess_to_native_process(jprocess, env);
152
153           if (!process) {
154             jxbt_throw_notbound(env, "process", jprocess);
155             return;
156           }
157           MSG_error_t rv = MSG_process_sleep((double)jseconds);
158
159           jxbt_check_res("MSG_process_sleep()", rv, MSG_OK,
160                          bprintf("unexpected error , please report this bug"));
161 }
162
163
164 JNIEXPORT void JNICALL
165 Java_org_simgrid_msg_MsgNative_processResume(JNIEnv * env, jclass cls,
166                                          jobject jprocess)
167 {
168   m_process_t process = jprocess_to_native_process(jprocess, env);
169
170   if (!process) {
171     jxbt_throw_notbound(env, "process", jprocess);
172     return;
173   }
174
175   /* try to resume the process */
176   MSG_error_t rv = MSG_process_resume(process);
177
178   jxbt_check_res("MSG_process_resume()", rv, MSG_OK,
179                  bprintf("unexpected error , please report this bug"));
180 }
181
182 JNIEXPORT jboolean JNICALL
183 Java_org_simgrid_msg_MsgNative_processIsSuspended(JNIEnv * env, jclass cls,
184                                               jobject jprocess)
185 {
186   m_process_t process = jprocess_to_native_process(jprocess, env);
187
188   if (!process) {
189     jxbt_throw_notbound(env, "process", jprocess);
190     return 0;
191   }
192
193   /* true is the process is suspended, false otherwise */
194   return (jboolean) MSG_process_is_suspended(process);
195 }
196
197 JNIEXPORT void JNICALL
198 Java_org_simgrid_msg_MsgNative_processKill(JNIEnv * env, jclass cls,
199                                        jobject jprocess)
200 {
201   /* get the native instances from the java ones */
202   m_process_t process = jprocess_to_native_process(jprocess, env);
203
204   if (!process) {
205     jxbt_throw_notbound(env, "process", jprocess);
206     return;
207   }
208
209   /* kill the native process (this wrapper is call by the destructor of the java 
210    * process instance)
211    */
212   MSG_process_kill(process);
213 }
214
215 JNIEXPORT jobject JNICALL
216 Java_org_simgrid_msg_MsgNative_processGetHost(JNIEnv * env, jclass cls,
217                                           jobject jprocess)
218 {
219   /* get the native instances from the java ones */
220   m_process_t process = jprocess_to_native_process(jprocess, env);
221   m_host_t host;
222
223   if (!process) {
224     jxbt_throw_notbound(env, "process", jprocess);
225     return NULL;
226   }
227
228   host = MSG_process_get_host(process);
229
230   if (!MSG_host_get_data(host)) {
231     jxbt_throw_jni(env, "MSG_process_get_host() failed");
232     return NULL;
233   }
234
235   /* return the global reference to the java host instance */
236   return (jobject) MSG_host_get_data(host);
237
238 }
239
240 JNIEXPORT jobject JNICALL
241 Java_org_simgrid_msg_MsgNative_processFromPID(JNIEnv * env, jclass cls,
242                                           jint PID)
243 {
244   m_process_t process = MSG_process_from_PID(PID);
245
246   if (!process) {
247     jxbt_throw_process_not_found(env, bprintf("PID = %d",(int) PID));
248     return NULL;
249   }
250
251   if (!native_to_java_process(process)) {
252     jxbt_throw_jni(env, "SIMIX_process_get_jprocess() failed");
253     return NULL;
254   }
255
256   return (jobject) (native_to_java_process(process));
257 }
258
259
260 JNIEXPORT jint JNICALL
261 Java_org_simgrid_msg_MsgNative_processGetPID(JNIEnv * env, jclass cls,
262                                          jobject jprocess)
263 {
264   m_process_t process = jprocess_to_native_process(jprocess, env);
265
266   if (!process) {
267     jxbt_throw_notbound(env, "process", jprocess);
268     return 0;
269   }
270
271   return (jint) MSG_process_get_PID(process);
272 }
273
274
275 JNIEXPORT jint JNICALL
276 Java_org_simgrid_msg_MsgNative_processGetPPID(JNIEnv * env, jclass cls,
277                                           jobject jprocess)
278 {
279   m_process_t process = jprocess_to_native_process(jprocess, env);
280
281   if (!process) {
282     jxbt_throw_notbound(env, "process", jprocess);
283     return 0;
284   }
285
286   return (jint) MSG_process_get_PPID(process);
287 }
288
289 JNIEXPORT jobject JNICALL
290 Java_org_simgrid_msg_MsgNative_processSelf(JNIEnv * env, jclass cls)
291 {
292   m_process_t process = MSG_process_self();
293   jobject jprocess;
294
295   if (!process) {
296     jxbt_throw_jni(env, xbt_strdup("MSG_process_self() failed"));
297     return NULL;
298   }
299
300   jprocess = native_to_java_process(process);
301
302   if (!jprocess)
303     jxbt_throw_jni(env, xbt_strdup("SIMIX_process_get_jprocess() failed"));
304
305   return jprocess;
306 }
307
308 JNIEXPORT void JNICALL
309 Java_org_simgrid_msg_MsgNative_processMigrate(JNIEnv * env, jclass cls,
310                                              jobject jprocess, jobject jhost)
311 {
312   m_process_t process = jprocess_to_native_process(jprocess, env);
313
314   if (!process) {
315     jxbt_throw_notbound(env, "process", jprocess);
316     return;
317   }
318
319   m_host_t host = jhost_get_native(env, jhost);
320
321   if (!host) {
322     jxbt_throw_notbound(env, "host", jhost);
323     return;
324   }
325
326   /* try to change the host of the process */
327   MSG_error_t rv = MSG_process_migrate(process, host);
328   jxbt_check_res("MSG_process_migrate()", rv, MSG_OK,
329                  bprintf("unexpected error , please report this bug"));
330
331 }
332
333 JNIEXPORT void JNICALL
334 Java_org_simgrid_msg_MsgNative_processWaitFor(JNIEnv * env, jclass cls,
335                                           jdouble seconds)
336 {
337   MSG_error_t rv = MSG_process_sleep((double) seconds);
338
339   jxbt_check_res("MSG_process_sleep()", rv, MSG_HOST_FAILURE,
340                  bprintf("while process was waiting for %f seconds",
341                          (double) seconds));
342
343 }
344
345
346 /***************************************************************************************
347  * The MSG host connected functions implementation.                                    *
348  ***************************************************************************************/
349
350 JNIEXPORT jobject JNICALL
351 Java_org_simgrid_msg_MsgNative_hostGetByName(JNIEnv * env, jclass cls,
352                                          jstring jname)
353 {
354   m_host_t host;                /* native host                                          */
355   jobject jhost;                /* global reference to the java host instance returned  */
356
357   /* get the C string from the java string */
358   const char *name = (*env)->GetStringUTFChars(env, jname, 0);
359   XBT_DEBUG("Looking for host '%s'",name);
360   /* get the host by name       (the hosts are created during the grid resolution) */
361   host = MSG_get_host_by_name(name);
362   XBT_DEBUG("MSG gave %p as native host (smx_host=%p)", host,host? host->smx_host:NULL);
363
364   if (!host) {                  /* invalid name */
365     jxbt_throw_host_not_found(env, name);
366     (*env)->ReleaseStringUTFChars(env, jname, name);
367     return NULL;
368   }
369   (*env)->ReleaseStringUTFChars(env, jname, name);
370
371   if (!MSG_host_get_data(host)) {       /* native host not associated yet with java host */
372
373     /* Instantiate a new java host */
374     jhost = jhost_new_instance(env);
375
376     if (!jhost) {
377       jxbt_throw_jni(env, "java host instantiation failed");
378       return NULL;
379     }
380
381     /* get a global reference to the newly created host */
382     jhost = jhost_ref(env, jhost);
383
384     if (!jhost) {
385       jxbt_throw_jni(env, "new global ref allocation failed");
386       return NULL;
387     }
388
389     /* bind the java host and the native host */
390     jhost_bind(jhost, host, env);
391
392     /* the native host data field is set with the global reference to the 
393      * java host returned by this function 
394      */
395     MSG_host_set_data(host, (void *) jhost);
396   }
397
398   /* return the global reference to the java host instance */
399   return (jobject) MSG_host_get_data(host);
400 }
401
402 JNIEXPORT jstring JNICALL
403 Java_org_simgrid_msg_MsgNative_hostGetName(JNIEnv * env, jclass cls,
404                                        jobject jhost)
405 {
406   m_host_t host = jhost_get_native(env, jhost);
407
408   if (!host) {
409     jxbt_throw_notbound(env, "host", jhost);
410     return NULL;
411   }
412
413   return (*env)->NewStringUTF(env, MSG_host_get_name(host));
414 }
415
416 JNIEXPORT jint JNICALL
417 Java_org_simgrid_msg_MsgNative_hostGetNumber(JNIEnv * env, jclass cls)
418 {
419   xbt_dynar_t hosts =  MSG_hosts_as_dynar();
420   int nb_host = xbt_dynar_length(hosts);
421   xbt_dynar_free(&hosts);
422   return (jint) nb_host;
423 }
424
425 JNIEXPORT jobject JNICALL
426 Java_org_simgrid_msg_MsgNative_hostSelf(JNIEnv * env, jclass cls)
427 {
428   jobject jhost;
429
430   m_host_t host = MSG_host_self();
431
432   if (!MSG_host_get_data(host)) {
433     /* the native host not yet associated with the java host instance */
434
435     /* instanciate a new java host instance */
436     jhost = jhost_new_instance(env);
437
438     if (!jhost) {
439       jxbt_throw_jni(env, "java host instantiation failed");
440       return NULL;
441     }
442
443     /* get a global reference to the newly created host */
444     jhost = jhost_ref(env, jhost);
445
446     if (!jhost) {
447       jxbt_throw_jni(env, "global ref allocation failed");
448       return NULL;
449     }
450
451     /* Bind & store it */
452     jhost_bind(jhost, host, env);
453     MSG_host_set_data(host, (void *) jhost);
454   } else {
455     jhost = (jobject) MSG_host_get_data(host);
456   }
457
458   return jhost;
459 }
460
461 JNIEXPORT jdouble JNICALL
462 Java_org_simgrid_msg_MsgNative_hostGetSpeed(JNIEnv * env, jclass cls,
463                                         jobject jhost)
464 {
465   m_host_t host = jhost_get_native(env, jhost);
466
467   if (!host) {
468     jxbt_throw_notbound(env, "host", jhost);
469     return -1;
470   }
471
472   return (jdouble) MSG_get_host_speed(host);
473 }
474
475 JNIEXPORT jint JNICALL
476 Java_org_simgrid_msg_MsgNative_hostGetLoad(JNIEnv * env, jclass cls,
477                                        jobject jhost)
478 {
479   m_host_t host = jhost_get_native(env, jhost);
480
481   if (!host) {
482     jxbt_throw_notbound(env, "host", jhost);
483     return -1;
484   }
485
486   return (jint) MSG_get_host_msgload(host);
487 }
488
489
490 JNIEXPORT jboolean JNICALL
491 Java_org_simgrid_msg_MsgNative_hostIsAvail(JNIEnv * env, jclass cls,
492                                        jobject jhost)
493 {
494   m_host_t host = jhost_get_native(env, jhost);
495
496   if (!host) {
497     jxbt_throw_notbound(env, "host", jhost);
498     return 0;
499   }
500
501   return (jboolean) MSG_host_is_avail(host);
502 }
503
504
505 /***************************************************************************************
506  * The MSG task connected functions implementation.                                    *
507  ***************************************************************************************/
508
509 JNIEXPORT void JNICALL
510 Java_org_simgrid_msg_MsgNative_taskCreate(JNIEnv * env, jclass cls,
511                                       jobject jtask, jstring jname,
512                                       jdouble jcomputeDuration,
513                                       jdouble jmessageSize)
514 {
515   m_task_t task;                /* the native task to create                            */
516   const char *name = NULL;      /* the name of the task                                 */
517
518   if (jcomputeDuration < 0) {
519     jxbt_throw_illegal(env,
520                        bprintf
521                        ("Task ComputeDuration (%f) cannot be negative",
522                         (double) jcomputeDuration));
523     return;
524   }
525
526   if (jmessageSize < 0) {
527     jxbt_throw_illegal(env,
528                        bprintf("Task MessageSize (%f) cannot be negative",
529                                (double) jmessageSize));
530     return;
531   }
532
533   if (jname) {
534     /* get the C string from the java string */
535     name = (*env)->GetStringUTFChars(env, jname, 0);
536   }
537
538
539   /* create the task */
540   task =
541       MSG_task_create(name, (double) jcomputeDuration,
542                       (double) jmessageSize, NULL);
543
544   if (jname)
545     (*env)->ReleaseStringUTFChars(env, jname, name);
546
547   /* bind & store the task */
548   jtask_bind(jtask, task, env);
549   MSG_task_set_data(task, jtask);
550 }
551
552 JNIEXPORT void JNICALL
553 Java_org_simgrid_msg_MsgNative_parallel_taskCreate(JNIEnv * env, jclass cls,
554                                                jobject jtask,
555                                                jstring jname,
556                                                jobjectArray jhosts,
557                                                jdoubleArray
558                                                jcomputeDurations_arg,
559                                                jdoubleArray
560                                                jmessageSizes_arg)
561 {
562
563   m_task_t task;                /* the native parallel task to create           */
564   const char *name;             /* the name of the task                         */
565   int host_count;
566   m_host_t *hosts;
567   double *computeDurations;
568   double *messageSizes;
569   jdouble *jcomputeDurations;
570   jdouble *jmessageSizes;
571
572   jobject jhost;
573   int index;
574
575
576   if (!jcomputeDurations_arg) {
577     jxbt_throw_null(env,
578                     xbt_strdup
579                     ("Parallel task compute durations cannot be null"));
580     return;
581   }
582
583   if (!jmessageSizes_arg) {
584     jxbt_throw_null(env,
585                     xbt_strdup
586                     ("Parallel task message sizes cannot be null"));
587     return;
588   }
589
590   if (!jname) {
591     jxbt_throw_null(env, xbt_strdup("Parallel task name cannot be null"));
592     return;
593   }
594
595   host_count = (int) (*env)->GetArrayLength(env, jhosts);
596
597
598   hosts = xbt_new0(m_host_t, host_count);
599   computeDurations = xbt_new0(double, host_count);
600   messageSizes = xbt_new0(double, host_count * host_count);
601
602   jcomputeDurations =
603       (*env)->GetDoubleArrayElements(env, jcomputeDurations_arg, 0);
604   jmessageSizes =
605       (*env)->GetDoubleArrayElements(env, jmessageSizes_arg, 0);
606
607   for (index = 0; index < host_count; index++) {
608     jhost = (*env)->GetObjectArrayElement(env, jhosts, index);
609     hosts[index] = jhost_get_native(env, jhost);
610     computeDurations[index] = jcomputeDurations[index];
611   }
612   for (index = 0; index < host_count * host_count; index++) {
613     messageSizes[index] = jmessageSizes[index];
614   }
615
616   (*env)->ReleaseDoubleArrayElements(env, jcomputeDurations_arg,
617                                      jcomputeDurations, 0);
618   (*env)->ReleaseDoubleArrayElements(env, jmessageSizes_arg, jmessageSizes,
619                                      0);
620
621
622   /* get the C string from the java string */
623   name = (*env)->GetStringUTFChars(env, jname, 0);
624
625   task =
626       MSG_parallel_task_create(name, host_count, hosts, computeDurations,
627                                messageSizes, NULL);
628
629   (*env)->ReleaseStringUTFChars(env, jname, name);
630
631   /* associate the java task object and the native task */
632   jtask_bind(jtask, task, env);
633
634   MSG_task_set_data(task, (void *) jtask);
635
636   if (!MSG_task_get_data(task))
637     jxbt_throw_jni(env, "global ref allocation failed");
638 }
639
640 JNIEXPORT jobject JNICALL
641 Java_org_simgrid_msg_MsgNative_taskGetSender(JNIEnv * env, jclass cls,
642                                          jobject jtask)
643 {
644   m_process_t process;
645
646   m_task_t task = jtask_to_native_task(jtask, env);
647
648   if (!task) {
649     jxbt_throw_notbound(env, "task", jtask);
650     return NULL;
651   }
652
653   process = MSG_task_get_sender(task);
654   return (jobject) native_to_java_process(process);
655 }
656
657 JNIEXPORT jobject JNICALL
658 Java_org_simgrid_msg_MsgNative_taskGetSource(JNIEnv * env, jclass cls,
659                                          jobject jtask)
660 {
661   m_host_t host;
662   m_task_t task = jtask_to_native_task(jtask, env);
663
664   if (!task) {
665     jxbt_throw_notbound(env, "task", jtask);
666     return NULL;
667   }
668
669   host = MSG_task_get_source(task);
670
671   if (!MSG_host_get_data(host)) {
672     jxbt_throw_jni(env, "MSG_task_get_source() failed");
673     return NULL;
674   }
675
676   return (jobject) MSG_host_get_data(host);
677 }
678
679
680 JNIEXPORT jstring JNICALL
681 Java_org_simgrid_msg_MsgNative_taskGetName(JNIEnv * env, jclass cls,
682                                        jobject jtask)
683 {
684   m_task_t task = jtask_to_native_task(jtask, env);
685
686   if (!task) {
687     jxbt_throw_notbound(env, "task", jtask);
688     return NULL;
689   }
690
691   return (*env)->NewStringUTF(env, MSG_task_get_name(task));
692 }
693
694 JNIEXPORT void JNICALL
695 Java_org_simgrid_msg_MsgNative_taskCancel(JNIEnv * env, jclass cls,
696                                       jobject jtask)
697 {
698   m_task_t ptask = jtask_to_native_task(jtask, env);
699
700   if (!ptask) {
701     jxbt_throw_notbound(env, "task", jtask);
702     return;
703   }
704
705   MSG_error_t rv = MSG_task_cancel(ptask);
706
707   jxbt_check_res("MSG_task_cancel()", rv, MSG_OK,
708                  bprintf("unexpected error , please report this bug"));
709 }
710
711 JNIEXPORT jdouble JNICALL
712 Java_org_simgrid_msg_MsgNative_taskGetComputeDuration(JNIEnv * env, jclass cls,
713                                                   jobject jtask)
714 {
715   m_task_t ptask = jtask_to_native_task(jtask, env);
716
717   if (!ptask) {
718     jxbt_throw_notbound(env, "task", jtask);
719     return -1;
720   }
721   return (jdouble) MSG_task_get_compute_duration(ptask);
722 }
723
724 JNIEXPORT jdouble JNICALL
725 Java_org_simgrid_msg_MsgNative_taskGetRemainingDuration(JNIEnv * env,
726                                                     jclass cls,
727                                                     jobject jtask)
728 {
729   m_task_t ptask = jtask_to_native_task(jtask, env);
730
731   if (!ptask) {
732     jxbt_throw_notbound(env, "task", jtask);
733     return -1;
734   }
735   return (jdouble) MSG_task_get_remaining_computation(ptask);
736 }
737
738 JNIEXPORT void JNICALL
739 Java_org_simgrid_msg_MsgNative_taskSetPriority(JNIEnv * env, jclass cls,
740                                            jobject jtask, jdouble priority)
741 {
742   m_task_t task = jtask_to_native_task(jtask, env);
743
744   if (!task) {
745     jxbt_throw_notbound(env, "task", jtask);
746     return;
747   }
748   MSG_task_set_priority(task, (double) priority);
749 }
750
751 JNIEXPORT void JNICALL
752 Java_org_simgrid_msg_MsgNative_taskDestroy(JNIEnv * env, jclass cls,
753                                        jobject jtask_arg)
754 {
755
756   /* get the native task */
757   m_task_t task = jtask_to_native_task(jtask_arg, env);
758
759   if (!task) {
760     jxbt_throw_notbound(env, "task", task);
761     return;
762   }
763
764   MSG_error_t rv = MSG_task_destroy(task);
765
766   jxbt_check_res("MSG_task_destroy()", rv, MSG_OK,
767                  bprintf("unexpected error , please report this bug"));
768 }
769
770 JNIEXPORT void JNICALL
771 Java_org_simgrid_msg_MsgNative_taskExecute(JNIEnv * env, jclass cls,
772                                        jobject jtask)
773 {
774   m_task_t task = jtask_to_native_task(jtask, env);
775
776   if (!task) {
777     jxbt_throw_notbound(env, "task", jtask);
778     return;
779   }
780
781   MSG_error_t rv = MSG_task_execute(task);
782
783   jxbt_check_res("MSG_task_execute()", rv,
784                  MSG_HOST_FAILURE | MSG_TASK_CANCELED,
785                  bprintf("while executing task %s",
786                          MSG_task_get_name(task)));
787 }
788
789 /***************************************************************************************
790  * Unsortable functions                                                        *
791  ***************************************************************************************/
792
793 JNIEXPORT jdouble JNICALL
794 Java_org_simgrid_msg_Msg_getClock(JNIEnv * env, jclass cls)
795 {
796   return (jdouble) MSG_get_clock();
797 }
798
799 JNIEXPORT void JNICALL
800 Java_org_simgrid_msg_Msg_init(JNIEnv * env, jclass cls, jobjectArray jargs)
801 {
802   char **argv = NULL;
803   int index;
804   int argc = 0;
805   jstring jval;
806   const char *tmp;
807
808   smx_factory_initializer_to_use = SIMIX_ctx_java_factory_init;
809
810   if (jargs)
811     argc = (int) (*env)->GetArrayLength(env, jargs);
812
813   argc++;
814   argv = xbt_new(char *, argc + 1);
815   argv[0] = strdup("java");
816
817   for (index = 0; index < argc - 1; index++) {
818     jval = (jstring) (*env)->GetObjectArrayElement(env, jargs, index);
819     tmp = (*env)->GetStringUTFChars(env, jval, 0);
820     argv[index + 1] = strdup(tmp);
821     (*env)->ReleaseStringUTFChars(env, jval, tmp);
822   }
823   argv[argc] = NULL;
824
825   MSG_global_init(&argc, argv);
826
827   for (index = 0; index < argc; index++)
828     free(argv[index]);
829
830   free(argv);
831
832   (*env)->GetJavaVM(env, &__java_vm);
833 }
834
835 JNIEXPORT void JNICALL
836     JNICALL Java_org_simgrid_msg_Msg_run(JNIEnv * env, jclass cls)
837 {
838   MSG_error_t rv;
839   int index;
840   xbt_dynar_t hosts;
841   jobject jhost;
842
843   /* Run everything */
844   XBT_INFO("Ready to run MSG_MAIN");
845   rv = MSG_main();
846   XBT_INFO("Done running MSG_MAIN");
847   jxbt_check_res("MSG_main()", rv, MSG_OK,
848                  bprintf
849                  ("unexpected error : MSG_main() failed .. please report this bug "));
850
851   XBT_INFO("MSG_main finished");
852
853   XBT_INFO("Clean java world");
854   /* Cleanup java hosts */
855   hosts = MSG_hosts_as_dynar();
856   for (index = 0; index < xbt_dynar_length(hosts) - 1; index++) {
857     jhost = (jobject) MSG_host_get_data(xbt_dynar_get_as(hosts,index,m_host_t));
858     if (jhost)
859       jhost_unref(env, jhost);
860
861   }
862   xbt_dynar_free(&hosts);
863   XBT_INFO("Clean native world");
864 }
865 JNIEXPORT void JNICALL
866     JNICALL Java_org_simgrid_msg_Msg_clean(JNIEnv * env, jclass cls)
867 {
868   /* cleanup native stuff. Calling it is ... useless since leaking memory at the end of the simulation is a non-issue */
869   MSG_error_t rv = MSG_OK != MSG_clean();
870   jxbt_check_res("MSG_clean()", rv, MSG_OK,
871                  bprintf
872                  ("unexpected error : MSG_clean() failed .. please report this bug "));
873 }
874    
875 JNIEXPORT jint JNICALL
876 Java_org_simgrid_msg_MsgNative_processKillAll(JNIEnv * env, jclass cls,
877                                           jint jresetPID)
878 {
879   return (jint) MSG_process_killall((int) jresetPID);
880 }
881
882 JNIEXPORT void JNICALL
883 Java_org_simgrid_msg_Msg_createEnvironment(JNIEnv * env, jclass cls,
884                                        jstring jplatformFile)
885 {
886
887   const char *platformFile =
888       (*env)->GetStringUTFChars(env, jplatformFile, 0);
889
890   MSG_create_environment(platformFile);
891
892   (*env)->ReleaseStringUTFChars(env, jplatformFile, platformFile);
893 }
894
895 JNIEXPORT void JNICALL
896 Java_org_simgrid_msg_MsgNative_processExit(JNIEnv * env, jclass cls,
897                                        jobject jprocess)
898 {
899
900   m_process_t process = jprocess_to_native_process(jprocess, env);
901
902   if (!process) {
903     jxbt_throw_notbound(env, "process", jprocess);
904     return;
905   }
906
907   smx_ctx_java_stop(MSG_process_get_smx_ctx(process));
908 }
909
910 JNIEXPORT void JNICALL
911 Java_org_simgrid_msg_Msg_info(JNIEnv * env, jclass cls, jstring js)
912 {
913   const char *s = (*env)->GetStringUTFChars(env, js, 0);
914   XBT_INFO("%s", s);
915   (*env)->ReleaseStringUTFChars(env, js, s);
916 }
917
918 JNIEXPORT jobjectArray JNICALL
919 Java_org_simgrid_msg_MsgNative_allHosts(JNIEnv * env, jclass cls_arg)
920 {
921   int index;
922   jobjectArray jtable;
923   jobject jhost;
924   jstring jname;
925   m_host_t host;
926
927   xbt_dynar_t table =  MSG_hosts_as_dynar();
928   int count = xbt_dynar_length(table);
929
930   jclass cls = jxbt_get_class(env, "org/simgrid/msg/Host");
931
932   if (!cls) {
933     return NULL;
934   }
935
936   jtable = (*env)->NewObjectArray(env, (jsize) count, cls, NULL);
937
938   if (!jtable) {
939     jxbt_throw_jni(env, "Hosts table allocation failed");
940     return NULL;
941   }
942
943   for (index = 0; index < count; index++) {
944     host = xbt_dynar_get_as(table,index,m_host_t);
945     jhost = (jobject) (MSG_host_get_data(host));
946
947     if (!jhost) {
948       jname = (*env)->NewStringUTF(env, MSG_host_get_name(host));
949
950       jhost =
951           Java_org_simgrid_msg_MsgNative_hostGetByName(env, cls_arg, jname);
952       /* FIXME: leak of jname ? */
953     }
954
955     (*env)->SetObjectArrayElement(env, jtable, index, jhost);
956   }
957   xbt_dynar_free(&table);
958   return jtable;
959 }
960
961 JNIEXPORT void JNICALL
962 Java_org_simgrid_msg_MsgNative_taskSend(JNIEnv * env, jclass cls,
963                                     jstring jalias, jobject jtask,
964                                     jdouble jtimeout)
965 {
966
967   MSG_error_t rv;
968   const char *alias = (*env)->GetStringUTFChars(env, jalias, 0);
969
970   m_task_t task = jtask_to_native_task(jtask, env);
971
972
973   if (!task) {
974     (*env)->ReleaseStringUTFChars(env, jalias, alias);
975     jxbt_throw_notbound(env, "task", jtask);
976     return;
977   }
978
979   /* Pass a global ref to the Jtask into the Ctask so that the receiver can use it */
980   MSG_task_set_data(task, (void *) (*env)->NewGlobalRef(env, jtask));
981   rv = MSG_task_send_with_timeout(task, alias, (double) jtimeout);
982
983   (*env)->ReleaseStringUTFChars(env, jalias, alias);
984
985   jxbt_check_res("MSG_task_send_with_timeout()", rv,
986                  MSG_HOST_FAILURE | MSG_TRANSFER_FAILURE | MSG_TIMEOUT,
987                  bprintf("while sending task %s to mailbox %s",
988                          MSG_task_get_name(task), alias));
989 }
990
991 static void msg_task_cancel_on_failed_dsend(void*t) {
992         m_task_t task = t;
993         JNIEnv *env =get_current_thread_env();
994         jobject jtask_global = MSG_task_get_data(task);
995
996         /* Destroy the global ref so that the JVM can free the stuff */
997         (*env)->DeleteGlobalRef(env, jtask_global);
998         MSG_task_set_data(task, NULL);
999         MSG_task_destroy(task);
1000 }
1001
1002 JNIEXPORT void JNICALL
1003 Java_org_simgrid_msg_MsgNative_taskDSend(JNIEnv * env, jclass cls,
1004                                     jstring jalias, jobject jtask)
1005 {
1006
1007   const char *alias = (*env)->GetStringUTFChars(env, jalias, 0);
1008
1009   m_task_t task = jtask_to_native_task(jtask, env);
1010
1011
1012   if (!task) {
1013     (*env)->ReleaseStringUTFChars(env, jalias, alias);
1014     jxbt_throw_notbound(env, "task", jtask);
1015     return;
1016   }
1017
1018   /* Pass a global ref to the Jtask into the Ctask so that the receiver can use it */
1019   MSG_task_set_data(task, (void *) (*env)->NewGlobalRef(env, jtask));
1020   MSG_task_dsend(task, alias, msg_task_cancel_on_failed_dsend);
1021
1022   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1023 }
1024
1025
1026 JNIEXPORT void JNICALL
1027 Java_org_simgrid_msg_MsgNative_taskSendBounded(JNIEnv * env, jclass cls,
1028                                            jstring jalias, jobject jtask,
1029                                            jdouble jmaxRate)
1030 {
1031   m_task_t task = jtask_to_native_task(jtask, env);
1032   MSG_error_t rv;
1033   const char *alias;
1034
1035   if (!task) {
1036     jxbt_throw_notbound(env, "task", jtask);
1037     return;
1038   }
1039
1040   alias = (*env)->GetStringUTFChars(env, jalias, 0);
1041
1042   /* Pass a global ref to the Jtask into the Ctask so that the receiver can use it */
1043   MSG_task_set_data(task, (void *) (*env)->NewGlobalRef(env, jtask));
1044   rv = MSG_task_send_bounded(task, alias, (double) jmaxRate);
1045
1046   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1047
1048   jxbt_check_res("MSG_task_send_bounded()", rv,
1049                  MSG_HOST_FAILURE | MSG_TRANSFER_FAILURE | MSG_TIMEOUT,
1050                  bprintf
1051                  ("while sending task %s to mailbox %s with max rate %f",
1052                   MSG_task_get_name(task), alias, (double) jmaxRate));
1053
1054 }
1055
1056 JNIEXPORT jobject JNICALL
1057 Java_org_simgrid_msg_MsgNative_taskReceive(JNIEnv * env, jclass cls,
1058                                        jstring jalias, jdouble jtimeout,
1059                                        jobject jhost)
1060 {
1061   MSG_error_t rv;
1062   m_task_t task = NULL;
1063   m_host_t host = NULL;
1064   jobject jtask_global, jtask_local;
1065   const char *alias;
1066
1067   if (jhost) {
1068     host = jhost_get_native(env, jhost);
1069
1070     if (!host) {
1071       jxbt_throw_notbound(env, "host", jhost);
1072       return NULL;
1073     }
1074   }
1075
1076   alias = (*env)->GetStringUTFChars(env, jalias, 0);
1077
1078   rv = MSG_task_receive_ext(&task, alias, (double) jtimeout, host);
1079   if (rv != MSG_OK) {
1080         switch (rv) {
1081                 case MSG_TIMEOUT:
1082                         jxbt_throw_time_out_failure(env,NULL);
1083                 break;
1084                 case MSG_TRANSFER_FAILURE:
1085                         jxbt_throw_transfer_failure(env,NULL);
1086                 break;
1087                 case MSG_HOST_FAILURE:
1088                         jxbt_throw_host_failure(env,NULL);
1089                 break;
1090                 default:
1091                         jxbt_throw_native(env,bprintf("receive failed"));
1092         }
1093         return NULL;
1094   }
1095   jtask_global = MSG_task_get_data(task);
1096
1097   /* Convert the global ref into a local ref so that the JVM can free the stuff */
1098   jtask_local = (*env)->NewLocalRef(env, jtask_global);
1099   (*env)->DeleteGlobalRef(env, jtask_global);
1100   MSG_task_set_data(task, NULL);
1101
1102   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1103
1104   jxbt_check_res("MSG_task_receive_ext()", rv,
1105                  MSG_HOST_FAILURE | MSG_TRANSFER_FAILURE | MSG_TIMEOUT,
1106                  bprintf("while receiving from mailbox %s", alias));
1107
1108   return (jobject) jtask_local;
1109 }
1110
1111 JNIEXPORT jboolean JNICALL
1112 Java_org_simgrid_msg_MsgNative_taskListen(JNIEnv * env, jclass cls,
1113                                       jstring jalias)
1114 {
1115
1116   const char *alias;
1117   int rv;
1118
1119   alias = (*env)->GetStringUTFChars(env, jalias, 0);
1120
1121   rv = MSG_task_listen(alias);
1122
1123   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1124
1125   return (jboolean) rv;
1126 }
1127
1128 JNIEXPORT jint JNICALL
1129 Java_org_simgrid_msg_MsgNative_taskListenFromHost(JNIEnv * env, jclass cls,
1130                                               jstring jalias,
1131                                               jobject jhost)
1132 {
1133   int rv;
1134   const char *alias;
1135
1136   m_host_t host = jhost_get_native(env, jhost);
1137
1138   if (!host) {
1139     jxbt_throw_notbound(env, "host", jhost);
1140     return -1;
1141   }
1142   alias = (*env)->GetStringUTFChars(env, jalias, 0);
1143
1144   rv = MSG_task_listen_from_host(alias, host);
1145
1146   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1147
1148   return (jint) rv;
1149 }
1150
1151 JNIEXPORT jint JNICALL
1152 Java_org_simgrid_msg_MsgNative_taskListenFrom(JNIEnv * env, jclass cls,
1153                                           jstring jalias)
1154 {
1155
1156   int rv;
1157   const char *alias = (*env)->GetStringUTFChars(env, jalias, 0);
1158
1159   rv = MSG_task_listen_from(alias);
1160
1161   (*env)->ReleaseStringUTFChars(env, jalias, alias);
1162
1163   return (jint) rv;
1164 }
1165
1166 JNIEXPORT void JNICALL
1167 Java_org_simgrid_msg_Msg_deployApplication(JNIEnv * env, jclass cls,
1168                                        jstring jdeploymentFile)
1169 {
1170
1171   const char *deploymentFile =
1172       (*env)->GetStringUTFChars(env, jdeploymentFile, 0);
1173
1174   surf_parse_reset_callbacks();
1175
1176   surfxml_add_callback(STag_surfxml_process_cb_list,
1177                        japplication_handler_on_begin_process);
1178
1179   surfxml_add_callback(ETag_surfxml_argument_cb_list,
1180                        japplication_handler_on_process_arg);
1181
1182   surfxml_add_callback(STag_surfxml_prop_cb_list,
1183                        japplication_handler_on_property);
1184
1185   surfxml_add_callback(ETag_surfxml_process_cb_list,
1186                        japplication_handler_on_end_process);
1187
1188   surf_parse_open(deploymentFile);
1189
1190   japplication_handler_on_start_document();
1191
1192   if (surf_parse())
1193     jxbt_throw_jni(env, "surf_parse() failed");
1194
1195   surf_parse_close();
1196
1197   japplication_handler_on_end_document();
1198
1199   (*env)->ReleaseStringUTFChars(env, jdeploymentFile, deploymentFile);
1200 }