Logo AND Algorithmique Numérique Distribuée

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