Skip to content
Snippets Groups Projects
Select Git revision
  • 903b884818af0cc5f0180b4ef11e06bf2ba1a0a1
  • master default
2 results

alloc.c

Blame
  • 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));
    	}
    }