Example #1
0
int64
MediaBlockMapWriter::WriteFrames(void* buffer, int64 frameCount)
{
    MediaBlock* block = CurrentBlock();

    int64 remaining = frameCount;
    int64 totalWrite = 0;
    int64 offset = 0;
    while (remaining > 0) {

        if (block == NULL || block->CurrentFrame() == MEDIA_BLOCK_MAX_FRAMES) {
            block = NextBlock();

            if (block == NULL)
                block = RequestBlock();
        }

        int64 writeSize = 0;
        int64 freeSize = MEDIA_BLOCK_MAX_FRAMES-block->CurrentFrame();

        printf("Got a block %d available space from block %"
               B_PRId64 " we want to write %" B_PRId64 "\n",
               (int)fCurrentIndex, freeSize, remaining);

        if (freeSize < remaining) {
            writeSize = freeSize;
            remaining -= freeSize;
        } else {
            writeSize = remaining;
            remaining -= writeSize;
        }

        totalWrite += block->WriteFrames(buffer+offset,
                                         writeSize);
        offset += writeSize;
        block->SetFlushed(false);

        printf("Data written %" B_PRId64 "available %"
               B_PRId64 "\n", writeSize,
               MEDIA_BLOCK_MAX_FRAMES - block->CurrentFrame());
    }
    return totalWrite;
}
Example #2
0
	TByte* CMemPool::GetMemory(unsigned int size)
	{
		ASSERT(size > 0);
#ifdef _THREAD_SAFE
		EnterCriticalSection(&m_CriticalSection);
#endif
		PMemoryBlock pMemoryBlock = RequestBlock(size);

#ifdef _THREAD_SAFE
		LeaveCriticalSection(&m_CriticalSection);
#endif
		if (pMemoryBlock)
		{
			return pMemoryBlock->pData;
		}
		else
		{
			return NULL;
		}
	}
Example #3
0
    TEST_F(GlobalAllocatorTest, RequestBlock)
	{
		auto instance = gcix::GlobalAllocator::Instance;
		ASSERT_NE(nullptr, instance);

		// Check internals
		ASSERT_EQ(0, instance->Chunks.Count());

		// Request a memory block
		auto blockData0 = instance->RequestBlock(false);
		ASSERT_EQ(1, instance->Chunks.Count());

		// Gets the chunk
		auto chunk0 = instance->Chunks[0];
		ASSERT_NE(nullptr, chunk0);

		// Check that a chunk has the same address as the first block data
		EXPECT_EQ((void*)chunk0, (void*)blockData0);

        EXPECT_TRUE(chunk0->IsFree());
        EXPECT_TRUE(chunk0->HasFreeBlocks());
        EXPECT_FALSE(chunk0->HasRecyclableBlocks());

		// Check block count per chunk
		EXPECT_EQ(Constants::BlockCountPerChunk, chunk0->GetBlockCount());

		// Check allocated blocks
		for (int i = 0; i < chunk0->GetBlockCount(); i++)
		{
			auto block = chunk0->GetBlock(i);

			if (i == 0)
			{
				EXPECT_EQ(block, blockData0);
			}

			EXPECT_TRUE(block->IsFree());
			EXPECT_FALSE(block->IsRecyclable());
			EXPECT_FALSE(block->IsUnavailable());

			// Check that all block data are aligned on a block size
			EXPECT_EQ(0, (intptr_t)block & Constants::BlockSizeInBytesMask);

            // Check line flags are empty
            for (uint32_t lineIndex = Constants::HeaderLineCount; lineIndex < Constants::LineCount; lineIndex++)
            {
                EXPECT_EQ(LineFlags::Empty, block->Header.LineFlags[lineIndex]);

                // Check line datas are empty
                for (uint32_t columnIndex = 0; columnIndex < Constants::LineSizeInBytes; columnIndex++)
                {
                    EXPECT_EQ(0, block->Lines[lineIndex][columnIndex]);
                }
            }
		}

		// Check Bump cursor in BlockData, must be equal to the header size
		EXPECT_EQ(Constants::HeaderSizeInBytes, blockData0->Header.Info.BumpCursor);

		// Check BumpCursorLimit = 0
		EXPECT_EQ(0, blockData0->Header.Info.BumpCursorLimit);

		// Check Chunk min/max memory
		auto minChunkAddress = chunk0;
		auto maxChunkAddress = (Chunk*)((intptr_t)chunk0 + Constants::BlockSizeInBytes * Constants::BlockCountPerChunk);

		// Check pointers inside the chunk
		EXPECT_TRUE(instance->Chunks.Contains(chunk0));
		EXPECT_TRUE(instance->Chunks.Contains((Chunk*)((intptr_t)maxChunkAddress - 1)));

		// Check pointers outside the chunk
		EXPECT_FALSE(instance->Chunks.Contains((Chunk*)((intptr_t)chunk0 - 1)));
		EXPECT_FALSE(instance->Chunks.Contains(maxChunkAddress));

		// Allocate remaining blocks into the chunk
		for (int i = 1; i < chunk0->GetBlockCount(); i++)
		{
			auto nextBlock = instance->RequestBlock(false);
			EXPECT_TRUE(instance->Chunks.Contains((Chunk*)nextBlock));
		}

		// Reallocate a new block from a new chunk
		auto nextBlockOfNextChunj = instance->RequestBlock(false);
		auto nextChunk = (Chunk*)nextBlockOfNextChunj;
		EXPECT_TRUE(nextChunk < minChunkAddress || nextChunk > maxChunkAddress);

		// Recycle freshly allocated block, as they have not been marked, the nextChunk must be freed by the recycle
		// while the firstChunk must be kept for future allocation.
		instance->Recycle();
		EXPECT_EQ(1, instance->Chunks.Count());

		// TODO Add tests after recycle

	}