Logo AND Algorithmique Numérique Distribuée

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