X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/c924fe6229cf13ed8de5cf4fbda1fa1b85c72cdd..410c20fdb9b68068548b9f4686eae70898a2b0ba:/src/smx_context_cojava.c diff --git a/src/smx_context_cojava.c b/src/smx_context_cojava.c index 58efe2d555..00fe9b5db4 100644 --- a/src/smx_context_cojava.c +++ b/src/smx_context_cojava.c @@ -77,37 +77,38 @@ void SIMIX_ctx_cojava_factory_init(smx_context_factory_t * factory) 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."); + 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."); } smx_context_t smx_ctx_cojava_self(void) { @@ -124,19 +125,19 @@ smx_ctx_cojava_factory_create_context(xbt_main_func_t code, int argc, /* If the user provided a function for the process then use it otherwise is the context for maestro */ if (code) { - if (argc == 0) { - context->jprocess = (jobject) code; - } - else { - context->jprocess = NULL; - } - context->super.cleanup_func = cleanup_func; - - context->super.argc = argc; - context->super.argv = argv; - context->super.code = code; - - smx_ctx_cojava_run(context); + if (argc == 0) { + context->jprocess = (jobject) code; + } + else { + context->jprocess = NULL; + } + context->super.cleanup_func = cleanup_func; + + context->super.argc = argc; + context->super.argv = argv; + context->super.code = code; + + smx_ctx_cojava_run(context); } else { context->jcoroutine = NULL; @@ -149,24 +150,24 @@ smx_ctx_cojava_factory_create_context(xbt_main_func_t code, int argc, } static void* smx_ctx_cojava_run(void *data) { - smx_ctx_cojava_t context = (smx_ctx_cojava_t)data; - my_current_context = (smx_context_t)context; - //Create the "Process" object if needed. - if (context->super.argc <= 0) { - smx_ctx_cojava_create_coroutine(context); - } - my_current_context = maestro_context; + smx_ctx_cojava_t context = (smx_ctx_cojava_t)data; + my_current_context = (smx_context_t)context; + //Create the "Process" object if needed. + if (context->super.argc <= 0) { + smx_ctx_cojava_create_coroutine(context); + } + my_current_context = maestro_context; return NULL; } 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); - } + 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); } @@ -174,89 +175,107 @@ static void smx_ctx_cojava_free(smx_context_t context) 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(); - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", bprintf("Process killed :)")); - THROWF(cancel_error, 0, "process cancelled"); + /* + * The java stack needs to be empty, otherwise weird stuff + * will happen + */ + 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 { + smx_ctx_base_stop(context); + smx_ctx_cojava_suspend(context); } - else { - smx_ctx_base_stop(context); - smx_ctx_cojava_suspend(context); - } } static void smx_ctx_cojava_suspend(smx_context_t context) { - smx_context_t previous_context = context; - unsigned long int i = cojava_process_index++; - jobject next_coroutine; - - if (i < xbt_dynar_length(cojava_processes)) { - smx_context_t next_context = SIMIX_process_get_context(xbt_dynar_get_as( - cojava_processes,i, smx_process_t)); - my_current_context = next_context; - XBT_DEBUG("Switching to %p",my_current_context); - smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(next_context); - - if (!java_context->jprocess) { - (*(java_context->super.code))(java_context->super.argc, java_context->super.argv); - smx_ctx_cojava_create_coroutine(java_context); - } - else if (!java_context->bound) { - java_context->bound = 1; - smx_process_t process = SIMIX_process_self(); - (*global_env)->SetLongField(global_env, java_context->jprocess, jprocess_field_Process_bind, (jlong)process); - } - - next_coroutine = java_context->jcoroutine; - } - else { - //Give maestro the control back. - next_coroutine = cojava_maestro_coroutine; - my_current_context = maestro_context; - } + smx_context_t previous_context = context; + unsigned long int i = cojava_process_index++; + jobject next_coroutine; + + if (i < xbt_dynar_length(cojava_processes)) { + smx_context_t next_context = SIMIX_process_get_context(xbt_dynar_get_as( + cojava_processes,i, smx_process_t)); + my_current_context = next_context; + XBT_DEBUG("Switching to %p",my_current_context); + smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(next_context); + if (!java_context->jprocess) { + (*(java_context->super.code))(java_context->super.argc, java_context->super.argv); + smx_ctx_cojava_create_coroutine(java_context); + } + else if (!java_context->bound) { + java_context->bound = 1; + smx_process_t process = SIMIX_process_self(); + (*global_env)->SetLongField(global_env, java_context->jprocess, jprocess_field_Process_bind, (jlong)process); + } + + next_coroutine = java_context->jcoroutine; + } + else { + //Give maestro the control back. + next_coroutine = cojava_maestro_coroutine; + my_current_context = maestro_context; + } (*global_env)->CallStaticVoidMethod(global_env, coclass, coroutine_yieldTo, next_coroutine); my_current_context = previous_context; } static void smx_ctx_cojava_resume(smx_context_t new_context) { - my_current_context = new_context; - smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(new_context); - - if (!java_context->jprocess) { - (*(java_context->super.code))(java_context->super.argc, java_context->super.argv); - smx_ctx_cojava_create_coroutine(java_context); - java_context->bound = 1; - } - else if (!java_context->bound) { - java_context->bound = 1; - smx_process_t process = SIMIX_process_self(); - (*global_env)->SetLongField(global_env, java_context->jprocess, jprocess_field_Process_bind, (jlong)process); - } + my_current_context = new_context; + smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(new_context); + + if (!java_context->jprocess) { + (*(java_context->super.code))(java_context->super.argc, java_context->super.argv); + smx_ctx_cojava_create_coroutine(java_context); + java_context->bound = 1; + } + else if (!java_context->bound) { + java_context->bound = 1; + smx_process_t process = SIMIX_process_self(); + (*global_env)->SetLongField(global_env, java_context->jprocess, jprocess_field_Process_bind, (jlong)process); + } (*global_env)->CallStaticVoidMethod(global_env, coclass, coroutine_yieldTo, java_context->jcoroutine); } static void smx_ctx_cojava_runall(void) { cojava_processes = SIMIX_process_get_runnable(); - smx_process_t process; - process = xbt_dynar_get_as(cojava_processes, 0, smx_process_t); - cojava_process_index = 1; - /* Execute the first process */ - smx_ctx_cojava_resume(SIMIX_process_get_context(process)); + smx_process_t process; + if (xbt_dynar_length(cojava_processes) > 0) { + process = xbt_dynar_get_as(cojava_processes, 0, smx_process_t); + cojava_process_index = 1; + /* Execute the first process */ + smx_ctx_cojava_resume(SIMIX_process_get_context(process)); + } } 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"); + 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); - xbt_assert((jcoroutine != NULL), "Can't create coroutine object."); + if (jcoroutine == NULL) { + FILE *conf= fopen("/proc/sys/vm/max_map_count","r"); + if (conf) { + int limit=-1; + fscanf(conf,"%d",&limit); + 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; }