bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

recursive locks


From: Thomas Bushnell, BSG
Subject: recursive locks
Date: 05 Jul 2001 09:28:22 -0700
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

You want something like:

struct recursive_lock
{
  spin_lock_t guard;
  int count;
  thread_t owner;
  mutex_t lock;
};

"guard" protects "count" and "owner", and it looks like this:

lock:
  spin_lock (guard)

  if (not owned)
    assert (count == 0)
    owner = me
    mutex_lock (lock)

  if (owner == me)
    increment count
    spin_unlock (guard)
  else
    spin_unlock (guard)
    mutex_lock (lock)
    spin_lock (guard)
    assert (not owned && count == 0)
    owner = me
    increment count


unlock
  spin_lock (guard)
  assert (owner = me && count > 0)
  decrement count
  if (count == 0)
    owner = not owned
    mutex_unlock (lock)
  spin_unlock (guard)


Now if you look closely at this, you'll see that we don't really need
the mutex LOCK at all.  It is only being used to provide a way for the
waiters to block (that is, when we call it, we always know for sure
whether we will succeed or not).  We should use a condition variable
instead.  In fact, we should.  Condition variables have to be
protected by a mutex though, so we would convert LOCK into a condition
at the cost of converting GUARD into a mutex.  Now we have:

struct recursive_lock
{
  struct mutex guard;
  int count;
  thread_t owner;
  condition_t wakeup;
};

lock:
  mutex_lock (guard)
  do
    if (not owned)
      assert (count = 0)
      owner = me
    if (owner == me)
      increment count
      GOT IT
    else
      condition_wait (wakeup, guard)
  while (not GOT IT)

unlock:
  mutex_lock (guard)
  assert (owner == me && count > 0)
  decrement count
  if (count == 0)
    owner = not owned
    condition_signal (wakeup)
  mutex_unlock (guard)


If this is too expensive, then you should implement your own queue,
and do something like:

struct recursive_lock
{
  spin_lock_t held;
  spin_lock_t guard;
  int count;
  thread_t owner
  struct cthread_queue queue;
};

See __mutex_lock_solid and __mutex_unlock_solid in libthread/cprocs.c
for the guts of how to manipulate QUEUE.

Thomas



reply via email to

[Prev in Thread] Current Thread [Next in Thread]