| View previous topic :: View next topic |
| Author |
Message |
albrecht.fritzsche Guest
|
Posted: Thu Aug 25, 2005 12:19 pm Post subject: Implementation of shared_ptr in boost |
|
|
While looking at the internal implementation of shared_ptr<>
I found the quoted function use_count(). What I don't understand
is the following
What is the rational of the static_cast in it? Has it something
to do with avoiding to cache that value? How is this
different to simply returning the member use_count_?
Thanks for any explanations
Ali
namespace boost {
namespace detail{
class sp_counted_base {
private:
long use_count_; // #shared
public:
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Frank Chang Guest
|
Posted: Thu Aug 25, 2005 11:13 pm Post subject: Re: Implementation of shared_ptr in boost |
|
|
Yes, The use of the static_cast<long const volatile&> in use_count is
to disable the caching of use_count_ in registers. This is especially
important in multithreaded applications where you want every invocation
of use_count() to access the actual memory address of use_count_.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Thu Aug 25, 2005 11:40 pm Post subject: Re: Implementation of shared_ptr in boost |
|
|
albrecht.fritzsche <albrecht.fritzsche (AT) arcor (DOT) de> wrote:
| Quote: | While looking at the internal implementation of shared_ptr
I found the quoted function use_count(). What I don't understand
is the following
What is the rational of the static_cast in it? Has it something
to do with avoiding to cache that value? How is this
different to simply returning the member use_count_?
snip |
I believe the intent is to discourage the compiler from optimising
away duplicate reads. This doesn't guarantee that the function will
return the latest value of use_count_ as the read (that would require
the use of an acquire memory barrier, I think). However, the count
can in any case change between use_count() reading it and its caller
uses it, so there is little value in adding a memory barrier. The
function is mainly useful for diagnostic output.
--
Ben Hutchings
Having problems with C++ templates? Your questions may be answered by
<http://womble.decadentplace.org.uk/c++/template-faq.html>.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Thu Aug 25, 2005 11:43 pm Post subject: Re: Implementation of shared_ptr in boost |
|
|
albrecht.fritzsche wrote:
| Quote: | While looking at the internal implementation of shared_ptr
I found the quoted function use_count(). What I don't understand
is the following
class sp_counted_base {
private:
long use_count_; // #shared
public:
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
What is the rational of the static_cast in it? Has it something
to do with avoiding to cache that value? How is this
different to simply returning the member use_count_?
|
This is a "quality of implementation" issue; reading use_count_ as
volatile ensures that the compiler doesn't cache the old value of
use_count_ when there are no visible updates in the current thread.
This doesn't guarantee that the value that is returned by use_count()
is correct because it doesn't enforce proper memory visibility on
multicore/CPU machines; however in practice it does guarantee that if
the actual value of use_count_ is a constant 2 and you spin in a loop
calling use_count(), you will eventually get 2 as a return value once
it propagates to the current CPU.
In other words, use_count() returns the value of use_count_ as it was
at some point in the recent past. Without proper synchronization
between the threads that update the use_count_ and the thread that
calls use_count(), its return value is subject to races no matter how
the function is implemented, so there is no good reason to enforce
memory synchronization.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alexander Terekhov Guest
|
Posted: Sat Aug 27, 2005 7:12 pm Post subject: Re: Implementation of shared_ptr in boost |
|
|
Peter Dimov wrote:
[...]
| Quote: | This is a "quality of implementation" issue; reading use_count_ as
volatile ensures that the compiler doesn't cache the old value of
use_count_ when there are no visible updates in the current thread.
|
In absence of sig_atomic_t static and async signals (not threads),
the effect on "caching" of volatile stuff with standard storage
duration (i.e. stuff having really nothing to do with memory mapped
I/O) is actually implementation-defined. You're just lucky (due to
stupid compiler(s)):
http://tinyurl.com/9zgjc
I wish it would state instead that "blah-blah ... MT data race on a
volatile constitutes abort() invoked by the implementation" (or
something like that).
regards,
alexander.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|