예제 #1
0
static size_t allocatedMemoryInVolume(memvolume_t *volume)
{
    memblock_t *block;
    size_t total = 0;

    for (block = volume->zone->blockList.next; !isRootBlock(volume, block);
        block = block->next)
    {
        if (!isFreeBlock(block))
        {
            total += block->size;
        }
    }
    return total;
}
예제 #2
0
	//-------------------------------------------------------------------------------------------------------------------
	void* MemoryPool::findAllocated(void* _start) const
	{
		// Determine start chunk and start block for searching
		// by the specified "_start" pointer.
		Chunk* chunk;
		Block* block;
		if(_start)
		{
			// Continue searching.
			chunk = findChunkByPointer(_start);
			void* beginBlocks = &(chunk->blocks[0]);
			size_t blockIndex = ((size_t) _start - (size_t) beginBlocks) / mRealBlockSize;
			++blockIndex;
			block = (Block*) ((size_t) beginBlocks + mRealBlockSize * blockIndex);
		}
		else
		{
			// Start searching.
			if(!mFirstChunk)
				return nullptr;
			chunk = mFirstChunk;;
			block = &(mFirstChunk->blocks[0]);
		}

		// Search next allocated block.
		while(chunk)
		{
			// Check blocks in the current chunk
			void* beginBlocks = &(chunk->blocks[0]);
			void* endBlocks = (void*) ((size_t) beginBlocks + chunk->numBlocks * mRealBlockSize);
			while( (void*) block < endBlocks)
			{
				if(!isFreeBlock(block))
					return block;
				block = (Block*) ((size_t) block + mRealBlockSize);
			}

			// Go to the next chunk.
			chunk = chunk->nextChunk;
			if(chunk)
				block = &(chunk->blocks[0]);
		}

		// Not found.
		return nullptr;
	}
예제 #3
0
/**
 * The static rovers should be rewound back near the beginning of the volume
 * periodically in order for them to be effective. Currently this is done
 * whenever tag ranges are purged (e.g., before map changes).
 */
