Ejemplo n.º 1
0
static void smx_ctx_cojava_create_coroutine(smx_ctx_cojava_t context) {
  JNIEnv *env = get_current_thread_env();
  jclass coclass = (*env)->FindClass(env, "java/dyn/Coroutine");
  xbt_assert((coclass != NULL), "Can't find coroutine class ! :(");
  jobject jcoroutine = (*env)->NewObject(env, coclass, coroutine_init, context->jprocess);
  if (jcoroutine == NULL) {
     FILE *conf= fopen("/proc/sys/vm/max_map_count","r");
     if (conf) {
	int limit=-1;
        if(fscanf(conf,"%d",&limit) != 1)
           xbt_die("Error while creating a new coroutine. Parse error.");
	fclose(conf);
	if (limit!=-1 && SIMIX_process_count() > (limit - 100) /2)
	   xbt_die("Error while creating a new coroutine. "
		   "This seem due to the the vm.max_map_count system limit that is only equal to %d while we already have %d coroutines. "
		   "Please check the install documentation to see how to increase this limit", limit, SIMIX_process_count());
	if (limit == -1)
	  xbt_die("Error while creating a new coroutine. "
		  "This seems to be a non-linux system, disabling the automatic verification that the system limit on the amount of memory maps is high enough.");
	xbt_die("Error while creating a new coroutine. ");
     }
     
  }
   
  jcoroutine = (*env)->NewGlobalRef(env, jcoroutine);
  context->jcoroutine = jcoroutine;
}
Ejemplo n.º 2
0
void JavaContext::stop()
{
  /* I am the current process and I am dying */
  if (this->iwannadie) {
    this->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 JavaContext.cpp)",
      simcall_process_get_name((smx_process_t) SIMIX_context_get_process(this))) );
    XBT_DEBUG("Trigger a cancel error at the C level");
    THROWF(cancel_error, 0, "process cancelled");
  } else {
    Context::stop();
    /* detach the thread and kills it */
    JNIEnv *env = this->jenv;
    env->DeleteGlobalRef(this->jprocess);
    XBT_ATTRIB_UNUSED jint error = __java_vm->DetachCurrentThread();
    xbt_assert((error == JNI_OK), "The thread couldn't be detached.");
    xbt_os_sem_release(this->end);
    xbt_os_thread_exit(NULL);
  }
}
Ejemplo n.º 3
0
void SIMIX_ctx_cojava_factory_init(smx_context_factory_t * factory)
{
  /* instantiate the context factory */
  smx_ctx_base_factory_init(factory);

  (*factory)->create_context = smx_ctx_cojava_factory_create_context;
  /* Leave default behavior of (*factory)->finalize */
  (*factory)->free = smx_ctx_cojava_free;
  (*factory)->stop = smx_ctx_cojava_stop;
  (*factory)->suspend = smx_ctx_cojava_suspend;
  (*factory)->runall = smx_ctx_cojava_runall;
  (*factory)->name = "ctx_cojava_factory";
  //(*factory)->finalize = smx_ctx_base_factory_finalize;
  (*factory)->self = smx_ctx_cojava_self;
  (*factory)->get_process = smx_ctx_base_get_process;

  global_env = get_current_thread_env();

  coclass = (*global_env)->FindClass(global_env, "java/dyn/Coroutine");
  xbt_assert((coclass != NULL), "Can't find java.dyn.Coroutine class.");
  //Cache the method id we are going to use
  coroutine_init = (*global_env)->GetMethodID(global_env, coclass, "<init>", "(Ljava/lang/Runnable;)V");
  xbt_assert((coroutine_init != NULL), "Can't find <init>");
  coroutine_stop = (*global_env)->GetMethodID(global_env, coclass, "stop", "()V");
  xbt_assert((coroutine_stop != NULL), "Method not found...");
  coroutine_yield = (*global_env)->GetStaticMethodID(global_env, coclass, "yield", "()V");
  xbt_assert((coroutine_yield != NULL), "Method yield not found.");
  coroutine_yieldTo = (*global_env)->GetStaticMethodID(global_env, coclass, "yieldTo", "(Ljava/dyn/Coroutine;)V");
  xbt_assert((coroutine_yieldTo != NULL), "Method yieldTo not found.");

  jclass class_thread = (*global_env)->FindClass(global_env, "java/lang/Thread");
  xbt_assert((class_thread != NULL), "Can't find java.lang.Thread class");
  
  jclass class_coroutine_support = (*global_env)->FindClass(global_env, "java/dyn/CoroutineSupport");
  xbt_assert((class_coroutine_support != NULL), "Can't find java.dyn.CoroutineSupport class");
  jmethodID thread_get_current = (*global_env)->GetStaticMethodID(global_env, class_thread, "currentThread", "()Ljava/lang/Thread;");
  xbt_assert((thread_get_current != NULL), "Can't find Thread.currentThread() method.");

  /**
   * Retrieve maetro coroutine object
   */
  jobject jthread;
  jthread = (*global_env)->CallStaticObjectMethod(global_env, class_thread, thread_get_current);
  xbt_assert((jthread != NULL), "Can't find current thread.");

  jmethodID thread_get_coroutine_support = (*global_env)->GetMethodID(global_env, class_thread, "getCoroutineSupport", "()Ljava/dyn/CoroutineSupport;");
  xbt_assert((thread_get_coroutine_support != NULL), "Can't find Thread.getCoroutineSupport method");

  jobject jcoroutine_support;
  jcoroutine_support = (*global_env)->CallObjectMethod(global_env, jthread, thread_get_coroutine_support);
  xbt_assert((jcoroutine_support != NULL), "Can't find coroutine support object");
  //FIXME ? Be careful, might change in the implementation (we are relying on private fields, so...).
  jfieldID coroutine_support_thread_coroutine = (*global_env)->GetFieldID(global_env, class_coroutine_support, "threadCoroutine", "Ljava/dyn/Coroutine;");
  xbt_assert((coroutine_support_thread_coroutine != NULL), "Can't find threadCoroutine field");
  cojava_maestro_coroutine = (jobject)(*global_env)->GetObjectField(global_env, jcoroutine_support, coroutine_support_thread_coroutine);
  xbt_assert((cojava_maestro_coroutine != NULL), "Can't find the thread coroutine.");
  cojava_maestro_coroutine = (*global_env)->NewGlobalRef(global_env, cojava_maestro_coroutine);
  xbt_assert((cojava_maestro_coroutine != NULL), "Can't get a global reference to the thread coroutine.");
}
Ejemplo n.º 4
0
static void smx_ctx_cojava_free(smx_context_t context)
{
  if (context) {
    smx_ctx_cojava_t ctx_java = (smx_ctx_cojava_t) context;
    if (ctx_java->jcoroutine) { /* We are not in maestro context */
      JNIEnv *env = get_current_thread_env();
      (*env)->DeleteGlobalRef(env, ctx_java->jcoroutine);
      (*env)->DeleteGlobalRef(env, ctx_java->jprocess);
    }
  }
  smx_ctx_base_free(context);
}
Ejemplo n.º 5
0
/** Run the Java org.simgrid.msg.Process */
void java_main_jprocess(jobject jprocess)
{
  JNIEnv *env = get_current_thread_env();
  simgrid::java::JavaContext* context = (simgrid::java::JavaContext*) SIMIX_context_self();
  context->jprocess = jprocess;
  smx_process_t process = SIMIX_process_self();
  jprocess_bind(context->jprocess, process, env);

  // 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 == nullptr)
    return;
  else
    run_jprocess(env, context->jprocess);
}
Ejemplo n.º 6
0
void smx_ctx_cojava_stop(smx_context_t context)
{
  /*
   * The java stack needs to be empty, otherwise weird stuff
   * will happen
   */
  if (context->iwannadie) {
    context->iwannadie = 0;
    JNIEnv *env = get_current_thread_env();
    // 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", xbt_strdup("Process killed :) (file smx_context_cojava.c)"));
    THROWF(cancel_error, 0, "process cancelled");
  }
  else {
    smx_ctx_base_stop(context);
    smx_ctx_cojava_suspend(context);
  }
}
Ejemplo n.º 7
0
void* JavaContext::wrapper(void *data)
{
  JavaContext* context = (JavaContext*)data;
  xbt_os_thread_set_extra_data(context);
  //Attach the thread to the JVM

  JNIEnv *env;
  XBT_ATTRIB_UNUSED jint error =
    __java_vm->AttachCurrentThread((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.
  (*context)();
  context->stop();
  return nullptr;
}
Ejemplo n.º 8
0
/** Create a Java org.simgrid.msg.Process with the arguments and run it */
static int java_main(int argc, char *argv[])
{
  JNIEnv *env = get_current_thread_env();
  simgrid::java::JavaContext* context = (simgrid::java::JavaContext*) SIMIX_context_self();

  //Change the "." in class name for "/".
  xbt_str_subst(argv[0],'.','/',0);
  jclass class_Process = env->FindClass(argv[0]);
  xbt_str_subst(argv[0],'/','.',0);
  //Retrieve the methodID for the constructor
  xbt_assert((class_Process != nullptr), "Class not found (%s). The deployment file must use the fully qualified class name, including the package. The case is important.", argv[0]);
  jmethodID constructor_Process = env->GetMethodID(class_Process, "<init>", "(Lorg/simgrid/msg/Host;Ljava/lang/String;[Ljava/lang/String;)V");
  xbt_assert((constructor_Process != nullptr), "Constructor not found for class %s. Is there a (Host, String ,String[]) constructor in your class ?", argv[0]);

  //Retrieve the name of the process.
  jstring jname = env->NewStringUTF(argv[0]);
  //Build the arguments
  jobjectArray args = (jobjectArray)env->NewObjectArray(argc - 1,
    env->FindClass("java/lang/String"),
    env->NewStringUTF(""));
  int i;
  for (i = 1; i < argc; i++)
      env->SetObjectArrayElement(args,i - 1, env->NewStringUTF(argv[i]));
  //Retrieve the host for the process.
  jstring jhostName = env->NewStringUTF(MSG_host_get_name(MSG_host_self()));
  jobject jhost = Java_org_simgrid_msg_Host_getByName(env, nullptr, jhostName);
  //creates the process
  jobject jprocess = env->NewObject(class_Process, constructor_Process, jhost, jname, args);
  xbt_assert((jprocess != nullptr), "Process allocation failed.");
  jprocess = env->NewGlobalRef(jprocess);
  //bind the process to the context
  msg_process_t process = MSG_process_self();

  context->jprocess = jprocess;
  /* sets the PID and the PPID of the process */
  env->SetIntField(jprocess, jprocess_field_Process_pid,(jint) MSG_process_get_PID(process));
  env->SetIntField(jprocess, jprocess_field_Process_ppid, (jint) MSG_process_get_PPID(process));
  jprocess_bind(jprocess, process, env);

  run_jprocess(env, context->jprocess);
  return 0;
}