#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define process_num 100 //随机生成的进程数量
#define similize_time 10000 //仿真时长
#define total_size 1024 //存储大小
#define process_max_size 200 //进程占用最大内存大小
#define process_max_time 1000 //进程占用的最长时间
#define error_address total_size+1 //无效地址
typedef struct process process;
typedef struct memlist memlist;
struct process {
long unsigned int coming_time;
int running_time;
unsigned int size;
};
struct memlist {
unsigned int addr;
unsigned int size;
int using_time;
memlist *next;
};
process* undo;
memlist free_head; //保存没有被占用的内存块,链表形式
memlist using_head; //保存正在占用的内存块,链表形式
void random_process();
void similize_process();
void sim_free();
unsigned int sim_alloc(process A);
memlist*best_fit(unsigned int size);
memlist*worst_fit(unsigned int size);
int main() {
undo = (struct process*)malloc(sizeof(process)*process_num);
random_process();
similize_process();
return 0;
}
void random_process() {//生成随机进程的记录表,输出到process文件中,将undo数组按时间按输入的时间排列
long unsigned int coming_time;
int running_time;
unsigned int size;
process tmp;
int i = 0;
int j = 0;
int k = 0;
int undo_size = 0;
FILE* fp;
fp = fopen("process.txt", "w");
//srand((unsigned)time(NULL));
coming_time = rand() % similize_time;
running_time = rand() % process_max_time;
size = rand() % process_max_size;
undo[0].coming_time = coming_time;
undo[0].running_time = running_time;
undo[0].size = size;
while (undo_size < process_num - 1) {
coming_time = rand() % similize_time;
running_time = rand() % process_max_time;
size = rand() % process_max_size;
tmp.coming_time = coming_time;
tmp.running_time = running_time;
tmp.size = size;
j = 0;
while (j <= undo_size && j < process_num&&tmp.coming_time > undo[j].coming_time) {
j++;
}
k = undo_size;
while (k >= 0 && k >= j) {
undo[k + 1] = undo[k];
k--;
}
undo[j] = tmp;
undo_size = undo_size + 1;
}
while (i < process_num) {
fprintf(fp, "%d:coming time %d, running time %d, size %dKB\n", i,
undo[i].coming_time, undo[i].running_time, undo[i].size);
i++;
}
if (fp) fclose(fp);
return;
}
void similize_process() {
FILE*fp;
fp = fopen("sim_worst.txt", "w");
memlist *test_p;
int max_use = 0, use;
unsigned long sim_time = 0;
unsigned int address;
int i = 0;
int last_deny = 0;
int accept_time = 0;
int deny_time = 0;
free_head.addr = 0;
free_head.next = (memlist*)malloc(sizeof(memlist));
free_head.size = 0;
free_head.using_time = 0; //初始化链表头,起始时只有一个元素,是全地址,内部按地址从小到大排序
free_head.next->addr = 0; //初始化链表,使内存皆为未占用,内部按地址从小到大排序
free_head.next->next = NULL;
free_head.next->size = total_size;
free_head.next->using_time = 0;
using_head.addr = 0;
using_head.next = NULL;
using_head.size = 0;
using_head.using_time = 0;
while (sim_time < similize_time)
{
sim_time = sim_time + 1; //向后推时间
sim_free(); //推进每一个进程,回收并且合并
if (sim_time < undo[i].coming_time);
else {
while (sim_time >= undo[i].coming_time) {
address = sim_alloc(undo[i]); //分配,分配成功返回分配的内存地址,分配失败则返回error_address
if (address == error_address) {
if (i != last_deny) {
deny_time++;
last_deny = i;
fprintf(fp, "at %d ,process %d is denied\n", sim_time, i);
}
break;
}
else {
fprintf(fp, "at %d ,process %d is accepted\n", sim_time, i);
accept_time++;
}
i++;
}
}
printf("%d\n", sim_time);
test_p = free_head.next;
use = 0;
while (test_p != NULL) {
use += test_p->size;
test_p = test_p->next;
}
if (total_size - use > max_use)
max_use = total_size - use;
}
fprintf(fp, "total deny time %d\ntotal accept time %d\nuse max %dMB", deny_time, accept_time, max_use);
fclose(fp);
system("pause");
return;
}
void sim_free() { //推进每一个进程,回收并且合并内存单元
memlist*p_f, *p_u, *tmp, *p_u_insert, *p_u_back;
p_f = &free_head;
p_u = using_head.next;
p_u_back = &using_head;
p_u_insert = NULL;
tmp = NULL;
while (p_u != NULL) {
p_u->using_time = p_u->using_time - 1; //向后推时间
if (p_u->using_time <= 0) {
p_u->using_time = 0;
p_u_insert = (memlist*)malloc(sizeof(memlist));
*p_u_insert = *p_u;
while (p_f->next != NULL && p_f->next->addr < p_u->addr) {
p_f = p_f->next; //找到应该回收的位置
}
if (p_f->next != NULL && p_u_insert->addr + p_u_insert->size == p_f->next->addr) {//将回收的内存进行拼接,先尝试将刚释放的节点和后面节点相拼接
p_f->next->addr = p_u_insert->addr;
p_f->next->size = p_f->next->size + p_u_insert->size;
free(p_u_insert);
if (p_f->addr + p_f->size == p_f->next->addr&&p_f != &free_head) { //如果可以和后面节点相拼接,则尝试前后两个节点是否可以相连
p_f->size = p_f->size + p_f->next->size;
tmp = p_f->next;
p_f->next = tmp->next;
free(tmp);
}
}
else if (p_f != &free_head&&p_f->addr + p_f->size == p_u_insert->addr) { //不能向后拼接,则向前拼接
p_f->size = p_f->size + p_u_insert->size;
free(p_u_insert);
}
else { //如果内存块不相接则将这块地址插入free_list
p_u_insert->next = p_f->next;
p_f->next = p_u_insert;
}
tmp = p_u; //删除usinglist中的当前节点,防止重复释放
p_u = p_u->next;
free(tmp);
p_u_back->next = p_u;
}
else {
p_u = p_u->next;
p_u_back = p_u_back->next;
}
}
}
unsigned int sim_alloc(process A) { // 输入进程,返回被分配的地址位置,如果无法分配内存,则将error_address返回
memlist *p_f, *p_u, *tmp;
p_u = NULL;
//p_f = best_fit(A.size); //得到的链表项的下一项是应该分配的内存块,否则不利于对链表的释放
p_f = worst_fit (A.size);
if (p_f != NULL) { //产生新的using_mem 块,并且插入using_list
p_u = (memlist*)malloc(sizeof(memlist));
p_u->addr = p_f->next->addr;
p_u->size = A.size;
p_u->using_time = A.running_time;
p_u->next = NULL;
p_f->next->addr = p_f->next->addr + A.size;
p_f->next->size = p_f->next->size - A.size;
if (p_f->next->size == 0 && p_f != &free_head) {
tmp = p_f->next->next;
free(p_f->next);
p_f->next = NULL;
}
tmp = &using_head;
while (tmp->next != NULL && tmp->next->addr < p_u->addr) {
tmp = tmp->next;
}
p_u->next = tmp->next;
tmp->next = p_u;
return p_u->addr;
}
else {
return error_address;
}
}
/*以下为两个确定应该使用哪一个内存块的选择算法*/
memlist*best_fit(unsigned int size) {
memlist *p_f, *result;
unsigned int dif = total_size;
unsigned int tmp_dif;
result = NULL;
p_f = &free_head;
while (p_f->next != NULL) {
tmp_dif = p_f->next->size - size;
if (tmp_dif < 0 || tmp_dif >= dif);
else {
dif = tmp_dif;
result = p_f;
}
p_f = p_f->next;
}
return result;
}
memlist*worst_fit(unsigned int size) {
memlist *p_f, *result;
unsigned int max = 0;
result = NULL;
p_f = &free_head;
while (p_f->next != NULL) {
if (p_f->next->size > max&&p_f->next->size >= size) {
max = p_f->next->size;
result = p_f;
}
p_f = p_f->next;
}
return result;
}
/*test program 测试是否正确生成了随机进程列*/
//int main() {
// int i = 0;
// undo = (process*)malloc(sizeof(process)*process_num);
// random_process();
// system("pause");
// return 0;
//}