David B. Held said:
Joe Seigh said:
David B. Held said:
Atomic means that for the expression "p->a" where p
is a smart pointer, a valid value (or null pointer exception)
will be returned even if some other thread deletes or
modifies p during the evaluation of that expression.
I wasn't laughing at the idea of a thread-safe pointer.
I was laughing at the idea that you know every other
type of smart pointer in existence. There is no doubt
in my mind that there are hundreds of smart pointer
types that you have never seen because they have not
been released to the public. So to say that: "No
other C++ smart pointer can make that claim" is just
ridiculous.
Well, there's "Lock-Free Reference Counting" by Detlifs et al,
but I don't know anyone using that since it requires something
like the MC68020 with a DCAS instruction. There's weighted
reference counting and something equivalent to it but my
impression is that they weren't efficient enough for practical
use. Reference counting is a form of GC, but you could use
another form of GC such as RCU or Maged Michael's hazard
pointers to make the refcount increment safe. Interestingly
enough if you use Michael's double check logic in conjuction
with LL/SC or ldwarx/stwcx instructions you can also increment
the refcount safely.
I can see why you want to do that, but ask yourself if
this is the right level of locking. After all, most of the
time that you want to access a resource in multiple
threads, you also want to lock it for longer than the
duration of one pointer access. So, for instance, if
you do two successive pointer accesses into the same
struct, it seems to me that you are locking the pointee
twice, instead of once. So what are you paying for
this "convenience"?
There's two classes of this pointer. A global shared pointer
class and a local non shared pointer class. The global
is for mainly for use in the actual data structure and the
local is for threads to access the struction. The local
pointers have overhead equal to the non-atomic threadsafe
pointers.
It's not so much that lock-free pointers are all that fast
by themselves, but they do let you implement other lock-free
solutions that do blow conventional locking solutions out
of the water.
And how many smart pointers do you know about?
The other question is, if other smart pointers typically
don't provide the functionality you wish to add, could
there be a good reason for doing not so?
Boost shared_ptr mainly. Either they didn't know how
to without adding more overhead than they wanted or they
decided it wasn't needed since they were requiring a
higher level of locking anyway. The latter is a
perfectly valid reason and seems to be the official
reason given.
I don't see how that prevents another pointer to the
same resource from deleting the resource out from
under you. After all, the standard is thread-agnostic,
so it makes no guarantees about program behaviour
in the presence of multiple threads. In particular, I
don't think it follows at all that a temp has some magical
property which influences other threads. But I could
just be misunderstanding your explanation.
The temp local copy of the pointer prevents the reference
count from going to zero during the evaluation of the
expression. If some other thread had deleted the global
pointer during the evaluation of the expression then the
dtor of the temp copy would actually delete the object
after the expression was evaluated, not during or before.
But I'm not trying sell anyone on this particular smart pointer.
The OP is about some compiler or language behavior I'm seeing
when trying to force the temp copy to be generated. It could
be this whole double conversion technique is not really supported
in C++ and I'd have do it in C instead.
Joe Seigh