Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
merge msg_vm.c - adrien (please note that there is one line (destruction of the tx_pr...
[simgrid.git] / src / bindings / java / smx_context_java.c
index 02f6f7b..29489d1 100644 (file)
@@ -1,30 +1,29 @@
 /* context_java - implementation of context switching for java threads */
 
-/* Copyright (c) 2009, 2010, 2012. The SimGrid Team.
+/* Copyright (c) 2009-2010, 2012-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-
 #include <xbt/function_types.h>
 #include <simgrid/simix.h>
 #include <xbt/ex.h>
 #include "smx_context_java.h"
 #include "jxbt_utilities.h"
 #include "xbt/dynar.h"
+#include "../../simix/smx_private.h"
 extern JavaVM *__java_vm;
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(jmsg, bindings, "MSG for Java(TM)");
 
 static smx_context_t
-smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc,
-                                    char **argv,
+smx_ctx_java_factory_create_context(xbt_main_func_t code,
+                                    int argc, char **argv,
                                     void_pfn_smxprocess_t cleanup_func,
-                                    void *data);
+                                    smx_process_t process);
 
 static void smx_ctx_java_free(smx_context_t context);
-static void smx_ctx_java_start(smx_context_t context);
 static void smx_ctx_java_suspend(smx_context_t context);
 static void smx_ctx_java_resume(smx_context_t new_context);
 static void smx_ctx_java_runall(void);
@@ -43,7 +42,7 @@ void SIMIX_ctx_java_factory_init(smx_context_factory_t * factory)
   (*factory)->name = "ctx_java_factory";
   //(*factory)->finalize = smx_ctx_base_factory_finalize;
   (*factory)->self = smx_ctx_java_self;
-  (*factory)->get_data = smx_ctx_base_get_data;
+  (*factory)->get_process = smx_ctx_base_get_process;
 }
 smx_context_t smx_ctx_java_self(void)
 {
@@ -51,15 +50,14 @@ smx_context_t smx_ctx_java_self(void)
 }
 
 static smx_context_t
-smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc,
-                                    char **argv,
+smx_ctx_java_factory_create_context(xbt_main_func_t code,
+                                    int argc, char **argv,
                                     void_pfn_smxprocess_t cleanup_func,
-                                    void* data)
+                                    smx_process_t process)
 {
-       xbt_ex_t e;
-       static int thread_amount=0;
-       smx_ctx_java_t context = xbt_new0(s_smx_ctx_java_t, 1);
-       thread_amount++;
+  static int thread_amount=0;
+  smx_ctx_java_t context = xbt_new0(s_smx_ctx_java_t, 1);
+  thread_amount++;
   /* If the user provided a function for the process then use it
      otherwise is the context for maestro */
   if (code) {
@@ -79,17 +77,17 @@ smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc,
 
     TRY {        
        context->thread = xbt_os_thread_create(NULL,smx_ctx_java_thread_run,context,NULL);
-    } CATCH(e) {
-       RETHROWF("Failed to create context #%d. You may want to switch to Java coroutines to increase your limits (error: %s)."
-                "See the Install section of simgrid-java documentation (in doc/install.html) for more on coroutines.",
-                       thread_amount);
     }
-  }
-  else {
+    CATCH_ANONYMOUS {
+      RETHROWF("Failed to create context #%d. You may want to switch to Java coroutines to increase your limits (error: %s)."
+               "See the Install section of simgrid-java documentation (in doc/install.html) for more on coroutines.",
+               thread_amount);
+    }
+  } else {
        context->thread = NULL;
     xbt_os_thread_set_extra_data(context);
   }
-  context->super.data = data;
+  context->super.process = process;
   
   return (smx_context_t) context;
 }
@@ -99,31 +97,37 @@ static void* smx_ctx_java_thread_run(void *data) {
   xbt_os_thread_set_extra_data(context);
   //Attach the thread to the JVM
   JNIEnv *env;
-  jint error = (*__java_vm)->AttachCurrentThread(__java_vm, (void **) &env, NULL);
+  _XBT_GNUC_UNUSED jint error = (*__java_vm)->AttachCurrentThread(__java_vm, (void **) &env, NULL);
   xbt_assert((error == JNI_OK), "The thread could not be attached to the JVM");
   context->jenv = get_current_thread_env();
   //Wait for the first scheduling round to happen.
   xbt_os_sem_acquire(context->begin);
   //Create the "Process" object if needed.
   if (context->super.argc > 0) {
-    (*(context->super.code))(context->super.argc, context->super.argv);
+    context->super.code(context->super.argc, context->super.argv);
   }
   else {
     smx_process_t process = SIMIX_process_self();
-    (*env)->SetLongField(env, context->jprocess, jprocess_field_Process_bind, (jlong)process);
+    (*env)->SetLongField(env, context->jprocess, jprocess_field_Process_bind,
+                         (intptr_t)process);
   }
-  xbt_assert((context->jprocess != NULL), "Process not created...");
-  //wait for the process to be able to begin
-  //TODO: Cache it
+
+  // Adrien, ugly path, just to bypass creation of context at low levels
+  // (i.e such as for the VM migration for instance)
+  if(context->jprocess != NULL){
+       xbt_assert((context->jprocess != NULL), "Process not created...");
+       //wait for the process to be able to begin
+       //TODO: Cache it
        jfieldID jprocess_field_Process_startTime = jxbt_get_sfield(env, "org/simgrid/msg/Process", "startTime", "D");
-  jdouble startTime =  (*env)->GetDoubleField(env, context->jprocess, jprocess_field_Process_startTime);
-  if (startTime > MSG_get_clock()) {
-       MSG_process_sleep(startTime - MSG_get_clock());
+       jdouble startTime =  (*env)->GetDoubleField(env, context->jprocess, jprocess_field_Process_startTime);
+       if (startTime > MSG_get_clock()) {
+               MSG_process_sleep(startTime - MSG_get_clock());
+       }
+       //Execution of the "run" method.
+       jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V");
+       xbt_assert( (id != NULL), "Method not found...");
+       (*env)->CallVoidMethod(env, context->jprocess, id);
   }
-  //Execution of the "run" method.
-  jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V");
-  xbt_assert( (id != NULL), "Method not found...");
-  (*env)->CallVoidMethod(env, context->jprocess, id);
   smx_ctx_java_stop((smx_context_t)context);
 
   return NULL;
@@ -148,17 +152,23 @@ void smx_ctx_java_stop(smx_context_t context)
   smx_ctx_java_t ctx_java = (smx_ctx_java_t)context;
   /* I am the current process and I am dying */
   if (context->iwannadie) {
-       context->iwannadie = 0;
-       JNIEnv *env = get_current_thread_env();
-       jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", bprintf("Process killed :)"));
-       THROWF(cancel_error, 0, "process cancelled");
-  }
-  else {
+    context->iwannadie = 0;
+    JNIEnv *env = get_current_thread_env();
+    XBT_DEBUG("Gonna launch Killed Error");
+    // TODO Adrien, if the process has not been created at the java layer, why should we raise the exception/error at the java level (this happens
+    // for instance during the migration process that creates at the C level two processes: one on the SRC node and one on the DST node, if the DST process is killed. 
+    // it is not required to raise an exception at the JAVA level, the low level should be able to manage such an issue correctly but this is not the case right now unfortunately ...
+    // TODO it will be nice to have the name of the process to help the end-user to know which Process has been killed
+   // jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", bprintf("Process %s killed :) (file smx_context_java.c)", MSG_process_get_name( (msg_process_t)context) ));
+    jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", bprintf("Process %s killed :) (file smx_context_java.c)", simcall_process_get_name((smx_process_t) SIMIX_context_get_process(context))) );
+    XBT_DEBUG("Trigger a cancel error at the C level");
+    THROWF(cancel_error, 0, "process cancelled");
+  } else {
     smx_ctx_base_stop(context);
     /* detach the thread and kills it */
     JNIEnv *env = ctx_java->jenv;
     (*env)->DeleteGlobalRef(env,ctx_java->jprocess);
-    jint error = (*__java_vm)->DetachCurrentThread(__java_vm);
+    _XBT_GNUC_UNUSED jint error = (*__java_vm)->DetachCurrentThread(__java_vm);
     xbt_assert((error == JNI_OK), "The thread couldn't be detached.");
     xbt_os_sem_release(((smx_ctx_java_t)context)->end);
     xbt_os_thread_exit(NULL);