Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
772fa427
提交
772fa427
2月 20, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A FILE implementation that uses sys_async
上级
d41ef66a
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
323 行增加
和
58 行删除
+323
-58
Makefrag
bin/Makefrag
+1
-0
ftest.cc
bin/ftest.cc
+58
-0
preadtest.cc
bin/preadtest.cc
+0
-49
fstream.h
include/fstream.h
+15
-0
ipc.hh
include/ipc.hh
+31
-8
Makefrag
lib/Makefrag
+1
-1
fstream.cc
lib/fstream.cc
+168
-0
ipc.cc
lib/ipc.cc
+49
-0
没有找到文件。
bin/Makefrag
浏览文件 @
772fa427
...
...
@@ -18,6 +18,7 @@ UPROGS= \
usertests \
lockstat \
preadtest \
ftest \
perf
ifeq ($(HAVE_LWIP),y)
...
...
bin/ftest.cc
0 → 100644
浏览文件 @
772fa427
#include "types.h"
#include "stat.h"
#include "fcntl.h"
#include "user.h"
#include "lib.h"
#include "amd64.h"
#include "ipc.hh"
extern
"C"
{
#include "fstream.h"
}
#define FSIZE (64 << 10)
#define BSIZE 4096
static
char
wbuf
[
512
];
static
char
rbuf
[
BSIZE
];
static
int
check
=
0
;
int
main
(
int
ac
,
char
**
av
)
{
size_t
count
;
off_t
off
;
FILE
*
fp
;
int
fd
;
int
i
;
memset
(
ipcctl
,
0
,
sizeof
(
*
ipcctl
));
for
(
i
=
0
;
i
<
sizeof
(
wbuf
);
i
++
)
wbuf
[
i
]
=
i
%
16
;
unlink
(
"ftest.x"
);
fd
=
open
(
"ftest.x"
,
O_CREATE
|
O_RDWR
);
for
(
i
=
0
;
i
<
FSIZE
;
)
{
count
=
MIN
(
sizeof
(
wbuf
),
FSIZE
-
i
);
if
(
write
(
fd
,
wbuf
,
count
)
!=
count
)
die
(
"write failed"
);
i
+=
count
;
}
fp
=
fdopen
(
fd
,
"r"
);
if
(
fp
==
0
)
die
(
"fdopen"
);
off
=
0
;
while
((
count
=
fread
(
rbuf
,
1
,
BSIZE
,
fp
)))
{
if
(
check
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
rbuf
[
i
]
!=
(
i
+
off
)
%
16
)
die
(
"ftest %u: %u != %u"
,
i
,
(
int
)(
rbuf
[
i
]),
(
off
+
i
)
%
16
);
off
+=
count
;
}
}
fclose
(
fp
);
exit
();
}
bin/preadtest.cc
浏览文件 @
772fa427
...
...
@@ -7,9 +7,6 @@
#include "amd64.h"
#include "ipc.hh"
// XXX(sbw) add a memlayout.h?
#define KSHARED 0xFFFFF00000000000ull
#define FSIZE (64 << 10)
#define BSIZE 4096
#define PSIZE (4*BSIZE)
...
...
@@ -18,8 +15,6 @@ static int use_async;
static
char
buf
[
BSIZE
];
struct
ipcctl
*
ipcctl
=
(
struct
ipcctl
*
)
KSHARED
;
struct
{
u64
acount
;
u64
atot
;
...
...
@@ -28,50 +23,6 @@ struct {
u64
ptot
;
}
stats
;
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
)
{
...
...
include/fstream.h
0 → 100644
浏览文件 @
772fa427
typedef
struct
fstream
{
int
fd
;
off_t
off
;
off_t
poff
;
struct
stat
stat
;
int
err
:
1
;
int
eof
:
1
;
int
pfill
:
1
;
}
FILE
;
FILE
*
fdopen
(
int
fd
,
const
char
*
mode
);
int
fclose
(
FILE
*
fp
);
size_t
fread
(
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
FILE
*
fp
);
int
feof
(
FILE
*
fp
);
int
ferror
(
FILE
*
fp
);
include/ipc.hh
浏览文件 @
772fa427
#define IPC_NMSG 16
typedef
u32
msgid_t
;
#define NULL_MSGID (-1)
// XXX(sbw) add a memlayout.h?
#define KSHARED 0xFFFFF00000000000ull
#define IPC_NPAGE ((KSHAREDSIZE/PGSIZE) - 1)
typedef
u32
pageid_t
;
typedef
u32
msgid_t
;
#define IPC_CTLSIZE 4096
#define IPC_PGSIZE 4096
#define IPC_NMSG 16
#define NULL_MSGID (-1)
#define NULL_PAGEID (-1)
#define IPC_NPAGE ((KSHAREDSIZE/IPC_PGSIZE) - 1)
struct
ipcmsg
{
volatile
char
done
:
1
;
...
...
@@ -16,10 +21,28 @@ struct ipcmsg {
};
struct
ipcctl
{
int
msghead
;
int
msgtail
;
volatile
int
msghead
;
volatile
int
msgtail
;
struct
ipcmsg
msg
[
IPC_NMSG
];
int
pagehead
;
int
pagetail
;
volatile
int
pagehead
;
volatile
int
pagetail
;
};
extern
struct
ipcctl
*
ipcctl
;
msgid_t
ipc_msg_alloc
(
void
);
void
ipc_msg_free
(
int
msgid
);
pageid_t
ipc_page_alloc
(
void
);
void
ipc_page_free
(
pageid_t
pageid
);
static
inline
struct
ipcmsg
*
getmsg
(
msgid_t
id
)
{
return
&
ipcctl
->
msg
[
id
];
}
static
inline
char
*
getpage
(
pageid_t
id
)
{
return
(
char
*
)(
KSHARED
+
IPC_CTLSIZE
+
(
id
*
IPC_PGSIZE
));
}
lib/Makefrag
浏览文件 @
772fa427
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o
fstream.o ipc.o
ULIB := $(addprefix $(O)/lib/, $(ULIB))
.PRECIOUS: $(O)/lib/%.o
...
...
lib/fstream.cc
0 → 100644
浏览文件 @
772fa427
extern
"C"
{
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fstream.h"
#include "lib.h"
#include "amd64.h"
}
#include "ipc.hh"
static
const
size_t
pstride
=
4096
*
4
;
static
ssize_t
fasync
(
FILE
*
fp
,
size_t
count
,
off_t
off
)
{
struct
ipcmsg
*
msg
;
msgid_t
msgid
;
pageid_t
pageid
;
msgid
=
ipc_msg_alloc
();
if
(
msgid
==
NULL_MSGID
)
{
fprintf
(
2
,
"fasync: ipc_msg_alloc failed
\n
"
);
return
-
1
;
}
pageid
=
ipc_page_alloc
();
if
(
pageid
==
NULL_PAGEID
)
{
fprintf
(
2
,
"fasync: ipc_alloc_page failed
\n
"
);
return
-
1
;
}
msg
=
&
ipcctl
->
msg
[
msgid
];
msg
->
done
=
0
;
msg
->
pageid
=
pageid
;
if
(
async
(
fp
->
fd
,
count
,
off
,
msgid
,
pageid
)
!=
0
)
{
fprintf
(
2
,
"fasync: async failed
\n
"
);
return
-
1
;
}
return
count
;
}
static
void
fprefill
(
FILE
*
fp
)
{
size_t
target
;
if
(
!
fp
->
pfill
)
return
;
target
=
MIN
(
fp
->
off
+
pstride
,
fp
->
stat
.
size
);
while
(
target
-
fp
->
poff
>=
IPC_PGSIZE
)
{
size_t
count
;
int
r
;
count
=
MIN
(
target
-
fp
->
poff
,
IPC_PGSIZE
);
r
=
fasync
(
fp
,
count
,
fp
->
poff
);
if
(
r
<
0
)
return
;
fp
->
poff
+=
r
;
}
}
FILE
*
fdopen
(
int
fd
,
const
char
*
mode
)
{
FILE
*
fp
;
if
(
mode
[
0
]
!=
'r'
)
return
0
;
fp
=
(
FILE
*
)
malloc
(
sizeof
(
*
fp
));
if
(
fp
==
0
)
return
0
;
if
(
fstat
(
fd
,
&
fp
->
stat
))
return
0
;
fp
->
fd
=
fd
;
fp
->
off
=
0
;
fp
->
poff
=
0
;
fp
->
pfill
=
mode
[
1
]
==
'p'
;
fprefill
(
fp
);
return
fp
;
}
int
fclose
(
FILE
*
fp
)
{
int
r
;
r
=
close
(
fp
->
fd
);
free
(
fp
);
return
r
;
// XXX(sbw) free ipcmsgs
}
static
ssize_t
fpostfill
(
void
*
ptr
,
size_t
count
,
FILE
*
fp
)
{
struct
ipcmsg
*
msg
;
msgid_t
msgid
;
if
(
!
fp
->
pfill
)
return
-
2
;
again:
msgid
=
ipcctl
->
msgtail
%
IPC_NMSG
;
msg
=
getmsg
(
msgid
);
if
(
!
msg
->
submitted
)
return
-
2
;
while
(
msg
->
done
==
0
)
nop_pause
();
// XXX(sbw) yield somewhere?
if
(
msg
->
result
==
-
1
)
return
-
1
;
if
(
msg
->
off
>
fp
->
off
)
{
return
-
2
;
}
else
if
((
msg
->
off
+
msg
->
result
)
<
fp
->
off
)
{
msg
->
submitted
=
0
;
ipc_page_free
(
msg
->
pageid
);
ipc_msg_free
(
msgid
);
goto
again
;
}
char
*
buf
=
getpage
(
msg
->
pageid
);
off_t
boff
=
fp
->
off
-
msg
->
off
;
size_t
bcount
=
MIN
(
count
,
msg
->
result
-
boff
);
memmove
(
ptr
,
buf
+
boff
,
bcount
);
msg
->
submitted
=
0
;
ipc_page_free
(
msg
->
pageid
);
ipc_msg_free
(
msgid
);
return
bcount
;
}
size_t
fread
(
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
FILE
*
fp
)
{
ssize_t
r
;
r
=
fpostfill
(
ptr
,
size
*
nmemb
,
fp
);
if
(
r
==
-
2
)
r
=
pread
(
fp
->
fd
,
ptr
,
size
*
nmemb
,
fp
->
off
);
if
(
r
<
0
)
{
fp
->
err
=
1
;
return
0
;
}
else
if
(
r
==
0
)
{
fp
->
eof
=
1
;
return
0
;
}
fp
->
off
+=
r
;
fprefill
(
fp
);
return
r
;
}
int
feof
(
FILE
*
fp
)
{
return
fp
->
eof
;
}
int
ferror
(
FILE
*
fp
)
{
return
fp
->
err
;
}
lib/ipc.cc
0 → 100644
浏览文件 @
772fa427
#include "types.h"
#include "user.h"
#include "ipc.hh"
struct
ipcctl
*
ipcctl
=
(
struct
ipcctl
*
)
KSHARED
;
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
;
}
void
ipc_msg_free
(
int
msgid
)
{
msgid_t
i
;
i
=
ipcctl
->
msgtail
%
IPC_NMSG
;
if
(
i
!=
msgid
)
die
(
"ipc_free_msg: oops %u %u"
,
i
,
msgid
);
ipcctl
->
msgtail
++
;
}
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
;
}
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
++
;
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论