Re: Atomic Reference Counting - Do you think this would be useful to Boost?
"kanze" <kanze@gabi-soft.fr> wrote in message
news:1160641223.253521.56670@m73g2000cwd.googlegroups.com...
Earl Purple wrote:
Chris Thomasson wrote:
Currently, Boost doesn't provide support for "true"
atomically thread-safe atomic reference counting:
[...]
Does anybody think that Boost could make use of this level of
thread-safety?
[...]
shared_ptr doesn't have the semantics you want when passing
objects accross threads.
I also think that shared_ptr<...> does not provide efficient, or any?,
support for strong/atomically thread-safe competing ref-count increments
from multiple threads in parallel; I don't think the following contrived
scenario is valid with shared_ptr<...>. Please correct me if I am wrong:
(pseudo-code)
static shared_ptr<app> g_app(new app(...))
static shared_ptr<foo> g_foo;
void a_number_of_threads() {
for(...) {
// I don't think the following is atomic in current shared_ptr<...>:
shared_ptr<foo> l_foo(g_foo);
if (l_foo) {
if (l_foo->some_predicate(...)) {
shared_ptr<foo> n_foo(new foo(...));
n_foo->local_update(l_foo);
// I don't this cas is even possible in current shared_ptr<...>:
if (! g_foo.cas(l_foo, n_foo)) {
n_foo->local_rollback(l_foo);
g_app->log_rollback(l_foo, n_foo);
}
}
l_foo->some_real_processing(n_foo);
} else { g_app->some_other_processing(...); }
}
return 0;
}
What you need is auto_ptr.
Regretfully, there's no way of getting an auto_ptr from a
shared_ptr. (On the other hand, I've never had any problem with
auto_ptr's semantics in this case, using raw pointers for
weak_ptr's. Perhaps a weak_ptr for auto_ptr would be the
answer.)
Once you have "pure" word-based atomic ref-counts, you can apply normal
word-based atomic operations (e.g., CAS, SWAP; no DWCAS needed) directly to
shared locations that hold a pointer to a ref-count object. So, in order to
get lock-free auto_ptr<...> like semantics with them you could do something
like this contrived scenario:
foo *raw = new foo(...);
atomic_lptr<foo> l_foo(raw);
atomic_sptr<foo> s_new_owner;
// a lock-free transfer-of-ownership from l_foo to s_new_owner
s_new_owner.swap_weak(l_foo, 0);
// l_foo is invalid; if it's non-null we can use it if it does not point to
raw!
if(l_foo && l_foo != raw) {
// we have gained ownership of a new object that we did not create.
}
An example implementation of a lock-free s_new_owner.swap_weak(...)
function, in IA-32 Assembly, can be found here:
http://appcore.home.comcast.net/vzoom/refcount/refcount_ia32_gcc.asm
(in the refcount_ia32_add_swap_weak at the bottom of the file)
It expects the calling thread to own a reference, that why I postfix's the
function name with _weak. If you pass it a count increment of zero (e.g.,
transferring the calling threads reference to the shared location), it just
skips the XADD and does the XCHG. That's virtually equal to auto_ptr<...>
semantics.
I am currently getting a C++ wrapper around my C API's which help implement
a couple of smart pointer classes. Once I release the smart pointers, people
can use them and compare-contrast against shared_ptr<...>. Humm... Could be
interesting...
Any thoughts?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]