slowLockMutex and the deadlock

Dr. Java kaffe@rufus.w3.org
Sun, 28 May 2000 21:03:42 +0200


Hello everybody,

I'm currently trying to upgrade KaffePC to the Kaffe 1.0.5 core. If you
don't know KaffePC, it's a project started by some Japanese guys that
aims to make Kaffe run on pure DOS (using DJGPP): . KaffePC 1.0.b3 works
nicely; the sad thing is that they stopped development after that
release. And b3 has some nasty bugs that are ruled out in 1.0.5 (I
think).

Well... My home-grown KaffePC 1.0.5 compiles now, but I keep getting a
"deadlock" error. I'm just running a trivial test program (with an empty
main method), so the error must come from somewhere inside Kaffe itself
(KaffePC uses unix-jthreads, btw).

I'm using the offiicial Kaffe 1.0.5 distribution. I didn't apply the
ksem patches, maybe I should do that first?

The function that plays a major role in producing the deadlock is
slowLockMutex. This is what I'd like to to ask you: How does
slowLockMutex work?

I don't understand the details (I'd love to have a detailed description
of how Kaffe's threading works), but one thing seems strange to me:
Under certain circumstances, doesn't slowLockMutex acquire the semaphore
more than once? This is the main part of slowLockMutex (locks.c):

 for (;;) {
  lk = getHeavyLock(lkp);

  /* If I hold the heavy lock then just keep on going */
  if (jthread_on_current_stack(lk->holder)) {
   putHeavyLock(lkp, lk);
   return;
  }

  /* If no one holds the heavy lock then claim it */
  if (lk->holder == 0) {
   lk->holder = where;
   putHeavyLock(lkp, lk);
   return;
  }

  /* Otherwise wait for holder to release it */
  tid = getCurrentThread();
  unhand(tid)->nextlk = lk->mux;
  lk->mux = tid;
  putHeavyLock(lkp, lk);
  SEMGET(unhand(tid)->sem, 0);
 }

What happens after SEMGET is executed? Is it clear that one of the if
branches will be executed and the loop ends?

A second question I have concerns the same area. In lock-impl.h it says:

#define SETUP_POSIX_LOCKS(L) \
 (L)->mux = thread_malloc(sizeof(jmutex)); \
        (L)->cv = thread_malloc(sizeof(jcondvar)); \
        jmutex_initialise((L)->mux); \
        jcondvar_initialise((L)->cv);

thread_malloc fills the area it returns with zeros, so (L)->count is 0
after the above code was executed. But shouldn't it be 1 to indicate
that the lock isn't acquired?

What causes the threading problems might also be that pipe() apparently
doesn't work in DJGPP. So all the sigPipe-related code in
unix-threads/jthread.c is commented out in KaffePC. I did the same in
KaffePC 1.0.5.

Any ideas anyone? I would greatly appreciate some help!

Doc