Logo AND Algorithmique Numérique Distribuée

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