/* 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 <functional>
+#include <utility>
+
#include <xbt/function_types.h>
#include <simgrid/simix.h>
#include <xbt/ex.h>
+#include <xbt/ex.hpp>
#include "JavaContext.hpp"
#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)");
+XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg, "MSG for Java(TM)");
namespace simgrid {
-namespace java {
+namespace kernel {
+namespace context {
-simgrid::simix::ContextFactory* java_factory()
+ContextFactory* java_factory()
{
XBT_INFO("Using regular java threads.");
return new JavaContextFactory();
}
-JavaContextFactory::JavaContextFactory()
- : ContextFactory("JavaContextFactory")
+JavaContextFactory::JavaContextFactory(): ContextFactory("JavaContextFactory")
{
}
-JavaContextFactory::~JavaContextFactory()
-{
-}
+JavaContextFactory::~JavaContextFactory()=default;
JavaContext* JavaContextFactory::self()
{
- return (JavaContext*) xbt_os_thread_get_extra_data();
+ return static_cast<JavaContext*>(xbt_os_thread_get_extra_data());
}
JavaContext* JavaContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
+ std::function<void()> code,
void_pfn_smxprocess_t cleanup, smx_process_t process)
{
- return this->new_context<JavaContext>(code, argc, argv, cleanup, process);
+ return this->new_context<JavaContext>(std::move(code), cleanup, process);
}
void JavaContextFactory::run_all()
}
}
-
-JavaContext::JavaContext(xbt_main_func_t code,
- int argc, char **argv,
+JavaContext::JavaContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process)
- : Context(code, argc, argv, cleanup_func, process)
+ : Context(std::move(code), cleanup_func, process)
{
static int thread_amount=0;
thread_amount++;
- /* If the user provided a function for the process then use it
- otherwise is the context for maestro */
- if (code) {
- if (argc == 0)
- this->jprocess = (jobject) code;
- else
- this->jprocess = nullptr;
+ /* If the user provided a function for the process then use it otherwise is the context for maestro */
+ if (has_code()) {
+ this->jprocess = nullptr;
this->begin = xbt_os_sem_init(0);
this->end = xbt_os_sem_init(0);
- TRY {
+ try {
this->thread = xbt_os_thread_create(
nullptr, JavaContext::wrapper, this, nullptr);
}
- 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);
+ catch (xbt_ex& ex) {
+ char* str = bprintf(
+ "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, ex.what());
+ xbt_ex new_exception(XBT_THROW_POINT, str);
+ new_exception.category = ex.category;
+ new_exception.value = ex.value;
+ std::throw_with_nested(std::move(new_exception));
}
} else {
this->thread = nullptr;
void* JavaContext::wrapper(void *data)
{
- JavaContext* context = (JavaContext*)data;
+ JavaContext* context = static_cast<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);
+ __java_vm->AttachCurrentThread((void **)&env, nullptr);
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->argc_ > 0)
- (*context)();
- else {
- smx_process_t process = SIMIX_process_self();
- env->SetLongField(context->jprocess, jprocess_field_Process_bind,
- (intptr_t)process);
- }
-
- // 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){
- xbt_assert((context->jprocess != nullptr), "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(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 != nullptr), "Method not found...");
- env->CallVoidMethod(context->jprocess, id);
- }
+ (*context)();
context->stop();
return nullptr;
}
// 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))) );
+ this->process()->name.c_str() ));
XBT_DEBUG("Trigger a cancel error at the C level");
THROWF(cancel_error, 0, "process cancelled");
} else {
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);
+ xbt_os_thread_exit(nullptr);
}
}
xbt_os_sem_acquire(this->end);
}
-}
-}
+}}} // namespace simgrid::kernel::context