Results 1 to 2 of 2
  1. #1
    ignacio is offline Member
    Join Date
    Oct 2009
    Location
    Argentina
    Posts
    1
    Rep Power
    0

    Default 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:

    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]
    }
    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:
    pthread_t tid;
    int thr_id;
    
    // native_thread is main thread method
    thr_id=pthread_create(&tid,NULL,native_thread,NULL);
    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:
    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);
    All code described above runs successfully.

    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.

    Java Code:
    ucontext_t new_coroutine;
    ucontext_t thread_coroutine;
    new_coroutine is the coroutine I switch to where I wan't to access JVM.
    Initialization on "thread_coroutine" is done this way:

    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]
    }
    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 *native_thread(void *arg){
    
    prepare_context();
    
    // swap to new_coroutine to run "my_coroutine_method".
    swapcontext(&(thread_coroutine), &(new_coroutine));
    When coroutine reaches AttachCurrentThread, JVM generates a fatal error:

    Java Code:
    #  Internal Error (threadLocalStorage.cpp:40), pid=4797, tid=3035433872
    #  Error: guarantee(get_thread() == thread,"must be the same thread, quickly")
    threadLocalStorage.cpp::set_thread method is:

    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");
    }
    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.

    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:

    Java Code:
    siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x00000094
    Did anyone face this problem before?

    Sorry for this mega-description of my situation, hope it isn't difficult to understand.

    Many thanks in advance

    Ignacio

  2. #2
    r035198x is offline Senior Member
    Join Date
    Aug 2009
    Posts
    2,388
    Rep Power
    8

    Default

    You are better off asking in a C forum because any solutions do not involve changing any Java code at all.

Similar Threads

  1. JDK @ ubuntu
    By M77 in forum New To Java
    Replies: 2
    Last Post: 09-16-2009, 08:43 AM
  2. Eclipse in Ubuntu
    By DavidG24 in forum Eclipse
    Replies: 2
    Last Post: 04-18-2009, 03:10 PM
  3. SWT is not working on ubuntu
    By shreedharghare in forum SWT / JFace
    Replies: 0
    Last Post: 12-17-2008, 05:21 PM
  4. Eclipse in Ubuntu
    By detcader in forum Eclipse
    Replies: 3
    Last Post: 12-13-2008, 01:23 AM
  5. Log rotation in ubuntu
    By sarah11 in forum New To Java
    Replies: 0
    Last Post: 11-04-2008, 07:46 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •