コード例 #1
0
void CopiedSpace::doneFillingBlock(CopiedBlock* block)
{
    ASSERT(block);
    ASSERT(block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
    ASSERT(m_inCopyingPhase);

    if (block->m_offset == block->payload()) {
        recycleBlock(block);
        return;
    }

    {
        MutexLocker locker(m_toSpaceLock);
        m_toSpace->push(block);
        m_toSpaceSet.add(block);
        m_toSpaceFilter.add(reinterpret_cast<Bits>(block));
    }

    {
        MutexLocker locker(m_loanedBlocksLock);
        ASSERT(m_numberOfLoanedBlocks > 0);
        m_numberOfLoanedBlocks--;
        if (!m_numberOfLoanedBlocks)
            m_loanedBlocksCondition.signal();
    }
}
コード例 #2
0
/**
  * Refresh the physical pages associated with the file table.
  * Any logical blocks marked for deletion on those pages are recycled back to UNUSED.
  *
  * @return MICROBIT_OK on success.
  */
int MicroBitFileSystem::recycleFileTable()
{
    bool pageRecycled = false;
    
    for (uint16_t block = 0; block < fileSystemSize; block++)
    {
        // if we just crossed a page boundary, reset pageRecycled.
        if (block % (PAGE_SIZE / MBFS_BLOCK_SIZE) == 0)
            pageRecycled = false;

        if (fileSystemTable[block] == MBFS_DELETED && !pageRecycled)
        {
            recycleBlock(block);
            pageRecycled = true;
        }
    }

    // now, recycle the FileSystemTable itself, upcycling entries marked as DELETED to UNUSED as we go.
    for (uint16_t block = 0; getPage(block) < (uint32_t *)rootDirectory; block += PAGE_SIZE / MBFS_BLOCK_SIZE)
        recycleBlock(block);

    return MICROBIT_OK;
}
コード例 #3
0
ファイル: Block.cpp プロジェクト: 3qwasd/jobs
void Block::release(){
	if(this->shapes != NULL)
		for(size_t i = 0 ; i != 4 ; i++){
			if(this->shapes[this->currShape-1] != NULL){
				recycleBlock(this->shapes[this->currShape-1],this->height);
				this->currShape = this->currShape >= 4 ? 1 : 1 + this->currShape;
				size_t temp = this->height;
				this->height = this->width;
				this->width = temp;
			}
		}

	this->rect = this->getRect();
	if(rect != NULL)
		delete this->rect;
	
	delete [] this->shapes;
}
コード例 #4
0
/**
  * Allocate a free DiretoryEntry in the given directory, extending and refreshing the directory block if necessary.
  *
  * @param directory The directory to add a DirectoryEntry to
  * @return A pointer to the new DirectoryEntry for the given file, or NULL if it was not possible to allocated resources.
  */
DirectoryEntry* MicroBitFileSystem::createDirectoryEntry(DirectoryEntry *directory)
{
    Directory *dir;
    uint16_t block;
    DirectoryEntry *dirent;
    DirectoryEntry *empty = NULL;
    DirectoryEntry *invalid = NULL;

    // Try to find an unused entry in the directory.
    block = directory->first_block;
    dir = (Directory *)getBlock(block);
    dirent = &dir->entry[0];

    // Iterate through the directory entries until we find and unused entry, or run out of space.
    while (1)
    {
        // Scan through each of the blocks in the directory
        if ((uint32_t)(dirent+1) > (uint32_t)dir + MBFS_BLOCK_SIZE)
        {
            block = getNextFileBlock(block);
            if (block == MBFS_EOF)
                break;

            dir = (Directory *)getBlock(block);
            dirent = &dir->entry[0];
        }

        // If we find an empty slot, use that.
        if (dirent->flags & MBFS_DIRECTORY_ENTRY_FREE)
        {
            empty = dirent;
            break;
        }

        // Record the first invalid block we find (used, but then deleted).
        if ((dirent->flags & MBFS_DIRECTORY_ENTRY_VALID) == 0 && invalid == NULL)
            invalid = dirent;

        // Move onto the next entry.
        dirent++;
    }


    // Now choose the best available slot, giving preference to entries that would avoid a FLASH page erase opreation.
    dirent = NULL;

    // Ideally, choose an unused entry within an existing block.
    if (empty)
    {
        dirent = empty;
    }

    // if not possible, try to re-use a second-hand block that has been freed. This will result in an erase operation of the block,
    // but will not consume any more resources.
    else if (invalid)
    {
        dirent = invalid;
        uint16_t b = getBlockNumber(dirent);
        recycleBlock(b, MBFS_BLOCK_TYPE_DIRECTORY);
    }

    // If nothing is available, extend the directory with a new block.
    else
    {
        // Allocate a new logical block
        uint16_t newBlock = getFreeBlock();
        if (newBlock == 0)
            return NULL;

        // Append this to the directory
        uint16_t lastBlock = directory->first_block;
        while (getNextFileBlock(lastBlock) != MBFS_EOF)
            lastBlock = getNextFileBlock(lastBlock);

        // Append the block.
        fileTableWrite(lastBlock, newBlock);
        fileTableWrite(newBlock, MBFS_EOF);

        dirent = (DirectoryEntry *)getBlock(newBlock);
    }

    return dirent;
}