Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
a8e17d76
提交
a8e17d76
6月 15, 2011
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rcu-free disk blocks, for lock-free exec
上级
d564ca3d
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
74 行增加
和
29 行删除
+74
-29
defs.h
defs.h
+1
-0
exec.c
exec.c
+11
-7
fs.c
fs.c
+3
-3
rcu.c
rcu.c
+59
-19
没有找到文件。
defs.h
浏览文件 @
a8e17d76
...
@@ -143,6 +143,7 @@ void rcu_end_write(struct spinlock *);
...
@@ -143,6 +143,7 @@ void rcu_end_write(struct spinlock *);
void
rcu_begin_read
(
void
);
void
rcu_begin_read
(
void
);
void
rcu_end_read
(
void
);
void
rcu_end_read
(
void
);
void
rcu_delayed
(
void
*
,
void
(
*
dofree
)(
void
*
));
void
rcu_delayed
(
void
*
,
void
(
*
dofree
)(
void
*
));
void
rcu_delayed2
(
int
,
uint
,
void
(
*
dofree
)(
int
,
uint
));
void
rcu_gc
(
void
);
void
rcu_gc
(
void
);
// swtch.S
// swtch.S
...
...
exec.c
浏览文件 @
a8e17d76
...
@@ -28,7 +28,8 @@ exec(char *path, char **argv)
...
@@ -28,7 +28,8 @@ exec(char *path, char **argv)
if
((
ip
=
namei
(
path
))
==
0
)
if
((
ip
=
namei
(
path
))
==
0
)
return
-
1
;
return
-
1
;
ilock
(
ip
,
0
);
// ilock(ip, 0);
rcu_begin_read
();
// Check ELF header
// Check ELF header
if
(
ip
->
type
!=
T_FILE
)
if
(
ip
->
type
!=
T_FILE
)
...
@@ -73,10 +74,11 @@ exec(char *path, char **argv)
...
@@ -73,10 +74,11 @@ exec(char *path, char **argv)
goto
bad
;
goto
bad
;
vmn
=
0
;
vmn
=
0
;
}
}
if
(
odp
)
if
(
odp
)
{
iunlock
(
ip
);
// iunlock(ip);
else
{
}
else
{
iunlockput
(
ip
);
// iunlockput(ip);
iput
(
ip
);
ip
=
0
;
ip
=
0
;
}
}
...
@@ -133,15 +135,17 @@ exec(char *path, char **argv)
...
@@ -133,15 +135,17 @@ exec(char *path, char **argv)
migrate
(
proc
);
migrate
(
proc
);
rcu_end_read
();
return
0
;
return
0
;
bad:
bad:
cprintf
(
"exec failed
\n
"
);
cprintf
(
"exec failed
\n
"
);
if
(
ip
)
//
if(ip)
iunlockput
(
ip
);
//
iunlockput(ip);
if
(
vmap
)
if
(
vmap
)
vmap_decref
(
vmap
);
vmap_decref
(
vmap
);
if
(
vmn
)
if
(
vmn
)
vmn_free
(
vmn
);
vmn_free
(
vmn
);
rcu_end_read
();
return
-
1
;
return
-
1
;
}
}
fs.c
浏览文件 @
a8e17d76
...
@@ -419,7 +419,7 @@ itrunc(struct inode *ip)
...
@@ -419,7 +419,7 @@ itrunc(struct inode *ip)
for
(
i
=
0
;
i
<
NDIRECT
;
i
++
){
for
(
i
=
0
;
i
<
NDIRECT
;
i
++
){
if
(
ip
->
addrs
[
i
]){
if
(
ip
->
addrs
[
i
]){
bfree
(
ip
->
dev
,
ip
->
addrs
[
i
]
);
rcu_delayed2
(
ip
->
dev
,
ip
->
addrs
[
i
],
bfree
);
ip
->
addrs
[
i
]
=
0
;
ip
->
addrs
[
i
]
=
0
;
}
}
}
}
...
@@ -429,10 +429,10 @@ itrunc(struct inode *ip)
...
@@ -429,10 +429,10 @@ itrunc(struct inode *ip)
a
=
(
uint
*
)
bp
->
data
;
a
=
(
uint
*
)
bp
->
data
;
for
(
j
=
0
;
j
<
NINDIRECT
;
j
++
){
for
(
j
=
0
;
j
<
NINDIRECT
;
j
++
){
if
(
a
[
j
])
if
(
a
[
j
])
bfree
(
ip
->
dev
,
a
[
j
]
);
rcu_delayed2
(
ip
->
dev
,
a
[
j
],
bfree
);
}
}
brelse
(
bp
,
0
);
brelse
(
bp
,
0
);
bfree
(
ip
->
dev
,
ip
->
addrs
[
NDIRECT
]
);
rcu_delayed2
(
ip
->
dev
,
ip
->
addrs
[
NDIRECT
],
bfree
);
ip
->
addrs
[
NDIRECT
]
=
0
;
ip
->
addrs
[
NDIRECT
]
=
0
;
}
}
...
...
rcu.c
浏览文件 @
a8e17d76
...
@@ -9,10 +9,21 @@
...
@@ -9,10 +9,21 @@
#include "proc.h"
#include "proc.h"
struct
rcu
{
struct
rcu
{
void
*
item
;
unsigned
long
epoch
;
unsigned
long
epoch
;
struct
rcu
*
next
;
struct
rcu
*
next
;
void
(
*
dofree
)(
void
*
);
union
{
struct
{
void
(
*
dofree
)(
void
*
);
void
*
item
;
}
f1
;
struct
{
void
(
*
dofree
)(
int
,
uint
);
int
arg1
;
uint
arg2
;
}
f2
;
}
u
;
int
type
;
};
};
static
struct
{
struct
rcu
*
x
__attribute__
((
aligned
(
CACHELINE
)));
}
rcu_delayed_head
[
NCPU
];
static
struct
{
struct
rcu
*
x
__attribute__
((
aligned
(
CACHELINE
)));
}
rcu_delayed_head
[
NCPU
];
static
struct
{
struct
rcu
*
x
__attribute__
((
aligned
(
CACHELINE
)));
}
rcu_delayed_tail
[
NCPU
];
static
struct
{
struct
rcu
*
x
__attribute__
((
aligned
(
CACHELINE
)));
}
rcu_delayed_tail
[
NCPU
];
...
@@ -63,9 +74,16 @@ rcu_gc(void)
...
@@ -63,9 +74,16 @@ rcu_gc(void)
if
(
r
->
epoch
>=
min_epoch
[
cpu
->
id
].
x
)
if
(
r
->
epoch
>=
min_epoch
[
cpu
->
id
].
x
)
break
;
break
;
// cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item);
// cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item);
if
(
r
->
dofree
==
0
)
switch
(
r
->
type
)
{
panic
(
"rcu_gc"
);
case
1
:
r
->
dofree
(
r
->
item
);
r
->
u
.
f1
.
dofree
(
r
->
u
.
f1
.
item
);
break
;
case
2
:
r
->
u
.
f2
.
dofree
(
r
->
u
.
f2
.
arg1
,
r
->
u
.
f2
.
arg2
);
break
;
default
:
panic
(
"rcu type"
);
}
delayed_nfree
[
cpu
->
id
].
v
--
;
delayed_nfree
[
cpu
->
id
].
v
--
;
n
++
;
n
++
;
rcu_delayed_head
[
cpu
->
id
].
x
=
r
->
next
;
rcu_delayed_head
[
cpu
->
id
].
x
=
r
->
next
;
...
@@ -84,34 +102,56 @@ rcu_gc(void)
...
@@ -84,34 +102,56 @@ rcu_gc(void)
}
}
// XXX Use atomic instruction to update list (instead of holding lock)
// XXX Use atomic instruction to update list (instead of holding lock)
static
void
rcu_delayed_int
(
struct
rcu
*
r
)
{
pushcli
();
acquire
(
&
rcu_lock
[
cpu
->
id
].
l
);
// cprintf("rcu_delayed: %d\n", global_epoch);
if
(
rcu_delayed_tail
[
cpu
->
id
].
x
!=
0
)
rcu_delayed_tail
[
cpu
->
id
].
x
->
next
=
r
;
rcu_delayed_tail
[
cpu
->
id
].
x
=
r
;
if
(
rcu_delayed_head
[
cpu
->
id
].
x
==
0
)
rcu_delayed_head
[
cpu
->
id
].
x
=
r
;
release
(
&
rcu_lock
[
cpu
->
id
].
l
);
delayed_nfree
[
cpu
->
id
].
v
++
;
popcli
();
}
void
void
rcu_delayed
(
void
*
e
,
void
(
*
dofree
)(
void
*
))
rcu_delayed
(
void
*
e
,
void
(
*
dofree
)(
void
*
))
{
{
if
(
rcu_debug
)
{
if
(
rcu_debug
)
{
cprintf
(
"rcu_delayed: %x %x
\n
"
,
dofree
,
e
);
cprintf
(
"rcu_delayed: %x %x
\n
"
,
dofree
,
e
);
for
(
struct
rcu
*
r
=
rcu_delayed_head
[
cpu
->
id
].
x
;
r
;
r
=
r
->
next
)
for
(
struct
rcu
*
r
=
rcu_delayed_head
[
cpu
->
id
].
x
;
r
;
r
=
r
->
next
)
if
(
r
->
item
==
e
&&
r
->
dofree
==
dofree
)
if
(
r
->
u
.
f1
.
item
==
e
&&
r
->
u
.
f1
.
dofree
==
dofree
)
panic
(
"rcu_delayed double free"
);
panic
(
"rcu_delayed double free"
);
}
}
struct
rcu
*
r
=
rcu_alloc
();
struct
rcu
*
r
=
rcu_alloc
();
if
(
r
==
0
)
if
(
r
==
0
)
panic
(
"rcu_delayed"
);
panic
(
"rcu_delayed"
);
r
->
dofree
=
dofree
;
r
->
u
.
f1
.
dofree
=
dofree
;
r
->
item
=
e
;
r
->
u
.
f1
.
item
=
e
;
r
->
next
=
0
;
r
->
next
=
0
;
r
->
epoch
=
global_epoch
;
r
->
epoch
=
global_epoch
;
pushcli
();
r
->
type
=
1
;
acquire
(
&
rcu_lock
[
cpu
->
id
].
l
);
rcu_delayed_int
(
r
);
// cprintf("rcu_delayed: %d\n", global_epoch);
}
if
(
rcu_delayed_tail
[
cpu
->
id
].
x
!=
0
)
rcu_delayed_tail
[
cpu
->
id
].
x
->
next
=
r
;
void
rcu_delayed_tail
[
cpu
->
id
].
x
=
r
;
rcu_delayed2
(
int
a1
,
uint
a2
,
void
(
*
dofree
)(
int
,
uint
))
if
(
rcu_delayed_head
[
cpu
->
id
].
x
==
0
)
{
rcu_delayed_head
[
cpu
->
id
].
x
=
r
;
struct
rcu
*
r
=
rcu_alloc
();
release
(
&
rcu_lock
[
cpu
->
id
].
l
);
if
(
r
==
0
)
delayed_nfree
[
cpu
->
id
].
v
++
;
panic
(
"rcu_delayed"
);
popcli
();
r
->
u
.
f2
.
dofree
=
dofree
;
r
->
u
.
f2
.
arg1
=
a1
;
r
->
u
.
f2
.
arg2
=
a2
;
r
->
next
=
0
;
r
->
epoch
=
global_epoch
;
r
->
type
=
2
;
rcu_delayed_int
(
r
);
}
}
void
void
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论