Logo AND Algorithmique Numérique Distribuée

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