Green threads - some experience

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'd just like to describe my experiences of getting m-to-n threading 
going with classpath gtk peers and the Jikes RVM. It could possibly be 
instructive for developers and/or other JVMs.

There are different models of threading:

1) native threads: map Java threads to native pthreads - talking to 
people suggests this is the preferred method by classpath developers and 
is in the widest use
2) green threads 1: run Java threads as a single thread then on timer 
switch the running thread. This method is used by Kaffe's jthreads.
3) green threads 2: run Java threads as a single thread, on a timer 
interrupt set a flag indicating a yield is desired. At points in the 
code test this flag and yield if necessary.
4) m-to-n: run m green Java threads on n native threads. This approach 
is adopted in the Jikes RVM with green threads 2.

The biggest problem is:

Java threads can call into native code. This native code can call out to 
Java code. Not all native code will return to Java code or call out to 
Java code (e.g. gtk_main). If your JVM uses the green threads 2 model 
this presents a problem scheduling other threads.

The Jikes RVM solves this problem by having a back up thread that 
non-blocked Java threads can be switched onto. The original Java thread 
continues to be blocked on the native thread. However, if the back up 
thread becomes blocked there's a problem. To reduce and optimise this 
problem the Jikes RVM replaces some system calls with non-blocking 
alternatives.

The AWT peer problems were caused primarily by pthread mechanisms being 
used by GTK. These are wrapped in a library called gthreads. A Java 
thread would:
1) enter some native code that acquired a pthread mutex
2) call back into the JVM
3) the JVM would switch Java thread
4) the Java thread would call code that required the original mutex and 
block in native code not allowing other threads to get scheduled

To solve this there is the portable native sync option with classpath. 
This option swaps the gthread mechanisms with ones that call back into 
the JVM. Unfortunately it is broken, will only work for GTK code and 
won't work if there is already GTK code using the gthread library (for 
example, if the JVM is a plugin).

Another option is to modify classpath so that at the points where mutexs 
are acquired, if a mutex is busy then call back into the JVM. However, 
this option isn't desirable as its not required for a lot of JVMs.

Another option is to try to stop the Java threads entering native code 
if on that native thread a Java thread is already in native code. This 
proved to be buggy and slow, it is likely the scheduler needs work with 
this option.

So the simplest solution[1] was to hijack the pthread mutex locking and 
waiting calls and replace them with versions that call back into the 
JVM. This works well but the final implementation isn't quite bug free.

[1] changing the threading model to using native threads wasn't 
considered simple.

The current Jikes RVM CVS head is using this mechanism and is no longer 
using portable native sync. It is very likely that this code is now 
redundant.

The JNI spec. and programmers guide section 8.1.5:
http://java.sun.com/docs/books/jni/html/other.html#29406
describes consulting JVM documentation before embarking on threaded 
native code.

Regards,

Ian Rogers
---
http://www.cs.man.ac.uk/~irogers/


[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux