[kaffe] race during thread creation and gc invocation

Alexander Boettcher ab764283 at os.inf.tu-dresden.de
Sat Dec 11 12:50:54 PST 2004


Hi,

i have a race condition in thread.c found which (may) causes Kaffe to
hang - for our L4 system it happens. In the function "startThread" in
kaffe/kaffevm/thread.c

startThread(Hjava_lang_VMThread* tid)
{ ...
        nativeTid = createThread(tid, &firstStartThread,
                                 jthread_current(),
                                 threadStackSize, &info);
  ...
        ksemGet(&THREAD_DATA()->sem, (jlong)0);
        linkNativeAndJavaThread (nativeTid, tid);
        ksemPut(&jthread_get_data(nativeTid)->sem);
}

a thread is created and later the native thread and the java object
are linked.
 
In the function "createThread" the pointer(to jthread_current()) is
saved - during the call to jthread_create - in (somewhat
jthread_t)->data.jlThread. In "linkNativeAndJavaThread" the pointer(
to tid) is saved in (somewhat jthread_t)->data.jlThread. This means,
different types of pointers are used in data.jlThread ... jthread* and
Hjava_lang_VMThread* .
 
The problem appears if between "createThread" and
"linkNativeAndJavaThread" the GarbageCollector is invoked (which
happens in my testcase sporatic). The gc calls for each thread -
during its work - "liveThreadWalker" in
kaffe/kaffevm/kaffe-gc/gc-refs.c, which assumes that jlThread is of
type Hjava_lang_VMThread. But the pointer between "createThread" and
"linkNativeThread" is of type jthread_t. In my case, Kaffe hangs and
does not return from KGC_markObject.

 The new created thread is already listed (createThread) in the
activeThread list of the current thread implementation (i looked at
unix-pthreads & unix-jthreads and it is also so for our l4thread
implementation). Therefore, the gc calls "jthread_walkLiveThreads" and
the function found the new created - but unready( still wrong
jthread_t pointer) - thread.
 

liveThreadWalker(jthread_t tid, void *private)
{
  Collector *c = (Collector *)private;
  threadData *thread_data = jthread_get_data(tid);
  Hjava_lang_VMThread *thread = (Hjava_lang_VMThread
*)thread_data->jlThread;

  printf("livethread jtid=%p unhandthread=%p
vmthread=%p\n",tid,unhand(thread)->thread,thread);
  KGC_markObject(c, NULL, unhand(thread)->thread);
  KGC_markObject(c, NULL, thread);
  ...
}

 
 So, jlThread can not be used in this form, a other pointer would be
necessary in the threadData structure or the gc may not assume that
jlThread is of type VMThread and has to handle it.
 
 What do you think ?
 
 Thanks - sorry for my english,
 
 Alexander Boettcher.




More information about the kaffe mailing list