Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
b548df15
提交
b548df15
7月 11, 2006
创建
作者:
rtm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
pre-empt both user and kernel, in clock interrupt
usertest.c tests pre-emption kill()
上级
5ce9751c
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
152 行增加
和
47 行删除
+152
-47
Notes
Notes
+18
-12
defs.h
defs.h
+2
-0
kalloc.c
kalloc.c
+0
-2
main.c
main.c
+4
-3
proc.c
proc.c
+42
-0
proc.h
proc.h
+1
-0
spinlock.c
spinlock.c
+2
-2
syscall.c
syscall.c
+22
-26
syscall.h
syscall.h
+1
-0
trap.c
trap.c
+11
-0
usertests.c
usertests.c
+47
-2
usys.S
usys.S
+2
-0
没有找到文件。
Notes
浏览文件 @
b548df15
...
...
@@ -80,16 +80,22 @@ trap() ought to lgdt on return, since currently only done in swtch()
protect hardware interrupt vectors from user INT instructions?
i'm getting a curious interrupt when jumping into user space. maybe
it's IRQ 0, but it comes at a weird and changing vector (e.g. 119) if
you don't initialize the PIC. why doesn't jos see this? if i
initialize the PIC with IRQ_OFFSET 32, the interrupt arrives at vector
32.
test out-of-fd cases for creating pipe.
test pipe circular buffer
test pipe writer or reader closes while other active or waiting
test exit vs fd reference counts
test write of more than PIPESIZE
test reader goes first vs writer goes first
test streaming of a lot of data
test pipe reader closes then write
test two readers, two writers.
test children being inherited by grandparent &c
kill
sleep()ing for something
running at user level
running in kernel
ooh, the relevant CPU may never get a clock interrupt
should each cpu have its own clock?
where to check?
loops around sleep()
return from any trap
rules about being killed deep inside a system call
test above cases
cli/sti in acquire/release should nest!
in case you acquire two locks
defs.h
浏览文件 @
b548df15
...
...
@@ -17,6 +17,8 @@ void swtch(void);
void
sleep
(
void
*
);
void
wakeup
(
void
*
);
void
scheduler
(
void
);
void
proc_exit
(
void
);
void
yield
(
void
);
// swtch.S
struct
jmpbuf
;
...
...
kalloc.c
浏览文件 @
b548df15
...
...
@@ -158,6 +158,4 @@ ktest()
if
(
p1
==
0
)
panic
(
"ktest2"
);
kfree
(
p1
,
PAGE
*
20
);
cprintf
(
"ktest ok
\n
"
);
}
main.c
浏览文件 @
b548df15
...
...
@@ -66,11 +66,12 @@ main()
ide_init
();
// become interruptable
write_eflags
(
read_eflags
()
|
FL_IF
);
sti
(
);
p
=
newproc
();
// load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
load_icode
(
p
,
_binary_userfs_start
,
(
unsigned
)
_binary_userfs_size
);
load_icode
(
p
,
_binary_usertests_start
,
(
unsigned
)
_binary_usertests_size
);
//load_icode(p, _binary_userfs_start, (unsigned) _binary_userfs_size);
cprintf
(
"loaded userfs
\n
"
);
scheduler
();
...
...
proc.c
浏览文件 @
b548df15
...
...
@@ -184,3 +184,45 @@ wakeup(void *chan)
if
(
p
->
state
==
WAITING
&&
p
->
chan
==
chan
)
p
->
state
=
RUNNABLE
;
}
// give up the CPU but stay marked as RUNNABLE
void
yield
()
{
if
(
curproc
[
cpu
()]
==
0
||
curproc
[
cpu
()]
->
state
!=
RUNNING
)
panic
(
"yield"
);
curproc
[
cpu
()]
->
state
=
RUNNABLE
;
swtch
();
}
void
proc_exit
()
{
struct
proc
*
p
;
struct
proc
*
cp
=
curproc
[
cpu
()];
int
fd
;
cprintf
(
"exit %x
\n
"
,
cp
);
for
(
fd
=
0
;
fd
<
NOFILE
;
fd
++
){
if
(
cp
->
fds
[
fd
]){
fd_close
(
cp
->
fds
[
fd
]);
cp
->
fds
[
fd
]
=
0
;
}
}
cp
->
state
=
ZOMBIE
;
// wake up parent
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
pid
==
cp
->
ppid
)
wakeup
(
p
);
// abandon children
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
ppid
==
cp
->
pid
)
p
->
pid
=
1
;
// switch into scheduler
swtch
();
}
proc.h
浏览文件 @
b548df15
...
...
@@ -41,6 +41,7 @@ struct proc{
int
pid
;
int
ppid
;
void
*
chan
;
// sleep
int
killed
;
struct
fd
*
fds
[
NOFILE
];
struct
Taskstate
ts
;
// only to give cpu address of kernel stack
...
...
spinlock.c
浏览文件 @
b548df15
...
...
@@ -20,7 +20,7 @@ acquire_spinlock(uint32_t* lock)
// on a real machine there would be a memory barrier here
if
(
DEBUG
)
cprintf
(
"cpu%d: acquiring at %x
\n
"
,
cpu_id
,
getcallerpc
(
&
lock
));
write_eflags
(
read_eflags
()
&
~
FL_IF
);
cli
(
);
if
(
*
lock
==
cpu_id
)
panic
(
"recursive lock"
);
...
...
@@ -37,7 +37,7 @@ release_spinlock(uint32_t* lock)
panic
(
"release_spinlock: releasing a lock that i don't own
\n
"
);
*
lock
=
LOCK_FREE
;
// on a real machine there would be a memory barrier here
write_eflags
(
read_eflags
()
|
FL_IF
);
sti
(
);
}
void
...
...
syscall.c
浏览文件 @
b548df15
...
...
@@ -155,32 +155,7 @@ sys_fork()
int
sys_exit
()
{
struct
proc
*
p
;
struct
proc
*
cp
=
curproc
[
cpu
()];
int
fd
;
for
(
fd
=
0
;
fd
<
NOFILE
;
fd
++
){
if
(
cp
->
fds
[
fd
]){
fd_close
(
cp
->
fds
[
fd
]);
cp
->
fds
[
fd
]
=
0
;
}
}
cp
->
state
=
ZOMBIE
;
// wake up parent
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
pid
==
cp
->
ppid
)
wakeup
(
p
);
// abandon children
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
ppid
==
cp
->
pid
)
p
->
pid
=
1
;
// switch into scheduler
swtch
();
proc_exit
();
return
0
;
}
...
...
@@ -250,6 +225,24 @@ sys_block(void)
return
0
;
}
int
sys_kill
()
{
int
pid
;
struct
proc
*
p
;
fetcharg
(
0
,
&
pid
);
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
){
if
(
p
->
pid
==
pid
&&
p
->
state
!=
UNUSED
){
p
->
killed
=
1
;
if
(
p
->
state
==
WAITING
)
p
->
state
=
RUNNABLE
;
return
0
;
}
}
return
-
1
;
}
void
syscall
()
{
...
...
@@ -286,6 +279,9 @@ syscall()
case
SYS_block
:
ret
=
sys_block
();
break
;
case
SYS_kill
:
ret
=
sys_kill
();
break
;
default:
cprintf
(
"unknown sys call %d
\n
"
,
num
);
// XXX fault
...
...
syscall.h
浏览文件 @
b548df15
...
...
@@ -7,3 +7,4 @@
#define SYS_read 7
#define SYS_close 8
#define SYS_block 9
#define SYS_kill 10
trap.c
浏览文件 @
b548df15
...
...
@@ -45,6 +45,8 @@ trap(struct Trapframe *tf)
struct
proc
*
cp
=
curproc
[
cpu
()];
if
(
cp
==
0
)
panic
(
"syscall with no proc"
);
if
(
cp
->
killed
)
proc_exit
();
cp
->
tf
=
tf
;
syscall
();
if
(
cp
!=
curproc
[
cpu
()])
...
...
@@ -55,11 +57,20 @@ trap(struct Trapframe *tf)
panic
(
"trap ret wrong tf"
);
if
(
read_esp
()
<
(
unsigned
)
cp
->
kstack
||
read_esp
()
>=
(
unsigned
)
cp
->
kstack
+
KSTACKSIZE
)
panic
(
"trap ret esp wrong"
);
if
(
cp
->
killed
)
proc_exit
();
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_TIMER
)){
struct
proc
*
cp
=
curproc
[
cpu
()];
lapic_timerintr
();
if
(
cp
){
sti
();
if
(
cp
->
killed
)
proc_exit
();
yield
();
}
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_IDE
)){
...
...
usertests.c
浏览文件 @
b548df15
// simple fork and pipe read/write
char
buf
[
2048
];
// simple fork and pipe read/write
void
pipe1
()
{
...
...
@@ -47,9 +47,54 @@ pipe1()
puts
(
"pipe1 ok
\n
"
);
}
// meant to be run w/ at most two CPUs
void
preempt
()
{
int
pid1
,
pid2
,
pid3
;
int
pfds
[
2
];
pid1
=
fork
();
if
(
pid1
==
0
)
while
(
1
)
;
pid2
=
fork
();
if
(
pid2
==
0
)
while
(
1
)
;
pipe
(
pfds
);
pid3
=
fork
();
if
(
pid3
==
0
){
close
(
pfds
[
0
]);
if
(
write
(
pfds
[
1
],
"x"
,
1
)
!=
1
)
puts
(
"preempt write error"
);
close
(
pfds
[
1
]);
while
(
1
)
;
}
close
(
pfds
[
1
]);
if
(
read
(
pfds
[
0
],
buf
,
sizeof
(
buf
))
!=
1
){
puts
(
"preempt read error"
);
return
;
}
close
(
pfds
[
0
]);
kill
(
pid1
);
kill
(
pid2
);
kill
(
pid3
);
wait
();
wait
();
wait
();
puts
(
"preempt ok
\n
"
);
}
main
()
{
puts
(
"usertests starting
\n
"
);
pipe1
();
//preempt();
while
(
1
)
;
...
...
usys.S
浏览文件 @
b548df15
...
...
@@ -10,9 +10,11 @@
STUB(fork)
STUB(exit)
STUB(wait)
STUB(cons_putc)
STUB(pipe)
STUB(read)
STUB(write)
STUB(close)
STUB(block)
STUB(kill)
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论