Matthew Toseland <toad at amphibian.dyndns.org> wrote:
> Beyond that, the only realistic option appears to be an external daemon
> running at a lower nice level to do CPU-intensive jobs and FEC encoding and
> decoding in particular.
Thread.yield() comes to mind. But this is ugly.
Wouldn't it be sufficient if the java threads set their own nice level? Instead
of shoving it all off to a daemon? This is quite trivial, and it might be
worthwhile to ask the java people to have Thread.setPriority do just that as
long as Linux NPTL does not support SCHED_OTHER prioritizing. We might even do
it ourselves. Here is something quick and dirty:
public class NativeThread extends Thread {
private static final int PRIO_RANGE = MAX_PRIORITY - MIN_PRIORITY;
private static final int NATIVE_PRIO_RANGE = 19;
/**
* set linux priority.
*
* @return true if successful, false otherwise.
*/
private native boolean setLinuxPriority(int prio);
/**
* rescale java priority to linux priority and
* set linux priority.
* On failure, fall back to standard setPriority()
*/
public void setNativePriority(int prio) {
int nPrio = NATIVE_PRIO_RANGE - (NATIVE_PRIO_RANGE * (prio -
MIN
_PRIORITY)) / PRIO_RANGE;
if (setLinuxPriority(nPrio))
return;
else
System.err.println("Setting Linux priority failed.");
setPriority(prio);
}
static {
System.loadLibrary("NativeThread");
}
}
The native setLinuxPriority() would look like this:
#include<sys/resource.h>
#include<sys/time.h>
#include<stdio.h>
#include"NativeThread.h"
JNIEXPORT jboolean JNICALL Java_NativeThread_setLinuxPriority
(JNIEnv * env, jobject jobj, jint prio) {
if (setpriority(PRIO_PROCESS, 0, prio) == 0)
return JNI_TRUE;
return JNI_FALSE;
}
I have tested both NativeThread and Thread.yield():
public class NativeThreadTest {
static class ThreadA extends NativeThread {
public void run() {
setNativePriority(MAX_PRIORITY - 1);
while (true)
System.out.print("A");
}
}
static class ThreadB extends NativeThread {
public void run() {
setNativePriority(MAX_PRIORITY);
while (true)
System.out.print("B");
}
}
public static void main(String[] args) {
Thread ta = new ThreadA();
Thread tb = new ThreadB();
Thread tm = Thread.currentThread();
ta.start();
tb.start();
while (true) {
System.out.print("M");
tm.yield();
}
}
}
So the main thread (call it "M") creates to new threads "A" and "B" which set
their priority to MAX-1 and MAX, respectively. All threads then print
characters continuously, with M constantly yielding. Now B gets indeed the most
CPU time, and the yielding M gets almost nothing. I performed this test with
with other priorities than MAX-1 for A and found the outcome to be very
sensitive to these changes. In particular, when A's priority was set to MIN, it
did not print a single character in several minutes.
Of course, this is only a rather crude test, so you might want to reconcile the
outcome with data from your own testbed.
Jack
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now.
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