Topic: Are all stdlib types in C++0x movable?


Author: "Balog Pal" <pasa@lib.hu>
Date: Wed, 7 Apr 2010 15:16:51 CST
Raw View
"Anthony Williams" <anthony.ajw@gmail.com>
>>>
>>> all mutex types,
>>> all condition variable types
>>>
>> ... but why not allow
>> mutexes, locks, or condition variables to be moved?
>
> ... Also, the identity of a mutex is
> vital for its operation, and that identity often includes the address,
> which means that the mutex CANNOT be moved. Similar reasons apply to
> condition variables.

Is that so?  Though all 3 thread APIs I worked have the
mutex/critical_session structures passed by pointer, I thought they
keep all the state inside that structure. the pthread_* family even
support static initialization of the structure.

Which systems use the identity beyond the state?


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Thu, 8 Apr 2010 00:24:50 CST
Raw View
"Balog Pal" <pasa@lib.hu> writes:

> "Anthony Williams" <anthony.ajw@gmail.com>
>>>>
>>>> all mutex types,
>>>> all condition variable types
>>>>
>>> ... but why not allow
>>> mutexes, locks, or condition variables to be moved?
>>
>> ... Also, the identity of a mutex is
>> vital for its operation, and that identity often includes the address,
>> which means that the mutex CANNOT be moved. Similar reasons apply to
>> condition variables.
>
> Is that so?  Though all 3 thread APIs I worked have the
> mutex/critical_session structures passed by pointer, I thought they
> keep all the state inside that structure. the pthread_* family even
> support static initialization of the structure.
>
> Which systems use the identity beyond the state?

On linux, the wait queue for a contended mutex or a condition variable
is often managed with a futex, which is tied to a specific address. When
there are no waiting threads (as at initialization) then the state is
entirely within the structure, so static initialization is indeed
possible. When waiting, the kernel ties the queue to the address, and
doesn't actually care what the value at that address is when queueing or
waking threads.

Anthony
--
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++0x thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Thu, 8 Apr 2010 12:40:01 CST
Raw View
On Apr 7, 5:16 pm, "Balog Pal" <p...@lib.hu> wrote:
> "Anthony Williams" <anthony....@gmail.com>
>
>
>
> >>> all mutex types,
> >>> all condition variable types
>
> >> ... but why not allow
> >> mutexes, locks, or condition variables to be moved?
>
> > ... Also, the identity of a mutex is
> > vital for its operation, and that identity often includes the address,
> > which means that the mutex CANNOT be moved. Similar reasons apply to
> > condition variables.
>
> Is that so?  Though all 3 thread APIs I worked have the
> mutex/critical_session structures passed by pointer, I thought they
> keep all the state inside that structure. the pthread_* family even
> support static initialization of the structure.
>
> Which systems use the identity beyond the state?

A std::mutex is just like a pthread_mutex_t.  If you want to pass
around a pointer to it, please do.  There's no reason you can't.

It is intended that std::mutex be implementable as nothing more than a
simple wrapper around pthread_mutex_t.

Additionally C++0X offers layered-on functionality to make using
mutexes easier and less error prone (such as wrapping it in a
std::lock_guard or std::unique_lock).

Ditto for std::condition_variable.

C++ has a long history of being an extremely low level language, and
an extremely high level language, all at the same time.  The threading
components in C++0X continue that tradition.  You can work at the
atomics level, the mutex level, the thread level, or the futures
level.  Or even portably build your own higher-level layer upon any
one of these foundations.

-Howard


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Thu, 8 Apr 2010 18:24:28 CST
Raw View
"Anthony Williams" <anthony.ajw@gmail.com>
>>>>
>>>> ... but why not allow
>>>> mutexes, locks, or condition variables to be moved?
>>>
>>> ... Also, the identity of a mutex is
>>> vital for its operation, and that identity often includes the address,
>>> which means that the mutex CANNOT be moved. Similar reasons apply to
>>> condition variables.
>>
>> Is that so?  Though all 3 thread APIs I worked have the
>> mutex/critical_session structures passed by pointer, I thought they
>> keep all the state inside that structure. the pthread_* family even
>> support static initialization of the structure.
>>
>> Which systems use the identity beyond the state?
>
> On linux, the wait queue for a contended mutex or a condition variable
> is often managed with a futex, which is tied to a specific address. When
> there are no waiting threads (as at initialization) then the state is
> entirely within the structure, so static initialization is indeed
> possible. When waiting, the kernel ties the queue to the address, and
> doesn't actually care what the value at that address is when queueing or
> waking threads.

After posting I realized that I really wanted to ask a more specific
question -- that is tied to unlocked mutexes only...  As moving around
a locked mutex felt fishy. (Obviously restricted to the owning thread,
still could not see a realistic need...)

While the case Scott mentioned do make sense, to create and pass
around a mutex before its locking will begin.  Suppose there are no
problems with implementation if 'unliocked state' is a precondition
for the mutex move operation.  Then it could be allowed.

Though that would break simplicity and open a path for errors --
probably we're better off with the strict way to start.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <NeverRead@aristeia.com>
Date: Tue, 30 Mar 2010 10:52:00 CST
Raw View
Are there any types in the C++0x standard library that are not
movable?  I can't think of any offhand, but that doesn't mean
anything.  I can't think of a way to search the draft standard for
them, so I decided to post the question here...

Thanks,

Scott

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SG <s.gesemann@gmail.com>
Date: Wed, 31 Mar 2010 17:59:41 CST
Raw View
Scott Meyers wrote:
> Are there any types in the C++0x standard library that are not
> movable?  I can't think of any offhand, but that doesn't mean
> anything.  I can't think of a way to search the draft standard for
> them, so I decided to post the question here...

Here are a couple (not exhaustive):
type_info, error_category, locale::facet, random_device, seed_seq,
mutex, recursive_mutex, timed_mutex, recursive_timed_mutex, ...

They have explicitly deleted copy ctors and assignments which also
prevents the compiler from generating special move operations
automatically. So, searching for copy ctors with "= delete;" is one
way to find those.

Cheers,
SG


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Wed, 31 Mar 2010 18:01:05 CST
Raw View
On 30 Mrz., 18:52, Scott Meyers <NeverR...@aristeia.com> wrote:
> Are there any types in the C++0x standard library that are not
> movable?  I can't think of any offhand, but that doesn't mean
> anything.  I can't think of a way to search the draft standard for
> them, so I decided to post the question here...

An incomplete list:

type_info,
error_category,
all exception classes,
reference_wrapper,
All specializations from the primary allocator template,
weak_ptr,
enable_shared_from_this,
duration,
time_point,
all iterators / iterator adaptors I am aware of,
local::facet,
locale::id,
random_device,
seed_seq,
ios_base,
[basic_ios], // only derived classes
basic_istream<charT,traits>::sentry,
basic_ostream<charT,traits>::sentry,
all atomic types,
once_flag,
all mutex types,
lock_guard,
all condition variable types

These aren't moveable and probably some more by
accident, because the rules for implicitly generated
move operations became clarified just at the Pittsburgh
meeting. A general library issue has been opened

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1331

to cope for lack of move support in the library. Be sure
that you contact you national body representative, because
I've heart that this issue is not a sufficient replacement for a
national body comment against the FCD.

HTH & Greetings from Bremen,

Daniel Kr=FCgler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Niels Dekker - no reply address" <invalid@this.is.invalid>
Date: Fri, 2 Apr 2010 11:35:36 CST
Raw View
Scott Meyers wrote:
> Are there any types in the C++0x standard library that are not
> movable?

Excuse me, what is your definition of movable?  For example, do you consider
any copyable type "movable"?  And do you consider a MoveConstructible type
"movable", even if it isn't MoveAssignable?

Kind regards,

 Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <NeverRead@aristeia.com>
Date: Sun, 4 Apr 2010 12:04:43 CST
Raw View
Niels Dekker - no reply address wrote:
>
> Excuse me, what is your definition of movable?  For example, do you consider
> any copyable type "movable"?  And do you consider a MoveConstructible type
> "movable", even if it isn't MoveAssignable?

In posing the question, I was thinking about the rules for the
automatic generation of move operations that were added to the FCD.
For that purpose, copyability alone doesn't qualify.  If class X has a
data member of a type with a user-declared copy constructor but no
declared move constructor, X can't have an automatically-generated
move constructor.  As for moveconstructability vs. moveassignability,
you're correct that I need to think about these as separate
capabilities.

