Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
34295f46
提交
34295f46
5月 31, 2009
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
group locks into structs they protect.
few naming nits.
上级
949e5590
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
82 行增加
和
80 行删除
+82
-80
bio.c
bio.c
+1
-1
console.c
console.c
+15
-12
file.c
file.c
+1
-1
fs.c
fs.c
+1
-1
ide.c
ide.c
+2
-2
init.c
init.c
+2
-2
kalloc.c
kalloc.c
+14
-12
proc.c
proc.c
+42
-44
proc.h
proc.h
+2
-2
usertests.c
usertests.c
+2
-3
没有找到文件。
bio.c
浏览文件 @
34295f46
...
...
@@ -41,7 +41,7 @@ binit(void)
{
struct
buf
*
b
;
initlock
(
&
bcache
.
lock
,
"b
uf_tabl
e"
);
initlock
(
&
bcache
.
lock
,
"b
cach
e"
);
//PAGEBREAK!
// Create linked list of buffers
...
...
console.c
浏览文件 @
34295f46
...
...
@@ -17,9 +17,12 @@
static
ushort
*
crt
=
(
ushort
*
)
0xb8000
;
// CGA memory
static
struct
spinlock
console_lock
;
int
panicked
=
0
;
volatile
int
use_console_lock
=
0
;
static
struct
{
struct
spinlock
lock
;
int
locking
;
}
cons
;
static
int
panicked
=
0
;
static
void
cgaputc
(
int
c
)
...
...
@@ -99,9 +102,9 @@ cprintf(char *fmt, ...)
uint
*
argp
;
char
*
s
;
locking
=
use_console_lock
;
locking
=
cons
.
locking
;
if
(
locking
)
acquire
(
&
cons
ole_
lock
);
acquire
(
&
cons
.
lock
);
argp
=
(
uint
*
)(
void
*
)
&
fmt
+
1
;
state
=
0
;
...
...
@@ -146,7 +149,7 @@ cprintf(char *fmt, ...)
}
if
(
locking
)
release
(
&
cons
ole_
lock
);
release
(
&
cons
.
lock
);
}
int
...
...
@@ -155,10 +158,10 @@ consolewrite(struct inode *ip, char *buf, int n)
int
i
;
iunlock
(
ip
);
acquire
(
&
cons
ole_
lock
);
acquire
(
&
cons
.
lock
);
for
(
i
=
0
;
i
<
n
;
i
++
)
consputc
(
buf
[
i
]
&
0xff
);
release
(
&
cons
ole_
lock
);
release
(
&
cons
.
lock
);
ilock
(
ip
);
return
n
;
...
...
@@ -255,12 +258,12 @@ consoleread(struct inode *ip, char *dst, int n)
void
consoleinit
(
void
)
{
initlock
(
&
cons
ole_
lock
,
"console"
);
initlock
(
&
input
.
lock
,
"
console
input"
);
initlock
(
&
cons
.
lock
,
"console"
);
initlock
(
&
input
.
lock
,
"input"
);
devsw
[
CONSOLE
].
write
=
consolewrite
;
devsw
[
CONSOLE
].
read
=
consoleread
;
use_console_lock
=
1
;
cons
.
locking
=
1
;
picenable
(
IRQ_KBD
);
ioapicenable
(
IRQ_KBD
,
0
);
...
...
@@ -273,7 +276,7 @@ panic(char *s)
uint
pcs
[
10
];
cli
();
use_console_lock
=
0
;
cons
.
locking
=
0
;
cprintf
(
"cpu%d: panic: "
,
cpu
());
cprintf
(
s
);
cprintf
(
"
\n
"
);
...
...
file.c
浏览文件 @
34295f46
...
...
@@ -14,7 +14,7 @@ struct {
void
fileinit
(
void
)
{
initlock
(
&
ftable
.
lock
,
"f
ile_
table"
);
initlock
(
&
ftable
.
lock
,
"ftable"
);
}
// Allocate a file structure.
...
...
fs.c
浏览文件 @
34295f46
...
...
@@ -138,7 +138,7 @@ struct {
void
iinit
(
void
)
{
initlock
(
&
icache
.
lock
,
"icache
.lock
"
);
initlock
(
&
icache
.
lock
,
"icache"
);
}
// Find the inode with number inum on device dev
...
...
ide.c
浏览文件 @
34295f46
...
...
@@ -30,13 +30,13 @@ static void idestart(struct buf*);
// Wait for IDE disk to become ready.
static
int
idewait
(
int
check
_erro
r
)
idewait
(
int
check
er
r
)
{
int
r
;
while
(((
r
=
inb
(
0x1f7
))
&
(
IDE_BSY
|
IDE_DRDY
))
!=
IDE_DRDY
)
;
if
(
check
_erro
r
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
if
(
check
er
r
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
return
-
1
;
return
0
;
}
...
...
init.c
浏览文件 @
34295f46
...
...
@@ -5,7 +5,7 @@
#include "user.h"
#include "fcntl.h"
char
*
sh_args
[]
=
{
"sh"
,
0
};
char
*
argv
[]
=
{
"sh"
,
0
};
int
main
(
void
)
...
...
@@ -27,7 +27,7 @@ main(void)
exit
();
}
if
(
pid
==
0
){
exec
(
"sh"
,
sh_args
);
exec
(
"sh"
,
argv
);
printf
(
1
,
"init: exec sh failed
\n
"
);
exit
();
}
...
...
kalloc.c
浏览文件 @
34295f46
...
...
@@ -10,13 +10,15 @@
#include "param.h"
#include "spinlock.h"
struct
spinlock
kalloc_lock
;
struct
run
{
struct
run
*
next
;
int
len
;
// bytes
};
struct
run
*
freelist
;
struct
{
struct
spinlock
lock
;
struct
run
*
freelist
;
}
kmem
;
// Initialize free list of physical pages.
// This code cheats by just considering one megabyte of
...
...
@@ -29,7 +31,7 @@ kinit(void)
uint
mem
;
char
*
start
;
initlock
(
&
k
alloc_lock
,
"kalloc
"
);
initlock
(
&
k
mem
.
lock
,
"kmem
"
);
start
=
(
char
*
)
&
end
;
start
=
(
char
*
)
(((
uint
)
start
+
PAGE
)
&
~
(
PAGE
-
1
));
mem
=
256
;
// assume computer has 256 pages of RAM
...
...
@@ -52,10 +54,10 @@ kfree(char *v, int len)
// Fill with junk to catch dangling refs.
memset
(
v
,
1
,
len
);
acquire
(
&
k
alloc_
lock
);
acquire
(
&
k
mem
.
lock
);
p
=
(
struct
run
*
)
v
;
pend
=
(
struct
run
*
)(
v
+
len
);
for
(
rp
=&
freelist
;
(
r
=*
rp
)
!=
0
&&
r
<=
pend
;
rp
=&
r
->
next
){
for
(
rp
=&
kmem
.
freelist
;
(
r
=*
rp
)
!=
0
&&
r
<=
pend
;
rp
=&
r
->
next
){
rend
=
(
struct
run
*
)((
char
*
)
r
+
r
->
len
);
if
(
r
<=
p
&&
p
<
rend
)
panic
(
"freeing free page"
);
...
...
@@ -80,7 +82,7 @@ kfree(char *v, int len)
*
rp
=
p
;
out:
release
(
&
k
alloc_
lock
);
release
(
&
k
mem
.
lock
);
}
// Allocate n bytes of physical memory.
...
...
@@ -95,21 +97,21 @@ kalloc(int n)
if
(
n
%
PAGE
||
n
<=
0
)
panic
(
"kalloc"
);
acquire
(
&
k
alloc_
lock
);
for
(
rp
=&
freelist
;
(
r
=*
rp
)
!=
0
;
rp
=&
r
->
next
){
acquire
(
&
k
mem
.
lock
);
for
(
rp
=&
kmem
.
freelist
;
(
r
=*
rp
)
!=
0
;
rp
=&
r
->
next
){
if
(
r
->
len
==
n
){
*
rp
=
r
->
next
;
release
(
&
k
alloc_
lock
);
release
(
&
k
mem
.
lock
);
return
(
char
*
)
r
;
}
if
(
r
->
len
>
n
){
r
->
len
-=
n
;
p
=
(
char
*
)
r
+
r
->
len
;
release
(
&
k
alloc_
lock
);
release
(
&
k
mem
.
lock
);
return
p
;
}
}
release
(
&
k
alloc_
lock
);
release
(
&
k
mem
.
lock
);
cprintf
(
"kalloc: out of memory
\n
"
);
return
0
;
...
...
proc.c
浏览文件 @
34295f46
...
...
@@ -6,9 +6,11 @@
#include "proc.h"
#include "spinlock.h"
struct
spinlock
proc_table_lock
;
struct
{
struct
spinlock
lock
;
struct
proc
proc
[
NPROC
];
}
ptable
;
struct
proc
proc
[
NPROC
];
static
struct
proc
*
initproc
;
int
nextpid
=
1
;
...
...
@@ -18,7 +20,7 @@ extern void forkret1(struct trapframe*);
void
pinit
(
void
)
{
initlock
(
&
p
roc_table_lock
,
"proc_
table"
);
initlock
(
&
p
table
.
lock
,
"p
table"
);
}
// Look in the process table for an UNUSED proc.
...
...
@@ -30,20 +32,19 @@ allocproc(void)
int
i
;
struct
proc
*
p
;
acquire
(
&
proc_table_lock
);
for
(
i
=
0
;
i
<
NPROC
;
i
++
){
p
=
&
proc
[
i
];
acquire
(
&
ptable
.
lock
);
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
state
==
UNUSED
){
p
->
state
=
EMBRYO
;
p
->
pid
=
nextpid
++
;
goto
found
;
}
}
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
return
0
;
found:
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
// Allocate kernel stack if necessary.
if
((
p
->
kstack
=
kalloc
(
KSTACKSIZE
))
==
0
){
...
...
@@ -215,14 +216,13 @@ scheduler(void)
sti
();
// Loop over process table looking for process to run.
acquire
(
&
proc_table_lock
);
for
(
i
=
0
;
i
<
NPROC
;
i
++
){
p
=
&
proc
[
i
];
acquire
(
&
ptable
.
lock
);
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
state
!=
RUNNABLE
)
continue
;
// Switch to chosen process. It is the process's job
// to release p
roc_table_
lock and then reacquire it
// to release p
table.
lock and then reacquire it
// before jumping back to us.
cp
=
p
;
usegment
();
...
...
@@ -234,12 +234,12 @@ scheduler(void)
cp
=
0
;
usegment
();
}
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
}
}
// Enter scheduler. Must already hold p
roc_table_
lock
// Enter scheduler. Must already hold p
table.
lock
// and have changed cp->state.
void
sched
(
void
)
...
...
@@ -250,8 +250,8 @@ sched(void)
panic
(
"sched interruptible"
);
if
(
cp
->
state
==
RUNNING
)
panic
(
"sched running"
);
if
(
!
holding
(
&
p
roc_table_
lock
))
panic
(
"sched p
roc_table_
lock"
);
if
(
!
holding
(
&
p
table
.
lock
))
panic
(
"sched p
table.
lock"
);
if
(
c
->
ncli
!=
1
)
panic
(
"sched locks"
);
...
...
@@ -264,10 +264,10 @@ sched(void)
void
yield
(
void
)
{
acquire
(
&
p
roc_table_
lock
);
acquire
(
&
p
table
.
lock
);
cp
->
state
=
RUNNABLE
;
sched
();
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
}
// A fork child's very first scheduling by scheduler()
...
...
@@ -275,8 +275,8 @@ yield(void)
void
forkret
(
void
)
{
// Still holding p
roc_table_
lock from scheduler.
release
(
&
p
roc_table_
lock
);
// Still holding p
table.
lock from scheduler.
release
(
&
p
table
.
lock
);
// Jump into assembly, never to return.
forkret1
(
cp
->
tf
);
...
...
@@ -293,14 +293,14 @@ sleep(void *chan, struct spinlock *lk)
if
(
lk
==
0
)
panic
(
"sleep without lk"
);
// Must acquire p
roc_table_
lock in order to
// Must acquire p
table.
lock in order to
// change p->state and then call sched.
// Once we hold p
roc_table_
lock, we can be
// Once we hold p
table.
lock, we can be
// guaranteed that we won't miss any wakeup
// (wakeup runs with p
roc_table_
lock locked),
// (wakeup runs with p
table.
lock locked),
// so it's okay to release lk.
if
(
lk
!=
&
p
roc_table_
lock
){
acquire
(
&
p
roc_table_
lock
);
if
(
lk
!=
&
p
table
.
lock
){
acquire
(
&
p
table
.
lock
);
release
(
lk
);
}
...
...
@@ -313,15 +313,15 @@ sleep(void *chan, struct spinlock *lk)
cp
->
chan
=
0
;
// Reacquire original lock.
if
(
lk
!=
&
p
roc_table_
lock
){
release
(
&
p
roc_table_
lock
);
if
(
lk
!=
&
p
table
.
lock
){
release
(
&
p
table
.
lock
);
acquire
(
lk
);
}
}
//PAGEBREAK!
// Wake up all processes sleeping on chan.
//
Proc_table_
lock must be held.
//
The ptable
lock must be held.
static
void
wakeup1
(
void
*
chan
)
{
...
...
@@ -336,9 +336,9 @@ wakeup1(void *chan)
void
wakeup
(
void
*
chan
)
{
acquire
(
&
p
roc_table_
lock
);
acquire
(
&
p
table
.
lock
);
wakeup1
(
chan
);
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
}
// Kill the process with the given pid.
...
...
@@ -349,18 +349,18 @@ kill(int pid)
{
struct
proc
*
p
;
acquire
(
&
p
roc_table_
lock
);
for
(
p
=
p
roc
;
p
<
&
proc
[
NPROC
];
p
++
){
acquire
(
&
p
table
.
lock
);
for
(
p
=
p
table
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
pid
==
pid
){
p
->
killed
=
1
;
// Wake process from sleep if necessary.
if
(
p
->
state
==
SLEEPING
)
p
->
state
=
RUNNABLE
;
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
return
0
;
}
}
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
return
-
1
;
}
...
...
@@ -387,13 +387,13 @@ exit(void)
iput
(
cp
->
cwd
);
cp
->
cwd
=
0
;
acquire
(
&
p
roc_table_
lock
);
acquire
(
&
p
table
.
lock
);
// Parent might be sleeping in wait().
wakeup1
(
cp
->
parent
);
// Pass abandoned children to init.
for
(
p
=
p
roc
;
p
<
&
proc
[
NPROC
];
p
++
){
for
(
p
=
p
table
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
parent
==
cp
){
p
->
parent
=
initproc
;
if
(
p
->
state
==
ZOMBIE
)
...
...
@@ -416,12 +416,11 @@ wait(void)
struct
proc
*
p
;
int
i
,
havekids
,
pid
;
acquire
(
&
p
roc_table_
lock
);
acquire
(
&
p
table
.
lock
);
for
(;;){
// Scan through table looking for zombie children.
havekids
=
0
;
for
(
i
=
0
;
i
<
NPROC
;
i
++
){
p
=
&
proc
[
i
];
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
state
==
UNUSED
)
continue
;
if
(
p
->
parent
==
cp
){
...
...
@@ -435,7 +434,7 @@ wait(void)
p
->
pid
=
0
;
p
->
parent
=
0
;
p
->
name
[
0
]
=
0
;
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
return
pid
;
}
}
...
...
@@ -443,12 +442,12 @@ wait(void)
// No point waiting if we don't have any children.
if
(
!
havekids
||
cp
->
killed
){
release
(
&
p
roc_table_
lock
);
release
(
&
p
table
.
lock
);
return
-
1
;
}
// Wait for children to exit. (See wakeup1 call in proc_exit.)
sleep
(
cp
,
&
p
roc_table_
lock
);
sleep
(
cp
,
&
p
table
.
lock
);
}
}
...
...
@@ -471,8 +470,7 @@ procdump(void)
char
*
state
;
uint
pc
[
10
];
for
(
i
=
0
;
i
<
NPROC
;
i
++
){
p
=
&
proc
[
i
];
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
state
==
UNUSED
)
continue
;
if
(
p
->
state
>=
0
&&
p
->
state
<
NELEM
(
states
)
&&
states
[
p
->
state
])
...
...
proc.h
浏览文件 @
34295f46
...
...
@@ -24,14 +24,14 @@ struct context {
uint
eip
;
};
enum
proc
_
state
{
UNUSED
,
EMBRYO
,
SLEEPING
,
RUNNABLE
,
RUNNING
,
ZOMBIE
};
enum
procstate
{
UNUSED
,
EMBRYO
,
SLEEPING
,
RUNNABLE
,
RUNNING
,
ZOMBIE
};
// Per-process state
struct
proc
{
char
*
mem
;
// Start of process memory (kernel address)
uint
sz
;
// Size of process memory (bytes)
char
*
kstack
;
// Bottom of kernel stack for this process
enum
proc
_
state
state
;
// Process state
enum
procstate
state
;
// Process state
volatile
int
pid
;
// Process ID
struct
proc
*
parent
;
// Parent process
struct
trapframe
*
tf
;
// Trap frame for current syscall
...
...
usertests.c
浏览文件 @
34295f46
...
...
@@ -6,8 +6,7 @@
char
buf
[
2048
];
char
name
[
3
];
char
*
echo_args
[]
=
{
"echo"
,
"ALL"
,
"TESTS"
,
"PASSED"
,
0
};
char
*
cat_args
[]
=
{
"cat"
,
"README"
,
0
};
char
*
echoargv
[]
=
{
"echo"
,
"ALL"
,
"TESTS"
,
"PASSED"
,
0
};
int
stdout
=
1
;
// simple file system tests
...
...
@@ -191,7 +190,7 @@ void
exectest
(
void
)
{
printf
(
stdout
,
"exec test
\n
"
);
if
(
exec
(
"echo"
,
echo
_args
)
<
0
)
{
if
(
exec
(
"echo"
,
echo
argv
)
<
0
)
{
printf
(
stdout
,
"exec echo failed
\n
"
);
exit
();
}
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论