Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
rcore-os
RCore Tutorial V3
提交
5389b7ad
R
RCore Tutorial V3
项目概览
rcore-os
/
RCore Tutorial V3
上一次同步 1 年多
通知
15
Star
793
Fork
260
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
RCore Tutorial V3
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
5389b7ad
编写于
1月 18, 2022
作者:
Y
Yifan Wu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove pipe && Fix cat and huge_write.
上级
57f7debb
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
7 addition
and
332 deletion
+7
-332
os/src/fs/mod.rs
os/src/fs/mod.rs
+1
-3
os/src/fs/pipe.rs
os/src/fs/pipe.rs
+0
-168
os/src/syscall/fs.rs
os/src/syscall/fs.rs
+1
-31
os/src/syscall/mod.rs
os/src/syscall/mod.rs
+0
-4
user/src/bin/cat.rs
user/src/bin/cat.rs
+3
-5
user/src/bin/huge_write.rs
user/src/bin/huge_write.rs
+2
-2
user/src/bin/pipe_large_test.rs
user/src/bin/pipe_large_test.rs
+0
-69
user/src/bin/pipetest.rs
user/src/bin/pipetest.rs
+0
-44
user/src/lib.rs
user/src/lib.rs
+0
-1
user/src/syscall.rs
user/src/syscall.rs
+0
-5
未找到文件。
os/src/fs/mod.rs
浏览文件 @
5389b7ad
mod
pipe
;
mod
stdio
;
mod
inode
;
...
...
@@ -11,6 +10,5 @@ pub trait File : Send + Sync {
fn
write
(
&
self
,
buf
:
UserBuffer
)
->
usize
;
}
pub
use
pipe
::{
Pipe
,
make_pipe
};
pub
use
stdio
::{
Stdin
,
Stdout
};
pub
use
inode
::{
OSInode
,
open_file
,
OpenFlags
,
list_apps
};
\ No newline at end of file
pub
use
inode
::{
OSInode
,
open_file
,
OpenFlags
,
list_apps
};
os/src/fs/pipe.rs
已删除
100644 → 0
浏览文件 @
57f7debb
use
super
::
File
;
use
alloc
::
sync
::{
Arc
,
Weak
};
use
crate
::
sync
::
UPSafeCell
;
use
crate
::
mm
::
UserBuffer
;
use
crate
::
task
::
suspend_current_and_run_next
;
pub
struct
Pipe
{
readable
:
bool
,
writable
:
bool
,
buffer
:
Arc
<
UPSafeCell
<
PipeRingBuffer
>>
,
}
impl
Pipe
{
pub
fn
read_end_with_buffer
(
buffer
:
Arc
<
UPSafeCell
<
PipeRingBuffer
>>
)
->
Self
{
Self
{
readable
:
true
,
writable
:
false
,
buffer
,
}
}
pub
fn
write_end_with_buffer
(
buffer
:
Arc
<
UPSafeCell
<
PipeRingBuffer
>>
)
->
Self
{
Self
{
readable
:
false
,
writable
:
true
,
buffer
,
}
}
}
const
RING_BUFFER_SIZE
:
usize
=
32
;
#[derive(Copy,
Clone,
PartialEq)]
enum
RingBufferStatus
{
FULL
,
EMPTY
,
NORMAL
,
}
pub
struct
PipeRingBuffer
{
arr
:
[
u8
;
RING_BUFFER_SIZE
],
head
:
usize
,
tail
:
usize
,
status
:
RingBufferStatus
,
write_end
:
Option
<
Weak
<
Pipe
>>
,
}
impl
PipeRingBuffer
{
pub
fn
new
()
->
Self
{
Self
{
arr
:
[
0
;
RING_BUFFER_SIZE
],
head
:
0
,
tail
:
0
,
status
:
RingBufferStatus
::
EMPTY
,
write_end
:
None
,
}
}
pub
fn
set_write_end
(
&
mut
self
,
write_end
:
&
Arc
<
Pipe
>
)
{
self
.write_end
=
Some
(
Arc
::
downgrade
(
write_end
));
}
pub
fn
write_byte
(
&
mut
self
,
byte
:
u8
)
{
self
.status
=
RingBufferStatus
::
NORMAL
;
self
.arr
[
self
.tail
]
=
byte
;
self
.tail
=
(
self
.tail
+
1
)
%
RING_BUFFER_SIZE
;
if
self
.tail
==
self
.head
{
self
.status
=
RingBufferStatus
::
FULL
;
}
}
pub
fn
read_byte
(
&
mut
self
)
->
u8
{
self
.status
=
RingBufferStatus
::
NORMAL
;
let
c
=
self
.arr
[
self
.head
];
self
.head
=
(
self
.head
+
1
)
%
RING_BUFFER_SIZE
;
if
self
.head
==
self
.tail
{
self
.status
=
RingBufferStatus
::
EMPTY
;
}
c
}
pub
fn
available_read
(
&
self
)
->
usize
{
if
self
.status
==
RingBufferStatus
::
EMPTY
{
0
}
else
{
if
self
.tail
>
self
.head
{
self
.tail
-
self
.head
}
else
{
self
.tail
+
RING_BUFFER_SIZE
-
self
.head
}
}
}
pub
fn
available_write
(
&
self
)
->
usize
{
if
self
.status
==
RingBufferStatus
::
FULL
{
0
}
else
{
RING_BUFFER_SIZE
-
self
.available_read
()
}
}
pub
fn
all_write_ends_closed
(
&
self
)
->
bool
{
self
.write_end
.as_ref
()
.unwrap
()
.upgrade
()
.is_none
()
}
}
/// Return (read_end, write_end)
pub
fn
make_pipe
()
->
(
Arc
<
Pipe
>
,
Arc
<
Pipe
>
)
{
let
buffer
=
Arc
::
new
(
unsafe
{
UPSafeCell
::
new
(
PipeRingBuffer
::
new
())
});
let
read_end
=
Arc
::
new
(
Pipe
::
read_end_with_buffer
(
buffer
.clone
())
);
let
write_end
=
Arc
::
new
(
Pipe
::
write_end_with_buffer
(
buffer
.clone
())
);
buffer
.exclusive_access
()
.set_write_end
(
&
write_end
);
(
read_end
,
write_end
)
}
impl
File
for
Pipe
{
fn
readable
(
&
self
)
->
bool
{
self
.readable
}
fn
writable
(
&
self
)
->
bool
{
self
.writable
}
fn
read
(
&
self
,
buf
:
UserBuffer
)
->
usize
{
assert_eq!
(
self
.readable
(),
true
);
let
mut
buf_iter
=
buf
.into_iter
();
let
mut
read_size
=
0u
size
;
loop
{
let
mut
ring_buffer
=
self
.buffer
.exclusive_access
();
let
loop_read
=
ring_buffer
.available_read
();
if
loop_read
==
0
{
if
ring_buffer
.all_write_ends_closed
()
{
return
read_size
;
}
drop
(
ring_buffer
);
suspend_current_and_run_next
();
continue
;
}
// read at most loop_read bytes
for
_
in
0
..
loop_read
{
if
let
Some
(
byte_ref
)
=
buf_iter
.next
()
{
unsafe
{
*
byte_ref
=
ring_buffer
.read_byte
();
}
read_size
+=
1
;
}
else
{
return
read_size
;
}
}
}
}
fn
write
(
&
self
,
buf
:
UserBuffer
)
->
usize
{
assert_eq!
(
self
.writable
(),
true
);
let
mut
buf_iter
=
buf
.into_iter
();
let
mut
write_size
=
0u
size
;
loop
{
let
mut
ring_buffer
=
self
.buffer
.exclusive_access
();
let
loop_write
=
ring_buffer
.available_write
();
if
loop_write
==
0
{
drop
(
ring_buffer
);
suspend_current_and_run_next
();
continue
;
}
// write at most loop_write bytes
for
_
in
0
..
loop_write
{
if
let
Some
(
byte_ref
)
=
buf_iter
.next
()
{
ring_buffer
.write_byte
(
unsafe
{
*
byte_ref
});
write_size
+=
1
;
}
else
{
return
write_size
;
}
}
}
}
}
\ No newline at end of file
os/src/syscall/fs.rs
浏览文件 @
5389b7ad
use
crate
::
mm
::{
UserBuffer
,
translated_byte_buffer
,
translated_refmut
,
translated_str
,
};
use
crate
::
task
::{
current_user_token
,
current_task
};
use
crate
::
fs
::{
make_pipe
,
OpenFlags
,
open_file
};
use
alloc
::
sync
::
Arc
;
use
crate
::
fs
::{
OpenFlags
,
open_file
};
pub
fn
sys_write
(
fd
:
usize
,
buf
:
*
const
u8
,
len
:
usize
)
->
isize
{
let
token
=
current_user_token
();
...
...
@@ -81,31 +79,3 @@ pub fn sys_close(fd: usize) -> isize {
inner
.fd_table
[
fd
]
.take
();
0
}
pub
fn
sys_pipe
(
pipe
:
*
mut
usize
)
->
isize
{
let
task
=
current_task
()
.unwrap
();
let
token
=
current_user_token
();
let
mut
inner
=
task
.inner_exclusive_access
();
let
(
pipe_read
,
pipe_write
)
=
make_pipe
();
let
read_fd
=
inner
.alloc_fd
();
inner
.fd_table
[
read_fd
]
=
Some
(
pipe_read
);
let
write_fd
=
inner
.alloc_fd
();
inner
.fd_table
[
write_fd
]
=
Some
(
pipe_write
);
*
translated_refmut
(
token
,
pipe
)
=
read_fd
;
*
translated_refmut
(
token
,
unsafe
{
pipe
.add
(
1
)
})
=
write_fd
;
0
}
pub
fn
sys_dup
(
fd
:
usize
)
->
isize
{
let
task
=
current_task
()
.unwrap
();
let
mut
inner
=
task
.inner_exclusive_access
();
if
fd
>=
inner
.fd_table
.len
()
{
return
-
1
;
}
if
inner
.fd_table
[
fd
]
.is_none
()
{
return
-
1
;
}
let
new_fd
=
inner
.alloc_fd
();
inner
.fd_table
[
new_fd
]
=
Some
(
Arc
::
clone
(
inner
.fd_table
[
fd
]
.as_ref
()
.unwrap
()));
new_fd
as
isize
}
\ No newline at end of file
os/src/syscall/mod.rs
浏览文件 @
5389b7ad
const
SYSCALL_DUP
:
usize
=
24
;
const
SYSCALL_OPEN
:
usize
=
56
;
const
SYSCALL_CLOSE
:
usize
=
57
;
const
SYSCALL_PIPE
:
usize
=
59
;
const
SYSCALL_READ
:
usize
=
63
;
const
SYSCALL_WRITE
:
usize
=
64
;
const
SYSCALL_EXIT
:
usize
=
93
;
...
...
@@ -20,10 +18,8 @@ use process::*;
pub
fn
syscall
(
syscall_id
:
usize
,
args
:
[
usize
;
3
])
->
isize
{
match
syscall_id
{
SYSCALL_DUP
=>
sys_dup
(
args
[
0
]),
SYSCALL_OPEN
=>
sys_open
(
args
[
0
]
as
*
const
u8
,
args
[
1
]
as
u32
),
SYSCALL_CLOSE
=>
sys_close
(
args
[
0
]),
SYSCALL_PIPE
=>
sys_pipe
(
args
[
0
]
as
*
mut
usize
),
SYSCALL_READ
=>
sys_read
(
args
[
0
],
args
[
1
]
as
*
const
u8
,
args
[
2
]),
SYSCALL_WRITE
=>
sys_write
(
args
[
0
],
args
[
1
]
as
*
const
u8
,
args
[
2
]),
SYSCALL_EXIT
=>
sys_exit
(
args
[
0
]
as
i32
),
...
...
user/src/bin/cat.rs
浏览文件 @
5389b7ad
...
...
@@ -21,14 +21,12 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
panic!
(
"Error occured when opening file"
);
}
let
fd
=
fd
as
usize
;
let
mut
buf
=
[
0u8
;
16
];
let
mut
s
=
String
::
new
();
let
mut
buf
=
[
0u8
;
256
];
loop
{
let
size
=
read
(
fd
,
&
mut
buf
)
as
usize
;
if
size
==
0
{
break
;
}
s
.push_str
(
core
::
str
::
from_utf8
(
&
buf
[
..
size
])
.unwrap
());
println!
(
"{}"
,
core
::
str
::
from_utf8
(
&
buf
[
..
size
])
.unwrap
());
}
println!
(
"{}"
,
s
);
close
(
fd
);
0
}
\ No newline at end of file
}
user/src/bin/huge_write.rs
浏览文件 @
5389b7ad
...
...
@@ -18,7 +18,7 @@ pub fn main() -> i32 {
for
i
in
0
..
buffer
.len
()
{
buffer
[
i
]
=
i
as
u8
;
}
let
f
=
open
(
"testf"
,
OpenFlags
::
CREATE
|
OpenFlags
::
WRONLY
);
let
f
=
open
(
"testf
\0
"
,
OpenFlags
::
CREATE
|
OpenFlags
::
WRONLY
);
if
f
<
0
{
panic!
(
"Open test file failed!"
);
}
...
...
@@ -33,4 +33,4 @@ pub fn main() -> i32 {
let
speed_kbs
=
size_mb
*
1000000
/
time_ms
;
println!
(
"{}MiB written, time cost = {}ms, write speed = {}KiB/s"
,
size_mb
,
time_ms
,
speed_kbs
);
0
}
\ No newline at end of file
}
user/src/bin/pipe_large_test.rs
已删除
100644 → 0
浏览文件 @
57f7debb
#![no_std]
#![no_main]
#[macro_use]
extern
crate
user_lib
;
extern
crate
alloc
;
use
user_lib
::{
fork
,
close
,
pipe
,
read
,
write
,
wait
,
get_time
};
use
alloc
::
format
;
const
LENGTH
:
usize
=
3000
;
#[no_mangle]
pub
fn
main
()
->
i32
{
// create pipes
// parent write to child
let
mut
down_pipe_fd
=
[
0u
size
;
2
];
// child write to parent
let
mut
up_pipe_fd
=
[
0u
size
;
2
];
pipe
(
&
mut
down_pipe_fd
);
pipe
(
&
mut
up_pipe_fd
);
let
mut
random_str
=
[
0u8
;
LENGTH
];
if
fork
()
==
0
{
// close write end of down pipe
close
(
down_pipe_fd
[
1
]);
// close read end of up pipe
close
(
up_pipe_fd
[
0
]);
assert_eq!
(
read
(
down_pipe_fd
[
0
],
&
mut
random_str
)
as
usize
,
LENGTH
);
close
(
down_pipe_fd
[
0
]);
let
sum
:
usize
=
random_str
.iter
()
.map
(|
v
|
*
v
as
usize
)
.sum
::
<
usize
>
();
println!
(
"sum = {}(child)"
,
sum
);
let
sum_str
=
format!
(
"{}"
,
sum
);
write
(
up_pipe_fd
[
1
],
sum_str
.as_bytes
());
close
(
up_pipe_fd
[
1
]);
println!
(
"Child process exited!"
);
0
}
else
{
// close read end of down pipe
close
(
down_pipe_fd
[
0
]);
// close write end of up pipe
close
(
up_pipe_fd
[
1
]);
// generate a long random string
for
i
in
0
..
LENGTH
{
random_str
[
i
]
=
get_time
()
as
u8
;
}
// send it
assert_eq!
(
write
(
down_pipe_fd
[
1
],
&
random_str
)
as
usize
,
random_str
.len
());
// close write end of down pipe
close
(
down_pipe_fd
[
1
]);
// calculate sum(parent)
let
sum
:
usize
=
random_str
.iter
()
.map
(|
v
|
*
v
as
usize
)
.sum
::
<
usize
>
();
println!
(
"sum = {}(parent)"
,
sum
);
// recv sum(child)
let
mut
child_result
=
[
0u8
;
32
];
let
result_len
=
read
(
up_pipe_fd
[
0
],
&
mut
child_result
)
as
usize
;
close
(
up_pipe_fd
[
0
]);
// check
assert_eq!
(
sum
,
str
::
parse
::
<
usize
>
(
core
::
str
::
from_utf8
(
&
child_result
[
..
result_len
])
.unwrap
()
)
.unwrap
()
);
let
mut
_u
nused
:
i32
=
0
;
wait
(
&
mut
_u
nused
);
println!
(
"pipe_large_test passed!"
);
0
}
}
\ No newline at end of file
user/src/bin/pipetest.rs
已删除
100644 → 0
浏览文件 @
57f7debb
#![no_std]
#![no_main]
#[macro_use]
extern
crate
user_lib
;
use
user_lib
::{
fork
,
close
,
pipe
,
read
,
write
,
wait
};
static
STR
:
&
str
=
"Hello, world!"
;
#[no_mangle]
pub
fn
main
()
->
i32
{
// create pipe
let
mut
pipe_fd
=
[
0u
size
;
2
];
pipe
(
&
mut
pipe_fd
);
// read end
assert_eq!
(
pipe_fd
[
0
],
3
);
// write end
assert_eq!
(
pipe_fd
[
1
],
4
);
if
fork
()
==
0
{
// child process, read from parent
// close write_end
close
(
pipe_fd
[
1
]);
let
mut
buffer
=
[
0u8
;
32
];
let
len_read
=
read
(
pipe_fd
[
0
],
&
mut
buffer
)
as
usize
;
// close read_end
close
(
pipe_fd
[
0
]);
assert_eq!
(
core
::
str
::
from_utf8
(
&
buffer
[
..
len_read
])
.unwrap
(),
STR
);
println!
(
"Read OK, child process exited!"
);
0
}
else
{
// parent process, write to child
// close read end
close
(
pipe_fd
[
0
]);
assert_eq!
(
write
(
pipe_fd
[
1
],
STR
.as_bytes
()),
STR
.len
()
as
isize
);
// close write end
close
(
pipe_fd
[
1
]);
let
mut
child_exit_code
:
i32
=
0
;
wait
(
&
mut
child_exit_code
);
assert_eq!
(
child_exit_code
,
0
);
println!
(
"pipetest passed!"
);
0
}
}
\ No newline at end of file
user/src/lib.rs
浏览文件 @
5389b7ad
...
...
@@ -71,7 +71,6 @@ bitflags! {
pub
fn
dup
(
fd
:
usize
)
->
isize
{
sys_dup
(
fd
)
}
pub
fn
open
(
path
:
&
str
,
flags
:
OpenFlags
)
->
isize
{
sys_open
(
path
,
flags
.bits
)
}
pub
fn
close
(
fd
:
usize
)
->
isize
{
sys_close
(
fd
)
}
pub
fn
pipe
(
pipe_fd
:
&
mut
[
usize
])
->
isize
{
sys_pipe
(
pipe_fd
)
}
pub
fn
read
(
fd
:
usize
,
buf
:
&
mut
[
u8
])
->
isize
{
sys_read
(
fd
,
buf
)
}
pub
fn
write
(
fd
:
usize
,
buf
:
&
[
u8
])
->
isize
{
sys_write
(
fd
,
buf
)
}
pub
fn
exit
(
exit_code
:
i32
)
->
!
{
sys_exit
(
exit_code
);
}
...
...
user/src/syscall.rs
浏览文件 @
5389b7ad
...
...
@@ -3,7 +3,6 @@ use core::arch::asm;
const
SYSCALL_DUP
:
usize
=
24
;
const
SYSCALL_OPEN
:
usize
=
56
;
const
SYSCALL_CLOSE
:
usize
=
57
;
const
SYSCALL_PIPE
:
usize
=
59
;
const
SYSCALL_READ
:
usize
=
63
;
const
SYSCALL_WRITE
:
usize
=
64
;
const
SYSCALL_EXIT
:
usize
=
93
;
...
...
@@ -40,10 +39,6 @@ pub fn sys_close(fd: usize) -> isize {
syscall
(
SYSCALL_CLOSE
,
[
fd
,
0
,
0
])
}
pub
fn
sys_pipe
(
pipe
:
&
mut
[
usize
])
->
isize
{
syscall
(
SYSCALL_PIPE
,
[
pipe
.as_mut_ptr
()
as
usize
,
0
,
0
])
}
pub
fn
sys_read
(
fd
:
usize
,
buffer
:
&
mut
[
u8
])
->
isize
{
syscall
(
SYSCALL_READ
,
[
fd
,
buffer
.as_mut_ptr
()
as
usize
,
buffer
.len
()])
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录