Skip to content

Instantly share code, notes, and snippets.

@andrestc
Created June 14, 2017 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrestc/47ef12f731fba0243ce55d48d015dd80 to your computer and use it in GitHub Desktop.
Save andrestc/47ef12f731fba0243ce55d48d015dd80 to your computer and use it in GitHub Desktop.
/* scan_merge scans the free list in order to find
* continuous free blocks that can be merged and also
* checks if our last free block ends where the program
* break is. If it does, and the free block is larger then
* MIN_DEALLOC then the block is released to the OS, by
* calling brk to set the program break to the begin of
* the block */
void
scan_merge()
{
block_t *curr = head;
unsigned long header_curr, header_next;
unsigned long program_break = (unsigned long)sbrk(0);
if (program_break == 0) {
printf("failed to retrieve program break\n");
return;
}
while (curr->next) {
header_curr = (unsigned long)curr;
header_next = (unsigned long)curr->next;
if (header_curr + curr->size + sizeof(block_t) == header_next) {
/* found two continuous addressed blocks, merge them
* and create a new block with the sum of their sizes */
curr->size += curr->next->size + sizeof(block_t);
curr->next = curr->next->next;
if (curr->next) {
curr->next->prev = curr;
} else {
break;
}
}
curr = curr->next;
}
stats("after merge");
header_curr = (unsigned long)curr;
/* last check if our last free block ends on the program break and is
* big enough to be released to the OS (this check is to reduce the
* number of calls to sbrk/brk */
if (header_curr + curr->size + sizeof(block_t) == program_break
&& curr->size >= MIN_DEALLOC) {
fl_remove(curr);
if (brk(curr) != 0) {
printf("error freeing memory\n");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment