1 /* context_java - implementation of context switching for java threads */
3 /* Copyright (c) 2009-2010, 2012-2014. The SimGrid Team.
4 * All rights reserved. */
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. */
12 #include <xbt/function_types.h>
13 #include <simgrid/simix.h>
15 #include "JavaContext.hpp"
16 #include "jxbt_utilities.h"
17 #include "xbt/dynar.h"
18 #include "../../simix/smx_private.h"
19 extern JavaVM *__java_vm;
21 XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg, "MSG for Java(TM)");
26 simgrid::simix::ContextFactory* java_factory()
28 XBT_INFO("Using regular java threads.");
29 return new JavaContextFactory();
32 JavaContextFactory::JavaContextFactory()
33 : ContextFactory("JavaContextFactory")
37 JavaContextFactory::~JavaContextFactory()
41 JavaContext* JavaContextFactory::self()
43 return (JavaContext*) xbt_os_thread_get_extra_data();
46 JavaContext* JavaContextFactory::create_context(
47 std::function<void()> code,
48 void_pfn_smxprocess_t cleanup, smx_process_t process)
50 return this->new_context<JavaContext>(std::move(code), cleanup, process);
53 void JavaContextFactory::run_all()
55 xbt_dynar_t processes = SIMIX_process_get_runnable();
56 smx_process_t process;
58 xbt_dynar_foreach(processes, cursor, process) {
59 static_cast<JavaContext*>(SIMIX_process_get_context(process))->resume();
63 JavaContext::JavaContext(std::function<void()> code,
64 void_pfn_smxprocess_t cleanup_func,
65 smx_process_t process)
66 : Context(std::move(code), cleanup_func, process)
68 static int thread_amount=0;
71 /* If the user provided a function for the process then use it otherwise is the context for maestro */
73 this->jprocess = nullptr;
74 this->begin = xbt_os_sem_init(0);
75 this->end = xbt_os_sem_init(0);
78 this->thread = xbt_os_thread_create(
79 nullptr, JavaContext::wrapper, this, nullptr);
83 "Failed to create context #%d. You may want to switch to Java coroutines to increase your limits (error: %s)."
84 "See the Install section of simgrid-java documentation (in doc/install.html) for more on coroutines.",
85 thread_amount, ex.what());
86 xbt_ex new_exception(str);
88 new_exception.category = ex.category;
89 new_exception.value = ex.value;
90 new_exception.procname = ex.procname;
91 new_exception.file = ex.file;
92 new_exception.line = ex.line;
93 new_exception.func = ex.func;
94 new_exception.pid = ex.pid;
95 new_exception.bt = ex.bt;
96 new_exception.bt_strings = ex.bt_strings;
100 this->thread = nullptr;
101 xbt_os_thread_set_extra_data(this);
105 JavaContext::~JavaContext()
108 // We are not in maestro context
109 xbt_os_thread_join(this->thread, nullptr);
110 xbt_os_sem_destroy(this->begin);
111 xbt_os_sem_destroy(this->end);
115 void* JavaContext::wrapper(void *data)
117 JavaContext* context = (JavaContext*)data;
118 xbt_os_thread_set_extra_data(context);
119 //Attach the thread to the JVM
122 XBT_ATTRIB_UNUSED jint error =
123 __java_vm->AttachCurrentThread((void **) &env, nullptr);
124 xbt_assert((error == JNI_OK), "The thread could not be attached to the JVM");
125 context->jenv = get_current_thread_env();
126 //Wait for the first scheduling round to happen.
127 xbt_os_sem_acquire(context->begin);
128 //Create the "Process" object if needed.
134 void JavaContext::stop()
136 /* I am the current process and I am dying */
137 if (this->iwannadie) {
139 JNIEnv *env = get_current_thread_env();
140 XBT_DEBUG("Gonna launch Killed Error");
141 // 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
142 // 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.
143 // 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 ...
144 // TODO it will be nice to have the name of the process to help the end-user to know which Process has been killed
145 // 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) ));
146 jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError",
147 bprintf("Process %s killed :) (file JavaContext.cpp)",
148 simcall_process_get_name(this->process()) ));
149 XBT_DEBUG("Trigger a cancel error at the C level");
150 THROWF(cancel_error, 0, "process cancelled");
153 /* detach the thread and kills it */
154 JNIEnv *env = this->jenv;
155 env->DeleteGlobalRef(this->jprocess);
156 XBT_ATTRIB_UNUSED jint error = __java_vm->DetachCurrentThread();
157 xbt_assert((error == JNI_OK), "The thread couldn't be detached.");
158 xbt_os_sem_release(this->end);
159 xbt_os_thread_exit(nullptr);
163 void JavaContext::suspend()
165 xbt_os_sem_release(this->end);
166 xbt_os_sem_acquire(this->begin);
169 // FIXME: inline those functions
170 void JavaContext::resume()
172 xbt_os_sem_release(this->begin);
173 xbt_os_sem_acquire(this->end);