Google Groups Home
Help | Sign in
recursive mutexes
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 26 - 50 of 129 - Collapse all < Older  Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
Uenal Mutlu  
View profile
 More options May 15 2005, 11:11 am
Newsgroups: comp.programming.threads
From: "Uenal Mutlu" <520001085531-0...@t-online.de>
Date: Sun, 15 May 2005 17:11:46 +0200
Local: Sun, May 15 2005 11:11 am
Subject: Re: recursive mutexes
"Uenal Mutlu" wrote

Besides being slower, the first version is also buggy. And I don't know
what he or you want do if the object is not already locked. I guess you will do the following:
void X::g()
{
  bool fILockedItHere = false;
  if (!IsLocked())
     {
       Lock();
       fILockedItHere = true;
     }
  //...do..something...
  if (fILockedItHere)
     Unlock();

}

But, this is not thread safe!!! :-) Do you know why?
The only consequence is: my method is the only right one, believe me! :-)

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Uenal Mutlu  
View profile
 More options May 15 2005, 11:48 am
Newsgroups: comp.programming.threads
From: "Uenal Mutlu" <520001085531-0...@t-online.de>
Date: Sun, 15 May 2005 17:48:09 +0200
Local: Sun, May 15 2005 11:48 am
Subject: Re: recursive mutexes
"Peter Dimov" wrote

:-) Of course g() was meant.

No I haven't. See below

The above solution works only if your Lock() understands recursive locking.
Otherwise a deadlock will happen.

I don't like the above because one usually uses a locker
class like this one to automate the unlocking:

Locker
{
  Locker(mutex& Am) : m(Am)
   {
    m.Lock();
   }
  ~Locker()
   {
     m.Unlock();
   }
  private:
    mutex& m;

};

void X::f()
{
   Locker(m);
   for (int i = 0; i < 1000; i++)
     g();

}

void X::g()
{
  //...do..something...

You don't need 2 versions of g() if you use recursive locking.
The overhead of recursive locking is neglectable because
it's just incrementing a counter in Lock() and decrementing it in Unlock().

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Giancarlo Niccolai  
View profile
 More options May 15 2005, 1:24 pm
Newsgroups: comp.programming.threads
From: Giancarlo Niccolai <searchfo...@ingoogle.com>
Date: Sun, 15 May 2005 13:24:16 -0400
Local: Sun, May 15 2005 1:24 pm
Subject: Re: recursive mutexes

Uenal Mutlu wrote:

>> In all the years I've been programming, I have never used a recursive
>> mutex (except in Java, but that's another story).

> Then you must have overlooked their real value.

Sorry if I jump in late in the discussion, but I believed that David was
enough to fix this mental bug that you have encountered.

IMHO usage of recursive mutexes is generally an immediate and incontestable
proof of poor design.

It's not a matter of multithreading theoremes, it's a matter of parallel
activity design. Coordination is an high level activity in any parallel
process, be it coordination between firm divisions, production chains,
information processing or simply programming.

You don't want a magazine clerk of the production function to coordinate
with a magazine clerk of the provisions. The production manager will raise
the phone and talk with the provision manager (or the other way around)
when they need coordination. And believe me, they both know when they take
up the phone (lock) and when they put it down (unlock), and it's unlikely
that they can raise the phone twice without lowering it first.

Same for threads. When threads need coordination, a well designed system
will put this coordination in a place that each thread can perfectly
manage, and will make sure that coordination will 1) take less time and
computational power as possible and 2) nothing else will be done during
coordination step.

Locking a mutex means your agents are phoning each other. It's not polite to
have listener(s) hanging because you must do something while phoning them,
even if this something is somehow a recursive function call.

Locking for everything else except coordination (that is, inter-thread
communication) is bad design. Not just bad programming, but bad
understanding of parallel processing logic.

Bests,
Giancarlo Niccolai.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Schwartz  
View profile
 More options May 15 2005, 2:56 pm
Newsgroups: comp.programming.threads, comp.unix.programmer
From: "David Schwartz" <dav...@webmaster.com>
Date: Sun, 15 May 2005 11:56:08 -0700
Local: Sun, May 15 2005 2:56 pm
Subject: Re: recursive mutexes

"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67fm3$hah$00$1@news.t-online.com...

> Recursive locking has less dangers than locking without recursive feature.
> Proof: using recursive locking you never can block or deadlock yourself,
> but using a locking method without recursive feature you can very easily
> deadlock
> yourself.
> In the latter case even just blocking (ie. waiting for the lock) means
> deadlock!
> Don't you see that?

    Okay, suppose I write a function that supposed to only be called if X is
not locked. Calling it with X locked is a *bug*. Now suppose I  make a
mistake -- I am only human. I call the function by mistake with X locked.
The function goes to lock X itself. I *want* this to break because it
indicates a *bug*. It is *bad* if this just magically works because then the
bug will not get discovered.

    DS


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Schwartz  
View profile
 More options May 15 2005, 2:58 pm
Newsgroups: comp.programming.threads
From: "David Schwartz" <dav...@webmaster.com>
Date: Sun, 15 May 2005 11:58:45 -0700
Local: Sun, May 15 2005 2:58 pm
Subject: Re: recursive mutexes

"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67h31$utf$01$1@news.t-online.com...

>> > The code above is IMO wrong, obviously it should be:
>> >  A) Lock mutex
>> >  B) Do something
>> >  C) Unlock mutex
>> David meant what he said.  What if the something is signaling another
>> thread to go ahead with something that locks the mutex, and then wait
>> for that other thread to signal you back?  Deadlock.
> This has nothing to do with recursive locking per se, does it?

    Yes, it does.

