Logo AND Algorithmique Numérique Distribuée

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