Massive performance loss from OS::sleep hack

Kurt Miller kurt at intricatesoftware.com
Tue Sep 18 07:16:13 PDT 2007


Hi Daniel,

Daniel Eischen wrote:
> On Tue, 18 Sep 2007, Kurt Miller wrote:
> 
>> David Xu confirmed for me that pthread_yield() does give some
>> time to lower priority threads on 7.0 using thr. Attached and inline
>> are two patches for the 1.5 port that is how I suggest the issue be
>> addressed.
> 
> I don't think you should rely on pthread_yield() doing that,
> it is dependent on the scheduler, and if you are running
> in SCHED_FIFO/SCHED_RR, it won't work with libthr either.
> Currently, you can only run in SCHED_FIFO or SCHED_RR as
> root using libthr, but that hopefully won't always be
> true.

Shoot I forgot to mention a few things in my last email...
The c test program I resurrected from 18 months ago had

pthread_attr_setschedpolicy(&attr, SCHED_FIFO);

in it. The jdk doesn't set the schedpolicy it uses the
default one. That line was left over from my testing
different policies under kse to see if I could work-
around the problem. Since the jdk doesn't set the policy,
I believe we don't need to be concerned with SCHED_FIFO
and SCHED_RR.

> I think the way that will always work is to lower the
> priority and raise it back again after the yield, when
> using thread priorities.  This should work for libthr,
> libc_r, and libkse under all versions of the OS.

On the surface this sounded promising, but I can envision
at least one case where temporarily lowering a thread
priority will not work very well. Take three threads A, B &
C each with different priorities: A highest, C lowest. Let's
say A is in a busy loop calling Thread.Yield(). B is in a busy
loop also calling Thread.Yield(). C is doing something that
needs some time slices every so often. A calls Thread.Yield(),
lowers priority to C's level, B gets some time next, it calls
Thread.Yield(), lowers priority to C's level. A, B, C are all
at equal level now. Perhaps C will get some time first, or B,
or A. Suppose the order is C first, B next. A will only get
a time slice if B continues to call yield and by chance the
system schedules A before B. The behavior becomes
non-deterministic. The worst case is A is starved.

Also to make matters a bit more complicated there are non-java
threads to contend with too. There could be some non-java
locking involved as well. It would require an investment
of someone else's time to work all the potential issues out.

> As for knobs, it would be nice to be able to turn off
> the default lowering and raising of priorities for
> Thread.yield() even when using thread priorities.  Most
> likely, the only applications that relies on that behavior
> are the TCK tests themselves.  I certainly wouldn't expect
> Thread.yield() to allow a lower priority thread to
> run.

Considering Sun's reluctance to correct the TCK test, I
would venture a guess that there are applications out there
that rely on Thread.Yield() to give time to lower priority
threads (in-spite of the significant amount of Java books,
white papers, certification tests, etc that say not to do
that).

> Are you allowed to supply knobs when running the TCK
> tests?  Or does the JVM have to do the right thing by
> default?

The JVM gets certified on the default threading library
for the standard options. Generally the non-standard options
(-Xfoo) are not certified. Attempting to certify the JVM
for multiple threading libraries, os versions, architectures,
and options would be cost prohibitive.

I believe what I've suggested provides a solution to the
performance issue (at the expense of supporting thread
priorities on < 7.0), while not introducing unexpected or
non-certifiable behavior.

Motivated people on this list should file bug reports w/Sun
against the Thread.Yield() API. It is about time Sun clarify
the expected behavior of of Thread.Yield() with respect to
thread priorities.

At a minimum the current description of Thread.Yield() is in
conflict with JSR-133: JavaTM Memory Model and Thread Specification,
Section 12: "The Java specification does not guarantee preemptive
multithreading or any kind of fairness guarantee. There is no hard
guarantee that any thread will surrender the CPU and allow other
threads to be scheduled."  Not to mention the 10 years of
non-official publications that say not to rely on Thread.Yield()
to do anything portable at all.

Regards,
-Kurt


More information about the freebsd-java mailing list