Logo AND Algorithmique Numérique Distribuée

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