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; }
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; }
/** * 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 }