Exemple #1
0
int test_sky_data_file_add_event_to_end_of_ending_path_causing_block_span() {
    sky_data_file *data_file;
    INIT_DATA_FILE("tests/fixtures/data_files/spanning/a", 0);
    ADD_EVENT_WITH_DATA(10, 12LL, 20, 30, "12345678901234567890123456789");
    ASSERT_DATA_FILE("tests/fixtures/data_files/spanning/j");
    mu_assert_int_equals(data_file->block_count, 3);
    ASSERT_BLOCK(data_file, 0, 0, false);
    ASSERT_BLOCK(data_file, 1, 1, true);
    ASSERT_BLOCK(data_file, 2, 2, true);
    sky_data_file_free(data_file);
    return 0;
}
Exemple #2
0
int test_sky_data_file_add_small_event_to_middle_of_starting_path_causing_block_span() {
    sky_data_file *data_file;
    INIT_DATA_FILE("tests/fixtures/data_files/spanning/a", 0);
    ADD_EVENT_WITH_DATA(3, 9LL, 20, 30, "1234567890");
    ASSERT_DATA_FILE("tests/fixtures/data_files/spanning/c");
    mu_assert_int_equals(data_file->block_count, 3);
    ASSERT_BLOCK(data_file, 0, 0, true);
    ASSERT_BLOCK(data_file, 1, 1, true);
    ASSERT_BLOCK(data_file, 2, 2, false);
    sky_data_file_free(data_file);
    return 0;
}
Exemple #3
0
/**
 * Free a memory block.
 *
 * @param   pHeapInt       The heap.
 * @param   pBlock         The memory block to free.
 */
