Logo AND Algorithmique Numérique Distribuée

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