in src/clds_hazard_pointers.c [579:622]
void clds_hazard_pointers_release(CLDS_HAZARD_POINTERS_THREAD_HANDLE clds_hazard_pointers_thread, CLDS_HAZARD_POINTER_RECORD_HANDLE clds_hazard_pointer_record)
{
if (clds_hazard_pointer_record == NULL)
{
LogError("Invalid arguments: CLDS_HAZARD_POINTERS_THREAD_HANDLE clds_hazard_pointers_thread=%p, CLDS_HAZARD_POINTER_RECORD_HANDLE clds_hazard_pointer_record=%p",
clds_hazard_pointers_thread, clds_hazard_pointer_record);
}
else
{
// remove it from the hazard pointers list for this thread, this thread is the only one removing
// so no contention on the list
CLDS_HAZARD_POINTER_RECORD_HANDLE previous_hazard_pointer = NULL;
CLDS_HAZARD_POINTER_RECORD_HANDLE clds_hazard_pointer = interlocked_compare_exchange_pointer((void* volatile_atomic*)&clds_hazard_pointers_thread->pointers, NULL, NULL);
(void)interlocked_exchange_pointer(&clds_hazard_pointer_record->node, NULL);
while (clds_hazard_pointer != NULL)
{
if (clds_hazard_pointer == clds_hazard_pointer_record)
{
if (previous_hazard_pointer != NULL)
{
(void)interlocked_exchange_pointer((void* volatile_atomic*)&previous_hazard_pointer->next, clds_hazard_pointer->next);
}
else
{
(void)interlocked_exchange_pointer((void* volatile_atomic*)&clds_hazard_pointers_thread->pointers, clds_hazard_pointer->next);
}
break;
}
else
{
previous_hazard_pointer = clds_hazard_pointer;
clds_hazard_pointer = clds_hazard_pointer->next;
}
}
// insert it in the free list
struct CLDS_HAZARD_POINTER_RECORD_TAG* current_free_pointers = interlocked_compare_exchange_pointer((void* volatile_atomic*)&clds_hazard_pointers_thread->free_pointers, NULL, NULL);
(void)interlocked_exchange_pointer((void* volatile_atomic*)&clds_hazard_pointer_record->next, current_free_pointers);
(void)interlocked_exchange_pointer((void* volatile_atomic*)&clds_hazard_pointers_thread->free_pointers, clds_hazard_pointer_record);
}
}