Logo AND Algorithmique Numérique Distribuée

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