Logo AND Algorithmique Numérique Distribuée

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