Select Git revision
Forked from
HyukSang Kwon / 1801_OS_assignment4
Source project has a limited visibility.
alloc.c 4.03 KiB
#include "alloc.h"
static meta p_meta = NULL;
void *origin=NULL;
void *m_malloc(size_t size){
if(p_meta == NULL || sbrk(0) == origin){
origin = sbrk(0);
p_meta = sbrk(size + sizeof(struct meta_struct));
p_meta->prev = NULL;
p_meta->next = NULL;
p_meta->size = size;
p_meta->free = 0;
return (void *)(p_meta+sizeof(struct meta_struct));
}
meta new = p_meta;
meta pre = p_meta;
if(fit == 'F'){
while(new){
if( (new->free == 1) && (size <= new->size) ){
break;
}
pre = new;
new = new->next;
}
}
if(fit == 'B'){
meta tmp = NULL;
int chk=0;
while(new){
if( (new->free == 1) && (size <= new->size) ){
if(tmp == NULL)
tmp = new;
if(new->size <= tmp->size){
tmp = new;
chk = 1;
}
}
pre = new;
new = new->next;
}
if(chk == 1)
new = tmp;
}
if(fit == 'W'){
meta tmp = NULL;
int chk=0;
while(new){
if( (new->free == 1) && (size <= new->size) ){
if(tmp == NULL)
tmp = new;
if(new->size >= tmp->size){
tmp = new;
chk = 1;
}
}
pre = new;
new = new->next;
}
if(chk == 1)
new = tmp;
}
if(new == NULL){
new = sbrk(0);
sbrk(size + sizeof(struct meta_struct));
new->prev = pre;
new->next = NULL;
new->size = size;
new->free = 0;
pre->next = new;
return (void *)(new+sizeof(struct meta_struct));
}
else{
pre = new;
new = (void *)(pre + size + sizeof(struct meta_struct));
new->prev = pre;
new->next = pre->next;
new->size = pre->size - size;
new->free = 1;
if(new->next != NULL)
new->next->prev = new;
if(new->size == 0){
if(new->next != NULL)
new->next->prev = new->prev;
new = new->next;
}
pre->next = new;
pre->size = size;
pre->free = 0;
return (void *)(pre + sizeof(struct meta_struct));
}
}
void *m_free(void *ptr){
meta cur = ptr;
cur = (void *)(cur-sizeof(struct meta_struct));
cur->free = 1;
if(cur->prev == NULL && cur->next == NULL){
brk(origin);
}
else if(cur->next == NULL){
cur->prev->next = NULL;
brk(cur);
}
if(cur->next != NULL && cur->next->free == 1){
cur->size = cur->size + cur->next->size;
if(cur->next->next != NULL)
cur->next->next->prev = cur;
cur->next = cur->next->next;
}
if(cur->prev != NULL && cur->prev->free == 1){
cur->prev->size = cur->size + cur->prev->size;
if(cur->prev->prev != NULL)
cur->prev->prev->next = cur->prev;
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
}
}
void *m_realloc(void *ptr,size_t size){
meta new = ptr;
new = (void *)(new-sizeof(struct meta_struct));
if(size > new->size){
if(new->next == NULL){
sbrk(size - new->size);
new->size = size;
return (void *)(new+sizeof(struct meta_struct));
}
else if(new->next != NULL && new->next->free == 1){
if( (new->size + new->next->size) > size){
new->next = (void *)new + sizeof(struct meta_struct) + size;
new->next->size = (new->size + new->next->size) - size;
new->next->prev = new;
new->next->free = 1;
return (void *)(new+sizeof(struct meta_struct));
}
else if((new->size + new->next->size) == size){
new->next = new->next->next;
new->next->next->prev = new;
new->size = size;
return (void *)(new+sizeof(struct meta_struct));
}
else{
meta tmp = m_malloc(size);
memcpy(tmp,new,size);
m_free(ptr);
return (void *)(tmp+sizeof(struct meta_struct));
}
}
else{
meta tmp = m_malloc(size);
tmp = (void *)(tmp-sizeof(struct meta_struct));
memcpy((void *)(tmp+sizeof(struct meta_struct)),
(void *)(new+sizeof(struct meta_struct)),
(size+sizeof(struct meta_struct)));
m_free(ptr);
return (void *)(tmp+sizeof(struct meta_struct));
}
}
else{ // size < ptr->size
meta tmp = (void *)new + sizeof(struct meta_struct) + size;
tmp->prev = new;
tmp->next = new->next;
tmp->next->prev = tmp;
tmp->size = new->size - size;
tmp->free = 1;
new->next = tmp;
new->size = size;
memcpy(new,ptr,(size+sizeof(struct meta_struct)));
return (void *)(new+sizeof(struct meta_struct));
}
}