Logo AND Algorithmique Numérique Distribuée

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