static int write_entry_to_dir(struct file_buffer *dir, char *name, int inode, int type) { struct lmfs_inode_entry *lp = (struct lmfs_inode_entry *)dir->inode_entry; char *buffer = dir->data_buffer + dir->data_pos; u32 *block_buffer = (u32 *)dir->block_buffer; u32 *inode_addr; struct lmfs_dir_entry *dent; if (dir->data_pos == 0) { /* flush data to the data block */ if (dir->data) flush_data(buffer, dir->data); dir->data = pop_block(); if (!dir->data) return -ENOSPC; memset(buffer, 0, 4096); if (dir->lvl1_pos == 0) { debug("allocate new lvl1 block\n"); if (dir->lvl1) flush_data((char *)block_buffer, dir->lvl1); dir->lvl1 = pop_block(); if (!dir->lvl1) return -ENOSPC; memset(block_buffer, 0, 4096); if (dir->lvl0_pos == 32) { return -ENOSPC; } else dir->lvl0_buf[dir->lvl0_pos] = dir->lvl1; } lp->block_nr++; block_buffer[dir->lvl1_pos] = dir->data; } dent = (struct lmfs_dir_entry *)buffer; strcpy(dent, name); dent->type = type; dent->inode_index = inode; dir->data_pos += 256; if (dir->data_pos == 4096) { dir->data_pos = 0; debug("write file entry, data pos is 4096\n"); dir->lvl1 ++; if (dir->lvl1 == 1024) { debug("write file entry, lvl1 pos is 1024\n"); dir->lvl1 = 0; } } lp->file_nr++; update_bitmap(dir); return 0; }
void new_piece(struct piece *held) { held->colour = &palette[rand() % 7 + 1]; held->type = rand()%7; held->rotation= rand()%4; update_bitmap(held); }
void rotate(struct piece *held, int direction) { held->rotation += direction; /* FIXME need to handle direction not in [-4, 4] */ if (held->rotation >= 4) held->rotation -= 4; if (held->rotation < 0) held->rotation += 4; update_bitmap(held); }
void* buddy_alloc(kma_size_t reqSize) { kma_size_t reqBufSize = get_roundup(reqSize); int reqBufClass = get_buf_class(reqBufSize); int bufClass = reqBufClass; void* bufPtr; /* find available buffer on free lists */ while ((budfls->fl[bufClass]).ptr == NULL && bufClass >= 0) { bufClass--; } /* buffer found */ if (bufClass == reqBufClass) { bufPtr = (budfls->fl[bufClass]).ptr; remove_buffer_from_free_list((budfls->fl[bufClass]).ptr, bufClass); update_bitmap(((bufferHeader_t*)bufPtr)->pagePtr, bufPtr, reqBufSize, USED); } else { if (bufClass < 0) { /* no buffer large enough for requested size, need new page */ kpage_t* page = get_page(); *((kpage_t**)page->ptr) = page; budfls->pagesUsed++; header_alloc(page->ptr, PAGEHEADERSIZE); return buddy_alloc(reqSize); } else { /* need to split a larger buffer */ bufPtr = (budfls->fl[bufClass]).ptr; remove_buffer_from_free_list((budfls->fl[bufClass]).ptr, bufClass); get_buffer_from_large_buffer(((bufferHeader_t*)bufPtr)->pagePtr, reqBufSize, (budfls->fl[bufClass]).size, (kma_size_t)(bufPtr - ((bufferHeader_t*)bufPtr)->pagePtr)); update_bitmap(((bufferHeader_t*)bufPtr)->pagePtr, bufPtr, reqBufSize, USED); } } /* update metadata */ ((pageHeader_t*)(((bufferHeader_t*)bufPtr)->pagePtr))->spaceUsed += reqBufSize; return bufPtr; }
uint32_t find_prefix(StorageIterator first, StorageIterator last) { // @see crowley2325::max_block_size() uint32_t size = sak::storage_size(first, last); assert(size <= m_max_block_size); assert(size > 0); std::fill(m_bitmap.begin(), m_bitmap.end(), 0); // Update the bitmap while (first != last) { // Size must be multiple of 4 bytes due to the field 2^32-5 assert((first->m_size % 4) == 0); uint32_t block_size = first->m_size / 4; const uint32_t* block_data = sak::cast_storage<uint32_t>(*first); for (uint32_t i = 0; i < block_size; ++i) { update_bitmap(block_data[i]); } ++first; } uint32_t prefix = 0; bool found = find_in_bitmap(&prefix); assert(found); return prefix; }
void kma_free(void* ptr, kma_size_t size) { void* pagePtr = ptr - ((long)ptr % PAGESIZE); /* buffer occupies one page; free the page */ if (size > PAGESIZE / 2) { kpage_t* page; page = *((kpage_t**)(pagePtr)); budfls->pagesUsed--; void* firstPagePtr = budfls->firstPagePtr; kma_size_t firstPageSpaceUsed = ((pageHeader_t*)(budfls->firstPagePtr))->spaceUsed; short pagesUsed = budfls->pagesUsed; free_page(page); /* if the freed page is the second last page, * and the last page (with the central information) is empty, * free the last page also. */ if (pagePtr != firstPagePtr) { if (firstPageSpaceUsed == 0 && pagesUsed == 1) { printf("freeing first page %lx\n", (unsigned long)firstPagePtr); free_page(((pageHeader_t*)firstPagePtr)->page); budfls = NULL; } } else { budfls = NULL; } return; } kma_size_t bufSize = get_roundup(size); update_bitmap(pagePtr, ptr, bufSize, FREE); ((pageHeader_t*)pagePtr)->spaceUsed -= bufSize; /* free an empty page */ if (((pageHeader_t*)pagePtr)->spaceUsed == 0) { kma_size_t sizeFreed; if (pagePtr == budfls->firstPagePtr) { /* if there are other pages, do not free the page with central information */ if (budfls->pagesUsed > 1) { coalesce(pagePtr, ptr, bufSize); return; } else { sizeFreed = get_roundup(FIRSTPAGEHEADERSIZE); } } else { sizeFreed = get_roundup(PAGEHEADERSIZE); } /* remove all buffers on this page from free lists */ bufferHeader_t* bufPtr = pagePtr + sizeFreed; while (sizeFreed < PAGESIZE) { if ((void*)bufPtr != ptr) { sizeFreed += bufPtr->size; remove_buffer_from_free_list(bufPtr, get_buf_class(bufPtr->size)); bufPtr = (void*)bufPtr + bufPtr->size; } else { sizeFreed += bufSize; bufPtr = (void*)bufPtr + bufSize; } } budfls->pagesUsed--; void* firstPagePtr = budfls->firstPagePtr; free_page(*((kpage_t**)pagePtr)); /* if the freed page is the second last page, * and the last page (with the central information) is empty, * free the last page also. */ if (pagePtr != firstPagePtr) { if (((pageHeader_t*)(budfls->firstPagePtr))->spaceUsed == 0 && budfls->pagesUsed == 1) { free_page(((pageHeader_t*)(budfls->firstPagePtr))->page); budfls = NULL; } } else { budfls = NULL; } return; } /* coalesce the freed buffer */ coalesce(pagePtr, ptr, bufSize); }