[Tdg] Reference Counting

Wesley Smith wesley.hoke at gmail.com
Wed Aug 22 09:33:02 PDT 2007


So I did some research on reference counting for the event system last
night.  for those who weren't at the meeting, here's the gist of what
we discussed.  In the event system, one od the design criteria is to
be able to send the same event to mutiple places without have to copy.
 This will require some sort of record keeping of how many references
to an objet there are out there.  Since events are read-only, there
isn't a problem of multiple threads accessing the same event memory
and preempting each other because they don't modify the memory, just
read it.

To implement reference counting, a way of keeping track of object
access through a pointer is necessary.  In C++ this has to be done
through a lightweight class the essentially wraps a pointer and
transparently allows object access by overloading the key pointer
operations like ->.  There are a number of ways to do this based on
application needs that make tradeoffs between ease of access to the
underlying object, memory footprint, and speed.  Boost has an
excellent set of references on the subject and in particular there was
a big argument over what was the right implementation so some people
put together some tests.  Here are the results:
http://www.boost.org/libs/smart_ptr/smarttests.htm .

Intrusive pointers are among the fastest and least memory hungry
implementation because they store the counter in the class they're
wrapping, not in intrusive pointer class.  The name intrusive comes
from them requiring new data to be added to the class they wrap.  For
any implementation of smart pointers to be valid, careful
consideration to access to the object address has to be made.  If one
can easily get the address of the object the smart pointer holds, then
any reference counting scheme will go out the window because the
address will have broken free from the smart pointer system and be
unable to keep track of what happens to it.  This is one place where
major bugs and headaches are introduced when using smart pointers.  An
example would be overloading the address-of operator for the spart
pointer to return the address of the raw pointer.  Who know what will
happen to the raw pointer once this data gets out of the smart
pointer's control. The smart pointer may at some point decide to free
it and some random object will stil have a reference to it and crash
the app.

So, if we want this feature, we're going to have to pay some price
somewhere.  There's no free lunch.  Mostly with intrusive pointers,
the prices comes from syntax and naming differences which is just a
fact of life if we want a meaningful reference counting system.  If
this is a deal breaker for anyone, then that would effectively negate
any kind of sophisticated pointer-to-object management which I think
we need in the Event system to enforce the thread-safety and memory
management policies we've designed.

I haven't implemented it yet so I might get the syntax wrong, but
basically it would look like this:

//ManagedObject will probably be parametrized by more than one policy
class, but this is a start
class Event : public ManagedObject<class ReferenceCountPolicy>
{


};

typedef IntrusivePtr<Event> EventPtr;

The point is that well be using an EventPtr type for pointers to
Events instead of Event *.  We could be verbose and use
IntrusivePtr<Event> but that's alot to write and unnecessary.

wes



More information about the Tdg mailing list