Logo AND Algorithmique Numérique Distribuée

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