RE: [boost] Re: Lock unification [move]

How 'bout scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Abrahams Sent: Friday, 23 July 2004 1:15 AM To: boost@lists.boost.org Subject: [boost] Re: Lock unification [move]
Howard Hinnant <hinnant@twcny.rr.com> writes:
scoped_lock lk1(m, deferred); scoped_lock lk2(m, tried);
<shrug> I disliked "tried" more than I liked "deferred". And I also felt that the benefit of symmetry was important to make the interface easier to learn.
You only need part-of-speech symmetry. "deferred" is an adjective, so "non_blocking", "optional", "permeable",... would work find for the other one, from a grammatical point of view. I don't think "try" makes a very good adjective, and adding "_lock" to the end of it doesn't help. So I don't see the symmetry in "try_lock"/"deferred_lock" other than the suffix :vP
-- Dave Abrahams Boost Consulting http://www.boost-consulting.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-) matt.

Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
Yeah. And I'm sick and tired of all these "lock" verbs and nouns. guard g1(m, disengaged); guard g2(m, try_engage); Oder? ;-) regards, alexander.

On Fri, 23 Jul 2004 01:22:48 +0200, Alexander Terekhov <terekhov@web.de> wrote:
Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
Yeah. And I'm sick and tired of all these "lock" verbs and nouns.
guard g1(m, disengaged); guard g2(m, try_engage);
Oder? ;-)
regards, alexander.
a mutex is often referred to as a guard and having a lock called a guard is not ideal IMO. however guard g(m, attack) for a spin lock is attractive :-) matt.

On Fri, 23 Jul 2004 09:30:39 +1000, Matt Hurd <matt.hurd@gmail.com> wrote:
On Fri, 23 Jul 2004 01:22:48 +0200, Alexander Terekhov <terekhov@web.de> wrote:
Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
Yeah. And I'm sick and tired of all these "lock" verbs and nouns.
guard g1(m, disengaged); guard g2(m, try_engage);
Oder? ;-)
regards, alexander.
a mutex is often referred to as a guard and having a lock called a guard is not ideal IMO.
<snip> Naming a lock anything but a lock is a helluva lot of current to swim against... A lock is common and understood but, like you, I'm not a fan of it because of the verb and nouns confusion you point out. Too many times have I landed at a workplace with mutexes called locks exposing a lock and unlock method :-( It would be nice to rename it, but impractical and might impede learning I think. A typedef of the "preferred" name to lock might suffice though?? I would love to keep a consistent nomenclature for other similar patterns, e.g. socket, file and timer interaction but my language skills let me down in trying to coming up with an appropriate name for the "acquirer" / lock. Resource and acquirer are the concepts with the action being an acquisition acquirer a(r, technique) ; Deferment is confusing to me as this could be related to deferring the the technique specification or deferring the acquisition action. Both make sense. Also specifying the technique when the action is deferred is, perhaps, just setting up defaults that can be overridden at the action site. Named parameters might help make the specification of the acquisition cuter. acquirer a(r, spec, deferred = true ); // named_params ? ... a.do(spec); // do, execute, or perhaps, cleaner... a(spec); // returns true for success which can be ignored depending on your idiom Also if you defer the action you could still wish to specify the technique at the site of the acquisition. E.g. try_locking with exponential time decay in a loop. 1. defer spec of action and the actual action 2. defer the action Is choice of deferment of the action really required at run-time? If not then perhaps different types would be better. acquirer_deferred a(r, spec); acquirer a(r, spec); Hmmm, dunno. One certainty though, the name "acquirer" certainly sux. Similar concepts could apply for file, socket, timer and other interaction. Would be nice to keep the conceptual framework for this clean and orthogonal if a way can be found. Code management might be an issue without Mike's / David Held's policy approach. Say if you wanted to add a spin_acquiring method for resource acquisition. You should be able to do this cleanly and allow for specialization for os / resource specific optimization. Interestingly, perhaps such a technique could apply equally well to socket and mutex acquisition from the one code point. The extensibility of the scheme should be clear. I'm not sure it is with scoped_lock lk( m, new_thing ); <$0.02, Matt Hurd.

Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
I like scoped_lock because of: scoped_lock<> lock( m ); I prefer to be able to name the lock variable 'lock' instead of 'lk'.

"Peter Dimov" <pdimov@mmltd.net> writes:
Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
I like scoped_lock because of:
scoped_lock<> lock( m );
I prefer to be able to name the lock variable 'lock' instead of 'lk'.
Suit yourself, but I think variable names should denote roles, not types. The type declaration is already there, and otherwise you end up with glorified hungarian. When there's really no suitable role, some one or two character identifier works fine, IMO. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Matt Hurd wrote:
On Fri, 23 Jul 2004 08:31:18 +1000, Batov, Vladimir <vladimir.batov@ca.com> wrote:
How 'bout
scoped_lock lk1(m, defer); scoped_lock lk2(m, try);
no comment except that perhaps scoped_lock can be dropped for just lock. scoped_lock seems so twentieth century ;-)
I like scoped_lock because of:
scoped_lock<> lock( m );
I prefer to be able to name the lock variable 'lock' instead of 'lk'.
Suit yourself, but I think variable names should denote roles, not types.
Hm. What is it that makes 'lock' not qualify as a role?

"Peter Dimov" <pdimov@mmltd.net> writes:
I prefer to be able to name the lock variable 'lock' instead of 'lk'.
Suit yourself, but I think variable names should denote roles, not types.
Hm. What is it that makes 'lock' not qualify as a role?
Well, OK, it's a role at a very low level of abstraction. Something more like "access_foo" for some mutex-protected resource "foo" might be better. For that matter, unlock() maybe ought to be release(). Hmm, a smart-pointerish model has some appeal for me. They are our canonical resource managers. Cheers, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
I prefer to be able to name the lock variable 'lock' instead of 'lk'.
Suit yourself, but I think variable names should denote roles, not types.
Hm. What is it that makes 'lock' not qualify as a role?
Well, OK, it's a role at a very low level of abstraction. Something more like "access_foo" for some mutex-protected resource "foo" might be better.
Compare: lock lk( m ); // the original examples with scoped_lock lock( m ); Or the role-based variation: lock access_foo( foo_mutex ); with scoped_lock foo_lock( foo_mutex ); Same but unnamed (because you won't be touching the lock afterwards): lock access( foo_mutex ); vs scoped_lock lock( foo_mutex );

Peter Dimov wrote:
lock lk( m ); // the original examples
with
scoped_lock lock( m );
you still need to select mutex type in lock template class, thus above would rather look something like: lock<fast_mutex> lk( m ); or: scoped_lock<fast_mutex> lock( m ); Assuming that m is actually "fast_mutex". And you need to know its type whenever you need to lock it or use such lock. Alternatively, if we have common base class ... class lock_base {/* .... */}; ... typedef ... typedef const lock_base& lock; ... and number of heloper functions, we could actually write: lock lk = sole_acquire(m); or: lock lk = acquire<scoped_lock>(m); Please note that no mutex type has been selected (hardcoded) above. The longer I think about such common base, the more I believe that it should be just abstract class with very simple interface (virtual destructor; locked() const; operator safe_bool() const calling locked(); bool same(const lock_base&) const; operator==(const lock_base&, const lock_base&) calling same; friend operator!=(const lock_base&, const lock_base&) calling same;). I will provide some prototype implementation this week. B.

Ok, new spec up at: http://home.twcny.rr.com/hinnant/cpp_extensions/threads.html Summary of changes: I had messed up copy semantics with sharable and upgradable locks. I don't believe copy semantics of these locks is warranted. All of the locks are now movable only. And conversions among the locks are limited to demotion from an rvalue, with the exception of upgradable->scoped. There is now a conversion summary section for a quick overview. Fixed the recursion bug pointed out by Eric (I think). I've looked over this point with respect to the sharable and upgradable assignment operators as well. try_move has been dumped in favor of overloaded |= and <<= operators. This does not mean that I'm set on these operators, or that ~= or %= wouldn't be better as Rob suggests. Just there were getting to be so many changes, I wanted to get a new spec up. I've added a new section: Summary of mutex operations, which describes each mutex function. Those lock functions that call a mutex function link into this section. Each mutex function is labeled "blocking" or "not blocking" as appropriate. The spec does not yet reflect Bronek's lock_base suggestion. Personally I'm still mulling that over. The spec still contains the debated "try-lock" constructors (and an additional one in fact: try-upgradable->scoped construction), and the spelling of the object tags is still defer_lock and try_lock. I don't intend for this to be the only spec considered. It might be beneficial for there to be several competing specs that we can easily compare against one another (maybe a spec that doesn't try to do move?) But I'm not volunteering to write an alternative spec at the moment. ;-) Fwiw, I'm continuing to back this spec with a prototype implementation so that I can have at least some confidence in what I'm writing. -Howard

From: Howard Hinnant <hinnant@twcny.rr.com>
try_move has been dumped in favor of overloaded |= and <<= operators. This does not mean that I'm set on these operators, or that ~= or %= wouldn't be better as Rob suggests. Just there were getting to be so many changes, I wanted to get a new spec up.
The good news, in case no one else considered it, is that the precedence of any of the X= operators is very low, so you can take your pick on esthetic grounds alone. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

On Jul 25, 2004, at 1:29 PM, Rob Stewart wrote:
From: Howard Hinnant <hinnant@twcny.rr.com>
try_move has been dumped in favor of overloaded |= and <<= operators. This does not mean that I'm set on these operators, or that ~= or %= wouldn't be better as Rob suggests. Just there were getting to be so many changes, I wanted to get a new spec up.
The good news, in case no one else considered it, is that the precedence of any of the X= operators is very low, so you can take your pick on esthetic grounds alone.
The bad news is that ~= isn't really available. ;-) Here's the full list to peruse: = += -= *= /= %= ^= &= |=
= <<=
-Howard

Howard Hinnant <hinnant@twcny.rr.com> writes:
The bad news is that ~= isn't really available. ;-)
Here's the full list to peruse:
= += -= *= /= %= ^= &= |=
= <<=
-Howard
Huh, ther's no ,= operator? That's too bad; it has a nice flavor for a blocking lock. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

From: Howard Hinnant <hinnant@twcny.rr.com>
On Jul 25, 2004, at 1:29 PM, Rob Stewart wrote:
The good news, in case no one else considered it, is that the precedence of any of the X= operators is very low, so you can take your pick on esthetic grounds alone.
The bad news is that ~= isn't really available. ;-)
Doh, I guess I should have double-checked myself on the list of available operators rather than creating my own!
Here's the full list to peruse:
= += -= *= /= %= ^= &= |=
= <<=
BTW, given the earlier examples using the conditional operator, I don't think we should consider any other operators (except <opening can with worms> the comma operator). (No, I wasn't serious about the comma operator, I just couldn't resist since it has lower precedence and there was a recent discussion about it.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Howard Hinnant wrote:
Ok, new spec up at:
http://home.twcny.rr.com/hinnant/cpp_extensions/threads.html
Wow, you guys have been busy. I see what happens when I have to lurk for a week. So, I understand that the prevaling opinion is that we should drop try_lock and timed_lock in favor of one all-encompasing scoped lock. Are we going to eliminate variations of Mutex as well, or will mutex/try_mutex/timed_mutex still exist? I recognize that Howard's spec is only a proposal, but there's been a lot of good work in it. Well done. Christopher -- Christopher Currie <codemonkey@gmail.com>

On Jul 27, 2004, at 10:45 AM, Christopher Currie wrote:
Howard Hinnant wrote:
Ok, new spec up at: http://home.twcny.rr.com/hinnant/cpp_extensions/threads.html
So, I understand that the prevaling opinion is that we should drop try_lock and timed_lock in favor of one all-encompasing scoped lock. Are we going to eliminate variations of Mutex as well, or will mutex/try_mutex/timed_mutex still exist?
The mutex end is still under debate. It's a good deal with locks because you can just not use (instantiate) the try_lock and timed_lock stuff if you don't want it, or if the mutex you're using doesn't support it. No harm is done. This is because the lock just contains a mutex reference and a bool, no matter what the capabilities. But it isn't that simple for the mutex. There's a tradeoff to be made. The more capability you stuff into a mutex, the more bloated it becomes. But even that statement is platform dependent. Some platforms already supply a native mutex with all the capability stuffed in, so there is no further penalty in supplying an all-in-one boost::mutex on such a platform. I think at some point we realized that we could make progress on the locks without tackling the very question you ask. -Howard
participants (10)
-
Alexander Terekhov
-
Batov, Vladimir
-
Bronek Kozicki
-
Christopher Currie
-
David Abrahams
-
Eric Niebler
-
Howard Hinnant
-
Matt Hurd
-
Peter Dimov
-
Rob Stewart