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