Scott

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <NeverRead@aristeia.com>
Date: Mon, 5 Apr 2010 19:21:23 CST
Raw View
=?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:

> all atomic types,
> all mutex types,
> lock_guard,
> all condition variable types
>

These types appear to be both unmovable and uncopyable.  Does anybody know
the reasoning behind this?  It means, among other things, that such types
can't be returned from functions.

For atomic types, I can imagine that copying/moving isn't permitted,
because, in general, such operations wouldn't be atomic, but why not allow
mutexes, locks, or condition variables to be moved?

Thanks,

Scott



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Tue, 6 Apr 2010 14:11:58 CST
Raw View
On Apr 6, 3:21 am, Scott Meyers <NeverR...@aristeia.com> wrote:
> =?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:
> > all atomic types,
> > all mutex types,
> > lock_guard,
> > all condition variable types
>
> These types appear to be both unmovable and uncopyable.  Does anybody kno=
w
> the reasoning behind this?  It means, among other things, that such types
> can't be returned from functions.
>
> For atomic types, I can imagine that copying/moving isn't permitted,
> because, in general, such operations wouldn't be atomic, but why not allo=
w
> mutexes, locks, or condition variables to be moved?

Note that not all locks are non-movable, but lock_guard
is. This is definitively intended, because lock_guard is
supposed to provide the minimum necessary functionality
with minimum overhead. If you need a movable lock,
you should use unique_lock.

In regard to mutex types and conditional variables these are
non-moveable and non-copyable by design, because they
have identity. The mutex requirements clearly say:

"A Mutex type shall not be copyable nor movable."

so this is indeed intended and AFAIK the current boost
mutexes/cond. variables are also not movable/copyable.

A bit of discussion when types should not be movable
can be found in e.g.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Exception=
%20safety%20and%20move

Note that the basic requirements in the library for a
move-from object is, that it still has a valid state, see
a the recent update of the tables [moveconstructible]
and [moveassignable]. What kind of state does a
moved-from mutex have?

Comparing with e.g. std::thread there is some notable
difference: A thread class has some clear "null" state,
that can be tested via the get_id() function. In fact, it
*must* have some null state like this, because the life-
times of the represented (native) thread and of the
thread object are completely different.

These are not the characteristics of mutexes and
conditional variables. There does not exist a
fundamental property from which such a null state
can be deduced from. So, if you need something
like that, you need to ensure that by some helper
structure, which holds a pointer to a mutex.

I'm not yet convinced that returning a mutex by
a function is an important use-case. Could you
please explain, why you think so?

HTH & Greetings from Bremen,

Daniel Kr=FCgler



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Tue, 6 Apr 2010 14:10:37 CST
Raw View
Scott Meyers <NeverRead@aristeia.com> writes:

> =?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:
>
>> all atomic types,
>> all mutex types,
>> lock_guard,
>> all condition variable types
>>
>
> These types appear to be both unmovable and uncopyable.  Does anybody know
> the reasoning behind this?  It means, among other things, that such types
> can't be returned from functions.
>
> For atomic types, I can imagine that copying/moving isn't permitted,
> because, in general, such operations wouldn't be atomic, but why not allow
> mutexes, locks, or condition variables to be moved?

You are right about atomics: copy/move wouldn't be atomic so isn't
permitted. Instead you have to explicitly load from one and store to
another.

std::atomic_int a,b;
a=b.load();
a.store(b);
a=(int)b;

Moving a mutex would be disasterous if that move raced with a lock or
unlock operation from another thread. Also, the identity of a mutex is
vital for its operation, and that identity often includes the address,
which means that the mutex CANNOT be moved. Similar reasons apply to
condition variables.

C++0x provides two types of lock object. std::lock_guard which is
non-copyable and non-movable, and std::unique_lock which is
movable.

std::lock_guard is a very lightweight, special purpose class which locks
(or adopts a lock) in its constructor, and unlocks in its destructor. No
moving, no support for unlocking during its lifetime or releasing
ownership. It is small and fast.

std::unique_lock is std::lock_guard's big brother. It supports locking
and unlocking a mutex whilst it is associated with the lock object, it
supports moving and releasing ownership. It is more complex, and
potentially has more overhead, such as a branch in the destructor to
check whether or not to unlock the associated mutex.

If you want to move your lock use std::unique_lock.

Anthony
--
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++0x thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]