Results 1 to 2 of 2
- 10-28-2009, 08:16 PM #1
Member
- Join Date
- Oct 2009
- Location
- Argentina
- Posts
- 1
- Rep Power
- 0
JNI, pthreads and ucontext in Ubuntu
Hi everyone,
I'm facing some trouble with JNI and ucontext under Linux Ubuntu 7.04. My JVM version is:
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode, sharing)
I have a C program that successfully starts the JVM (in main method) using the following code, getting in "JavaVM *jvm" variable the JVM instance:
After that, I launch a pthread in order to instantiate a precompiled java class named TestJNI using the already launched JVM. This class does nothing but printing "Hello!" inside it's default constructor. I instantiante pthread in main method this way:Java Code:static JavaVM *jvm; // Reference to JVM int main(void) { [INDENT]JNIEnv *env; JavaVMOption *options; JavaVMInitArgs vm_args; JNIEnv *env; jint result; options=(void*)malloc(4*sizeof(JavaVMOption)); options[0].optionString="-Djava.class.path=."; options[1].optionString="-Djava.compiler=NONE"; options[2].optionString="-verbose:gc,class,jni"; vm_args.version=JNI_VERSION_1_2; vm_args.options=options; vm_args.nOptions=3; vm_args.ignoreUnrecognized=JNI_FALSE; result=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args); // launch pthread, not shown here.[/INDENT] }
In order to make JVM accessible inside a thread method, I must obtain the JNIEnv reference to JVM. This is done with AttachCurrentThread. After that, I instantiate successfully my TestJNI class. Code for "native_thread" method is:Java Code:pthread_t tid; int thr_id; // native_thread is main thread method thr_id=pthread_create(&tid,NULL,native_thread,NULL);
All code described above runs successfully.Java Code:void *native_thread(void *arg){ JNIEnv *env; // cannot be cached, each thread must attach to JVM and acquire it's own JNIEnv // jvm has it's value set on first code snippet. (*jvm)->AttachCurrentThread(jvm,(void**)&env,NULL); // Get class reference (located on classpath ".") cls=(*env)->FindClass(env,"TestJNI"); // Get reference to default constructor mid=(*env)->GetMethodID(env,cls,"<init>","()V"); // Instantiate object (successfully) jobj=(*env)->NewObject(env,cls,mid);
However, my programs needs using <ucontext.h> capability of creating contexts to switch between them. Ucontext is used to implement, for example, coroutines. So my intention is to execute the same method "native_thread" after having switched the same thread to another context.
So, I have 2 ucontext_t variables.
new_coroutine is the coroutine I switch to where I wan't to access JVM.Java Code:ucontext_t new_coroutine; ucontext_t thread_coroutine;
Initialization on "thread_coroutine" is done this way:
This way, my coroutine will execute "my_coroutine_method" which is a literal copy of already show "native_thread" method. This way, my "native_thread" method becomes:Java Code:void prepare_context() { [INDENT]getcontext(&new_coroutine); new_coroutine.uc_link = NULL; // assign stack where coroutine can execute. 1MB stack. new_coroutine.uc_stack.ss_sp = malloc(1024*1024); new_coroutine.uc_stack.ss_size = (1024*1024); new_coroutine.uc_stack.ss_flags = 0; makecontext(&new_coroutine,(void *)my_coroutine_method,1,NULL);[/INDENT] }
When coroutine reaches AttachCurrentThread, JVM generates a fatal error:Java Code:void *native_thread(void *arg){ prepare_context(); // swap to new_coroutine to run "my_coroutine_method". swapcontext(&(thread_coroutine), &(new_coroutine));
threadLocalStorage.cpp::set_thread method is:Java Code:# Internal Error (threadLocalStorage.cpp:40), pid=4797, tid=3035433872 # Error: guarantee(get_thread() == thread,"must be the same thread, quickly")
This error makes me suspect that JVM tries to check that thread changed and exits. However, thread didn't change, only the stack where it executes, by means of ucontent_t.Java Code:void ThreadLocalStorage::set_thread(Thread* thread) { pd_set_thread(thread); // The following ensure that any optimization tricks we have tried // did not backfire on us: // THIS IS WHERE EXCEPTION IS GENERATED!!!! guarantee(get_thread() == thread, "must be the same thread, quickly"); guarantee(get_thread_slow() == thread, "must be the same thread, slowly"); }
I also tried executing AttachCurrentThread on main stack thread BEFORE switching to coroutine. In that case, AttachCurrentThread succeded inside coroutine. However, when i try to get reference to the class TestJNI (by means of FindClass method) i get a segmentation fault error:
Did anyone face this problem before?Java Code:siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x00000094
Sorry for this mega-description of my situation, hope it isn't difficult to understand.
Many thanks in advance
Ignacio
- 10-28-2009, 08:25 PM #2
Senior Member
- Join Date
- Aug 2009
- Posts
- 2,388
- Rep Power
- 6
Similar Threads
-
JDK @ ubuntu
By M77 in forum New To JavaReplies: 2Last Post: 09-16-2009, 08:43 AM -
Eclipse in Ubuntu
By DavidG24 in forum EclipseReplies: 2Last Post: 04-18-2009, 03:10 PM -
SWT is not working on ubuntu
By shreedharghare in forum SWT / JFaceReplies: 0Last Post: 12-17-2008, 05:21 PM -
Eclipse in Ubuntu
By detcader in forum EclipseReplies: 3Last Post: 12-13-2008, 01:23 AM -
Log rotation in ubuntu
By sarah11 in forum New To JavaReplies: 0Last Post: 11-04-2008, 07:46 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks