Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
44772003
提交
44772003
2月 16, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A bunch of random kernlet/pread hacking
上级
39024ea6
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
158 行增加
和
52 行删除
+158
-52
ipc.hh
ipc.hh
+19
-1
kern_c.h
kern_c.h
+3
-1
kernel.hh
kernel.hh
+1
-1
kernlet.cc
kernlet.cc
+36
-25
preadtest.cc
preadtest.cc
+93
-21
user.h
user.h
+2
-1
wq.cc
wq.cc
+3
-2
wq.hh
wq.hh
+1
-0
没有找到文件。
ipc.hh
浏览文件 @
44772003
struct
ipcctl
{
#define IPC_NMSG 16
typedef
u32
msgid_t
;
#define NULL_MSGID (-1)
#define IPC_NPAGE ((KSHAREDSIZE/PGSIZE) - 1)
typedef
u32
pageid_t
;
#define NULL_PAGEID (-1)
struct
ipcmsg
{
volatile
char
done
:
1
;
volatile
char
submitted
:
1
;
pageid_t
pageid
;
off_t
off
;
volatile
long
result
;
};
struct
ipcctl
{
int
msghead
;
int
msgtail
;
struct
ipcmsg
msg
[
IPC_NMSG
];
int
pagehead
;
int
pagetail
;
};
kern_c.h
浏览文件 @
44772003
#include "mmu.h"
#include "lib.h"
struct
ipcmsg
;
// console.c
void
consoleintr
(
int
(
*
)(
void
));
...
...
@@ -44,7 +46,7 @@ long sys_bind(int, void*, int);
long
sys_listen
(
int
,
int
);
long
sys_accept
(
int
,
void
*
,
void
*
);
long
sys_pread
(
int
fd
,
void
*
ubuf
,
size_t
count
,
off_t
offset
);
long
sys_kernlet
(
int
,
size_t
,
off_t
);
long
sys_kernlet
(
int
,
size_t
,
off_t
,
u32
,
u32
);
extern
long
(
*
syscalls
[])(
u64
,
u64
,
u64
,
u64
,
u64
,
u64
);
// other exported/imported functions
...
...
kernel.hh
浏览文件 @
44772003
...
...
@@ -335,7 +335,7 @@ long sys_bind(int, void*, int);
long
sys_listen
(
int
,
int
);
long
sys_accept
(
int
,
void
*
,
void
*
);
long
sys_pread
(
int
fd
,
void
*
ubuf
,
size_t
count
,
off_t
offset
);
long
sys_kernlet
(
int
,
size_t
,
off_t
);
long
sys_kernlet
(
int
,
size_t
,
off_t
,
u32
,
u32
);
extern
long
(
*
syscalls
[])(
u64
,
u64
,
u64
,
u64
,
u64
,
u64
);
// other exported/imported functions
...
...
kernlet.cc
浏览文件 @
44772003
...
...
@@ -10,56 +10,67 @@
#include "vm.hh"
#include "file.hh"
static_assert
(
sizeof
(
struct
ipcctl
)
<
PGSIZE
,
"struct ipcctl too large"
);
static
void
pread_work
(
struct
work
*
w
,
void
*
a0
,
void
*
a1
,
void
*
a2
,
void
*
a3
)
pread_work
(
struct
work
*
w
,
void
*
a0
,
void
*
a1
,
void
*
a2
,
void
*
a3
,
void
*
a4
)
{
struct
inode
*
ip
=
(
inode
*
)
a0
;
void
*
kshared
=
(
void
*
)
a1
;
struct
ipcctl
*
ipc
=
(
ipcctl
*
)
kshared
;
s
ize_t
count
=
(
uptr
)
a2
;
off_t
off
=
(
uptr
)
a3
;
size_t
count
=
(
uptr
)
a1
;
off_t
off
=
(
uptr
)
a2
;
s
truct
ipcmsg
*
msg
=
(
struct
ipcmsg
*
)
a3
;
void
*
ubuf
=
(
void
*
)
a4
;
int
r
;
if
(
count
>
KSHAREDSIZE
-
PGSIZE
)
panic
(
"pread_work"
);
//cprintf("1: %p %p %lu %lu\n", ip, buf, count, off);
ilock
(
ip
,
0
);
r
=
readi
(
ip
,
(
(
char
*
)
kshared
)
+
PGSIZE
,
off
,
count
);
r
=
readi
(
ip
,
(
char
*
)
ubuf
,
off
,
count
);
iunlock
(
ip
);
ipc
->
result
=
r
;
msg
->
result
=
r
;
barrier
();
ipc
->
done
=
1
;
msg
->
done
=
1
;
iput
(
ip
);
}
static
struct
work
*
pread_allocwork
(
struct
inode
*
ip
,
void
*
buf
,
size_t
count
,
off_t
off
)
pread_allocwork
(
struct
inode
*
ip
,
size_t
count
,
off_t
off
,
struct
ipcmsg
*
msg
,
void
*
ubuf
)
{
struct
work
*
w
=
allocwork
();
if
(
w
==
NULL
)
return
0
;
//cprintf("0: %p %p %lu %lu\n", ip, buf, count, off);
w
->
rip
=
(
void
*
)
pread_work
;
w
->
arg0
=
ip
;
w
->
arg1
=
buf
;
w
->
arg2
=
(
void
*
)
count
;
w
->
arg3
=
(
void
*
)
off
;
w
->
arg1
=
(
void
*
)
count
;
w
->
arg2
=
(
void
*
)
off
;
w
->
arg3
=
msg
;
w
->
arg4
=
ubuf
;
return
w
;
}
long
sys_kernlet
(
int
fd
,
size_t
count
,
off_t
off
)
sys_kernlet
(
int
fd
,
size_t
count
,
off_t
off
,
msgid_t
msgid
,
pageid_t
pageid
)
{
struct
file
*
f
;
struct
work
*
w
;
struct
ipcctl
*
ipc
=
(
struct
ipcctl
*
)
myproc
()
->
vmap
->
kshared
;
char
*
kshared
=
myproc
()
->
vmap
->
kshared
;
struct
ipcctl
*
ipcctl
=
(
struct
ipcctl
*
)
kshared
;
struct
ipcmsg
*
msg
;
void
*
ubuf
;
if
(
msgid
>
IPC_NMSG
)
return
-
1
;
if
(
pageid
>
IPC_NPAGE
)
return
-
1
;
msg
=
&
ipcctl
->
msg
[
msgid
];
ubuf
=
(
kshared
+
PGSIZE
+
(
pageid
*
PGSIZE
));
if
(
fd
<
0
||
fd
>=
NOFILE
||
(
f
=
myproc
()
->
ofile
[
fd
])
==
0
)
return
-
1
;
...
...
@@ -67,7 +78,7 @@ sys_kernlet(int fd, size_t count, off_t off)
return
-
1
;
f
->
ip
->
ref
++
;
w
=
pread_allocwork
(
f
->
ip
,
myproc
()
->
vmap
->
kshared
,
count
,
of
f
);
w
=
pread_allocwork
(
f
->
ip
,
count
,
off
,
msg
,
ubu
f
);
if
(
w
==
NULL
)
{
iput
(
f
->
ip
);
return
-
1
;
...
...
@@ -77,7 +88,7 @@ sys_kernlet(int fd, size_t count, off_t off)
freework
(
w
);
return
-
1
;
}
ipc
->
off
=
off
;
ipc
->
submitted
=
1
;
msg
->
off
=
off
;
msg
->
submitted
=
1
;
return
0
;
}
preadtest.cc
浏览文件 @
44772003
#define PGSIZE 4096
#include "types.h"
#include "stat.h"
#include "fcntl.h"
...
...
@@ -19,36 +20,106 @@ static char buf[BSIZE];
struct
ipcctl
*
ipcctl
=
(
struct
ipcctl
*
)
KSHARED
;
static
msgid_t
ipc_msg_alloc
(
void
)
{
if
(
ipcctl
->
msghead
-
ipcctl
->
msgtail
==
IPC_NMSG
)
return
NULL_MSGID
;
msgid_t
i
=
ipcctl
->
msghead
%
IPC_NMSG
;
ipcctl
->
msghead
++
;
return
i
;
}
static
void
ipc_msg_free
(
int
msgid
)
{
msgid_t
i
;
i
=
ipcctl
->
msgtail
%
IPC_NMSG
;
if
(
i
!=
msgid
)
die
(
"ipc_free_msg: oops"
);
ipcctl
->
msgtail
++
;
}
static
pageid_t
ipc_page_alloc
(
void
)
{
if
(
ipcctl
->
pagehead
-
ipcctl
->
pagetail
==
IPC_NPAGE
)
return
NULL_PAGEID
;
pageid_t
i
=
ipcctl
->
pagehead
%
IPC_NPAGE
;
ipcctl
->
pagehead
++
;
return
i
;
}
static
void
ipc_page_free
(
pageid_t
pageid
)
{
pageid_t
i
;
i
=
ipcctl
->
pagetail
%
IPC_NPAGE
;
if
(
i
!=
pageid
)
die
(
"ipc_free_page: oops"
);
ipcctl
->
pagetail
++
;
}
static
void
kernlet_pread
(
int
fd
,
size_t
count
,
off_t
off
)
{
ipcctl
->
done
=
0
;
if
(
kernlet
(
fd
,
count
,
off
)
!=
0
)
struct
ipcmsg
*
msg
;
msgid_t
msgid
;
pageid_t
pageid
;
msgid
=
ipc_msg_alloc
();
if
(
msgid
==
NULL_MSGID
)
{
printf
(
2
,
"kernlet_pread: ipc_alloc_msg failed"
);
return
;
}
if
(
count
>
PGSIZE
)
die
(
"kernlet_pread: count oops"
);
pageid
=
ipc_page_alloc
();
if
(
pageid
==
NULL_PAGEID
)
{
printf
(
2
,
"kernlet_pread: ipc_alloc_page failed"
);
return
;
}
msg
=
&
ipcctl
->
msg
[
msgid
];
msg
->
done
=
0
;
msg
->
pageid
=
pageid
;
if
(
kernlet
(
fd
,
count
,
off
,
msgid
,
pageid
)
!=
0
)
die
(
"kernlet"
);
}
static
ssize_t
xpread
(
int
fd
,
void
*
buf
,
size_t
count
,
off_t
off
)
{
if
(
ipcctl
->
submitted
)
{
while
(
ipcctl
->
done
==
0
)
struct
ipcmsg
*
msg
;
int
msgid
;
msgid
=
ipcctl
->
msgtail
%
IPC_NMSG
;
msg
=
&
ipcctl
->
msg
[
msgid
];
if
(
msg
->
submitted
)
{
while
(
msg
->
done
==
0
)
nop_pause
();
if
(
ipcctl
->
result
==
-
1
)
goto
slow
;
if
(
off
<
ipcctl
->
off
)
goto
slow
;
if
(
off
>
ipcctl
->
off
+
ipcctl
->
result
)
goto
slow
;
if
(
msg
->
result
==
-
1
)
die
(
"xpread: result oops"
);
if
(
msg
->
off
!=
off
)
die
(
"xpread: off oops"
);
char
*
kbuf
=
(
char
*
)
(
KSHARED
+
4096
);
off_t
kbufoff
=
off
-
ipcctl
->
off
;
size_t
kbufcount
=
MIN
(
count
,
ipcctl
->
result
-
kbufoff
);
char
*
kbuf
=
(
char
*
)
(
KSHARED
+
PGSIZE
+
(
msg
->
pageid
*
PGSIZE
)
);
off_t
kbufoff
=
off
-
msg
->
off
;
size_t
kbufcount
=
MIN
(
count
,
msg
->
result
-
kbufoff
);
memmove
(
buf
,
kbuf
+
kbufoff
,
kbufcount
);
ipc_msg_free
(
msgid
);
ipc_page_free
(
msg
->
pageid
);
return
kbufcount
;
}
slow:
return
pread
(
fd
,
buf
,
count
,
off
);
}
...
...
@@ -56,8 +127,10 @@ int
main
(
int
ac
,
char
**
av
)
{
u64
t0
,
t1
;
int
i
,
k
;
int
fd
;
int
i
;
memset
(
ipcctl
,
0
,
sizeof
(
*
ipcctl
));
if
(
ac
>
1
)
usekernlet
=
av
[
1
][
0
]
==
'k'
;
...
...
@@ -71,12 +144,11 @@ main(int ac, char **av)
die
(
"write failed"
);
t0
=
rdtsc
();
for
(
k
=
0
;
k
<
FSIZE
;
k
+=
PSIZE
)
{
kernlet_pread
(
fd
,
PSIZE
,
k
);
for
(
i
=
k
;
i
<
k
+
PSIZE
;
i
+=
BSIZE
)
if
(
xpread
(
fd
,
buf
,
BSIZE
,
i
)
!=
BSIZE
)
die
(
"pread failed"
);
kernlet_pread
(
fd
,
BSIZE
,
0
);
for
(
i
=
0
;
i
<
FSIZE
;
i
+=
BSIZE
)
{
if
(
xpread
(
fd
,
buf
,
BSIZE
,
i
)
!=
BSIZE
)
die
(
"pread failed"
);
kernlet_pread
(
fd
,
BSIZE
,
i
+
BSIZE
);
}
t1
=
rdtsc
();
...
...
user.h
浏览文件 @
44772003
BEGIN_DECLS
struct
stat
;
struct
ipcmsg
;
// system calls
int
fork
(
int
);
...
...
@@ -27,7 +28,7 @@ int map(void *addr, int len);
int
unmap
(
void
*
addr
,
int
len
);
void
halt
(
void
);
ssize_t
pread
(
int
,
void
*
,
size_t
,
off_t
);
int
kernlet
(
int
,
size_t
,
off_t
);
int
kernlet
(
int
,
size_t
,
off_t
,
u32
,
u32
);
// ulib.c
int
stat
(
char
*
,
struct
stat
*
);
...
...
wq.cc
浏览文件 @
44772003
...
...
@@ -163,8 +163,9 @@ __wq_steal(int c)
static
void
__wq_run
(
struct
work
*
w
)
{
void
(
*
fn
)(
struct
work
*
,
void
*
,
void
*
,
void
*
,
void
*
)
=
(
void
(
*
)(
work
*
,
void
*
,
void
*
,
void
*
,
void
*
))
w
->
rip
;
fn
(
w
,
w
->
arg0
,
w
->
arg1
,
w
->
arg2
,
w
->
arg3
);
void
(
*
fn
)(
struct
work
*
,
void
*
,
void
*
,
void
*
,
void
*
,
void
*
)
=
(
void
(
*
)(
work
*
,
void
*
,
void
*
,
void
*
,
void
*
,
void
*
))
w
->
rip
;
fn
(
w
,
w
->
arg0
,
w
->
arg1
,
w
->
arg2
,
w
->
arg3
,
w
->
arg4
);
freework
(
w
);
}
...
...
wq.hh
浏览文件 @
44772003
...
...
@@ -4,5 +4,6 @@ struct work {
void
*
arg1
;
void
*
arg2
;
void
*
arg3
;
void
*
arg4
;
char
data
[];
};
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论