atomic operations for shared_ptr ?
Bronek Kozicki
brok@spamcop.net
Sat Aug 24 20:27:00 GMT 2013
On 24/08/2013 20:44, Bronek Kozicki wrote:
> On 24/08/2013 20:34, Bronek Kozicki wrote:
>>
>> Perhaps spinlock could be implemented without breaking ABI? Please check
>> performance comparison figures at the end of this document:
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2632.html
>>
>> Here they suggest use "a spinlock pool keyed on a hash of the address of
>> the instance", although perhaps a special value of _M_ptr might be used
>> instead (that value being the address of _M_ptr itself).
>>
>> Alternatively, a single bit might be sacrificed in existing data members
>> although that would most likely impose performance penalty on most
>> common uses, so I'm not really advocating it.
>
> Scratch the part starting with "although perhaps a special value of
> _M_ptr", it just occured to me it will have exactly same performance
> effect on common uses as taking a single bit from existing data members
> (i.e. not good).
Here is example naiive implementation with a spinlock pool. Even though
far from perfect, I feel it would be improvement over existing
siutuation, provided large enough pool.
B.
extern const size_t __shared_ptr_spinlocks_size = 256;
extern std::atomic_flag* __shared_ptr_spinlocks; // definition omitted
// platform dependent, drop least significant bits from a pointer
#define PTR_ALIGNMENT_BITS 3
namespace std
{
template <typename T>
shared_ptr<T> atomic_load(const shared_ptr<T>* p)
{
const size_t i = ((reinterpret_cast<size_t>(p) >>
PTR_ALIGNMENT_BITS) & (__shared_ptr_spinlocks_size - 1));
while (__shared_ptr_spinlocks[i].test_and_set()) ; // spin
shared_ptr<T> r = *p;
__shared_ptr_spinlocks[i].clear();
}
template <typename T>
shared_ptr<T> atomic_store(shared_ptr<T>* p, shared_ptr<T> r)
{
const size_t i = ((reinterpret_cast<size_t>(p) >>
PTR_ALIGNMENT_BITS) & (__shared_ptr_spinlocks_size - 1));
while (__shared_ptr_spinlocks[i].test_and_set()) ; // spin
swap(*p, r);
__shared_ptr_spinlocks[i].clear();
}
// etc.
}
More information about the Libstdc++
mailing list