操作系统实验四

  1. 1. 实验代码
  2. 2. 实验结果
  3. 3. 实验过程中遇到的问题,原因和解决方法
  4. 4. 实验代码中空闲区域表中空闲区按何种顺序组织,如果按尺寸由小到大和由大到小组织,算法应该如何修改?

存储管理——可变分区存储管理的分配和回收

实验内容:

  1. 了解可变分区存储管理中对内存空间的划分策略以及存储区的组织结构。
  2. 分析UNIX最先适应(FF)存储分配算法,仔细阅读UNIX源代码中map数据结构、malloc()存储分配函数、mfree()存储释放函数。
  3. 参照UNIX代码编写最佳适应分配算法和最坏适应分配算法。

设计原理:

参考教材13.4.2

实验代码

文本代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifdef  HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define MAPSIZE 100
struct map //存储资源表结构
{
int m_addr;
int m_size;
};
struct map map[MAPSIZE]; //存储资源表
//BF存储分配函数
int BF_malloc(struct map *mp,int size)
{
register int a,s;
register struct map *bp,*bpp;
for(bp = mp; bp->m_size; bp++)
{
if (bp->m_size >= size)
{
a = bp->m_addr;
s = bp->m_size;
for(bpp = bp; bpp->m_size; bpp++)
{ //最佳适应
if(bpp->m_size >= size && bpp->m_size < s)
{
a = bpp->m_addr;
s = bpp->m_size;
bp = bpp;
}
}

bp->m_addr += size;
if ((bp->m_size -= size) == 0)
do
{
bp++;
(bp-1)->m_addr = bp->m_addr;
}
while((bp-1)->m_size = bp->m_size);
return(a);
}
}
return(-1);
}

//WF存储分配函数
int WF_malloc(struct map *mp,int size)
{
register int a,s;
register struct map *bp,*bpp;
for(bp = mp; bp->m_size; bp++)
{
if (bp->m_size >= size)
{
a = bp->m_addr;
s = bp->m_size;
for(bpp = bp; bpp->m_size; bpp++)
{ //最坏适应
if(bpp->m_size > s)
{
a = bpp->m_addr;
s = bpp->m_size;
bp = bpp;
}
}
bp->m_addr += size;
if ((bp->m_size -=size) == 0)
do
{
bp++;
(bp-1)->m_addr = bp->m_addr;
}
while((bp-1)->m_size = bp->m_size);
return(a);
}
}
return(-1);
}

//存储释放函数
void mfree(struct map *mp,int aa,int size)
{
register struct map *bp;
register int t;
register int a;
a = aa;
for(bp = mp; bp->m_addr<=a && bp->m_size != 0; bp++)
;
if(bp>mp && (bp-1)->m_addr+(bp-1)->m_size==a)
{ //与前合并
(bp-1)->m_size += size;
if (a+size == bp->m_addr)
{ //前后合并
(bp-1)->m_size += bp->m_size;
while (bp->m_size)
{
bp++;
(bp-1)->m_addr = bp->m_addr;
(bp-1)->m_size = bp->m_size;
}
}
}

else
{
if (a+size == bp->m_addr && bp->m_size)
{ //与后合并
bp->m_addr -= size;
bp->m_size += size;
}
else if (size)
do
{ //无合并
t = bp->m_addr;
bp->m_addr = a;
a = t;
t = bp->m_size;
bp->m_size = size;
bp++;
}
while (size = t);
}
}
void init()
{
struct map *bp;
int addr,size;
int i=0;
bp=map;
printf("Please input starting addr and total size:");
scanf("%d,%d",&addr,&size);
getchar();
bp->m_addr=addr;
bp->m_size=size;
(++bp)->m_size=0; //表尾
}

void show_map()
{
int i=0;
//system("clear"); //清屏
struct map *bp;
bp=map;
printf("\nCurrent memory map...\n");
printf("Address\t\tSize\n");
while(bp->m_size!=0)
{
printf("<%d\t\t%d>\n",bp->m_addr,bp->m_size);
bp++;
}
printf("\n");
}
main()
{
int a,s;
char c;
int i;
init();
printf("please input, b for BF, w for WF:");
scanf("%c",&c);
getchar();
do
{
show_map(); //显示存储资源表

printf("Please input,1 for request,2 for release,0 for exit:");
scanf("%d",&i);
getchar();
switch(i)
{
case 1:
printf("Please input size:");
scanf("%d", &s);
getchar();
if(c=='b') //BF
a=BF_malloc(map,s);
else //WF
a=WF_malloc(map,s);
if(a==-1)
printf("request can't be satisfied\n");
else
printf("alloc memory at address:%d,size:%d\n",a,s);
break;
case 2:
printf("Please input addr and size:");
scanf("%d,%d",&a,&s);
getchar();
mfree(map,a,s);
break;
case 0:
exit(0);
}
}
while(1);
}

实验结果

结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Please input starting addr and total size:0,100
please input, b for BF, w for WF:b

Current memory map...
Address Size
<0 100>

Please input,1 for request,2 for release,0 for exit:1
Please input size:20
alloc memory at address:0,size:20

Current memory map...
Address Size
<20 80>

Please input,1 for request,2 for release,0 for exit:1
Please input size:35
alloc memory at address:20,size:35

Current memory map...
Address Size
<55 45>

Please input,1 for request,2 for release,0 for exit:1
Please input size:15
alloc memory at address:55,size:15

Current memory map...
Address Size
<70 30>

Please input,1 for request,2 for release,0 for exit:2
Please input addr and size:20,35

Current memory map...
Address Size
<20 35>
<70 30>

Please input,1 for request,2 for release,0 for exit:1
Please input size:15
alloc memory at address:70,size:15

Current memory map...
Address Size
<20 35>
<85 15>

Please input,1 for request,2 for release,0 for exit:2
Please input addr and size:0,20

Current memory map...
Address Size
<0 55>
<85 15>

Please input,1 for request,2 for release,0 for exit:0

实验过程中遇到的问题,原因和解决方法

  1. 无论程序运行过程中输入b还是w,执行的都是WF。int c 改为char c后解决
  2. scanf后需要getchar读取换行
  3. main函数的do-while循环中把第一个printf删去
  4. scanf里面改为%c

实验代码中空闲区域表中空闲区按何种顺序组织,如果按尺寸由小到大和由大到小组织,算法应该如何修改?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// WF存储分配函数(按尺寸由大到小组织空闲区)
int WF_malloc(struct map *mp, int size)
{
register int a, s;
register struct map *bp, *bpp;
for (bp = mp; bp->m_size; bp++)
{
if (bp->m_size >= size)
{
a = bp->m_addr;
s = bp->m_size;
for (bpp = mp + MAPSIZE - 1; bpp >= bp; bpp--)
{
if (bpp->m_size > s)
{
a = bpp->m_addr;
s = bpp->m_size;
bp = bpp;
}
}
bp->m_addr += size;
if ((bp->m_size -= size) == 0)
{
do
{
bp++;
(bp - 1)->m_addr = bp->m_addr;
} while ((bp - 1)->m_size = bp->m_size);
}
return (a);
}
}
return (-1);
}