23 karma · joined May 27, 2022
int lfstack_pop(_Atomic lfstack_t \*lfstack)
{
lfstack_t next;
lfstack_t orig = atomic_load(lfstack);
do
{
if (orig.head == NULL) // undefined behavior !!!
{
return -1;
}
next.head = orig.head->next;
} while (!atomic_compare_exchange_weak(lfstack,&orig,next));
free(orig.head);
return 0;
}
If the first thread is preempted before the if(...) is executed, and then the second thread executes the entire method, then you will use data after freeing when the first thread resumes. Consider why the boost container doesn't free memory.New processors use 56 bits of virtual address. It doesn't matter if you have that much memory, because addresses are virtual. Also, newer versions of Android do not allow the use of unused address bits.
- Memory managing of concurrent containers. Lock-free algorithms requires GC or the hazard pointers and these are basically based on GC.
- You often need the GC engine when you implementing or integrating another language.
tracked_ptr: 279.95ms (151MB)
shared_ptr: 1035.07ms (480MB)
source: https://godbolt.org/z/jP7ohPehY
The shared_ptr is an optional garbage collection based on reference counting. Slow, leaky, deterministic (that's an advantage and a disadvantage). C++ needs optional garbage collection if needs shared_ptr.