Logo AND Algorithmique Numérique Distribuée

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