I have a collection of information like this:
std::list< boost::shared_ptr<DataEntry> > m_Entries;
The list is accessed by multiple threads. The majority of the time the list is only read, but occasionally a thread will need to add or remove entries from the list. As such the list itself is protected by a reader/writer lock, but the entries are not.
The individual entries themselves are mostly immutable (with a few rarely-accessed mutable members separately locked to prevent concurrency problems), and shared_ptr
s are used to ensure that an entry isn't deleted while a thread is reading it, even if another thread removes the entry from the list.
The nature of access is such that a given thread will typically access one specific entry repeatedly and occasionally another (varying) entry. It does not matter if the data is stale, as long as it's not deleted while in use. At present, each time it needs an entry it has to acquire the lock, search the list, copy the shared_ptr
, and then release the lock. There is nowhere that a thread can store the pointer between accesses; it must release and reacquire each time.
As such, I think there could be a performance benefit from caching the most-used entry (as either a shared_ptr
or weak_ptr
) in thread local storage, to avoid having to acquire the lock at all in the most common case.
Unfortunately, I'm using VS2008 and its __declspec(thread)
doesn't support non-POD types such as smart pointers. I can't store a bare pointer, as that won't provide the non-deletion guarantees I need. I suppose I could store a weak_ptr*
but that would result in leaked memory (and weak reference counts) on thread exit (although I do have a hook that gets called on "normal" thread exit, so this could be mitigated a bit). And for hopefully obvious reasons storing a shared_ptr*
would be even worse.
Given the complexity, and that the locks are usually uncontended, I'm not sure the probably-marginal performance boost is worth the hassle. But I was wondering if I'm missing a better way to do it. (And I'm also curious if things improve in C++11, since it has better threading support.)