void clds_hazard_pointers_release()

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);
    }
}