Logo AND Algorithmique Numérique Distribuée

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