Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
6670d3b5
提交
6670d3b5
9月 11, 2016
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Straight replacement of B_BUSY with a sleeping lock.
上级
551c2f35
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
44 行增加
和
20 行删除
+44
-20
Makefile
Makefile
+1
-0
bio.c
bio.c
+20
-17
buf.h
buf.h
+1
-1
defs.h
defs.h
+7
-0
exec.c
exec.c
+3
-0
fs.c
fs.c
+8
-0
ide.c
ide.c
+3
-2
log.c
log.c
+1
-0
没有找到文件。
Makefile
浏览文件 @
6670d3b5
...
...
@@ -15,6 +15,7 @@ OBJS = \
picirq.o
\
pipe.o
\
proc.o
\
sleeplock.o
\
spinlock.o
\
string.o
\
swtch.o
\
...
...
bio.c
浏览文件 @
6670d3b5
...
...
@@ -13,9 +13,7 @@
// * Only one process at a time can use a buffer,
// so do not keep them longer than necessary.
//
// The implementation uses three state flags internally:
// * B_BUSY: the block has been returned from bread
// and has not been passed back to brelse.
// The implementation uses two state flags internally:
// * B_VALID: the buffer data has been read from the disk.
// * B_DIRTY: the buffer data has been modified
// and needs to be written to disk.
...
...
@@ -24,6 +22,7 @@
#include "defs.h"
#include "param.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
...
...
@@ -51,6 +50,7 @@ binit(void)
b
->
next
=
bcache
.
head
.
next
;
b
->
prev
=
&
bcache
.
head
;
b
->
dev
=
-
1
;
initsleeplock
(
&
b
->
lock
,
"buffer"
);
bcache
.
head
.
next
->
prev
=
b
;
bcache
.
head
.
next
=
b
;
}
...
...
@@ -58,7 +58,7 @@ binit(void)
// Look through buffer cache for block on device dev.
// If not found, allocate a buffer.
// In either case, return
B_BUSY
buffer.
// In either case, return
locked
buffer.
static
struct
buf
*
bget
(
uint
dev
,
uint
blockno
)
{
...
...
@@ -66,12 +66,14 @@ bget(uint dev, uint blockno)
acquire
(
&
bcache
.
lock
);
//cprintf("bget %d\n", blockno);
loop:
// Is the block already cached?
for
(
b
=
bcache
.
head
.
next
;
b
!=
&
bcache
.
head
;
b
=
b
->
next
){
if
(
b
->
dev
==
dev
&&
b
->
blockno
==
blockno
){
if
(
!
(
b
->
flags
&
B_BUSY
)){
b
->
flags
|=
B_BUSY
;
if
(
!
holdingsleep
(
&
b
->
lock
))
{
acquiresleep
(
&
b
->
lock
);
//cprintf("return buffer %p for blk %d\n", b - bcache.buf, blockno);
release
(
&
bcache
.
lock
);
return
b
;
}
...
...
@@ -80,14 +82,16 @@ bget(uint dev, uint blockno)
}
}
// Not cached; recycle some non-
busy
and clean buffer.
// "clean" because B_DIRTY and
!B_BUSY
means log.c
// Not cached; recycle some non-
locked
and clean buffer.
// "clean" because B_DIRTY and
not locked
means log.c
// hasn't yet committed the changes to the buffer.
for
(
b
=
bcache
.
head
.
prev
;
b
!=
&
bcache
.
head
;
b
=
b
->
prev
){
if
(
(
b
->
flags
&
B_BUSY
)
==
0
&&
(
b
->
flags
&
B_DIRTY
)
==
0
){
if
(
!
holdingsleep
(
&
b
->
lock
)
&&
(
b
->
flags
&
B_DIRTY
)
==
0
){
b
->
dev
=
dev
;
b
->
blockno
=
blockno
;
b
->
flags
=
B_BUSY
;
b
->
flags
=
0
;
// XXX
acquiresleep
(
&
b
->
lock
);
//cprintf("return buffer %p for blk %d\n", b - bcache.buf, blockno);
release
(
&
bcache
.
lock
);
return
b
;
}
...
...
@@ -95,7 +99,7 @@ bget(uint dev, uint blockno)
panic
(
"bget: no buffers"
);
}
// Return a
B_BUSY
buf with the contents of the indicated block.
// Return a
locked
buf with the contents of the indicated block.
struct
buf
*
bread
(
uint
dev
,
uint
blockno
)
{
...
...
@@ -108,22 +112,22 @@ bread(uint dev, uint blockno)
return
b
;
}
// Write b's contents to disk. Must be
B_BUSY
.
// Write b's contents to disk. Must be
locked
.
void
bwrite
(
struct
buf
*
b
)
{
if
(
(
b
->
flags
&
B_BUSY
)
==
0
)
if
(
b
->
lock
.
locked
==
0
)
panic
(
"bwrite"
);
b
->
flags
|=
B_DIRTY
;
iderw
(
b
);
}
// Release a
B_BUSY
buffer.
// Release a
locked
buffer.
// Move to the head of the MRU list.
void
brelse
(
struct
buf
*
b
)
{
if
(
(
b
->
flags
&
B_BUSY
)
==
0
)
if
(
b
->
lock
.
locked
==
0
)
panic
(
"brelse"
);
acquire
(
&
bcache
.
lock
);
...
...
@@ -134,8 +138,7 @@ brelse(struct buf *b)
b
->
prev
=
&
bcache
.
head
;
bcache
.
head
.
next
->
prev
=
b
;
bcache
.
head
.
next
=
b
;
b
->
flags
&=
~
B_BUSY
;
releasesleep
(
&
b
->
lock
);
wakeup
(
b
);
release
(
&
bcache
.
lock
);
...
...
buf.h
浏览文件 @
6670d3b5
...
...
@@ -2,12 +2,12 @@ struct buf {
int
flags
;
uint
dev
;
uint
blockno
;
struct
sleeplock
lock
;
struct
buf
*
prev
;
// LRU cache list
struct
buf
*
next
;
struct
buf
*
qnext
;
// disk queue
uchar
data
[
BSIZE
];
};
#define B_BUSY 0x1 // buffer is locked by some process
#define B_VALID 0x2 // buffer has been read from disk
#define B_DIRTY 0x4 // buffer needs to be written to disk
defs.h
浏览文件 @
6670d3b5
...
...
@@ -6,6 +6,7 @@ struct pipe;
struct
proc
;
struct
rtcdate
;
struct
spinlock
;
struct
sleeplock
;
struct
stat
;
struct
superblock
;
...
...
@@ -128,6 +129,12 @@ void release(struct spinlock*);
void
pushcli
(
void
);
void
popcli
(
void
);
// sleeplock.c
void
acquiresleep
(
struct
sleeplock
*
);
void
releasesleep
(
struct
sleeplock
*
);
int
holdingsleep
(
struct
sleeplock
*
);
void
initsleeplock
(
struct
sleeplock
*
,
char
*
);
// string.c
int
memcmp
(
const
void
*
,
const
void
*
,
uint
);
void
*
memmove
(
void
*
,
const
void
*
,
uint
);
...
...
exec.c
浏览文件 @
6670d3b5
...
...
@@ -19,6 +19,8 @@ exec(char *path, char **argv)
pde_t
*
pgdir
,
*
oldpgdir
;
begin_op
();
cprintf
(
"exec %s
\n
"
,
path
);
if
((
ip
=
namei
(
path
))
==
0
){
end_op
();
return
-
1
;
...
...
@@ -98,6 +100,7 @@ exec(char *path, char **argv)
proc
->
tf
->
esp
=
sp
;
switchuvm
(
proc
);
freevm
(
oldpgdir
);
cprintf
(
"exec succeeded
\n
"
);
return
0
;
bad:
...
...
fs.c
浏览文件 @
6670d3b5
...
...
@@ -16,6 +16,7 @@
#include "mmu.h"
#include "proc.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
#include "file.h"
...
...
@@ -455,6 +456,13 @@ readi(struct inode *ip, char *dst, uint off, uint n)
for
(
tot
=
0
;
tot
<
n
;
tot
+=
m
,
off
+=
m
,
dst
+=
m
){
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
));
m
=
min
(
n
-
tot
,
BSIZE
-
off
%
BSIZE
);
/*
cprintf("data off %d:\n", off);
for (int j = 0; j < min(m, 10); j++) {
cprintf("%x ", bp->data[off%BSIZE+j]);
}
cprintf("\n");
*/
memmove
(
dst
,
bp
->
data
+
off
%
BSIZE
,
m
);
brelse
(
bp
);
}
...
...
ide.c
浏览文件 @
6670d3b5
...
...
@@ -9,6 +9,7 @@
#include "x86.h"
#include "traps.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
...
...
@@ -139,8 +140,8 @@ iderw(struct buf *b)
{
struct
buf
**
pp
;
if
(
!
(
b
->
flags
&
B_BUSY
))
panic
(
"iderw: buf not
busy
"
);
if
(
!
holdingsleep
(
&
b
->
lock
))
panic
(
"iderw: buf not
locked
"
);
if
((
b
->
flags
&
(
B_VALID
|
B_DIRTY
))
==
B_VALID
)
panic
(
"iderw: nothing to do"
);
if
(
b
->
dev
!=
0
&&
!
havedisk1
)
...
...
log.c
浏览文件 @
6670d3b5
...
...
@@ -2,6 +2,7 @@
#include "defs.h"
#include "param.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论