Logo AND Algorithmique Numérique Distribuée

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