On 12/8/2023 10:27 PM, Chris M. Thomasson wrote:
> Food for thought. We can atomically increment a reference count along
> with obtaining a reference to an object in a single fetch-and-add. All
> in pure C++11
>
> Say we have some objects:
>
> collectors[CN];
>
>
> And a reference count, say, 32 bit words:
>
> RC = 0xRRRRRRCC
>
> Where R is reference count space, and C is an index into collectors...
>
> So, to obtain a reference we can simply:
>
> word = fetch_and_add(&RC, 0x100);
Fwiw, another trick is to increment by 0x200 and use the odd number
(0x300) for atomic quiescence detection. Proxy collectors sure beat the
heck out of rwlock when it comes down to the iteration of large
collections of nodes... Here is an example test unit in Relacy:
https://pastebin.com/raw/f71480694
If interested, take careful notice of the following functions:
________________
collector& acquire()
{
// increment the master count _and_ obtain current collector.
unsigned int current =
m_current.fetch_add(0x20U, std::memory_order_acquire);
// decode the collector index.
return m_collectors[current & 0xFU];
}
void release(collector& c)
{
// decrement the collector.
unsigned int count =
c.m_count.fetch_sub(0x20U, std::memory_order_release);
// check for the completion of the quiescence process.
if ((count & 0xFFFFFFF0U) == 0x30U)
{
// odd reference count and drop-to-zero condition detected!
prv_quiesce_complete(c);
}
}
________________