Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
359dab4a
提交
359dab4a
3月 25, 2012
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'scale-amd64' of
ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6
into scale-amd64
上级
585d8b5f
a099175e
隐藏空白字符变更
内嵌
并排
正在显示
30 个修改的文件
包含
290 行增加
和
206 行删除
+290
-206
Makefile
Makefile
+1
-1
asharing.cc
bin/asharing.cc
+3
-0
mktree.cc
bin/mktree.cc
+16
-7
wqtest.cc
bin/wqtest.cc
+0
-1
xdu.cc
bin/xdu.cc
+1
-5
xls.cc
bin/xls.cc
+0
-3
dirit.hh
include/dirit.hh
+16
-8
fcntl.h
include/fcntl.h
+4
-0
kernel.hh
include/kernel.hh
+1
-0
lockstat.h
include/lockstat.h
+1
-0
ns.hh
include/ns.hh
+40
-7
radix.hh
include/radix.hh
+1
-0
user.h
include/user.h
+1
-1
wqfor.hh
include/wqfor.hh
+36
-2
wqkernel.hh
include/wqkernel.hh
+0
-5
wquser.hh
include/wquser.hh
+0
-6
bio.cc
kernel/bio.cc
+1
-34
fs.cc
kernel/fs.cc
+63
-79
lapic.cc
kernel/lapic.cc
+3
-9
proc.cc
kernel/proc.cc
+9
-8
radix.cc
kernel/radix.cc
+1
-5
sysfile.cc
kernel/sysfile.cc
+9
-0
threads.cc
lib/threads.cc
+2
-1
uthread.S
lib/uthread.S
+1
-1
wq.cc
lib/wq.cc
+0
-6
mkfs.c
tools/mkfs.c
+2
-2
Makefrag.user
user/Makefrag.user
+2
-1
crange_arch.hh
user/crange_arch.hh
+6
-0
umain.cc
user/umain.cc
+70
-9
wqlinux.hh
user/wqlinux.hh
+0
-5
没有找到文件。
Makefile
浏览文件 @
359dab4a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
Q
?=
@
Q
?=
@
TOOLPREFIX
?=
x86_64-jos-elf-
TOOLPREFIX
?=
x86_64-jos-elf-
QEMU
?=
qemu-system-x86_64
QEMU
?=
qemu-system-x86_64
QEMUSMP
?=
4
QEMUSMP
?=
8
QEMUSRC
?=
../mtrace
QEMUSRC
?=
../mtrace
MTRACE
?=
$(QEMU)
MTRACE
?=
$(QEMU)
HW
?=
qemu
HW
?=
qemu
...
...
bin/asharing.cc
浏览文件 @
359dab4a
...
@@ -78,6 +78,9 @@ main(int ac, char **av)
...
@@ -78,6 +78,9 @@ main(int ac, char **av)
pthread_t
tid
;
pthread_t
tid
;
pthread_create
(
&
tid
,
0
,
op
,
(
void
*
)
i
);
pthread_create
(
&
tid
,
0
,
op
,
(
void
*
)
i
);
}
}
for
(
u64
i
=
0
;
i
<
ncore
;
i
++
)
wait
();
mtdisable
(
"xv6-asharing"
);
mtdisable
(
"xv6-asharing"
);
}
}
}
}
bin/mktree.cc
浏览文件 @
359dab4a
...
@@ -3,12 +3,19 @@
...
@@ -3,12 +3,19 @@
#include "user.h"
#include "user.h"
#include "lib.h"
#include "lib.h"
#include "fcntl.h"
#include "fcntl.h"
#include "wq.hh"
static
int
branch
;
static
void
static
void
dolevel
(
int
fd
,
int
branch
,
int
depth
)
dolevel
(
int
fd
,
int
depth
)
{
{
if
(
depth
>
0
)
{
if
(
depth
>
0
)
{
for
(
int
i
=
0
;
i
<
branch
;
i
++
)
{
int
it
=
0
;
wq_for_serial
<
int
>
(
it
,
[](
int
&
it
)
->
bool
{
return
it
<
branch
;
},
[
&
fd
,
&
depth
](
int
i
)
->
void
{
char
name
[]
=
"a"
;
char
name
[]
=
"a"
;
*
name
+=
i
;
*
name
+=
i
;
if
(
mkdirat
(
fd
,
name
)
<
0
)
if
(
mkdirat
(
fd
,
name
)
<
0
)
...
@@ -16,9 +23,9 @@ dolevel(int fd, int branch, int depth)
...
@@ -16,9 +23,9 @@ dolevel(int fd, int branch, int depth)
int
nfd
=
openat
(
fd
,
name
,
O_RDONLY
);
int
nfd
=
openat
(
fd
,
name
,
O_RDONLY
);
if
(
nfd
<
0
)
if
(
nfd
<
0
)
die
(
"openat
"
);
die
(
"openat
: %s at %u"
,
name
,
depth
);
dolevel
(
nfd
,
branch
,
depth
-
1
);
dolevel
(
nfd
,
depth
-
1
);
}
}
);
}
}
close
(
fd
);
close
(
fd
);
...
@@ -30,8 +37,10 @@ main(int ac, char **av)
...
@@ -30,8 +37,10 @@ main(int ac, char **av)
if
(
ac
<
4
)
if
(
ac
<
4
)
die
(
"usage: %s dir branch depth"
,
av
[
0
]);
die
(
"usage: %s dir branch depth"
,
av
[
0
]);
initwq
();
const
char
*
dir
=
av
[
1
];
const
char
*
dir
=
av
[
1
];
int
branch
=
atoi
(
av
[
2
]);
branch
=
atoi
(
av
[
2
]);
int
depth
=
atoi
(
av
[
3
]);
int
depth
=
atoi
(
av
[
3
]);
if
(
mkdir
(
dir
))
if
(
mkdir
(
dir
))
...
@@ -41,5 +50,5 @@ main(int ac, char **av)
...
@@ -41,5 +50,5 @@ main(int ac, char **av)
if
(
fd
<
0
)
if
(
fd
<
0
)
die
(
"open"
);
die
(
"open"
);
dolevel
(
fd
,
branch
,
depth
);
dolevel
(
fd
,
depth
);
}
}
bin/wqtest.cc
浏览文件 @
359dab4a
...
@@ -127,6 +127,5 @@ main(int ac, char **av)
...
@@ -127,6 +127,5 @@ main(int ac, char **av)
test0
();
test0
();
testfork
();
testfork
();
execwork
::
test
();
execwork
::
test
();
exitwq
();
return
0
;
return
0
;
}
}
bin/xdu.cc
浏览文件 @
359dab4a
...
@@ -51,15 +51,12 @@ du(int fd)
...
@@ -51,15 +51,12 @@ du(int fd)
[](
dirit
&
i
)
->
bool
{
return
!
i
.
end
();
},
[](
dirit
&
i
)
->
bool
{
return
!
i
.
end
();
},
[
&
size
,
&
fd
](
const
char
*
name
)
->
void
[
&
size
,
&
fd
](
const
char
*
name
)
->
void
{
{
if
(
!
strcmp
(
name
,
"."
)
||
!
strcmp
(
name
,
".."
))
{
if
(
!
strcmp
(
name
,
"."
)
||
!
strcmp
(
name
,
".."
))
free
((
void
*
)
name
);
return
;
return
;
}
int
nfd
=
openat
(
fd
,
name
,
0
);
int
nfd
=
openat
(
fd
,
name
,
0
);
if
(
nfd
>=
0
)
if
(
nfd
>=
0
)
size
+=
du
(
nfd
);
// should go into work queue
size
+=
du
(
nfd
);
// should go into work queue
free
((
void
*
)
name
);
});
});
}
else
{
}
else
{
close
(
fd
);
close
(
fd
);
...
@@ -79,6 +76,5 @@ main(int ac, char **av)
...
@@ -79,6 +76,5 @@ main(int ac, char **av)
perf_stop
();
perf_stop
();
printf
(
"%ld
\n
"
,
s
);
printf
(
"%ld
\n
"
,
s
);
wq_dump
();
wq_dump
();
exitwq
();
return
0
;
return
0
;
}
}
bin/xls.cc
浏览文件 @
359dab4a
...
@@ -67,14 +67,12 @@ ls(const char *path)
...
@@ -67,14 +67,12 @@ ls(const char *path)
struct
stat
st
;
struct
stat
st
;
if
(
xfstatat
(
fd
,
name
,
&
st
)
<
0
){
if
(
xfstatat
(
fd
,
name
,
&
st
)
<
0
){
printf
(
"ls: cannot stat %s
\n
"
,
name
);
printf
(
"ls: cannot stat %s
\n
"
,
name
);
free
((
void
*
)
name
);
return
;
return
;
}
}
if
(
!
silent
)
if
(
!
silent
)
printf
(
"%u %10lu %10lu %s
\n
"
,
printf
(
"%u %10lu %10lu %s
\n
"
,
ST_TYPE
(
st
),
ST_INO
(
st
),
ST_SIZE
(
st
),
name
);
ST_TYPE
(
st
),
ST_INO
(
st
),
ST_SIZE
(
st
),
name
);
free
((
void
*
)
name
);
});
});
}
else
{
}
else
{
close
(
fd
);
close
(
fd
);
...
@@ -99,6 +97,5 @@ main(int argc, char *argv[])
...
@@ -99,6 +97,5 @@ main(int argc, char *argv[])
perf_stop
();
perf_stop
();
wq_dump
();
wq_dump
();
exitwq
();
return
0
;
return
0
;
}
}
include/dirit.hh
浏览文件 @
359dab4a
...
@@ -13,14 +13,6 @@ public:
...
@@ -13,14 +13,6 @@ public:
return
*
this
;
return
*
this
;
}
}
const
char
*
copy_value
()
{
char
*
buf
=
(
char
*
)
malloc
(
256
);
return
name
(
buf
,
256
);
}
bool
end
()
const
{
return
end_
;
}
private
:
char
*
name
(
char
*
buf
,
size_t
n
)
const
{
char
*
name
(
char
*
buf
,
size_t
n
)
const
{
n
=
MIN
(
DIRSIZ
+
1
,
n
);
n
=
MIN
(
DIRSIZ
+
1
,
n
);
memmove
(
buf
,
de_
.
name
,
n
-
1
);
memmove
(
buf
,
de_
.
name
,
n
-
1
);
...
@@ -28,6 +20,9 @@ private:
...
@@ -28,6 +20,9 @@ private:
return
buf
;
return
buf
;
}
}
bool
end
()
const
{
return
end_
;
}
private
:
void
refill
(
void
)
{
void
refill
(
void
)
{
int
r
;
int
r
;
...
@@ -45,3 +40,16 @@ private:
...
@@ -45,3 +40,16 @@ private:
bool
end_
;
bool
end_
;
struct
dirent
de_
;
struct
dirent
de_
;
};
};
static
inline
const
char
*
copy_value
(
dirit
&
it
)
{
char
*
buf
=
(
char
*
)
malloc
(
256
);
return
it
.
name
(
buf
,
256
);
}
static
inline
void
free_value
(
dirit
&
it
,
const
char
*
name
)
{
free
((
void
*
)
name
);
}
include/fcntl.h
浏览文件 @
359dab4a
...
@@ -4,3 +4,7 @@
...
@@ -4,3 +4,7 @@
#define O_CREATE 0x200
#define O_CREATE 0x200
#define AT_FDCWD -100
#define AT_FDCWD -100
#define FORK_SHARE_VMAP (1<<0)
#define FORK_SHARE_FD (1<<1)
include/kernel.hh
浏览文件 @
359dab4a
...
@@ -91,6 +91,7 @@ struct inode* ialloc(u32, short);
...
@@ -91,6 +91,7 @@ struct inode* ialloc(u32, short);
struct
inode
*
namei
(
inode
*
cwd
,
const
char
*
);
struct
inode
*
namei
(
inode
*
cwd
,
const
char
*
);
void
iput
(
struct
inode
*
);
void
iput
(
struct
inode
*
);
struct
inode
*
iget
(
u32
dev
,
u32
inum
);
struct
inode
*
iget
(
u32
dev
,
u32
inum
);
struct
inode
*
igetnoref
(
u32
dev
,
u32
inum
);
void
ilock
(
struct
inode
*
,
int
writer
);
void
ilock
(
struct
inode
*
,
int
writer
);
void
iunlockput
(
struct
inode
*
);
void
iunlockput
(
struct
inode
*
);
void
iupdate
(
struct
inode
*
);
void
iupdate
(
struct
inode
*
);
...
...
include/lockstat.h
浏览文件 @
359dab4a
...
@@ -52,6 +52,7 @@ struct klockstat;
...
@@ -52,6 +52,7 @@ struct klockstat;
#define LOCKSTAT_KALLOC 1
#define LOCKSTAT_KALLOC 1
#define LOCKSTAT_KMALLOC 1
#define LOCKSTAT_KMALLOC 1
#define LOCKSTAT_NET 1
#define LOCKSTAT_NET 1
#define LOCKSTAT_NS 1
#define LOCKSTAT_PIPE 1
#define LOCKSTAT_PIPE 1
#define LOCKSTAT_PROC 1
#define LOCKSTAT_PROC 1
#define LOCKSTAT_SCHED 1
#define LOCKSTAT_SCHED 1
...
...
include/ns.hh
浏览文件 @
359dab4a
#pragma once
#pragma once
#include "gc.hh"
#include "gc.hh"
#include "percpu.hh"
// name spaces
// name spaces
// XXX maybe use open hash table, no chain, better cache locality
// XXX maybe use open hash table, no chain, better cache locality
...
@@ -15,11 +16,19 @@ template<class K, class V>
...
@@ -15,11 +16,19 @@ template<class K, class V>
class
xelem
:
public
rcu_freed
{
class
xelem
:
public
rcu_freed
{
public
:
public
:
V
val
;
V
val
;
std
::
atomic
<
int
>
next_lock
;
std
::
atomic
<
xelem
<
K
,
V
>*>
volatile
next
;
K
key
;
K
key
;
xelem
(
const
K
&
k
,
const
V
&
v
)
:
rcu_freed
(
"xelem"
),
val
(
v
),
next_lock
(
0
),
next
(
0
),
key
(
k
)
{}
std
::
atomic
<
int
>
next_lock
;
std
::
atomic
<
xelem
<
K
,
V
>*>
next
;
int
percore_c
;
std
::
atomic
<
xelem
<
K
,
V
>*>
percore_next
;
std
::
atomic
<
xelem
<
K
,
V
>*>*
percore_pprev
;
xelem
(
const
K
&
k
,
const
V
&
v
)
:
rcu_freed
(
"xelem"
),
val
(
v
),
key
(
k
),
next_lock
(
0
),
next
(
0
),
percore_next
(
0
),
percore_pprev
(
0
)
{}
virtual
void
do_gc
()
{
virtual
void
do_gc
()
{
delete
this
;
delete
this
;
}
}
...
@@ -39,6 +48,8 @@ class xns : public rcu_freed {
...
@@ -39,6 +48,8 @@ class xns : public rcu_freed {
bool
allowdup
;
bool
allowdup
;
std
::
atomic
<
u64
>
nextkey
;
std
::
atomic
<
u64
>
nextkey
;
xbucket
<
K
,
V
>
table
[
NHASH
];
xbucket
<
K
,
V
>
table
[
NHASH
];
std
::
atomic
<
xelem
<
K
,
V
>*>
percore
[
NCPU
];
spinlock
percore_lock
[
NCPU
];
public
:
public
:
xns
(
bool
dup
)
:
rcu_freed
(
"xns"
)
{
xns
(
bool
dup
)
:
rcu_freed
(
"xns"
)
{
...
@@ -46,6 +57,10 @@ class xns : public rcu_freed {
...
@@ -46,6 +57,10 @@ class xns : public rcu_freed {
nextkey
=
1
;
nextkey
=
1
;
for
(
int
i
=
0
;
i
<
NHASH
;
i
++
)
for
(
int
i
=
0
;
i
<
NHASH
;
i
++
)
table
[
i
].
chain
=
0
;
table
[
i
].
chain
=
0
;
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
{
percore
[
i
]
=
nullptr
;
initlock
(
&
percore_lock
[
i
],
"xns_lock"
,
LOCKSTAT_NS
);
}
}
}
~
xns
()
{
~
xns
()
{
...
@@ -86,8 +101,18 @@ class xns : public rcu_freed {
...
@@ -86,8 +101,18 @@ class xns : public rcu_freed {
}
}
e
->
next
=
root
.
load
();
e
->
next
=
root
.
load
();
if
(
cmpxch
(
&
table
[
i
].
chain
,
e
->
next
.
load
(),
e
))
if
(
cmpxch
(
&
table
[
i
].
chain
,
e
->
next
.
load
(),
e
))
{
int
c
=
mycpuid
();
acquire
(
&
percore_lock
[
c
]);
e
->
percore_c
=
c
;
e
->
percore_next
=
percore
[
c
].
load
();
if
(
percore
[
c
])
percore
[
c
].
load
()
->
percore_pprev
=
&
e
->
percore_next
;
e
->
percore_pprev
=
&
percore
[
c
];
percore
[
c
]
=
e
;
release
(
&
percore_lock
[
c
]);
return
0
;
return
0
;
}
}
}
}
}
...
@@ -134,6 +159,13 @@ class xns : public rcu_freed {
...
@@ -134,6 +159,13 @@ class xns : public rcu_freed {
break
;
break
;
}
}
int
c
=
e
->
percore_c
;
acquire
(
&
percore_lock
[
c
]);
*
e
->
percore_pprev
=
e
->
percore_next
.
load
();
if
(
e
->
percore_next
)
e
->
percore_next
.
load
()
->
percore_pprev
=
e
->
percore_pprev
;
release
(
&
percore_lock
[
c
]);
*
pelock
=
0
;
*
pelock
=
0
;
gc_delayed
(
e
);
gc_delayed
(
e
);
return
true
;
return
true
;
...
@@ -148,12 +180,13 @@ class xns : public rcu_freed {
...
@@ -148,12 +180,13 @@ class xns : public rcu_freed {
template
<
class
CB
>
template
<
class
CB
>
void
enumerate
(
CB
cb
)
{
void
enumerate
(
CB
cb
)
{
scoped_gc_epoch
gc
;
scoped_gc_epoch
gc
;
for
(
int
i
=
0
;
i
<
NHASH
;
i
++
)
{
int
cpuoffset
=
mycpuid
();
auto
e
=
table
[
i
].
chain
.
load
();
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
{
auto
e
=
percore
[(
i
+
cpuoffset
)
%
NCPU
].
load
();
while
(
e
)
{
while
(
e
)
{
if
(
cb
(
e
->
key
,
e
->
val
))
if
(
cb
(
e
->
key
,
e
->
val
))
return
;
return
;
e
=
e
->
next
;
e
=
e
->
percore_
next
;
}
}
}
}
}
}
...
...
include/radix.hh
浏览文件 @
359dab4a
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
* A page-table-like structure for mapping fixed-length keys to void* ptrs.
* A page-table-like structure for mapping fixed-length keys to void* ptrs.
*/
*/
#include "gc.hh"
#include "markptr.hh"
#include "markptr.hh"
enum
{
bits_per_level
=
9
};
enum
{
bits_per_level
=
9
};
...
...
include/user.h
浏览文件 @
359dab4a
...
@@ -54,7 +54,7 @@ void free(void*);
...
@@ -54,7 +54,7 @@ void free(void*);
int
atoi
(
const
char
*
);
int
atoi
(
const
char
*
);
// uthread.S
// uthread.S
int
forkt
(
void
*
sp
,
void
*
pc
,
void
*
arg
);
int
forkt
(
void
*
sp
,
void
*
pc
,
void
*
arg
,
int
forkflags
);
void
forkt_setup
(
u64
pid
);
void
forkt_setup
(
u64
pid
);
// printf.c
// printf.c
...
...
include/wqfor.hh
浏览文件 @
359dab4a
...
@@ -13,7 +13,7 @@ struct forwork : public work {
...
@@ -13,7 +13,7 @@ struct forwork : public work {
:
it_
(
it
),
cond_
(
cond
),
body_
(
body
),
frame_
(
frame
)
{}
:
it_
(
it
),
cond_
(
cond
),
body_
(
body
),
frame_
(
frame
)
{}
virtual
void
run
()
{
virtual
void
run
()
{
decltype
(
it_
.
copy_value
())
v
=
it_
.
copy_value
(
);
decltype
(
copy_value
(
it_
))
v
=
copy_value
(
it_
);
++
it_
;
++
it_
;
if
(
cond_
(
it_
))
{
if
(
cond_
(
it_
))
{
forwork
<
IT
,
BODY
>
*
w
=
new
forwork
<
IT
,
BODY
>
(
it_
,
cond_
,
body_
,
frame_
);
forwork
<
IT
,
BODY
>
*
w
=
new
forwork
<
IT
,
BODY
>
(
it_
,
cond_
,
body_
,
frame_
);
...
@@ -21,6 +21,7 @@ struct forwork : public work {
...
@@ -21,6 +21,7 @@ struct forwork : public work {
wq_push
(
w
);
wq_push
(
w
);
}
}
body_
(
v
);
body_
(
v
);
free_value
(
it_
,
v
);
frame_
.
dec
();
frame_
.
dec
();
delete
this
;
delete
this
;
}
}
...
@@ -48,15 +49,48 @@ wq_for(IT &init, bool (*cond)(IT &it), BODY body)
...
@@ -48,15 +49,48 @@ wq_for(IT &init, bool (*cond)(IT &it), BODY body)
// XXX(sbw) should be able to coarsen loop
// XXX(sbw) should be able to coarsen loop
decltype
(
init
.
copy_value
())
v
=
init
.
copy_value
();
if
(
!
cond
(
init
))
return
;
decltype
(
copy_value
(
init
))
v
=
copy_value
(
init
);
++
init
;
++
init
;
if
(
cond
(
init
))
{
if
(
cond
(
init
))
{
forwork
<
IT
,
BODY
>
*
w
=
new
forwork
<
IT
,
BODY
>
(
init
,
cond
,
body
,
frame
);
forwork
<
IT
,
BODY
>
*
w
=
new
forwork
<
IT
,
BODY
>
(
init
,
cond
,
body
,
frame
);
frame
.
inc
();
frame
.
inc
();
wq_push
(
w
);
wq_push
(
w
);
}
}
body
(
v
);
body
(
v
);
free_value
(
init
,
v
);
while
(
!
frame
.
zero
())
while
(
!
frame
.
zero
())
wq_trywork
();
wq_trywork
();
}
}
// For debugging
// Same API as wq_for but serially executes body
template
<
typename
IT
,
typename
BODY
>
static
inline
void
wq_for_serial
(
IT
&
init
,
bool
(
*
cond
)(
IT
&
it
),
BODY
body
)
{
for
(;
cond
(
init
);
++
init
)
{
decltype
(
copy_value
(
init
))
v
=
copy_value
(
init
);
body
(
v
);
free_value
(
init
,
v
);
}
}
// Default copy_value
template
<
typename
T
>
static
inline
T
copy_value
(
T
&
it
)
{
return
it
;
}
// Default free_value
template
<
typename
T
>
static
inline
void
free_value
(
T
&
it
,
T
&
v
)
{
}
include/wqkernel.hh
浏览文件 @
359dab4a
...
@@ -43,9 +43,4 @@ wqarch_init(void)
...
@@ -43,9 +43,4 @@ wqarch_init(void)
{
{
}
}
static
inline
void
wqarch_exit
(
void
)
{
}
#define xprintf cprintf
#define xprintf cprintf
include/wquser.hh
浏览文件 @
359dab4a
...
@@ -92,12 +92,6 @@ wqarch_init(void)
...
@@ -92,12 +92,6 @@ wqarch_init(void)
pthread_setspecific
(
idkey
,
(
void
*
)(
u64
)
id
);
pthread_setspecific
(
idkey
,
(
void
*
)(
u64
)
id
);
}
}
static
inline
void
wqarch_exit
(
void
)
{
exiting
=
1
;
}
#define xprintf printf
#define xprintf printf
#define pushcli()
#define pushcli()
#define popcli()
#define popcli()
kernel/bio.cc
浏览文件 @
359dab4a
...
@@ -46,11 +46,11 @@ static struct buf*
...
@@ -46,11 +46,11 @@ static struct buf*
bget
(
u32
dev
,
u64
sector
,
int
*
writer
)
bget
(
u32
dev
,
u64
sector
,
int
*
writer
)
{
{
struct
buf
*
b
;
struct
buf
*
b
;
scoped_gc_epoch
e
;
loop:
loop:
// Try for cached block.
// Try for cached block.
// XXX ignore dev
// XXX ignore dev
gc_begin_epoch
();
b
=
bufns
->
lookup
(
mkpair
(
dev
,
sector
));
b
=
bufns
->
lookup
(
mkpair
(
dev
,
sector
));
if
(
b
)
{
if
(
b
)
{
if
(
b
->
dev
!=
dev
||
b
->
sector
!=
sector
)
if
(
b
->
dev
!=
dev
||
b
->
sector
!=
sector
)
...
@@ -60,7 +60,6 @@ bget(u32 dev, u64 sector, int *writer)
...
@@ -60,7 +60,6 @@ bget(u32 dev, u64 sector, int *writer)
if
(
b
->
flags
&
B_BUSY
)
{
if
(
b
->
flags
&
B_BUSY
)
{
cv_sleep
(
&
b
->
cv
,
&
b
->
lock
);
cv_sleep
(
&
b
->
cv
,
&
b
->
lock
);
release
(
&
b
->
lock
);
release
(
&
b
->
lock
);
gc_end_epoch
();
goto
loop
;
goto
loop
;
}
}
...
@@ -72,45 +71,15 @@ bget(u32 dev, u64 sector, int *writer)
...
@@ -72,45 +71,15 @@ bget(u32 dev, u64 sector, int *writer)
// rcu_end_read() happens in brelse
// rcu_end_read() happens in brelse
return
b
;
return
b
;
}
}
gc_end_epoch
();
// Allocate fresh block.
// Allocate fresh block.
struct
buf
*
victim
=
0
;
bufns
->
enumerate
([
&
victim
](
const
pair
<
u32
,
u64
>&
,
buf
*
eb
)
->
bool
{
acquire
(
&
eb
->
lock
);
if
((
eb
->
flags
&
(
B_BUSY
|
B_DIRTY
|
B_VALID
))
==
0
)
{
victim
=
eb
;
return
true
;
}
release
(
&
eb
->
lock
);
return
false
;
});
if
(
victim
==
0
)
bufns
->
enumerate
([
&
victim
](
const
pair
<
u32
,
u64
>&
,
buf
*
eb
)
->
bool
{
acquire
(
&
eb
->
lock
);
if
((
eb
->
flags
&
(
B_BUSY
|
B_DIRTY
))
==
0
)
{
victim
=
eb
;
return
true
;
}
release
(
&
eb
->
lock
);
return
false
;
});
if
(
victim
==
0
)
panic
(
"bget all busy"
);
victim
->
flags
|=
B_BUSY
;
bufns
->
remove
(
mkpair
(
victim
->
dev
,
victim
->
sector
),
&
victim
);
release
(
&
victim
->
lock
);
gc_delayed
(
victim
);
b
=
new
buf
(
dev
,
sector
);
b
=
new
buf
(
dev
,
sector
);
b
->
flags
=
B_BUSY
;
b
->
flags
=
B_BUSY
;
*
writer
=
1
;
*
writer
=
1
;
gc_begin_epoch
();
if
(
bufns
->
insert
(
mkpair
(
b
->
dev
,
b
->
sector
),
b
)
<
0
)
{
if
(
bufns
->
insert
(
mkpair
(
b
->
dev
,
b
->
sector
),
b
)
<
0
)
{
gc_delayed
(
b
);
gc_delayed
(
b
);
goto
loop
;
goto
loop
;
}
}
// rcu_end_read() happens in brelse
return
b
;
return
b
;
}
}
...
@@ -152,8 +121,6 @@ brelse(struct buf *b, int writer)
...
@@ -152,8 +121,6 @@ brelse(struct buf *b, int writer)
b
->
flags
&=
~
B_BUSY
;
b
->
flags
&=
~
B_BUSY
;
cv_wakeup
(
&
b
->
cv
);
cv_wakeup
(
&
b
->
cv
);
}
}
// rcu_begin_read() happens in bread
gc_end_epoch
();
}
}
void
void
...
...
kernel/fs.cc
浏览文件 @
359dab4a
...
@@ -10,6 +10,22 @@
...
@@ -10,6 +10,22 @@
// routines. The (higher-level) system call implementations
// routines. The (higher-level) system call implementations
// are in sysfile.c.
// are in sysfile.c.
/*
* inode cache will be RCU-managed:
*
* - to evict, mark inode as a victim
* - lookups that encounter a victim inode must return an error (-E_RETRY)
* - E_RETRY rolls back to the beginning of syscall/pagefault and retries
* - out-of-memory error should be treated like -E_RETRY
* - once an inode is marked as victim, it can be gc_delayed()
* - the do_gc() method should remove inode from the namespace & free it
*
* - inodes have a refcount that lasts beyond a GC epoch
* - to bump refcount, first bump, then check victim flag
* - if victim flag is set, reduce the refcount and -E_RETRY
*
*/
#include "types.h"
#include "types.h"
#include "stat.h"
#include "stat.h"
#include "mmu.h"
#include "mmu.h"
...
@@ -185,7 +201,7 @@ ialloc(u32 dev, short type)
...
@@ -185,7 +201,7 @@ ialloc(u32 dev, short type)
//cprintf("ialloc oops %d\n", inum); // XXX harmless
//cprintf("ialloc oops %d\n", inum); // XXX harmless
}
}
}
}
cprintf
(
"ialloc:
no inodes
\n
"
);
cprintf
(
"ialloc:
0/%u inodes
\n
"
,
sb
.
ninodes
);
return
nullptr
;
return
nullptr
;
}
}
...
@@ -239,72 +255,36 @@ inode::~inode()
...
@@ -239,72 +255,36 @@ inode::~inode()
struct
inode
*
struct
inode
*
iget
(
u32
dev
,
u32
inum
)
iget
(
u32
dev
,
u32
inum
)
{
{
struct
inode
*
ip
;
struct
inode
*
ip
=
igetnoref
(
dev
,
inum
);
if
(
ip
)
idup
(
ip
);
return
ip
;
}
struct
inode
*
igetnoref
(
u32
dev
,
u32
inum
)
{
retry
:
retry
:
// Try for cached inode.
// Try for cached inode.
gc_begin_epoch
();
{
ip
=
ins
->
lookup
(
mkpair
(
dev
,
inum
));
scoped_gc_epoch
e
;
if
(
ip
)
{
struct
inode
*
ip
=
ins
->
lookup
(
mkpair
(
dev
,
inum
));
// tricky: first bump ref, then check free flag
if
(
ip
)
{
ip
->
ref
++
;
if
(
!
(
ip
->
flags
&
I_VALID
))
{
if
(
ip
->
flags
&
I_FREE
)
{
acquire
(
&
ip
->
lock
);
gc_end_epoch
();
while
((
ip
->
flags
&
I_VALID
)
==
0
)
ip
->
ref
--
;
cv_sleep
(
&
ip
->
cv
,
&
ip
->
lock
);
goto
retry
;
release
(
&
ip
->
lock
);
}
}
gc_end_epoch
();
if
(
!
(
ip
->
flags
&
I_VALID
))
{
acquire
(
&
ip
->
lock
);
while
((
ip
->
flags
&
I_VALID
)
==
0
)
cv_sleep
(
&
ip
->
cv
,
&
ip
->
lock
);
release
(
&
ip
->
lock
);
}
return
ip
;
return
ip
;
}
gc_end_epoch
();
// Allocate fresh inode cache slot.
retry_evict
:
(
void
)
0
;
u32
cur_free
=
icache_free
[
mycpu
()
->
id
].
x
;
if
(
cur_free
==
0
)
{
struct
inode
*
victim
=
0
;
ins
->
enumerate
([
&
victim
](
const
pair
<
u32
,
u32
>&
,
inode
*
eip
)
->
bool
{
if
(
eip
->
ref
||
eip
->
type
==
T_DIR
)
return
false
;
acquire
(
&
eip
->
lock
);
if
(
eip
->
ref
==
0
&&
eip
->
type
!=
T_DIR
&&
!
(
eip
->
flags
&
(
I_FREE
|
I_BUSYR
|
I_BUSYW
)))
{
victim
=
eip
;
return
true
;
}
release
(
&
eip
->
lock
);
return
false
;
});
if
(
!
victim
)
panic
(
"iget out of space"
);
// tricky: first flag as free, then check refcnt, then remove from ns
victim
->
flags
|=
I_FREE
;
if
(
victim
->
ref
>
0
)
{
victim
->
flags
&=
~
(
I_FREE
);
release
(
&
victim
->
lock
);
goto
retry_evict
;
}
}
release
(
&
victim
->
lock
);
ins
->
remove
(
mkpair
(
victim
->
dev
,
victim
->
inum
),
&
victim
);
gc_delayed
(
victim
);
}
else
{
if
(
!
cmpxch
(
&
icache_free
[
mycpu
()
->
id
].
x
,
cur_free
,
cur_free
-
1
))
goto
retry_evict
;
}
}
ip
=
new
inode
();
// Allocate fresh inode cache slot.
struct
inode
*
ip
=
new
inode
();
ip
->
dev
=
dev
;
ip
->
dev
=
dev
;
ip
->
inum
=
inum
;
ip
->
inum
=
inum
;
ip
->
ref
=
1
;
ip
->
ref
=
0
;
ip
->
flags
=
I_BUSYR
|
I_BUSYW
;
ip
->
flags
=
I_BUSYR
|
I_BUSYW
;
ip
->
readbusy
=
1
;
ip
->
readbusy
=
1
;
snprintf
(
ip
->
lockname
,
sizeof
(
ip
->
lockname
),
"cv:ino:%d"
,
ip
->
inum
);
snprintf
(
ip
->
lockname
,
sizeof
(
ip
->
lockname
),
"cv:ino:%d"
,
ip
->
inum
);
...
@@ -366,7 +346,7 @@ ilock(struct inode *ip, int writer)
...
@@ -366,7 +346,7 @@ ilock(struct inode *ip, int writer)
void
void
iunlock
(
struct
inode
*
ip
)
iunlock
(
struct
inode
*
ip
)
{
{
if
(
ip
==
0
||
!
(
ip
->
flags
&
(
I_BUSYR
|
I_BUSYW
))
||
ip
->
ref
<
1
)
if
(
ip
==
0
||
!
(
ip
->
flags
&
(
I_BUSYR
|
I_BUSYW
)))
panic
(
"iunlock"
);
panic
(
"iunlock"
);
acquire
(
&
ip
->
lock
);
acquire
(
&
ip
->
lock
);
...
@@ -407,6 +387,9 @@ iput(struct inode *ip)
...
@@ -407,6 +387,9 @@ iput(struct inode *ip)
ip
->
flags
|=
(
I_BUSYR
|
I_BUSYW
);
ip
->
flags
|=
(
I_BUSYR
|
I_BUSYW
);
ip
->
readbusy
++
;
ip
->
readbusy
++
;
// XXX: use gc_delayed() to truncate the inode later.
// flag it as a victim in the meantime.
release
(
&
ip
->
lock
);
release
(
&
ip
->
lock
);
itrunc
(
ip
);
itrunc
(
ip
);
...
@@ -619,7 +602,10 @@ namecmp(const char *s, const char *t)
...
@@ -619,7 +602,10 @@ namecmp(const char *s, const char *t)
u64
u64
namehash
(
const
strbuf
<
DIRSIZ
>
&
n
)
namehash
(
const
strbuf
<
DIRSIZ
>
&
n
)
{
{
return
n
.
_buf
[
0
];
/* XXX */
u64
h
=
0
;
for
(
int
i
=
0
;
i
<
DIRSIZ
&&
n
.
_buf
[
i
];
i
++
)
h
=
((
h
<<
8
)
^
n
.
_buf
[
i
])
%
0xdeadbeef
;
return
h
;
}
}
void
void
...
@@ -751,12 +737,12 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
...
@@ -751,12 +737,12 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
{
{
struct
inode
*
ip
,
*
next
;
struct
inode
*
ip
,
*
next
;
int
r
;
int
r
;
scoped_gc_epoch
e
;
gc_begin_epoch
();
if
(
*
path
==
'/'
)
if
(
*
path
==
'/'
)
ip
=
iget
(
ROOTDEV
,
ROOTINO
);
ip
=
iget
noref
(
ROOTDEV
,
ROOTINO
);
else
else
ip
=
idup
(
cwd
)
;
ip
=
cwd
;
while
((
r
=
skipelem
(
&
path
,
name
))
==
1
){
while
((
r
=
skipelem
(
&
path
,
name
))
==
1
){
// XXX Doing this here requires some annoying reasoning about all
// XXX Doing this here requires some annoying reasoning about all
...
@@ -773,32 +759,30 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
...
@@ -773,32 +759,30 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
if
(
next
==
0
){
if
(
next
==
0
){
if
(
ip
->
type
==
0
)
if
(
ip
->
type
==
0
)
panic
(
"namex"
);
panic
(
"namex"
);
if
(
ip
->
type
!=
T_DIR
){
if
(
ip
->
type
!=
T_DIR
)
iput
(
ip
);
gc_end_epoch
();
return
0
;
return
0
;
}
if
(
nameiparent
&&
*
path
==
'\0'
){
if
(
nameiparent
&&
*
path
==
'\0'
){
// Stop one level early.
// Stop one level early.
gc_end_epoch
(
);
idup
(
ip
);
return
ip
;
return
ip
;
}
}
if
((
next
=
dirlookup
(
ip
,
name
))
==
0
){
if
((
next
=
dirlookup
(
ip
,
name
))
==
0
)
iput
(
ip
);
gc_end_epoch
();
return
0
;
return
0
;
}
iput
(
ip
);
}
}
ip
=
next
;
ip
=
next
;
}
}
if
(
r
==
-
1
||
nameiparent
){
iput
(
ip
);
if
(
r
==
-
1
||
nameiparent
)
gc_end_epoch
();
return
0
;
return
0
;
}
mtreadavar
(
"inode:%x.%x"
,
ip
->
dev
,
ip
->
inum
);
// XXX write is necessary because of idup. not logically required,
gc_end_epoch
();
// so we should replace this with mtreadavar() eventually, perhaps
// once we implement sloppy counters for long-term inode refs.
// mtreadavar("inode:%x.%x", ip->dev, ip->inum);
mtwriteavar
(
"inode:%x.%x"
,
ip
->
dev
,
ip
->
inum
);
idup
(
ip
);
return
ip
;
return
ip
;
}
}
...
...
kernel/lapic.cc
浏览文件 @
359dab4a
...
@@ -142,16 +142,10 @@ cpunum(void)
...
@@ -142,16 +142,10 @@ cpunum(void)
{
{
// Cannot call cpu when interrupts are enabled:
// Cannot call cpu when interrupts are enabled:
// result not guaranteed to last long enough to be used!
// result not guaranteed to last long enough to be used!
// Would prefer to panic but even printing is chancy here:
// almost everything, including cprintf and panic, calls cpu,
// often indirectly through acquire and release.
if
(
readrflags
()
&
FL_IF
){
if
(
readrflags
()
&
FL_IF
){
static
int
n
__mpalign__
;
cli
();
if
(
n
==
0
)
{
panic
(
"cpunum() called from %p with interrupts enabled
\n
"
,
n
++
;
__builtin_return_address
(
0
));
cprintf
(
"cpu called from %p with interrupts enabled
\n
"
,
__builtin_return_address
(
0
));
}
}
}
if
(
lapic
)
if
(
lapic
)
...
...
kernel/proc.cc
浏览文件 @
359dab4a
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
#include "kalloc.hh"
#include "kalloc.hh"
#include "vm.hh"
#include "vm.hh"
#include "ns.hh"
#include "ns.hh"
#include "fcntl.h"
u64
u64
proc_hash
(
const
u32
&
p
)
proc_hash
(
const
u32
&
p
)
...
@@ -344,7 +345,10 @@ fork(int flags)
...
@@ -344,7 +345,10 @@ fork(int flags)
if
((
np
=
proc
::
alloc
())
==
0
)
if
((
np
=
proc
::
alloc
())
==
0
)
return
-
1
;
return
-
1
;
if
(
flags
==
0
)
{
if
(
flags
&
FORK_SHARE_VMAP
)
{
np
->
vmap
=
myproc
()
->
vmap
;
np
->
vmap
->
ref
++
;
}
else
{
// Copy process state from p.
// Copy process state from p.
if
((
np
->
vmap
=
myproc
()
->
vmap
->
copy
(
cow
))
==
0
){
if
((
np
->
vmap
=
myproc
()
->
vmap
->
copy
(
cow
))
==
0
){
ksfree
(
slab_stack
,
np
->
kstack
);
ksfree
(
slab_stack
,
np
->
kstack
);
...
@@ -354,9 +358,6 @@ fork(int flags)
...
@@ -354,9 +358,6 @@ fork(int flags)
freeproc
(
np
);
freeproc
(
np
);
return
-
1
;
return
-
1
;
}
}
}
else
{
np
->
vmap
=
myproc
()
->
vmap
;
np
->
vmap
->
ref
++
;
}
}
np
->
parent
=
myproc
();
np
->
parent
=
myproc
();
...
@@ -366,16 +367,16 @@ fork(int flags)
...
@@ -366,16 +367,16 @@ fork(int flags)
// Clear %eax so that fork returns 0 in the child.
// Clear %eax so that fork returns 0 in the child.
np
->
tf
->
rax
=
0
;
np
->
tf
->
rax
=
0
;
if
(
flags
==
0
)
{
if
(
flags
&
FORK_SHARE_FD
)
{
myproc
()
->
ftable
->
incref
();
np
->
ftable
=
myproc
()
->
ftable
;
}
else
{
np
->
ftable
=
new
filetable
(
*
myproc
()
->
ftable
);
np
->
ftable
=
new
filetable
(
*
myproc
()
->
ftable
);
if
(
np
->
ftable
==
nullptr
)
{
if
(
np
->
ftable
==
nullptr
)
{
// XXX(sbw) leaking?
// XXX(sbw) leaking?
freeproc
(
np
);
freeproc
(
np
);
return
-
1
;
return
-
1
;
}
}
}
else
{
myproc
()
->
ftable
->
incref
();
np
->
ftable
=
myproc
()
->
ftable
;
}
}
np
->
cwd
=
idup
(
myproc
()
->
cwd
);
np
->
cwd
=
idup
(
myproc
()
->
cwd
);
...
...
kernel/radix.cc
浏览文件 @
359dab4a
#include "types.h"
#include "crange_arch.hh"
#include "atomic.hh"
#include "spinlock.h"
#include "kernel.hh"
#include "cpputil.hh"
#include "radix.hh"
#include "radix.hh"
// Returns the level we stopped at.
// Returns the level we stopped at.
...
...
kernel/sysfile.cc
浏览文件 @
359dab4a
...
@@ -215,6 +215,9 @@ create(inode *cwd, const char *path, short type, short major, short minor)
...
@@ -215,6 +215,9 @@ create(inode *cwd, const char *path, short type, short major, short minor)
{
{
struct
inode
*
ip
,
*
dp
;
struct
inode
*
ip
,
*
dp
;
char
name
[
DIRSIZ
];
char
name
[
DIRSIZ
];
mt_ascope
ascope
(
"%s(%d.%d,%s,%d,%d,%d)"
,
__func__
,
cwd
->
dev
,
cwd
->
inum
,
path
,
type
,
major
,
minor
);
retry:
retry:
if
((
dp
=
nameiparent
(
cwd
,
path
,
name
))
==
0
)
if
((
dp
=
nameiparent
(
cwd
,
path
,
name
))
==
0
)
...
@@ -239,6 +242,8 @@ create(inode *cwd, const char *path, short type, short major, short minor)
...
@@ -239,6 +242,8 @@ create(inode *cwd, const char *path, short type, short major, short minor)
ip
->
nlink
=
1
;
ip
->
nlink
=
1
;
iupdate
(
ip
);
iupdate
(
ip
);
mtwriteavar
(
"inode:%x.%x"
,
ip
->
dev
,
ip
->
inum
);
if
(
type
==
T_DIR
){
// Create . and .. entries.
if
(
type
==
T_DIR
){
// Create . and .. entries.
dp
->
nlink
++
;
// for ".."
dp
->
nlink
++
;
// for ".."
iupdate
(
dp
);
iupdate
(
dp
);
...
@@ -291,6 +296,10 @@ sys_openat(int dirfd, const char *path, int omode)
...
@@ -291,6 +296,10 @@ sys_openat(int dirfd, const char *path, int omode)
if
(
omode
&
O_CREATE
){
if
(
omode
&
O_CREATE
){
if
((
ip
=
create
(
cwd
,
path
,
T_FILE
,
0
,
0
))
==
0
)
if
((
ip
=
create
(
cwd
,
path
,
T_FILE
,
0
,
0
))
==
0
)
return
-
1
;
return
-
1
;
// XXX necessary because the mtwriteavar() to the same abstract variable
// does not propagate to our scope, since create() has its own inner scope.
mtwriteavar
(
"inode:%x.%x"
,
ip
->
dev
,
ip
->
inum
);
}
else
{
}
else
{
retry:
retry:
if
((
ip
=
namei
(
cwd
,
path
))
==
0
)
if
((
ip
=
namei
(
cwd
,
path
))
==
0
)
...
...
lib/threads.cc
浏览文件 @
359dab4a
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
#include "pthread.h"
#include "pthread.h"
#include "user.h"
#include "user.h"
#include "atomic.hh"
#include "atomic.hh"
#include "fcntl.h"
enum
{
stack_size
=
8192
};
enum
{
stack_size
=
8192
};
static
std
::
atomic
<
int
>
nextkey
;
static
std
::
atomic
<
int
>
nextkey
;
...
@@ -22,7 +23,7 @@ pthread_create(pthread_t* tid, const pthread_attr_t* attr,
...
@@ -22,7 +23,7 @@ pthread_create(pthread_t* tid, const pthread_attr_t* attr,
void
*
(
*
start
)(
void
*
),
void
*
arg
)
void
*
(
*
start
)(
void
*
),
void
*
arg
)
{
{
char
*
base
=
(
char
*
)
sbrk
(
stack_size
);
char
*
base
=
(
char
*
)
sbrk
(
stack_size
);
int
t
=
forkt
(
base
+
stack_size
,
(
void
*
)
start
,
arg
);
int
t
=
forkt
(
base
+
stack_size
,
(
void
*
)
start
,
arg
,
FORK_SHARE_VMAP
|
FORK_SHARE_FD
);
if
(
t
<
0
)
if
(
t
<
0
)
return
t
;
return
t
;
...
...
lib/uthread.S
浏览文件 @
359dab4a
...
@@ -12,7 +12,7 @@ forkt:
...
@@ -12,7 +12,7 @@ forkt:
movq %rdx, 0x00(%r12) # arg
movq %rdx, 0x00(%r12) # arg
movq %rsi, 0x08(%r12) # function ptr
movq %rsi, 0x08(%r12) # function ptr
movq
$1, %rdi
# flag for sys_fork
movq
%rcx, %rdi
# flag for sys_fork
movq $SYS_fork, %rax
movq $SYS_fork, %rax
syscall
syscall
...
...
lib/wq.cc
浏览文件 @
359dab4a
...
@@ -79,12 +79,6 @@ initwq(void)
...
@@ -79,12 +79,6 @@ initwq(void)
wqarch_init
();
wqarch_init
();
}
}
void
exitwq
(
void
)
{
wqarch_exit
();
}
//
//
// wq
// wq
//
//
...
...
tools/mkfs.c
浏览文件 @
359dab4a
...
@@ -11,8 +11,8 @@
...
@@ -11,8 +11,8 @@
#include "include/stat.h"
#include "include/stat.h"
int
nblocks
=
4067
;
int
nblocks
=
4067
;
int
ninodes
=
2
00
;
int
ninodes
=
8
00
;
int
size
=
4
096
;
int
size
=
4
172
;
int
fsfd
;
int
fsfd
;
struct
superblock
sb
;
struct
superblock
sb
;
...
...
user/Makefrag.user
浏览文件 @
359dab4a
CXXFLAGS := -iquote user $(filter-out -nostdinc++ -Istdinc, $(CXXFLAGS)) -msse
CXXFLAGS := -iquote user $(filter-out -nostdinc++ -Istdinc
-Inet
, $(CXXFLAGS)) -msse
$(O)/utest: $(O)/kernel/crange.o \
$(O)/utest: $(O)/kernel/crange.o \
$(O)/kernel/gc.o \
$(O)/kernel/gc.o \
$(O)/kernel/rnd.o \
$(O)/kernel/rnd.o \
$(O)/kernel/radix.o \
$(O)/user/umain.o
$(O)/user/umain.o
@echo " LD $@"
@echo " LD $@"
$(Q)mkdir -p $(@D)
$(Q)mkdir -p $(@D)
...
...
user/crange_arch.hh
浏览文件 @
359dab4a
...
@@ -133,6 +133,12 @@ mycpu()
...
@@ -133,6 +133,12 @@ mycpu()
return
(
cpu
*
)
&
cpus
[
myproc
()
->
cpuid
];
return
(
cpu
*
)
&
cpus
[
myproc
()
->
cpuid
];
}
}
static
inline
int
mycpuid
()
{
return
mycpu
()
->
id
;
}
static
inline
void
pushcli
()
{}
static
inline
void
pushcli
()
{}
static
inline
void
popcli
()
{}
static
inline
void
popcli
()
{}
...
...
user/umain.cc
浏览文件 @
359dab4a
#include <unistd.h>
#include <unistd.h>
#include <signal.h>
#include <signal.h>
#include <getopt.h>
#include <getopt.h>
#include <string.h>
#include "crange_arch.hh"
#include "crange_arch.hh"
#include "gc.hh"
#include "gc.hh"
#include "crange.hh"
#include "crange.hh"
#include "radix.hh"
#include "atomic_util.hh"
#include "atomic_util.hh"
#include "ns.hh"
#include "ns.hh"
#include "uscopedperf.hh"
#include "uscopedperf.hh"
...
@@ -80,8 +82,13 @@ threadpin(void (*fn)(void*), void *arg, const char *name, int cpu)
...
@@ -80,8 +82,13 @@ threadpin(void (*fn)(void*), void *arg, const char *name, int cpu)
makeproc
(
p
);
makeproc
(
p
);
}
}
struct
my_range
:
public
range
{
struct
my_crange_range
:
public
range
{
my_range
(
crange
*
cr
,
u64
k
,
u64
sz
)
:
range
(
cr
,
k
,
sz
)
{}
my_crange_range
(
crange
*
cr
,
u64
k
,
u64
sz
)
:
range
(
cr
,
k
,
sz
)
{}
virtual
void
do_gc
()
{
delete
this
;
}
};
struct
my_radix_range
:
public
radix_elem
{
my_radix_range
(
radix
*
cr
,
u64
k
,
u64
sz
)
{}
virtual
void
do_gc
()
{
delete
this
;
}
virtual
void
do_gc
()
{
delete
this
;
}
};
};
...
@@ -92,7 +99,7 @@ enum { crange_items = 1024 };
...
@@ -92,7 +99,7 @@ enum { crange_items = 1024 };
enum
{
random_keys
=
0
};
enum
{
random_keys
=
0
};
static
void
static
void
worker
(
void
*
arg
)
worker
_crange
(
void
*
arg
)
{
{
crange
*
cr
=
(
crange
*
)
arg
;
crange
*
cr
=
(
crange
*
)
arg
;
...
@@ -106,7 +113,7 @@ worker(void *arg)
...
@@ -106,7 +113,7 @@ worker(void *arg)
span
.
replace
(
0
);
span
.
replace
(
0
);
}
else
{
}
else
{
ANON_REGION
(
"worker add"
,
&
perfgroup
);
ANON_REGION
(
"worker add"
,
&
perfgroup
);
span
.
replace
(
new
my_range
(
cr
,
k
,
1
));
span
.
replace
(
new
my_
crange_
range
(
cr
,
k
,
1
));
}
}
}
}
...
@@ -114,16 +121,48 @@ worker(void *arg)
...
@@ -114,16 +121,48 @@ worker(void *arg)
}
}
static
void
static
void
populate
(
void
*
arg
)
populate
_crange
(
void
*
arg
)
{
{
crange
*
cr
=
(
crange
*
)
arg
;
crange
*
cr
=
(
crange
*
)
arg
;
for
(
u32
i
=
0
;
i
<
crange_items
;
i
++
)
for
(
u32
i
=
0
;
i
<
crange_items
;
i
++
)
cr
->
search_lock
(
1
+
2
*
i
,
1
).
replace
(
new
my_range
(
cr
,
1
+
2
*
i
,
1
));
cr
->
search_lock
(
1
+
2
*
i
,
1
).
replace
(
new
my_crange_range
(
cr
,
1
+
2
*
i
,
1
));
pthread_barrier_wait
(
&
populate_b
);
}
static
void
worker_radix
(
void
*
arg
)
{
radix
*
cr
=
(
radix
*
)
arg
;
for
(
u32
i
=
0
;
i
<
iter_total
/
ncpu
;
i
++
)
{
ANON_REGION
(
"worker op"
,
&
perfgroup
);
u64
rval
=
random_keys
?
rnd
<
u32
>
()
:
myproc
()
->
cpuid
;
u64
k
=
1
+
rval
%
(
crange_items
*
2
);
auto
span
=
cr
->
search_lock
(
k
,
1
);
if
(
rnd
<
u8
>
()
&
1
)
{
ANON_REGION
(
"worker del"
,
&
perfgroup
);
span
.
replace
(
k
,
1
,
0
);
}
else
{
ANON_REGION
(
"worker add"
,
&
perfgroup
);
span
.
replace
(
k
,
1
,
new
my_radix_range
(
cr
,
k
,
1
));
}
}
pthread_barrier_wait
(
&
worker_b
);
}
static
void
populate_radix
(
void
*
arg
)
{
radix
*
cr
=
(
radix
*
)
arg
;
for
(
u32
i
=
0
;
i
<
crange_items
;
i
++
)
cr
->
search_lock
(
1
+
2
*
i
,
1
).
replace
(
1
+
2
*
i
,
1
,
new
my_radix_range
(
cr
,
1
+
2
*
i
,
1
));
pthread_barrier_wait
(
&
populate_b
);
pthread_barrier_wait
(
&
populate_b
);
}
}
static
const
struct
option
long_opts
[]
=
{
static
const
struct
option
long_opts
[]
=
{
{
"ncpu"
,
required_argument
,
0
,
'n'
},
{
"ncpu"
,
required_argument
,
0
,
'n'
},
{
"tree-type"
,
required_argument
,
0
,
't'
},
{
0
,
no_argument
,
0
,
0
}
{
0
,
no_argument
,
0
,
0
}
};
};
...
@@ -140,14 +179,17 @@ l2(u64 v)
...
@@ -140,14 +179,17 @@ l2(u64 v)
return
l
;
return
l
;
}
}
enum
{
type_crange
,
type_radix
};
int
int
main
(
int
ac
,
char
**
av
)
main
(
int
ac
,
char
**
av
)
{
{
ncpu
=
NCPU
;
ncpu
=
NCPU
;
int
treetype
=
type_crange
;
for
(;;)
{
for
(;;)
{
int
long_idx
;
int
long_idx
;
int
opt
=
getopt_long
(
ac
,
av
,
"n:"
,
long_opts
,
&
long_idx
);
int
opt
=
getopt_long
(
ac
,
av
,
"n:
t:
"
,
long_opts
,
&
long_idx
);
if
(
opt
==
-
1
)
if
(
opt
==
-
1
)
break
;
break
;
...
@@ -157,6 +199,15 @@ main(int ac, char **av)
...
@@ -157,6 +199,15 @@ main(int ac, char **av)
assert
(
ncpu
<=
NCPU
);
assert
(
ncpu
<=
NCPU
);
break
;
break
;
case
't'
:
if
(
!
strcmp
(
optarg
,
"crange"
))
treetype
=
type_crange
;
else
if
(
!
strcmp
(
optarg
,
"radix"
))
treetype
=
type_radix
;
else
assert
(
0
);
break
;
case
'?'
:
case
'?'
:
printf
(
"Options:
\n
"
);
printf
(
"Options:
\n
"
);
for
(
u32
i
=
0
;
long_opts
[
i
].
name
;
i
++
)
for
(
u32
i
=
0
;
long_opts
[
i
].
name
;
i
++
)
...
@@ -178,15 +229,25 @@ main(int ac, char **av)
...
@@ -178,15 +229,25 @@ main(int ac, char **av)
initgc
();
initgc
();
pthread_barrier_init
(
&
populate_b
,
0
,
2
);
pthread_barrier_init
(
&
populate_b
,
0
,
2
);
crange
cr
(
l2
(
crange_items
));
crange
cr
(
l2
(
crange_items
));
threadpin
(
populate
,
&
cr
,
"populate"
,
0
);
radix
rr
(
0
);
if
(
treetype
==
type_crange
)
threadpin
(
populate_crange
,
&
cr
,
"populate"
,
0
);
else
if
(
treetype
==
type_radix
)
threadpin
(
populate_radix
,
&
rr
,
"populate"
,
0
);
pthread_barrier_wait
(
&
populate_b
);
pthread_barrier_wait
(
&
populate_b
);
pthread_barrier_init
(
&
worker_b
,
0
,
ncpu
+
1
);
pthread_barrier_init
(
&
worker_b
,
0
,
ncpu
+
1
);
for
(
u32
i
=
0
;
i
<
ncpu
;
i
++
)
{
for
(
u32
i
=
0
;
i
<
ncpu
;
i
++
)
{
char
buf
[
32
];
char
buf
[
32
];
sprintf
(
buf
,
"worker%d"
,
i
);
sprintf
(
buf
,
"worker%d"
,
i
);
threadpin
(
worker
,
&
cr
,
buf
,
i
);
if
(
treetype
==
type_crange
)
threadpin
(
worker_crange
,
&
cr
,
buf
,
i
);
else
if
(
treetype
==
type_radix
)
threadpin
(
worker_radix
,
&
rr
,
buf
,
i
);
}
}
pthread_barrier_wait
(
&
worker_b
);
pthread_barrier_wait
(
&
worker_b
);
...
...
user/wqlinux.hh
浏览文件 @
359dab4a
...
@@ -83,11 +83,6 @@ wqarch_init(void)
...
@@ -83,11 +83,6 @@ wqarch_init(void)
}
}
}
}
static
inline
void
wqarch_exit
(
void
)
{
}
#define xprintf printf
#define xprintf printf
#define pushcli()
#define pushcli()
#define popcli()
#define popcli()
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论