Logo AND Algorithmique Numérique Distribuée

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