/* * Merge block with adjacent free blocks * Return: the pointer to the new free block */ static void *coalesce(void *block) { REQUIRES(block != NULL); REQUIRES(in_heap(block)); uint32_t *prev_block = block_prev(block); uint32_t *next_block = block_next(block); int prev_free = block_free(prev_block); int next_free = block_free(next_block); unsigned int words = block_size(block); if (prev_free && next_free) { // Case 4, both free block_delete(prev_block); block_delete(next_block); words += block_size(prev_block) + block_size(next_block) + 4; set_size(prev_block, words); block_mark(prev_block, FREE); block = (void *)prev_block; block_insert(block); ENSURES(in_list(block)); } else if (!prev_free && next_free) { // Case 2, next if free block_delete(next_block); words += block_size(next_block) + 2; set_size(block, words); block_mark(block, FREE); block_insert(block); ENSURES(in_list(block)); } else if (prev_free && !next_free) { // Case 3, prev is free block_delete(prev_block); words += block_size(prev_block) + 2; set_size(prev_block, words); block_mark(prev_block, FREE); block = (void *)prev_block; block_insert(block); ENSURES(in_list(block)); } else { // Case 1, both unfree block_insert(block); ENSURES(in_list(block)); return block; } return block; }
/* * Place the block and potentially split the block * Return: Nothing */ static void place(void *block, unsigned int awords) { REQUIRES(awords >= 2 && awords % 2 == 0); REQUIRES(block != NULL); REQUIRES(in_heap(block)); REQUIRES(in_list(block)); unsigned int cwords = block_size(block); //the size of the given freeblock block_delete(block); // delete block from the seg list ENSURES(!in_list(block)); if ((cwords - awords) >= 4) { set_size(block, awords); block_mark(block, ALLOCATED); block = block_next(block); set_size(block, cwords - awords - 2); block_mark(block, FREE); block_insert(block); ENSURES(in_list(block)); } else { set_size(block, cwords); block_mark(block, ALLOCATED); } }
void packet_delete(struct packet *p) { if (!p) return; if (p->data) block_delete(p->data); if (p->rawdata) free(p->rawdata); free(p); }
void uncompress(image* in, image* out, const float* quantify) { Block block = block_new(); int colBlock = 0; int lineBlock = 0; int kIn = 0; int n,m; out->size = in->h*in->w; out->h = in->h; out->w = in->w; // Iterator on image : block by block for(int i = 0 ; i < in->h * in->w ; i += 64) { kIn = 0; ZIterator zit = zIterator_new(block, 8); // Z Parcours for reposition of blocks block.data[0] = in->data[i]; // First iterator value while(zIterator_hasNext(zit)) { block.data[zit.line*8 + zit.column] = in->data[i + (kIn++)]; zIterator_next(&zit); } block.data[zit.line*8 + zit.column] = in->data[i + (kIn++)]; // last pixel // Quantify for(n = 0; n < 8 ; ++n) { for(m = 0; m < 8 ; ++m) { block.data[n*8 + m] *= quantify[n*8 + m]; } } idct(out, block.data, colBlock, lineBlock); colBlock += 8; if(colBlock >= in->w) { colBlock = 0; lineBlock += 8; } } block_delete(&block); }
/* * realloc - you may want to look at mm-naive.c */ void *realloc(void *oldptr, size_t size) { if (oldptr == NULL) // if oldptr is NULL, this works as malloc(size) return malloc(size); if (size == 0) { // if size is 0, this works as free(oldptr) free(oldptr); return NULL; } uint32_t *block = block_block(oldptr); REQUIRES(in_heap(block)); REQUIRES(!block_free(block)); unsigned int words = block_size(block); // old size in words unsigned int nwords; // new size in words uint32_t * ptr; // temp ptr /* Adjust size to include alignment and convert to multipes of 4 bytes */ if (size <= DSIZE) nwords = 2; else nwords = (((size) + (DSIZE-1)) & ~0x7) / WSIZE; /* if new size is the same as old size or the old size is larger but no larger * than 4 words, return oldptr without spliting */ //printf("RE, words = %d, nwords = %d\n", words, nwords); if (nwords == words || (words > nwords && words - nwords < 4)) return oldptr; else if (nwords < words) { /* if old size is at least 4 words larger than new size * return oldptr with spliting */ set_size(block, nwords); block_mark(block, ALLOCATED); ptr = block_next(block); ENSURES(words - nwords - 2 < words); set_size(ptr, words - nwords - 2); block_mark(ptr, FREE); block_insert(ptr); return oldptr; } else { /* if old size is smaller than new size, look for more space */ ptr = block_next(block); if (block_free(ptr)) { ENSURES(in_list(ptr)); // if next block is free unsigned int owords = block_size(ptr); //size of next blockdd int remain = owords + 2 - (nwords - words); if (remain >= 4) { // the next free block is enough large to split block_delete(ptr); set_size(block, nwords); block_mark(block, ALLOCATED); ptr = block_next(block); set_size(ptr, owords - (nwords - words)); block_mark(ptr, FREE); block_insert(ptr); return oldptr; } else if (remain >= 0) { // the next free block can not split block_delete(ptr); set_size(block, words + owords + 2); block_mark(block, ALLOCATED); return oldptr; } } /* the next free block is too small, or * next block is not free, malloc whole new one. */ ptr = malloc(size); /* Copy the old data. */ memcpy(ptr, oldptr, block_size(block) * WSIZE); /* Free the old block. */ free(oldptr); return ptr; } }