linux threads - preliminary evaluation

Date view Thread view Subject view Author view

From: Godmar Back (gback@cs.utah.edu)
Date: Thu Jan 14 1999 - 02:35:00 EST


 Having the OSKit pthreads implementation running I was so excited that
we may be able to get support for linux pthreads, namely the clone-based
implementation by Xavier Leroy that ships with current Linuxes.

It's a grossly inefficient setup, but it should give you stuff on an SMP,
plus we get kaffe finally smp-safe, or so I thought.

Well, it turns out that there is problems with both the way posix defines
things and with the way linux implements them.

These problems, you guessed right, are with

    1. signals.
    2. signals.
    3. signals.

ad 1.) The GC requires a way to suspend all processes, to stop the world.
So I contacted Xavier Leroy, who pointed me at Boehm's linuxthreads support.
The way to stop threads is as follows: you send them a signal, they
handle it, record their stack pointer, and use "sem_post" to say that
they've stopped.

What this means is that we cannot use "LOCK()" in the gc system to protect
manipulations of the lists. However, I don't think there is any reason
for that anyway. The gc should just grab the gc_lock while collecting ---
then the gc_lock would protect the white, gray, and black list.
(I surmise the reason LOCK() is used was to speed up list manipulation
in the previous attempt to do incremental gc?)

In essence, the GC must identify when it must stop the world and when
it will resume.

ad 2.) How do you handle NullPointerExceptions or arithmetic exceptions.
Linux threads functions are not async-safe. That is, they cannot be
safely called out of a signal handler. Hence, you can't just throw
a NullPointerException from there like we currently do.

However, if I assume for a moment that async-safety is only a question
of reentrancy, such synchronous exceptions shouldn't be that much of a
problem. I don't know.

ad 3.) How do you do Thread.stop()?
Two choices: either devote a signal, and throw the death exception from the
signal handler. Big problem again: nothing is async-safe, so you couldn't
continue. The alternative, blocking the cancellation signal while you're
in any pthread_ function, would be really expensive.

The OSKit pthreads implementation uses pthread's cancel mechanism.
pthread_cancel etc. This mechanism is supported in linux-threads as well,
it allows you to register cleanup handlers when a cancellation happens.
In the OSKit, these handlers throw the death exception.

However, posix says and linux-threads indeed implements that the result
of calling pthread_exit out of a cancellation handler is undefined. That
is, the only way to get that thread eventually to exit is to return from
the handler, excluding the possibility to throw an exception from there.

In addition, the fact that cleanup_push/pop have to occur in pairs
(which posix says, linux does, but the oskit does not do) means that the
main thread would have jump through a needle hole somehow to be embraced
by a matching pair.

In short, it's my opinion that with standard pthreads semantics, pthread_cancel
is unusable for Java.

Sun has a native port; I wonder how they do it.
One thing they can always do is simply to poll for stop and check for
null pointer exceptions (like Kaffe has an option to do).

Another alternative would be to simply adopt and extend linux-threads.
This would mean to not having to implement things on top of it.
For instance, it uses SIGUSR1/SIGUSR2 to suspend/resume -- why using yet
another signal pair for the gc stopworld/resumeworld operation.

Anyway, if any of you have any thoughts, that would be greatly appreciated.
Even if I may give up on it for now, I'll still check the changed
interfaces that distinguishes between "real" spinlocks and the stopworld/
resumeworld operation. Previously, those were mixed.
I've also added #ifdefs to unix-jthreads and I'll can the internal system
at this point.

        - Godmar


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Sat Sep 23 2000 - 19:57:41 EDT