int64_t TQUEUE_LL_GET_VOLATILE_COUNT()

in common/inc/c_pal/tqueue_ll.h [507:548]


int64_t TQUEUE_LL_GET_VOLATILE_COUNT(C)(TQUEUE_LL(T) tqueue)                                                                                                        \
{                                                                                                                                                                   \
    int64_t result;                                                                                                                                                 \
    /* Codes_SRS_TQUEUE_22_001: [ If tqueue is NULL then TQUEUE_GET_VOLATILE_COUNT(T) shall return zero. ]*/                                                        \
    if (tqueue == NULL)                                                                                                                                             \
    {                                                                                                                                                               \
        LogError("Invalid arguments: TQUEUE_LL(" MU_TOSTRING(T) ") tqueue=%p.", tqueue);                                                                            \
        result = 0;                                                                                                                                                 \
    }                                                                                                                                                               \
    else                                                                                                                                                            \
    {                                                                                                                                                               \
        TQUEUE_TYPEDEF_NAME(T)* tqueue_ptr = THANDLE_GET_T(TQUEUE_TYPEDEF_NAME(T))(tqueue);                                                                         \
        /* Codes_SRS_TQUEUE_01_080: [ TQUEUE_GET_VOLATILE_COUNT(T) shall acquire in shared mode the lock used to guard the growing of the queue. ] */               \
        srw_lock_ll_acquire_shared(&tqueue_ptr->resize_lock);                                                                                                       \
        {                                                                                                                                                           \
            int64_t current_tail = 0;                                                                                                                               \
            int64_t current_head = 0;                                                                                                                               \
            do                                                                                                                                                      \
            {                                                                                                                                                       \
                /* Codes_SRS_TQUEUE_22_003: [ TQUEUE_GET_VOLATILE_COUNT(T) shall obtain the current tail queue by calling interlocked_add_64. ]*/                   \
                current_tail = interlocked_add_64(&tqueue_ptr->tail, 0);                                                                                            \
                /* Codes_SRS_TQUEUE_22_002: [ TQUEUE_GET_VOLATILE_COUNT(T) shall obtain the current head queue by calling interlocked_add_64. ]*/                   \
                current_head = interlocked_add_64(&tqueue_ptr->head, 0);                                                                                            \
                /* Codes_SRS_TQUEUE_22_006: [ TQUEUE_GET_VOLATILE_COUNT(T) shall obtain the current tail queue again by calling interlocked_add_64 and compare with the previosuly obtained tail value.  The tail value is valid only if it has not changed. ]*/   \
            } while (current_tail != interlocked_add_64(&tqueue_ptr->tail, 0));                                                                                     \
                                                                                                                                                                    \
            if (current_tail >= current_head)                                                                                                                       \
            {                                                                                                                                                       \
                /* Codes_SRS_TQUEUE_22_004: [ If the queue is empty (current tail >= current head), TQUEUE_GET_VOLATILE_COUNT(T) shall return zero. ]*/             \
                result = 0;                                                                                                                                         \
            }                                                                                                                                                       \
            else                                                                                                                                                    \
            {                                                                                                                                                       \
                /* Codes_SRS_TQUEUE_22_005: [ TQUEUE_GET_VOLATILE_COUNT(T) shall return the item count of the queue. ]*/                                            \
                result = current_head - current_tail;                                                                                                               \
            }                                                                                                                                                       \
            /* Codes_SRS_TQUEUE_01_081: [ TQUEUE_GET_VOLATILE_COUNT(T) shall release in shared mode the lock used to guard the growing of the queue. ] */           \
            srw_lock_ll_release_shared(&tqueue_ptr->resize_lock);                                                                                                   \
        }                                                                                                                                                           \
    }                                                                                                                                                               \
    return result;                                                                                                                                                  \
}                                                                                                                                                                   \