Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
83d2db91
提交
83d2db91
8月 10, 2010
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
allow sbrk(-x) to de-allocate user memory
上级
c4cc10da
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
89 行增加
和
4 行删除
+89
-4
defs.h
defs.h
+1
-0
proc.c
proc.c
+7
-2
usertests.c
usertests.c
+56
-1
vm.c
vm.c
+25
-1
没有找到文件。
defs.h
浏览文件 @
83d2db91
...
...
@@ -159,6 +159,7 @@ void vminit(void);
pde_t
*
setupkvm
(
void
);
char
*
uva2ka
(
pde_t
*
,
char
*
);
int
allocuvm
(
pde_t
*
,
char
*
,
uint
);
int
deallocuvm
(
pde_t
*
pgdir
,
char
*
addr
,
uint
sz
);
void
freevm
(
pde_t
*
);
void
inituvm
(
pde_t
*
,
char
*
,
char
*
,
uint
);
int
loaduvm
(
pde_t
*
,
char
*
,
struct
inode
*
ip
,
uint
,
uint
);
...
...
proc.c
浏览文件 @
83d2db91
...
...
@@ -142,8 +142,13 @@ userinit(void)
int
growproc
(
int
n
)
{
if
(
!
allocuvm
(
proc
->
pgdir
,
(
char
*
)
proc
->
sz
,
n
))
return
-
1
;
if
(
n
>
0
){
if
(
!
allocuvm
(
proc
->
pgdir
,
(
char
*
)
proc
->
sz
,
n
))
return
-
1
;
}
else
if
(
n
<
0
){
if
(
!
deallocuvm
(
proc
->
pgdir
,
(
char
*
)(
proc
->
sz
+
n
),
0
-
n
))
return
-
1
;
}
proc
->
sz
+=
n
;
switchuvm
(
proc
);
return
0
;
...
...
usertests.c
浏览文件 @
83d2db91
...
...
@@ -1232,7 +1232,11 @@ forktest(void)
void
sbrktest
(
void
)
{
int
pid
;
printf
(
stdout
,
"sbrk test
\n
"
);
// can one sbrk() less than a page?
char
*
a
=
sbrk
(
0
);
int
i
;
for
(
i
=
0
;
i
<
5000
;
i
++
){
...
...
@@ -1244,7 +1248,7 @@ sbrktest(void)
*
b
=
1
;
a
=
b
+
1
;
}
int
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"sbrk test fork failed
\n
"
);
exit
();
...
...
@@ -1258,6 +1262,57 @@ sbrktest(void)
if
(
pid
==
0
)
exit
();
wait
();
// can one allocate the full 640K?
a
=
sbrk
(
0
);
uint
amt
=
(
640
*
1024
)
-
(
uint
)
a
;
char
*
p
=
sbrk
(
amt
);
if
(
p
!=
a
){
printf
(
stdout
,
"sbrk test failed 640K test, p %x a %x
\n
"
,
p
,
a
);
exit
();
}
char
*
lastaddr
=
(
char
*
)(
640
*
1024
-
1
);
*
lastaddr
=
99
;
// is one forbidden from allocating more than 640K?
c
=
sbrk
(
4096
);
if
(
c
!=
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk allocated more than 640K, c %x
\n
"
,
c
);
exit
();
}
// can one de-allocate?
a
=
sbrk
(
0
);
c
=
sbrk
(
-
4096
);
if
(
c
==
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk could not deallocate
\n
"
);
exit
();
}
c
=
sbrk
(
0
);
if
(
c
!=
a
-
4096
){
printf
(
stdout
,
"sbrk deallocation produced wrong address, a %x c %x
\n
"
,
a
,
c
);
exit
();
}
// can one re-allocate that page?
a
=
sbrk
(
0
);
c
=
sbrk
(
4096
);
if
(
c
!=
a
||
sbrk
(
0
)
!=
a
+
4096
){
printf
(
stdout
,
"sbrk re-allocation failed, a %x c %x
\n
"
,
a
,
c
);
exit
();
}
if
(
*
lastaddr
==
99
){
// should be zero
printf
(
stdout
,
"sbrk de-allocation didn't really deallocate
\n
"
);
exit
();
}
c
=
sbrk
(
4096
);
if
(
c
!=
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk was able to re-allocate beyond 640K, c %x
\n
"
,
c
);
exit
();
}
printf
(
stdout
,
"sbrk test OK
\n
"
);
}
...
...
vm.c
浏览文件 @
83d2db91
...
...
@@ -198,7 +198,7 @@ uva2ka(pde_t *pgdir, char *uva)
int
allocuvm
(
pde_t
*
pgdir
,
char
*
addr
,
uint
sz
)
{
if
(
addr
+
sz
>
=
(
char
*
)
USERTOP
)
if
(
addr
+
sz
>
(
char
*
)
USERTOP
)
return
0
;
char
*
first
=
PGROUNDDOWN
(
addr
);
char
*
last
=
PGROUNDDOWN
(
addr
+
sz
-
1
);
...
...
@@ -218,6 +218,30 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
return
1
;
}
// deallocate some of the user pages, in response to sbrk()
// with a negative argument. if addr is not page-aligned,
// then only deallocates starting at the next page boundary.
int
deallocuvm
(
pde_t
*
pgdir
,
char
*
addr
,
uint
sz
)
{
if
(
addr
+
sz
>
(
char
*
)
USERTOP
)
return
0
;
char
*
first
=
(
char
*
)
PGROUNDUP
((
uint
)
addr
);
char
*
last
=
PGROUNDDOWN
(
addr
+
sz
-
1
);
char
*
a
;
for
(
a
=
first
;
a
<=
last
;
a
+=
PGSIZE
){
pte_t
*
pte
=
walkpgdir
(
pgdir
,
a
,
0
);
if
(
pte
&&
(
*
pte
&
PTE_P
)
!=
0
){
uint
pa
=
PTE_ADDR
(
*
pte
);
if
(
pa
==
0
)
panic
(
"deallocuvm"
);
kfree
((
void
*
)
pa
,
PGSIZE
);
*
pte
=
0
;
}
}
return
1
;
}
// free a page table and all the physical memory pages
// in the user part.
void
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论