bug-hurd
[Top][All Lists]
Advanced

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

Re: a recursive lock prototype


From: Marcus Brinkmann
Subject: Re: a recursive lock prototype
Date: Thu, 5 Jul 2001 10:51:21 -0500
User-agent: Mutt/1.2.5i

On Wed, Jul 04, 2001 at 06:13:23PM -0700, Thomas Bushnell, BSG wrote:
> 
> Maybe I missed something, but what specifically is this for? 

You are missing out the LSM, a great event.  Many greetings from Bordeaux!

Moshe asked about recursive locks today, which we don´t have.  He said
it is easy to implement them ("five minutes"), but it turned out to take
a bit longer when doing it right :)

The C library needs recursive locks for the dynamic linker (loading object
files at run time), and they might be quite useful in libraries, too
(for better modularization).

We agreed, in an inspiring coordinated coding effort, on the following
implementation (thanks to Johannes, Neal, Moshe and Rene):


#include <assert.h>
#include <mach.h>
#include <cthreads.h>

struct recursive_lock
{
  unsigned int refcount;
  thread_t locking_thread;
  struct mutex lock;
};

typedef struct recursive_lock *recursive_lock_t;

void
recursive_lock_init (recursive_lock_t rl)
{
  assert (rl);

  rl->refcount = 0;
  rl->locking_thread = MACH_PORT_NULL;
  mutex_init (&rl->lock);
}

void
recursive_lock (recursive_lock_t rl)
{
  mach_port_t thread = mach_thread_self ();

  assert (rl);

  /* We assume that setting the locking_thread in recursive_unlock
     to MACH_PORT_NULL is an atomic operation.  XXX Use atomic int
     rather than thread_t?  */
  if (rl->locking_thread == thread)
    {
      rl->refcount++;
      mach_port_deallocate (mach_task_self (), thread);
      return;
    }
  else
    {
      mutex_lock (&rl->lock);
      rl->refcount = 1;
      rl->locking_thread = thread;
      return;   
    }
}

void
recursive_unlock (recursive_lock_t rl)
{
  mach_port_t thread = mach_thread_self ();

  assert (rl);
  assert (rl->locking_thread == thread);

  mach_port_deallocate (mach_task_self (), thread);

  if (-- (rl->refcount) == 0)
    {
      mach_port_deallocate (mach_task_self (), rl->locking_thread);
      rl->locking_thread = MACH_PORT_NULL;
      mutex_unlock (&rl->lock);
    }
}








reply via email to

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