Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
6600eed0
提交
6600eed0
5月 25, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
enumerate name space
compiling, but unused, primitive rcu
上级
50d66311
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
190 行增加
和
26 行删除
+190
-26
Makefile
Makefile
+2
-1
defs.h
defs.h
+5
-1
main.c
main.c
+1
-0
ns.c
ns.c
+13
-0
param.h
param.h
+1
-0
proc.c
proc.c
+19
-24
proc.h
proc.h
+2
-0
rcu.c
rcu.c
+147
-0
没有找到文件。
Makefile
浏览文件 @
6600eed0
...
...
@@ -28,7 +28,8 @@ OBJS = \
uart.o
\
vectors.o
\
vm.o
\
ns.o
ns.o
\
rcu.o
# Cross-compiling (e.g., on Mac OS X)
TOOLPREFIX
=
x86_64-jos-elf-
...
...
defs.h
浏览文件 @
6600eed0
...
...
@@ -102,6 +102,8 @@ int ns_allockey(struct ns*);
int
ns_insert
(
struct
ns
*
,
int
key
,
void
*
);
void
*
ns_lookup
(
struct
ns
*
,
int
);
int
ns_remove
(
struct
ns
*
ns
,
int
key
);
void
ns_enumerate
(
struct
ns
*
ns
,
void
(
*
f
)(
int
,
void
*
));
// picirq.c
void
picenable
(
int
);
...
...
@@ -122,7 +124,6 @@ int fork(int);
int
growproc
(
int
);
int
kill
(
int
);
void
pinit
(
void
);
void
procdump
(
int
);
void
procdumpall
(
void
);
void
scheduler
(
void
)
__attribute__
((
noreturn
));
void
sched
(
void
);
...
...
@@ -131,6 +132,9 @@ int wait(void);
void
yield
(
void
);
void
migrate
(
void
);
// rcu.c
void
rcuinit
(
void
);
// swtch.S
void
swtch
(
struct
context
**
,
struct
context
*
);
...
...
main.c
浏览文件 @
6600eed0
...
...
@@ -51,6 +51,7 @@ mainc(void)
uartinit
();
// serial port
kvmalloc
();
// initialize the kernel page table
nsinit
();
// initialize name space module
rcuinit
();
// initialize rcu module
pinit
();
// process table
tvinit
();
// trap vectors
binit
();
// buffer cache
...
...
ns.c
浏览文件 @
6600eed0
...
...
@@ -124,3 +124,16 @@ ns_remove(struct ns *ns, int key)
return
r
;
}
void
ns_enumerate
(
struct
ns
*
ns
,
void
(
*
f
)(
int
,
void
*
))
{
acquire
(
&
ns
->
lock
);
for
(
int
i
=
0
;
i
<
NHASH
;
i
++
)
{
struct
elem
*
e
=
TAILQ_FIRST
(
&
(
ns
->
table
[
i
].
chain
));
while
(
e
!=
NULL
)
{
(
*
f
)(
e
->
key
,
e
->
val
);
e
=
TAILQ_NEXT
(
e
,
chain
);
}
}
release
(
&
ns
->
lock
);
}
param.h
浏览文件 @
6600eed0
...
...
@@ -12,3 +12,4 @@
#define MAXARG 32 // max exec arguments
#define MAXNAME 16 // max string names
#define MINCYCTHRESH 1000000 // min cycles a proc executes on a core before allowed to be stolen
#define INF 0xFFFFFFFF
proc.c
浏览文件 @
6600eed0
...
...
@@ -11,8 +11,8 @@
struct
runq
runqs
[
NCPU
];
int
idle
[
NCPU
];
struct
ns
*
nspid
;
static
struct
proc
*
initproc
;
static
struct
ns
*
nspid
;
extern
void
forkret
(
void
);
extern
void
trapret
(
void
);
...
...
@@ -55,9 +55,11 @@ allocproc(void)
p
->
state
=
EMBRYO
;
p
->
pid
=
ns_allockey
(
nspid
);
p
->
epoch
=
INF
;
p
->
cpuid
=
cpu
->
id
;
if
(
ns_insert
(
nspid
,
p
->
pid
,
(
void
*
)
p
)
<
0
)
panic
(
"allocproc: ns_insert"
);
p
->
cpuid
=
cpu
->
id
;
// Allocate kernel stack if possible.
if
((
p
->
kstack
=
kalloc
())
==
0
){
...
...
@@ -614,13 +616,10 @@ kill(int pid)
return
0
;
}
//PAGEBREAK: 36
// Print a process listing to console. For debugging.
// Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further.
void
procdump
(
int
c
)
void
procdump
(
int
k
,
void
*
v
)
{
struct
proc
*
p
=
(
struct
proc
*
)
v
;
static
char
*
states
[]
=
{
[
UNUSED
]
"unused"
,
[
EMBRYO
]
"embryo"
,
...
...
@@ -631,31 +630,27 @@ procdump(int c)
};
char
*
state
;
#if 0
if
(
p
->
state
>=
0
&&
p
->
state
<
NELEM
(
states
)
&&
states
[
p
->
state
])
state
=
states
[
p
->
state
];
else
state
=
"???"
;
cprintf
(
"%d %s %s %d, "
,
p
->
pid
,
state
,
p
->
name
,
p
->
cpuid
);
uint
pc
[
10
];
if
(
p
->
state
==
SLEEPING
){
getcallerpcs
((
uint
*
)
p
->
context
->
ebp
+
2
,
pc
);
for(i=0; i<10 && pc[i] != 0; i++)
for
(
i
nt
i
=
0
;
i
<
10
&&
pc
[
i
]
!=
0
;
i
++
)
cprintf
(
" %p"
,
pc
[
i
]);
}
#endif
struct
proc
*
q
;
cprintf
(
"runq: "
);
STAILQ_FOREACH
(
q
,
&
runqs
[
c
].
runq
,
run_next
)
{
if
(
q
->
state
>=
0
&&
q
->
state
<
NELEM
(
states
)
&&
states
[
q
->
state
])
state
=
states
[
q
->
state
];
else
state
=
"???"
;
cprintf
(
"%d %s %s, "
,
q
->
pid
,
state
,
q
->
name
);
}
cprintf
(
"
\n
"
);
}
//PAGEBREAK: 36
// Print a process listing to console. For debugging.
// Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further.
void
procdumpall
(
void
)
{
int
c
;
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
procdump
(
c
);
}
ns_enumerate
(
nspid
,
procdump
);
}
proc.h
浏览文件 @
6600eed0
...
...
@@ -88,6 +88,7 @@ struct proc {
SLIST_HEAD
(
childlist
,
proc
)
childq
;
SLIST_ENTRY
(
proc
)
child_next
;
struct
condvar
cv
;
uint
epoch
;
};
// Process memory is laid out contiguously, low addresses first:
...
...
@@ -129,6 +130,7 @@ extern struct cpu cpus[NCPU];
extern
struct
runq
runqs
[
NCPU
];
extern
struct
condtab
condtabs
[
NCPU
];
extern
int
ncpu
;
extern
struct
ns
*
nspid
;
// Per-CPU variables, holding pointers to the
// current cpu and to the current process.
...
...
rcu.c
0 → 100644
浏览文件 @
6600eed0
#include "types.h"
#include "defs.h"
#include "param.h"
#include "mmu.h"
#include "x86.h"
#include "spinlock.h"
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#define NRCU 1000
#define NDELAY 500
struct
rcu
{
void
*
item
;
unsigned
long
epoch
;
struct
rcu
*
rcu
;
void
(
*
dofree
)(
void
*
);
};
static
struct
rcu
*
rcu_delayed_head
;
static
struct
rcu
*
rcu_delayed_tail
;
static
struct
rcu
*
rcu_freelist
;
static
uint
global_epoch
;
static
uint
min_epoch
;
static
struct
spinlock
rcu_lock
;
static
int
delayed_nfree
;
static
int
ninuse
;
void
rcuinit
(
void
)
{
struct
rcu
*
r
;
int
i
;
initlock
(
&
rcu_lock
,
"rcu"
);
for
(
i
=
0
;
i
<
NRCU
;
i
++
)
{
r
=
(
struct
rcu
*
)
kmalloc
(
sizeof
(
struct
rcu
));
r
->
rcu
=
rcu_freelist
;
rcu_freelist
=
r
;
}
cprintf
(
"rcu_init: allocated %ld bytes
\n
"
,
sizeof
(
struct
rcu
)
*
NRCU
);
}
struct
rcu
*
rcu_alloc
()
{
struct
rcu
*
r
=
rcu_freelist
;
if
(
r
==
0
)
{
panic
(
"rcu_alloc"
);
}
rcu_freelist
=
r
->
rcu
;
return
r
;
}
void
rcu_min
(
int
key
,
void
*
v
){
struct
proc
*
p
=
(
struct
proc
*
)
v
;
if
(
min_epoch
>
p
->
epoch
)
{
min_epoch
=
p
->
epoch
;
}
}
// XXX use atomic instruction to update list (instead of holding lock)
// lists of lists?
void
rcu_gc
(
void
)
{
struct
rcu
*
r
,
*
nr
;
int
n
=
0
;
min_epoch
=
global_epoch
;
ns_enumerate
(
nspid
,
rcu_min
);
for
(
r
=
rcu_delayed_head
;
r
!=
NULL
;
r
=
nr
)
{
if
(
r
->
epoch
>=
min_epoch
)
break
;
// printf("free: %ld\n", r->epoch);
if
(
r
->
dofree
==
0
)
panic
(
"rcu_gc"
);
r
->
dofree
(
r
->
item
);
delayed_nfree
--
;
n
++
;
rcu_delayed_head
=
r
->
rcu
;
if
(
rcu_delayed_head
==
0
)
rcu_delayed_tail
=
0
;
nr
=
r
->
rcu
;
r
->
rcu
=
rcu_freelist
;
rcu_freelist
=
r
;
}
// printf("rcu_gc: n=%d ndelayed_free=%d nfree=%d ninuse=%d\n", n, delayed_nfree,
// tree_nfree, tree_ninuse);
}
// XXX Use atomic instruction to update list (instead of holding lock)
void
rcu_delayed
(
void
*
e
,
void
(
*
dofree
)(
void
*
))
{
struct
rcu
*
r
=
rcu_alloc
();
if
(
r
==
0
)
panic
(
"rcu_delayed"
);
r
->
dofree
=
dofree
;
r
->
item
=
e
;
r
->
rcu
=
0
;
r
->
epoch
=
global_epoch
;
// printf("rcu_delayed: %ld\n", global_epoch);
if
(
rcu_delayed_tail
!=
0
)
rcu_delayed_tail
->
rcu
=
r
;
rcu_delayed_tail
=
r
;
if
(
rcu_delayed_head
==
0
)
rcu_delayed_head
=
r
;
delayed_nfree
++
;
ninuse
--
;
}
void
rcu_begin_read
(
int
tid
)
{
proc
->
epoch
=
global_epoch
;
__sync_synchronize
();
}
void
rcu_end_read
(
int
tid
)
{
proc
->
epoch
=
INF
;
}
void
rcu_begin_write
(
int
tid
)
{
acquire
(
&
rcu_lock
);
}
void
rcu_end_write
(
int
tid
)
{
// for other data structures using rcu, use atomic add:
__sync_fetch_and_add
(
&
global_epoch
,
1
);
rcu_gc
();
release
(
&
rcu_lock
);
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论