static void rewindStaticRovers(void)
{
    memvolume_t *volume;
    for (volume = volumeRoot; volume; volume = volume->next)
    {
        memblock_t *block;
        for (block = volume->zone->blockList.next;
            !isRootBlock(volume, block); block = block->next)
        {
            // Let's find the first free block at the beginning of the volume.
            if (isFreeBlock(block))
            {
                volume->zone->staticRover = block;
                break;
            }
        }
    }
}
예제 #4
0
bool Board::isPossibleMovement(int pX, int pY, int pPiece, int pRotation){
	for(int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++){
		for(int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++){
			// Check if the piece is outside the limits of the board
			if(i1 < 0 || i1 >= BOARD_WIDTH || j1 >= BOARD_HEIGHT){
				if(mPieces->getBlockType(pPiece, pRotation, j2, i2) != 0){
					return false;
				}
			}
			// Check if the piece have collisioned with a block already stored in the map
			if(j1 >= 0){
				if(mPieces->getBlockType(pPiece, pRotation, j2, i2) != 0 && !isFreeBlock(i1, j1)){
					return false;
				}
			}
		}
	}
	return true;
}
예제 #5
0
static __inline memblock_t *rewindRover(memvolume_t *vol, memblock_t *rover, int maxSteps, size_t optimal)
{
    memblock_t *base = rover;
    size_t prevBest = 0;
    int i;

    rover = rover->prev;
    for (i = 0; i < maxSteps && !isRootBlock(vol, rover); ++i)
    {
        // Looking for the smallest suitable free block.
        if (isFreeBlock(rover) && rover->size >= optimal && (!prevBest || rover->size < prevBest))
        {
            // Let's use this one.
            prevBest = rover->size;
            base = rover;
        }
        rover = rover->prev;
    }
    return base;
}
예제 #6
0
void fillMap()
{
	srand((unsigned int) time(NULL));

	int t_blocks = gRandom(25,8);
	int sal;
	initMap();

	for (int i = 0; i < t_blocks; i++)
	{
		sal = 0;
		while(!sal)
		{
			int n_level = gRandom(5,15);
			int b = gRandom(11,0);
			int c = gRandom(7,1);
			int j = 0; 

			while (j < BOARD_WIDTH)  
			{  
				if (map[j][n_level] == 0) //Checks if the row is fill or not
				{
					break;  
				}

				j++;  
			}  
  
			if (j == BOARD_WIDTH) //If it's fill doesn't put more blocks on this
			{
				continue;
			}
			
			if (isFreeBlock(b, n_level))
			{
				map[b][n_level] = c; //Put a block in the random position
				sal = 1;
			}
		}
	}
}
예제 #7
0
void drawBoard(Board *theBoard, Game *theGame )
{
    int mx1 = BOARD_POSITION - (BLOCK_SIZE * (BOARD_WIDTH / 2));
    int mx2 = BOARD_POSITION + (BLOCK_SIZE * (BOARD_WIDTH / 2));
    int my = SCREEN_HEIGHT - (BLOCK_SIZE * BOARD_HEIGHT);
    
    drawRectangle(mx1 - BOARD_LINE_WIDTH, my, mx1, SCREEN_HEIGHT - 1, "blue");
    drawRectangle(mx2, my, mx2 + BOARD_LINE_WIDTH, SCREEN_HEIGHT - 1, "blue");
    for(int i = BOARD_POSITION - (BOARD_WIDTH / 2) - 1; i < BOARD_POSITION + (BOARD_WIDTH / 2)+1; i++){
        terminal_color(color_from_name("blue"));
        terminal_put(i, 24, 0x2588);
    }
    //mx1 += 1;

    for (int i = 0; i < BOARD_WIDTH; i++){
        for(int j = 0; j < BOARD_HEIGHT; j++){
            if (!isFreeBlock(theBoard, i, j)){
                terminal_color(color_from_name("red"));
                terminal_put(mx1 + i, my+ j-1, 0x2588);
            }
        }
    }
}
예제 #8
0
void *Z_Malloc(size_t size, int tag, void *user)
{
    memblock_t *start, *iter;
    memvolume_t *volume;

    if (tag < PU_APPSTATIC || tag > PU_PURGELEVEL)
    {
        App_Log(DE2_LOG_WARNING, "Z_Malloc: Invalid purgelevel %i, cannot allocate memory.", tag);
        return NULL;
    }
    if (!size)
    {
        // You can't allocate "nothing."
        return NULL;
    }

    lockZone();

    // Align to pointer size.
    size = ALIGNED(size);

    // Account for size of block header.
    size += sizeof(memblock_t);

    // Iterate through memory volumes until we can find one with enough free
    // memory. (Note: we *will *find one that's large enough.)
    for (volume = volumeRoot; ; volume = volume->next)
    {
        uint numChecked = 0;
        dd_bool gotoNextVolume = false;

        if (volume == NULL)
        {
            // We've run out of volumes.  Let's allocate a new one
            // with enough memory.
            size_t newVolumeSize = MEMORY_VOLUME_SIZE;

            if (newVolumeSize < size + 0x1000)
                newVolumeSize = size + 0x1000; // with some spare memory

            volume = createVolume(newVolumeSize);
        }

        if (isVolumeTooFull(volume))
        {
            // We should skip this one.
            continue;
        }

        DENG_ASSERT(volume->zone);

        // Scan through the block list looking for the first free block of
        // sufficient size, throwing out any purgable blocks along the
        // way.

        if (tag == PU_APPSTATIC || tag == PU_GAMESTATIC)
        {
            // Appstatic allocations may be around for a long time so make sure
            // they don't litter the volume. Their own rover will keep them as
            // tightly packed as possible.
            iter = volume->zone->staticRover;
        }
        else
        {
            // Everything else is allocated using the rover.
            iter = volume->zone->rover;
        }
        assert(iter->prev);

        // Back up a little to see if we have some space available nearby.
        start = iter = rewindRover(volume, iter, 3, size);
        numChecked = 0;

        // If the start is in a sequence, move it to the beginning of the
        // entire sequence. Sequences are handled as a single unpurgable entity,
        // so we can stop checking at its start.
        if (start->seqFirst)
        {
            start = start->seqFirst;
        }

        // We will scan ahead until we find something big enough.
        for ( ; !(isFreeBlock(iter) && iter->size >= size); numChecked++)
        {
            // Check for purgable blocks we can dispose of.
            if (!isFreeBlock(iter))
            {
                if (iter->tag >= PU_PURGELEVEL)
                {
                    memblock_t *old = iter;
                    iter = iter->prev; // Step back.
#ifdef LIBDENG_FAKE_MEMORY_ZONE
                    freeBlock(old->area, &start);
#else
                    freeBlock((byte *) old + sizeof(memblock_t), &start);
#endif
                }
                else
                {
                    if (iter->seqFirst)
                    {
                        // This block is part of a sequence of blocks, none of
                        // which can be purged. Skip the entire sequence.
                        iter = iter->seqFirst->seqLast;
                    }
                }
            }

            // Move to the next block.
            iter = advanceBlock(volume, iter);

            // Ensure that iter will eventually touch start.
            assert(!start->seqFirst || start->seqFirst == start ||
                   !start->seqFirst->prev->seqFirst ||
                   start->seqFirst->prev->seqFirst == start->seqFirst->prev->seqLast);

            if (iter == start && numChecked > 0)
            {
                // Scanned all the way through, no suitable space found.
                gotoNextVolume = true;
                App_Log(DE2_LOG_DEBUG,
                        "Z_Malloc: gave up on volume after %i checks", numChecked);
                break;
            }
        }

        // At this point we've found/created a big enough block or we are
        // skipping this volume entirely.

        if (gotoNextVolume) continue;

        // Found a block big enough.
        if (iter->size - size > MINFRAGMENT)
        {
            splitFreeBlock(iter, size);
        }

#ifdef LIBDENG_FAKE_MEMORY_ZONE
        iter->areaSize = size - sizeof(memblock_t);
        iter->area = M_Malloc(iter->areaSize);
#endif

        if (user)
        {
            iter->user = user;      // mark as an in use block
#ifdef LIBDENG_FAKE_MEMORY_ZONE
            *(void **) user = iter->area;
#else
            *(void **) user = (void *) ((byte *) iter + sizeof(memblock_t));
#endif
        }
        else
        {
            // An owner is required for purgable blocks.
            DENG_ASSERT(tag < PU_PURGELEVEL);

            iter->user = MEMBLOCK_USER_ANONYMOUS; // mark as in use, but unowned
        }
        iter->tag = tag;

        if (tag == PU_MAPSTATIC)
        {
            // Level-statics are linked into unpurgable sequences so they can
            // be skipped en masse.
            iter->seqFirst = iter;
            iter->seqLast = iter;
            if (iter->prev->seqFirst)
            {
                iter->seqFirst = iter->prev->seqFirst;
                iter->seqFirst->seqLast = iter;
            }
        }
        else
        {
            // Not part of a sequence.
            iter->seqLast = iter->seqFirst = NULL;
        }

        // Next allocation will start looking here, at the rover.
        if (tag == PU_APPSTATIC || tag == PU_GAMESTATIC)
        {
            volume->zone->staticRover = advanceBlock(volume, iter);
        }
        else
        {
            volume->zone->rover = advanceBlock(volume, iter);
        }

        // Keep tabs on how much memory is used.
        volume->allocatedBytes += iter->size;

        iter->volume = volume;
        iter->id = LIBDENG_ZONEID;

        unlockZone();

#ifdef LIBDENG_FAKE_MEMORY_ZONE
        return iter->area;
#else
        return (void *) ((byte *) iter + sizeof(memblock_t));
#endif
    }
}