> I mean: the same
> would happen also without recursive locking, wouldn't it?

    No. Because with locks that are not recursive, an 'unlock' function
actually unlocks something.

> And, apart from that I don't think this way. In my thinking each thread
> knows itself only and tries to lock the shared object(s) before changing
> its/their content. We are talking of locking some shared objects here,
> don't we?
> You maybe should give a practical example in pseudocode for what you mean.

    Okay, let me put it as simple as possible. There are some things you can
only do when you hold a lock, like manipulate shared data. There are some
things you can only do when you don't hold a lock, like block or wait for
shared data to change. Thus code that manipulates shared data needs to know
whether it holds a lock or not.

> This is a shortsighted view. What do you think recursive locking is
> intended for?
> Recursive locking has nearly no overhead if the implementation of lock()
> and unlock() were properly done.
> They have many many advantages.

    The *only* advantage is that you can write code that acquires a
particular lock without knowing whether it already holds that same lock.
However, code has to know what locks it holds *anyway* in order to be
developed sanely.

    DS


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Måns Rullgård  
View profile
 More options May 15 2005, 3:01 pm
Newsgroups: comp.programming.threads, comp.unix.programmer
Followup-To: comp.unix.programmer
From: Måns Rullgård <m...@inprovide.com>
Date: Sun, 15 May 2005 21:01:10 +0200
Local: Sun, May 15 2005 3:01 pm
Subject: Re: recursive mutexes

In other words, recursive mutexes are nothing but a way of papering
over design flaws in an application.

--
Måns Rullgård
m...@inprovide.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Schwartz  
View profile
 More options May 15 2005, 3:03 pm
Newsgroups: comp.programming.threads
From: "David Schwartz" <dav...@webmaster.com>
Date: Sun, 15 May 2005 12:03:05 -0700
Local: Sun, May 15 2005 3:03 pm
Subject: Re: recursive mutexes

"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67mtf$roq$03$1@news.t-online.com...

> Since you don't believe me it's your turn to prove that recursive locking
> is more dangerous (your saying) than using no recursive locking.
> My point is: recursive locking is much safer than non-recursive locking.

    We've already done this over and over. Consider:

x.Lock();
DoSomeStuff();
x.Unlock();
DoSomeStuffThatTakesALongTime();

    If the lock for x is not recursive, we know that we can safely take a
long time without stalling other threads that might want the x lock. If the
lock is recursive, we might unknowingly hold the x lock while we do the
stuff that takes a long time.

    Here's another one:

x.Lock();
while (x.IsReservedByAnotherThread())
{
 x.Unlock();
 DoOtherStuffSinceXIsNotReady();

}

x.DoStuff();
x.Unlock();

    This code will deadlock if the x mutex is recursive. The other thread
can never clear its reservation because this thread might still hold the x
mutex through the entire 'while' loop.

    We really mean what we're saying. Really, really. Recursive mutexes are
really bad and they really do hide serious bugs.

    You could write either of the two code sections above and *never* detect
the problem because it may only result in performance issues during your
tests. But in another environment where the functions erroneously held with
locks take longer, the result could be catastrophic.

    DS


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Schwartz  
View profile
 More options May 15 2005, 3:06 pm
Newsgroups: comp.programming.threads
From: "David Schwartz" <dav...@webmaster.com>
Date: Sun, 15 May 2005 12:06:34 -0700
Local: Sun, May 15 2005 3:06 pm
Subject: Re: recursive mutexes

"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67npb$enc$01$1@news.t-online.com...

    I never argued the performance issue. But here's a more realistic
example:

    Without recursive mutexes:

protected:

f_locked(void)
{ // call with mutex locked
 DoStuff();

}

public:

f(void)
{ // call with mutex unlocked
 Lock();
 f_locked();
 Unlock();

}

many_f(void)
{ // call with mutex unlocked
 Lock();
 for(int i=0; i<1000; i++) f_locked();
 Unlock();

}

With recursive mutex:

public:

f(void)
{ // call with mutex in any state
 Lock();
 DoStuff();
 Unlock();

}

many_f(void)
{ // call with mutex in any state
 Lock();
 for(int i=0; i<1000; i++) f();
 Unlock();

}

    Which do you think is faster?

    DS


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
doug  
View profile
 More options May 15 2005, 3:24 pm
Newsgroups: comp.programming.threads
From: "doug" <no...@nowhere.co.uk>
Date: Sun, 15 May 2005 19:24:02 GMT
Local: Sun, May 15 2005 3:24 pm
Subject: Re: recursive mutexes

"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67qjn$9o1$00$1@news.t-online.com...

S'not true.  You can't just increment/decrement a counter in
Lock()/Unlock() - these operations require memory barriers or they won't
work properly across multiple threads and CPUs.  With recursive locks, too.

You keep arguing about silly things, proclaiming people to be wrong (e.g.
"see below..." - where!?!), and never providing evidence (only faulty code).
When someone questions you, you answer rather indignantly.  Each post sounds
as though you've read the next chapter in your threading book and want to
share.

Anyways, this is interesting.  More technical than alt.guitar.bass, but just
as much flamebait, if better disguised!

With baited breathe,
Doug


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
doug  
View profile
 More options May 15 2005, 3:24 pm
Newsgroups: comp.programming.threads
From: "doug" <no...@nowhere.co.uk>
Date: Sun, 15 May 2005 19:24:54 GMT
Local: Sun, May 15 2005 3:24 pm
Subject: Re: recursive mutexes
"Uenal Mutlu" <520001085531-0...@t-online.de> wrote in message

news:d67h31$utf$01$1@news.t-online.com...