Skip to content
Snippets Groups Projects
Commit 91a22009 authored by 강병수's avatar 강병수
Browse files

complete functions

parent 81530590
No related branches found
No related tags found
No related merge requests found
Operating system Assignment 4 # Operating system Assignment 4
===================
## TA Info & Assignment URL
TA Info & Assignment URL
--- ---
- TA Mail: ckai22@ajou.ac.kr - TA Mail: ckai22@ajou.ac.kr
- TA gitlab: http://git.ajou.ac.kr/ckai22 - TA gitlab: <http://git.ajou.ac.kr/ckai22>
## File Info
File Info
--- ---
- **main.c**: Implements input and output - **main.c**: Implements input and output
- **alloc.h**: Implements meta structure - **alloc.h**: Implements meta structure
- **alloc.c**: Implements malloc, free, and realloc - **alloc.c**: Implements malloc, free, and realloc
- **Makefile**: compiles the - **Makefile**: compiles the
- **input** directory: saves the input file - **input** directory: saves the input file
TEST ## TEST
---
##### Test proceeds as follows.
--- ---
### **Test proceeds as follows**
1. Input File name to the main function parameter. 1. Input File name to the main function parameter.
2. Read File (File IO) 2. Read File (File IO)
3. Interpret commands in File 3. Interpret commands in File
4. Output to stdout 4. Output to stdout
##### **Command structure in File** ### **Command structure in File**
- - -
"Number of command lines" "Fit"<br>
"Command" "Contents"<br>
"Command" "Contents"<br>
...<br>
##### **Fit type (case sensitive)** "Number of command lines" "Fit"
- - - "Command" "Contents"
F: first fit<br> "Command" "Contents"
B: Best fit<br> ...
W: worst fit<br>
##### **Command type** ### **Fit type (case sensitive)**
- - -
**s** String: String The command to put the value into<br>
**f** n: nth allocation area free<br>
**r** n m: reallocation with m bytes in the nth allocation area<br>
**e** n: Allocate space without contents to n bytes<br>
##### **Output** F: first fit
- - - B: Best fit
“Free" "size" "content (if command is m only)"<br> W: worst fit
"Free" "size" "content (if command is m only)"<br>
...<br>
##### **Example** ### **Command type**
- - -
E1)<br> **s** String: String The command to put the value into
**Input**<br> **f** n: nth allocation area free
3 F<br> **r** n m: reallocation with m bytes in the nth allocation area
m Think like a man of action and act like man of thought.<br> **e** n: Allocate space without contents to n bytes
m Courage is very important. Like a muscle, it is strengthened by use.<br>
m Life is the art of drawing sufficient conclusions from insufficient premises.<br> ### **Output**
**Output**<br>
0 56 Think like a man of action and act like man of thought.<br>
0 72 Courage is very important. Like a muscle, it is strengthened by use.<br>
0 80 Life is the art of drawing sufficient conclusions from insufficient premises.<br>
<br>
E2)<br>
**Input**<br>
2 F<br>
m Think like a man of action and act like man of thought.<br>
f 0<br>
**Output**<br>
1 56
“Free" "size" "content (if command is m only)"
"Free" "size" "content (if command is m only)"
...
### **Example**
E1)
**Input**
3 F
m Think like a man of action and act like man of thought.
m Courage is very important. Like a muscle, it is strengthened by use.
m Life is the art of drawing sufficient conclusions from insufficient premises.
**Output**
0 56 Think like a man of action and act like man of thought.
0 72 Courage is very important. Like a muscle, it is strengthened by use.
0 80 Life is the art of drawing sufficient conclusions from insufficient premises.
E2)
**Input**
2 F
m Think like a man of action and act like man of thought.
f 0
**Output**
1 56
\ No newline at end of file
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "alloc.h" #include "alloc.h"
#define align(n) (((n+3)/4)*4)
meta *base;
meta *last;
void *m_find(size_t size)
{
if(!base) return 0;
//else if(base==last) return base+1;
meta *cur=base, *ans=0;
size_t max=0, min=SIZE_T_MAX;
bool find=false;
do
{
switch(fit_type)
{
case FIRST_FIT:
if(cur->free && cur->size>=size) find=true;
break;
case BEST_FIT:
if(cur->free && cur->size>=size && cur->size<min)
{
ans=cur;
min=ans->size;
}
break;
case WORST_FIT:
if(cur->free && cur->size>=size && cur->size>max)
{
ans=cur;
max=ans->size;
}
break;
}
if(!find) cur=cur->next;
} while(cur && !find);
if(find) ans=cur;
return !ans?ans:ans+1;
}
void *m_merge(meta *cur1, meta *cur2)
{
cur1->next=cur2->next;
cur1->size+=(cur2->size+META_SIZE);
if(cur2->next && cur2->next->free)
m_merge(cur1, cur2->next);
else if(cur1->prev && cur1->prev->free)
cur1=(m_merge(cur1->prev, cur1)-META_SIZE);
return cur1+1;
}
void *m_split(meta *cur, size_t size)
{
if(cur->size<=size) return cur+1;
size_t size_sum=size+META_SIZE;
meta *new_meta=(void *)cur+size_sum;
new_meta->prev=cur;
new_meta->next=cur->next;
new_meta->free=true;
new_meta->size=cur->size-size_sum;
cur->size=size;
cur->next=new_meta;
return cur+1;
}
void *m_malloc(size_t size)
{
size=align(size);
size_t size_sum=size+META_SIZE;
void *result;
if(!base)
{
//if(sbrk(0)==-1) return;
base=sbrk(0);
sbrk((int)size_sum);
base->free=true;
base->size=size;
last=base;
}
result=m_find(size);
//if no result
if(!result)
{
if(last->free && (last->size < size))
size_sum=size-last->size;
meta *result_meta=last;
last=sbrk((int)size_sum);
last->prev=result_meta;
last->free=true;
last->size=size;
result_meta->next=last;
result=result_meta+1;
//realloc for the merging case
if(last->free && (last->size < size))
result=m_realloc(result, size);
else
result=last+1;
}
result=m_split(result-META_SIZE, size);
return result;
}
void *m_realloc(void *ptr, size_t size)
{
size=align(size);
void *cur=ptr;
meta *cur_meta=cur-META_SIZE;
if(cur_meta->size==size) return ptr;
//TODO: case when extra size is sufficient
if(cur_meta->size>size)
cur=m_split(cur_meta, size);
else if(cur_meta->next && cur_meta->next->free && cur_meta->size+cur_meta->next->size+META_SIZE > size)
{
m_free(ptr);
cur=m_merge(cur_meta, cur_meta->next);
cur_meta=cur-META_SIZE;
if(cur_meta->size+META_SIZE > size)
cur=m_split(cur_meta, size);
}
//nothing to merge or split
else
{
cur=m_malloc(size);
cur_meta=cur-META_SIZE;
memcpy(cur, ptr, size);
cur_meta->free=false;
m_free(ptr);
}
return cur;
}
void m_free(void *ptr)
{
//if(!ptr) return 0;
meta *cur=ptr-META_SIZE;
cur->free=true;
if(cur->prev && cur->prev->free)
cur=m_merge(cur->prev,cur);
else if(cur->next && cur->next->free)
cur=m_merge(cur,cur->next);
//release memory on the last block
if(cur->prev && cur==last)
{
last=last->prev;
last->next=NULL;
}
//back to origin state if there are no blocks
else if(!cur->prev && cur==last)
base=last=NULL;
//return 1;
}
void *m_travel(int idx)
{
if(!base) return 0;
meta *cur=base;
for(int i=0;cur && i<idx;i++)
cur=cur->next;
if(!cur) return 0;
else return cur+1;
}
void print_mem(void)
{
/*
if(!base)
{
fprintf(stdout, "No memory allocated!\n");
return;
}
*/
meta *cur=base;
while(cur)
{
fprintf(stdout, "%d %zu", cur->free, cur->size);
if(!cur->free) fprintf(stdout, " %s", (char *)(cur+1));
fprintf(stdout, "\n");
cur=cur->next;
}
return;
}
#include <stdio.h>
#include <stdbool.h>
#ifndef _ALLOC_H_ #ifndef _ALLOC_H_
#define _ALLOC_H_ #define _ALLOC_H_
#define FIRST_FIT 'F'
#define BEST_FIT 'B'
#define WORST_FIT 'W'
#define META_SIZE sizeof(struct meta_struct)
typedef struct meta_struct { typedef struct meta_struct {
struct meta_struct *prev;
struct meta_struct *next;
bool free;
size_t size;
} meta; } meta;
extern int fit_type;
void *m_find(size_t size);
void *m_merge(meta *cur1, meta *cur2);
void *m_split(meta *cur, size_t size);
void *m_malloc(size_t size);
void *m_realloc(void *ptr, size_t size);
void m_free(void *ptr);
void *m_travel(int idx);
void print_mem(void);
#endif #endif
#include <stdio.h>
#include <string.h>
#include "alloc.h" #include "alloc.h"
#define BUF_MAX 1000
#define FILE_PATH "test1.txt"
#define STRING 's'
#define FREE 'f'
#define REALLOC 'r'
#define ALLOC 'e'
char buf[BUF_MAX+10];
void *ptr;
int fit_type;
int main() int main()
{ {
FILE *fp=fopen(FILE_PATH, "rt");
if(!fp)
{
printf("Cannot open file!\n");
return 0;
}
char cmd;
int cmd_num, idx;
size_t size_alloc;
fscanf(fp, "%d %c\n", &cmd_num, &fit_type);
for(int i=0;i<cmd_num;i++)
{
fscanf(fp, "%c ", &cmd);
switch(cmd)
{
case STRING:
fgets(buf, BUF_MAX, fp);
size_alloc=strlen(buf);
buf[size_alloc-1]='\0';
ptr=m_malloc(size_alloc);
strcpy(ptr, buf);
meta *tmp=ptr-META_SIZE;
tmp->free=false;
//(meta *)(ptr-META_SIZE)->free=false;
break;
case FREE:
fscanf(fp, "%d\n", &idx);
ptr=m_travel(idx);
if(!ptr){}
//fprintf(stdout, "No allocation on block %d\n", idx);
else m_free(ptr);
break;
case REALLOC:
fscanf(fp, "%d %zd\n", &idx, &size_alloc);
ptr=m_realloc(m_travel(idx), size_alloc);
break;
case ALLOC:
fscanf(fp, "%zd\n", &size_alloc);
ptr=m_malloc(size_alloc);
break;
default:
fprintf(stdout, "Wrong command\n");
}
}
print_mem();
fclose(fp);
return 0; return 0;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment