|
|
@@ -0,0 +1,258 @@ |
|
|
// Omar Juma |
|
|
// W01090035 |
|
|
// CSCI 352, ASSIGNMENT 1 |
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
#include "HeapTestEngine.h" |
|
|
|
|
|
#define MIN(A,B) ((A)<(B)?(A):(B)) |
|
|
#define ALIGN(x) (((((x)-1)>>4)<<4)+16) |
|
|
#define HEADER_SIZE 16 |
|
|
#define MIN_UNIT 16 |
|
|
|
|
|
#ifndef DEBUG |
|
|
#define DEBUG 1 |
|
|
#endif |
|
|
|
|
|
/* |
|
|
typedef struct header *Header; |
|
|
|
|
|
struct header { |
|
|
Header *next; |
|
|
unsigned size; |
|
|
|
|
|
size_t size; |
|
|
t_block next; |
|
|
int free; |
|
|
}; |
|
|
*/ |
|
|
//void *base = NULL; |
|
|
//void *root = NULL; |
|
|
|
|
|
union header{ |
|
|
struct { |
|
|
union header *next; |
|
|
unsigned size; |
|
|
//char data[1]; //Pointer to our payload |
|
|
} this; |
|
|
long x; |
|
|
}; |
|
|
typedef union header Header; |
|
|
Header *increase_heap(int size); |
|
|
static Header base; |
|
|
static Header *freep = NULL; |
|
|
unsigned totalBlocks = 0; |
|
|
unsigned totalFreed = 0; |
|
|
struct Header *freeps[9]; |
|
|
int regular = 1; |
|
|
|
|
|
void print_debug(Header *freep){ |
|
|
Header *current = freep; |
|
|
int size; |
|
|
unsigned next_free, next_block; |
|
|
while (freep != NULL){ |
|
|
size = current->this.size; |
|
|
next_free = current->this.next; |
|
|
next_block = (current + (MIN_UNIT * size)); |
|
|
printf("Block at 0x%07x, size %d, next free at 0x%07x, next block at 0x%07x", current, size, next_free, next_block); |
|
|
if (next_free == next_block){ |
|
|
printf("******"); |
|
|
} |
|
|
printf("\n"); |
|
|
current = current->this.next; |
|
|
if(current == freep){ |
|
|
break; |
|
|
} |
|
|
} |
|
|
printf("\n\nBlocks allocated: %u, free: %u, total: %u\n", (totalBlocks-totalFreed), totalFreed, totalBlocks); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
Header *find_first_block(Header *previous , Header *current, int size ){ |
|
|
while (current && (current->this.size < size) ){ |
|
|
if (current == freep){ |
|
|
if ((current = increase_heap(size)) == NULL){ |
|
|
return NULL; |
|
|
} |
|
|
} |
|
|
previous = current; |
|
|
current = current->this.next; |
|
|
} |
|
|
return (current); |
|
|
} |
|
|
|
|
|
void split(Header *current, int size){ |
|
|
//size = size + HEADER_SIZE; |
|
|
current->this.size = current->this.size - size; |
|
|
current = current + size; |
|
|
current->this.size = size; |
|
|
/* |
|
|
temp = ((current + HEADER_SIZE) + size); |
|
|
temp->this.size = (current->this.size - size - HEADER_SIZE); |
|
|
temp->this.next = current->this.next; |
|
|
current->this.size = size; |
|
|
current->this.next = temp; |
|
|
*/ |
|
|
} |
|
|
|
|
|
Header *increase_heap(int size){ |
|
|
Header *current; |
|
|
int amount, sizeBytes; |
|
|
char *ptr; |
|
|
|
|
|
|
|
|
/* |
|
|
if ((HEADER_SIZE + size) > 1024){ |
|
|
amount = 1024; |
|
|
}else { |
|
|
amount = HEADER_SIZE + size; |
|
|
} |
|
|
*/ |
|
|
sizeBytes = size * HEADER_SIZE; |
|
|
amount = MIN(sizeBytes, 1024); |
|
|
|
|
|
|
|
|
//This line gets the addr for the current brake line |
|
|
ptr = sbrk(amount); |
|
|
|
|
|
//Test if sbrk returned error |
|
|
if (ptr == (char *) - 1){ |
|
|
printf("SBRK ERROR!\n"); |
|
|
return NULL; |
|
|
} |
|
|
current = (Header *)ptr; |
|
|
current->this.size = (ALIGN(amount) /16); |
|
|
//current->this.next = NULL; |
|
|
|
|
|
//extra->this.size = 1024 - amount; |
|
|
//if (extra->this.size > 0){ |
|
|
free352((void *)(current+1)); |
|
|
|
|
|
//Only execute if not first initialization |
|
|
//if (previous){ |
|
|
// previous->this.next = current; |
|
|
// } |
|
|
return freep; |
|
|
} |
|
|
|
|
|
void *malloc352(int nbytes){ |
|
|
Header *current, *previous; |
|
|
int size; |
|
|
int listIndex; |
|
|
|
|
|
size = (ALIGN(nbytes) / 16) + 1; |
|
|
|
|
|
if ( (size >= 2) && (size <= 10) ){ |
|
|
listIndex = size-1; |
|
|
}else { |
|
|
listIndex = 0; |
|
|
regular = 0; |
|
|
} |
|
|
freep = freeps[listIndex]; |
|
|
|
|
|
//Check if base needs to be initialized |
|
|
if ((previous = freep) == NULL){ |
|
|
//base = root; |
|
|
previous = &base; |
|
|
freep = previous; |
|
|
base.this.next = freep; |
|
|
base.this.size = 0; |
|
|
} |
|
|
|
|
|
|
|
|
//Verify that the list has been initialized |
|
|
if ((previous = freep) != NULL){ |
|
|
previous = freep; |
|
|
current = previous->this.next; |
|
|
current = find_first_block(previous, current, size); |
|
|
|
|
|
if (current){ |
|
|
//Check to see if we can break block up |
|
|
if ((current->this.size) >= size){ |
|
|
if (current->this.size > (size)){ |
|
|
split(current, size); |
|
|
} |
|
|
else{ |
|
|
previous->this.next = current->this.next; |
|
|
} |
|
|
//previous->this.next = current->this.next; //Used for allocating front end |
|
|
freep = previous; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#ifdef DEBUG |
|
|
totalBlocks += current->this.size; |
|
|
print_debug(freep); |
|
|
#endif |
|
|
return (void *)(current+1); |
|
|
|
|
|
} |
|
|
|
|
|
void *combineList(Header *new){ |
|
|
new->this.next = freep->this.next; |
|
|
freep->this.next = new; |
|
|
} |
|
|
|
|
|
void *combine(Header *current, Header *new){ |
|
|
Header *forward = (new + new->this.size); |
|
|
Header *previous = (current + current->this.size); |
|
|
|
|
|
if(current->this.next == new + new->this.size){ |
|
|
new->this.size += current->this.next->this.size; |
|
|
new->this.next = current->this.next->this.next; |
|
|
}else{ |
|
|
new->this.next = current->this.next; |
|
|
} |
|
|
|
|
|
if(current + current->this.size == new){ |
|
|
current->this.size += new->this.size; |
|
|
current->this.next = new->this.next; |
|
|
}else{ |
|
|
current->this.next = new; |
|
|
} |
|
|
freep = current; |
|
|
|
|
|
} |
|
|
|
|
|
Header *findSpot(Header *new){ |
|
|
Header *current; |
|
|
|
|
|
for (current = freep; !(new > current && new < current->this.next); current = current->this.next){ |
|
|
if (current >= current->this.next && (new > current || new < current->this.next)){ |
|
|
break; |
|
|
} |
|
|
} |
|
|
return current; |
|
|
} |
|
|
|
|
|
|
|
|
void free352(void *ptr){ |
|
|
|
|
|
|
|
|
Header *new = (Header *)ptr -1; |
|
|
#ifdef DEBUG |
|
|
totalFreed += new->this.size; |
|
|
#endif |
|
|
|
|
|
if (regular){ |
|
|
combineList(new); |
|
|
}else{ |
|
|
Header *spot = findSpot(new); |
|
|
combine(spot, new); |
|
|
freep = spot; |
|
|
} |
|
|
|
|
|
#ifdef DEBUG |
|
|
print_debug(freep); |
|
|
#endif |
|
|
} |
|
|
|
|
|
int main(){ |
|
|
|
|
|
heap_test(); |
|
|
|
|
|
return 0; |
|
|
} |