Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
b635db5d
提交
b635db5d
6月 18, 2011
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
different ns key types (int, str)
上级
8e18824b
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
134 行增加
和
50 行删除
+134
-50
bio.c
bio.c
+6
-6
defs.h
defs.h
+22
-6
fs.c
fs.c
+5
-5
ns.c
ns.c
+79
-20
proc.c
proc.c
+10
-10
rcu.c
rcu.c
+4
-3
string.c
string.c
+8
-0
没有找到文件。
bio.c
浏览文件 @
b635db5d
...
...
@@ -44,13 +44,13 @@ binit(void)
b
->
flags
=
0
;
initlock
(
&
b
->
lock
,
"bcache-lock"
);
initcondvar
(
&
b
->
cv
,
"bcache-cv"
);
if
(
ns_insert
(
bufns
,
b
->
sector
,
b
)
<
0
)
if
(
ns_insert
(
bufns
,
KI
(
b
->
sector
)
,
b
)
<
0
)
panic
(
"binit ns_insert"
);
}
}
static
void
*
evict
(
uint
key
,
void
*
bp
)
evict
(
void
*
v
key
,
void
*
bp
)
{
struct
buf
*
b
=
bp
;
acquire
(
&
b
->
lock
);
...
...
@@ -61,7 +61,7 @@ evict(uint key, void *bp)
}
static
void
*
evict_valid
(
uint
key
,
void
*
bp
)
evict_valid
(
void
*
v
key
,
void
*
bp
)
{
struct
buf
*
b
=
bp
;
acquire
(
&
b
->
lock
);
...
...
@@ -83,7 +83,7 @@ bget(uint dev, uint sector, int *writer)
// Try for cached block.
// XXX ignore dev
rcu_begin_read
();
b
=
ns_lookup
(
bufns
,
sector
);
b
=
ns_lookup
(
bufns
,
KI
(
sector
)
);
if
(
b
)
{
if
(
b
->
dev
!=
dev
)
panic
(
"dev mismatch"
);
...
...
@@ -113,7 +113,7 @@ bget(uint dev, uint sector, int *writer)
if
(
victim
==
0
)
panic
(
"bget all busy"
);
victim
->
flags
|=
B_BUSY
;
ns_remove
(
bufns
,
victim
->
sector
,
victim
);
ns_remove
(
bufns
,
KI
(
victim
->
sector
)
,
victim
);
release
(
&
victim
->
lock
);
rcu_delayed
(
victim
,
kmfree
);
...
...
@@ -126,7 +126,7 @@ bget(uint dev, uint sector, int *writer)
initlock
(
&
b
->
lock
,
b
->
lockname
+
3
);
initcondvar
(
&
b
->
cv
,
b
->
lockname
);
rcu_begin_read
();
if
(
ns_insert
(
bufns
,
b
->
sector
,
b
)
<
0
)
{
if
(
ns_insert
(
bufns
,
KI
(
b
->
sector
)
,
b
)
<
0
)
{
rcu_delayed
(
b
,
kmfree
);
goto
loop
;
}
...
...
defs.h
浏览文件 @
b635db5d
...
...
@@ -99,15 +99,30 @@ void mpinit(void);
void
mpstartthem
(
void
);
// ns.c
enum
{
nskey_int
=
1
,
nskey_str
,
};
struct
nskey
{
int
type
;
union
{
uint
i
;
char
*
s
;
}
u
;
};
#define KI(v) (struct nskey){.type=nskey_int,.u.i=v}
#define KS(v) (struct nskey){.type=nskey_str,.u.s=v}
void
nsinit
(
void
);
struct
ns
*
nsalloc
(
int
allowdup
);
int
ns_allockey
(
struct
ns
*
);
int
ns_insert
(
struct
ns
*
,
uint
key
,
void
*
);
void
*
ns_lookup
(
struct
ns
*
,
uint
);
int
ns_remove
(
struct
ns
*
ns
,
uint
key
,
void
*
val
);
void
*
ns_enumerate
(
struct
ns
*
ns
,
void
*
(
*
f
)(
uint
,
void
*
));
void
*
ns_enumerate_key
(
struct
ns
*
ns
,
uint
key
,
void
*
(
*
f
)(
void
*
));
int
ns_insert
(
struct
ns
*
,
struct
nskey
key
,
void
*
);
void
*
ns_lookup
(
struct
ns
*
,
struct
nskey
key
);
int
ns_remove
(
struct
ns
*
ns
,
struct
nskey
key
,
void
*
val
);
void
*
ns_enumerate
(
struct
ns
*
ns
,
void
*
(
*
f
)(
void
*
,
void
*
));
void
*
ns_enumerate_key
(
struct
ns
*
ns
,
struct
nskey
key
,
void
*
(
*
f
)(
void
*
));
// picirq.c
void
picenable
(
int
);
...
...
@@ -166,6 +181,7 @@ char* safestrcpy(char*, const char*, int);
int
strlen
(
const
char
*
);
int
strncmp
(
const
char
*
,
const
char
*
,
uint
);
char
*
strncpy
(
char
*
,
const
char
*
,
int
);
int
strcmp
(
const
char
*
p
,
const
char
*
q
);
// syscall.c
int
argint
(
int
,
int
*
);
...
...
fs.c
浏览文件 @
b635db5d
...
...
@@ -143,7 +143,7 @@ iinit(void)
ip
->
inum
=
-
i
-
1
;
initlock
(
&
ip
->
lock
,
"icache-lock"
);
initcondvar
(
&
ip
->
cv
,
"icache-cv"
);
ns_insert
(
ins
,
ip
->
inum
,
ip
);
ns_insert
(
ins
,
KI
(
ip
->
inum
)
,
ip
);
}
}
...
...
@@ -205,7 +205,7 @@ iupdate(struct inode *ip)
}
static
void
*
evict
(
uint
key
,
void
*
p
)
evict
(
void
*
v
key
,
void
*
p
)
{
struct
inode
*
ip
=
p
;
acquire
(
&
ip
->
lock
);
...
...
@@ -230,7 +230,7 @@ iget(uint dev, uint inum)
retry:
// Try for cached inode.
rcu_begin_read
();
ip
=
ns_lookup
(
ins
,
inum
);
// XXX ignore dev
ip
=
ns_lookup
(
ins
,
KI
(
inum
)
);
// XXX ignore dev
if
(
ip
)
{
if
(
ip
->
dev
!=
dev
)
panic
(
"iget dev mismatch"
);
// tricky: first bump ref, then check free flag
...
...
@@ -265,7 +265,7 @@ iget(uint dev, uint inum)
goto
retry_evict
;
}
release
(
&
victim
->
lock
);
ns_remove
(
ins
,
victim
->
inum
,
victim
);
ns_remove
(
ins
,
KI
(
victim
->
inum
)
,
victim
);
rcu_delayed
(
victim
,
kmfree
);
ip
=
kmalloc
(
sizeof
(
*
ip
));
...
...
@@ -277,7 +277,7 @@ iget(uint dev, uint inum)
snprintf
(
ip
->
lockname
,
sizeof
(
ip
->
lockname
),
"cv:ino:%d"
,
ip
->
inum
);
initlock
(
&
ip
->
lock
,
ip
->
lockname
+
3
);
initcondvar
(
&
ip
->
cv
,
ip
->
lockname
);
if
(
ns_insert
(
ins
,
ip
->
inum
,
ip
)
<
0
)
{
if
(
ns_insert
(
ins
,
KI
(
ip
->
inum
)
,
ip
)
<
0
)
{
rcu_delayed
(
ip
,
kmfree
);
goto
retry
;
}
...
...
ns.c
浏览文件 @
b635db5d
...
...
@@ -2,6 +2,7 @@
#include "defs.h"
#include "spinlock.h"
#include "param.h"
#include <stddef.h>
// name spaces
// XXX maybe use open hash table, no chain, better cache locality
...
...
@@ -13,10 +14,13 @@
#endif
struct
elem
{
uint
key
;
void
*
val
;
int
next_lock
;
struct
elem
*
volatile
next
;
union
{
uint
ikey
;
char
skey
[
0
];
};
};
struct
bucket
{
...
...
@@ -50,16 +54,71 @@ nsalloc(int allowdup)
}
static
struct
elem
*
elemalloc
(
void
)
elemalloc
(
struct
nskey
*
k
)
{
struct
elem
*
e
=
0
;
e
=
kmalloc
(
sizeof
(
struct
elem
));
int
sz
;
switch
(
k
->
type
)
{
case
nskey_int
:
sz
=
sizeof
(
*
e
);
break
;
case
nskey_str
:
sz
=
offsetof
(
struct
elem
,
skey
)
+
strlen
(
k
->
u
.
s
)
+
1
;
break
;
default:
panic
(
"key type"
);
}
e
=
kmalloc
(
sz
);
if
(
e
==
0
)
return
0
;
memset
(
e
,
0
,
s
izeof
(
struct
elem
)
);
memset
(
e
,
0
,
s
z
);
return
e
;
}
static
int
h
(
struct
nskey
*
k
)
{
switch
(
k
->
type
)
{
case
nskey_int
:
return
k
->
u
.
i
%
NHASH
;
case
nskey_str
:
return
k
->
u
.
s
[
0
]
%
NHASH
;
// XXX
default:
panic
(
"key type"
);
}
}
static
void
setkey
(
struct
elem
*
e
,
struct
nskey
*
k
)
{
switch
(
k
->
type
)
{
case
nskey_int
:
e
->
ikey
=
k
->
u
.
i
;
break
;
case
nskey_str
:
strncpy
(
e
->
skey
,
k
->
u
.
s
,
__INT_MAX__
);
break
;
default:
panic
(
"key type"
);
}
}
static
int
cmpkey
(
struct
elem
*
e
,
struct
nskey
*
k
)
{
switch
(
k
->
type
)
{
case
nskey_int
:
return
e
->
ikey
==
k
->
u
.
i
;
break
;
case
nskey_str
:
return
!
strcmp
(
e
->
skey
,
k
->
u
.
s
);
break
;
default:
panic
(
"key type"
);
}
}
// XXX need something more scalable; partition the name space?
int
ns_allockey
(
struct
ns
*
ns
)
...
...
@@ -69,13 +128,13 @@ ns_allockey(struct ns *ns)
}
int
ns_insert
(
struct
ns
*
ns
,
uint
key
,
void
*
val
)
ns_insert
(
struct
ns
*
ns
,
struct
nskey
key
,
void
*
val
)
{
struct
elem
*
e
=
elemalloc
();
struct
elem
*
e
=
elemalloc
(
&
key
);
if
(
e
)
{
e
->
key
=
key
;
setkey
(
e
,
&
key
)
;
e
->
val
=
val
;
uint
i
=
key
%
NHASH
;
uint
i
=
h
(
&
key
)
;
rcu_begin_write
(
0
);
retry:
...
...
@@ -83,7 +142,7 @@ ns_insert(struct ns *ns, uint key, void *val)
struct
elem
*
root
=
ns
->
table
[
i
].
chain
;
if
(
!
ns
->
allowdup
)
{
for
(
struct
elem
*
x
=
root
;
x
;
x
=
x
->
next
)
{
if
(
x
->
key
==
key
)
{
if
(
cmpkey
(
x
,
&
key
)
)
{
rcu_end_write
(
0
);
rcu_delayed
(
e
,
kmfree
);
return
-
1
;
...
...
@@ -102,15 +161,15 @@ ns_insert(struct ns *ns, uint key, void *val)
}
void
*
ns_lookup
(
struct
ns
*
ns
,
uint
key
)
ns_lookup
(
struct
ns
*
ns
,
struct
nskey
key
)
{
uint
i
=
key
%
NHASH
;
uint
i
=
h
(
&
key
)
;
rcu_begin_read
();
struct
elem
*
e
=
ns
->
table
[
i
].
chain
;
while
(
e
!=
NULL
)
{
if
(
e
->
key
==
key
)
{
if
(
cmpkey
(
e
,
&
key
)
)
{
rcu_end_read
();
return
e
->
val
;
}
...
...
@@ -122,9 +181,9 @@ ns_lookup(struct ns *ns, uint key)
}
int
ns_remove
(
struct
ns
*
ns
,
uint
key
,
void
*
v
)
ns_remove
(
struct
ns
*
ns
,
struct
nskey
key
,
void
*
v
)
{
uint
i
=
key
%
NHASH
;
uint
i
=
h
(
&
key
)
;
rcu_begin_write
(
0
);
retry:
...
...
@@ -138,7 +197,7 @@ ns_remove(struct ns *ns, uint key, void *v)
if
(
!
e
)
break
;
if
(
e
->
key
==
key
&&
(
e
->
val
==
v
||
v
==
0
))
{
if
(
cmpkey
(
e
,
&
key
)
&&
(
e
->
val
==
v
||
v
==
0
))
{
// XXX annotate as locks for mtrace
if
(
!
__sync_bool_compare_and_swap
(
&
e
->
next_lock
,
0
,
1
))
goto
retry
;
...
...
@@ -166,13 +225,13 @@ ns_remove(struct ns *ns, uint key, void *v)
}
void
*
ns_enumerate
(
struct
ns
*
ns
,
void
*
(
*
f
)(
uint
,
void
*
))
ns_enumerate
(
struct
ns
*
ns
,
void
*
(
*
f
)(
void
*
,
void
*
))
{
rcu_begin_read
();
for
(
int
i
=
0
;
i
<
NHASH
;
i
++
)
{
struct
elem
*
e
=
ns
->
table
[
i
].
chain
;
while
(
e
!=
NULL
)
{
void
*
r
=
(
*
f
)(
e
->
key
,
e
->
val
);
void
*
r
=
(
*
f
)(
&
e
->
i
key
,
e
->
val
);
if
(
r
)
{
rcu_end_read
();
return
r
;
...
...
@@ -185,13 +244,13 @@ ns_enumerate(struct ns *ns, void *(*f)(uint, void *))
}
void
*
ns_enumerate_key
(
struct
ns
*
ns
,
uint
key
,
void
*
(
*
f
)(
void
*
))
ns_enumerate_key
(
struct
ns
*
ns
,
struct
nskey
key
,
void
*
(
*
f
)(
void
*
))
{
uint
i
=
key
%
NHASH
;
uint
i
=
h
(
&
key
)
;
rcu_begin_read
();
struct
elem
*
e
=
ns
->
table
[
i
].
chain
;
while
(
e
)
{
if
(
e
->
key
==
key
)
{
if
(
cmpkey
(
e
,
&
key
)
)
{
void
*
r
=
(
*
f
)(
e
->
val
);
if
(
r
)
{
rcu_end_read
();
...
...
proc.c
浏览文件 @
b635db5d
...
...
@@ -63,12 +63,12 @@ allocproc(void)
initlock
(
&
p
->
lock
,
p
->
lockname
+
3
);
initcondvar
(
&
p
->
cv
,
p
->
lockname
);
if
(
ns_insert
(
nspid
,
p
->
pid
,
(
void
*
)
p
)
<
0
)
if
(
ns_insert
(
nspid
,
KI
(
p
->
pid
)
,
(
void
*
)
p
)
<
0
)
panic
(
"allocproc: ns_insert"
);
// Allocate kernel stack if possible.
if
((
p
->
kstack
=
kalloc
())
==
0
){
if
(
ns_remove
(
nspid
,
p
->
pid
,
p
)
<
0
)
if
(
ns_remove
(
nspid
,
KI
(
p
->
pid
)
,
p
)
<
0
)
panic
(
"allocproc: ns_remove"
);
rcu_delayed
(
p
,
kmfree
);
return
0
;
...
...
@@ -109,7 +109,7 @@ addrun(struct proc *p)
if
(
p
->
on_runq
>=
0
)
panic
(
"addrun on runq already"
);
ns_insert
(
nsrunq
,
p
->
cpuid
,
p
);
ns_insert
(
nsrunq
,
KI
(
p
->
cpuid
)
,
p
);
p
->
on_runq
=
p
->
cpuid
;
}
...
...
@@ -123,7 +123,7 @@ delrun(struct proc *p)
if
(
p
->
on_runq
<
0
)
panic
(
"delrun not on runq"
);
if
(
ns_remove
(
nsrunq
,
p
->
on_runq
,
p
)
<
0
)
if
(
ns_remove
(
nsrunq
,
KI
(
p
->
on_runq
)
,
p
)
<
0
)
panic
(
"delrun: ns_remove"
);
p
->
on_runq
=
-
1
;
}
...
...
@@ -269,7 +269,7 @@ fork(int flags)
kfree
(
np
->
kstack
);
np
->
kstack
=
0
;
np
->
state
=
UNUSED
;
if
(
ns_remove
(
nspid
,
np
->
pid
,
np
)
<
0
)
if
(
ns_remove
(
nspid
,
KI
(
np
->
pid
)
,
np
)
<
0
)
panic
(
"fork: ns_remove"
);
rcu_delayed
(
np
,
kmfree
);
return
-
1
;
...
...
@@ -384,7 +384,7 @@ wait(void)
p
->
kstack
=
0
;
vmap_decref
(
p
->
vmap
);
p
->
state
=
UNUSED
;
if
(
ns_remove
(
nspid
,
p
->
pid
,
p
)
<
0
)
if
(
ns_remove
(
nspid
,
KI
(
p
->
pid
)
,
p
)
<
0
)
panic
(
"wait: ns_remove"
);
p
->
pid
=
0
;
p
->
parent
=
0
;
...
...
@@ -445,7 +445,7 @@ migrate(struct proc *p)
}
static
void
*
steal_cb
(
uint
k
,
void
*
v
)
steal_cb
(
void
*
v
k
,
void
*
v
)
{
struct
proc
*
p
=
v
;
...
...
@@ -514,7 +514,7 @@ scheduler(void)
// Enable interrupts on this processor.
sti
();
struct
proc
*
p
=
ns_enumerate_key
(
nsrunq
,
cpu
->
id
,
choose_runnable
);
struct
proc
*
p
=
ns_enumerate_key
(
nsrunq
,
KI
(
cpu
->
id
)
,
choose_runnable
);
if
(
p
)
{
acquire
(
&
p
->
lock
);
if
(
p
->
state
!=
RUNNABLE
)
{
...
...
@@ -630,7 +630,7 @@ kill(int pid)
{
struct
proc
*
p
;
p
=
(
struct
proc
*
)
ns_lookup
(
nspid
,
pid
);
p
=
(
struct
proc
*
)
ns_lookup
(
nspid
,
KI
(
pid
)
);
if
(
p
==
0
)
{
panic
(
"kill"
);
return
-
1
;
...
...
@@ -653,7 +653,7 @@ kill(int pid)
return
0
;
}
void
*
procdump
(
uint
k
,
void
*
v
)
void
*
procdump
(
void
*
v
k
,
void
*
v
)
{
struct
proc
*
p
=
(
struct
proc
*
)
v
;
...
...
rcu.c
浏览文件 @
b635db5d
...
...
@@ -48,7 +48,7 @@ rcu_alloc()
}
void
*
rcu_min
(
uint
key
,
void
*
v
){
rcu_min
(
void
*
v
key
,
void
*
v
){
struct
proc
*
p
=
(
struct
proc
*
)
v
;
if
(
min_epoch
[
cpu
->
id
].
x
>
p
->
epoch
)
{
min_epoch
[
cpu
->
id
].
x
=
p
->
epoch
;
...
...
@@ -93,8 +93,9 @@ rcu_gc(void)
kmfree
(
r
);
}
release
(
&
rcu_lock
[
cpu
->
id
].
l
);
// cprintf("rcu_gc: cpu %d n %d delayed_nfree=%d min_epoch=%d\n",
// cpu->id, n, delayed_nfree[cpu->id], min_epoch[cpu->id]);
if
(
rcu_debug
)
cprintf
(
"rcu_gc: cpu %d n %d delayed_nfree=%d min_epoch=%d
\n
"
,
cpu
->
id
,
n
,
delayed_nfree
[
cpu
->
id
],
min_epoch
[
cpu
->
id
]);
popcli
();
// global_epoch can be bumped anywhere; this seems as good a place as any
...
...
string.c
浏览文件 @
b635db5d
...
...
@@ -99,3 +99,11 @@ strlen(const char *s)
return
n
;
}
int
strcmp
(
const
char
*
p
,
const
char
*
q
)
{
while
(
*
p
&&
*
p
==
*
q
)
p
++
,
q
++
;
return
(
uchar
)
*
p
-
(
uchar
)
*
q
;
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论