static void rtHeapOffsetFreeBlock(PRTHEAPOFFSETINTERNAL pHeapInt, PRTHEAPOFFSETBLOCK pBlock)
{
    PRTHEAPOFFSETFREE   pFree = (PRTHEAPOFFSETFREE)pBlock;
    PRTHEAPOFFSETFREE   pLeft;
    PRTHEAPOFFSETFREE   pRight;

#ifdef RTHEAPOFFSET_STRICT
    rtHeapOffsetAssertAll(pHeapInt);
#endif

    /*
     * Look for the closest free list blocks by walking the blocks right
     * of us (both lists are sorted by address).
     */
    pLeft = NULL;
    pRight = NULL;
    if (pHeapInt->offFreeTail)
    {
        pRight = RTHEAPOFF_TO_PTR_N(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETFREE);
        while (pRight && !RTHEAPOFFSETBLOCK_IS_FREE(&pRight->Core))
        {
            ASSERT_BLOCK(pHeapInt, &pRight->Core);
            pRight = RTHEAPOFF_TO_PTR_N(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETFREE);
        }
        if (!pRight)
            pLeft = RTHEAPOFF_TO_PTR_N(pHeapInt, pHeapInt->offFreeTail, PRTHEAPOFFSETFREE);
        else
        {
            ASSERT_BLOCK_FREE(pHeapInt, pRight);
            pLeft = RTHEAPOFF_TO_PTR_N(pHeapInt, pRight->offPrev, PRTHEAPOFFSETFREE);
        }
        if (pLeft)
            ASSERT_BLOCK_FREE(pHeapInt, pLeft);
    }
    AssertMsgReturnVoid(pLeft != pFree, ("Freed twice! pv=%p (pBlock=%p)\n", pBlock + 1, pBlock));
    ASSERT_L(RTHEAPOFF_TO_OFF(pHeapInt, pLeft), RTHEAPOFF_TO_OFF(pHeapInt, pFree));
    Assert(!pRight || (uintptr_t)pRight > (uintptr_t)pFree);
    Assert(!pLeft || RTHEAPOFF_TO_PTR_N(pHeapInt, pLeft->offNext, PRTHEAPOFFSETFREE) == pRight);

    /*
     * Insert at the head of the free block list?
     */
    if (!pLeft)
    {
        Assert(pRight == RTHEAPOFF_TO_PTR_N(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE));
        pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
        pFree->offPrev = 0;
        pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
        if (pRight)
            pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
        else
            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
        pHeapInt->offFreeHead = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    }
    else
    {
        /*
         * Can we merge with left hand free block?
         */
        if (pLeft->Core.offNext == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
        {
            pLeft->Core.offNext = pFree->Core.offNext;
            if (pFree->Core.offNext)
                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
            pHeapInt->cbFree -= pLeft->cb;
            pFree = pLeft;
        }
        /*
         * No, just link it into the free list then.
         */
        else
        {
            pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
            pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
            pFree->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
            pLeft->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
            if (pRight)
                pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
            else
                pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
        }
    }

    /*
     * Can we merge with right hand free block?
     */
    if (    pRight
        &&  pRight->Core.offPrev == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
    {
        /* core */
        pFree->Core.offNext = pRight->Core.offNext;
        if (pRight->Core.offNext)
            RTHEAPOFF_TO_PTR(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);

        /* free */
        pFree->offNext = pRight->offNext;
        if (pRight->offNext)
            RTHEAPOFF_TO_PTR(pHeapInt, pRight->offNext, PRTHEAPOFFSETFREE)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
        else
            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
        pHeapInt->cbFree -= pRight->cb;
    }

    /*
     * Calculate the size and update free stats.
     */
    pFree->cb = (pFree->Core.offNext ? pFree->Core.offNext : pHeapInt->cbHeap)
              - RTHEAPOFF_TO_OFF(pHeapInt, pFree) - sizeof(RTHEAPOFFSETBLOCK);
    pHeapInt->cbFree += pFree->cb;
    ASSERT_BLOCK_FREE(pHeapInt, pFree);

#ifdef RTHEAPOFFSET_STRICT
    rtHeapOffsetAssertAll(pHeapInt);
#endif
}
/**
 * Free a memory block.
 *
 * @param   pHeapInt       The heap.
 * @param   pBlock         The memory block to free.
 */
static void rtHeapSimpleFreeBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, PRTHEAPSIMPLEBLOCK pBlock)
{
    PRTHEAPSIMPLEFREE   pFree = (PRTHEAPSIMPLEFREE)pBlock;
    PRTHEAPSIMPLEFREE   pLeft;
    PRTHEAPSIMPLEFREE   pRight;

#ifdef RTHEAPSIMPLE_STRICT
    rtHeapSimpleAssertAll(pHeapInt);
#endif

    /*
     * Look for the closest free list blocks by walking the blocks right
     * of us (both lists are sorted by address).
     */
    pLeft = NULL;
    pRight = NULL;
    if (pHeapInt->pFreeTail)
    {
        pRight = (PRTHEAPSIMPLEFREE)pFree->Core.pNext;
        while (pRight && !RTHEAPSIMPLEBLOCK_IS_FREE(&pRight->Core))
        {
            ASSERT_BLOCK(pHeapInt, &pRight->Core);
            pRight = (PRTHEAPSIMPLEFREE)pRight->Core.pNext;
        }
        if (!pRight)
            pLeft = pHeapInt->pFreeTail;
        else
        {
            ASSERT_BLOCK_FREE(pHeapInt, pRight);
            pLeft = pRight->pPrev;
        }
        if (pLeft)
            ASSERT_BLOCK_FREE(pHeapInt, pLeft);
    }
    AssertMsgReturnVoid(pLeft != pFree, ("Freed twice! pv=%p (pBlock=%p)\n", pBlock + 1, pBlock));
    ASSERT_L(pLeft, pFree);
    Assert(!pRight || (uintptr_t)pRight > (uintptr_t)pFree);
    Assert(!pLeft || pLeft->pNext == pRight);

    /*
     * Insert at the head of the free block list?
     */
    if (!pLeft)
    {
        Assert(pRight == pHeapInt->pFreeHead);
        pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
        pFree->pPrev = NULL;
        pFree->pNext = pRight;
        if (pRight)
            pRight->pPrev = pFree;
        else
            pHeapInt->pFreeTail = pFree;
        pHeapInt->pFreeHead = pFree;
    }
    else
    {
        /*
         * Can we merge with left hand free block?
         */
        if (pLeft->Core.pNext == &pFree->Core)
        {
            pLeft->Core.pNext = pFree->Core.pNext;
            if (pFree->Core.pNext)
                pFree->Core.pNext->pPrev = &pLeft->Core;
            pHeapInt->cbFree -= pLeft->cb;
            pFree = pLeft;
        }
        /*
         * No, just link it into the free list then.
         */
        else
        {
            pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
            pFree->pNext = pRight;
            pFree->pPrev = pLeft;
            pLeft->pNext = pFree;
            if (pRight)
                pRight->pPrev = pFree;
            else
                pHeapInt->pFreeTail = pFree;
        }
    }

    /*
     * Can we merge with right hand free block?
     */
    if (    pRight
        &&  pRight->Core.pPrev == &pFree->Core)
    {
        /* core */
        pFree->Core.pNext = pRight->Core.pNext;
        if (pRight->Core.pNext)
            pRight->Core.pNext->pPrev = &pFree->Core;

        /* free */
        pFree->pNext = pRight->pNext;
        if (pRight->pNext)
            pRight->pNext->pPrev = pFree;
        else
            pHeapInt->pFreeTail = pFree;
        pHeapInt->cbFree -= pRight->cb;
    }

    /*
     * Calculate the size and update free stats.
     */
    pFree->cb = (pFree->Core.pNext ? (uintptr_t)pFree->Core.pNext : (uintptr_t)pHeapInt->pvEnd)
              - (uintptr_t)pFree - sizeof(RTHEAPSIMPLEBLOCK);
    pHeapInt->cbFree += pFree->cb;
    ASSERT_BLOCK_FREE(pHeapInt, pFree);

#ifdef RTHEAPSIMPLE_STRICT
    rtHeapSimpleAssertAll(pHeapInt);
#endif
}