Logo AND Algorithmique Numérique Distribuée

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