Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
69db41a0
提交
69db41a0
12月 21, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add a timeout to condvars.
Waking up a process after the its wait time expires might livelock core 0, but it's unlikely.
上级
9cd75414
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
99 行增加
和
39 行删除
+99
-39
condvar.c
condvar.c
+84
-22
condvar.h
condvar.h
+3
-1
kernel.h
kernel.h
+5
-3
proc.h
proc.h
+5
-2
trap.c
trap.c
+2
-11
没有找到文件。
condvar.c
浏览文件 @
69db41a0
...
@@ -8,15 +8,60 @@
...
@@ -8,15 +8,60 @@
#include "kernel.h"
#include "kernel.h"
#include "cpu.h"
#include "cpu.h"
void
struct
spinlock
tickslock
__mpalign__
;
initcondvar
(
struct
condvar
*
cv
,
char
*
n
)
struct
condvar
cv_ticks
__mpalign__
;
u64
ticks
__mpalign__
;
LIST_HEAD
(
sleepers
,
proc
)
sleepers
__mpalign__
;
struct
spinlock
sleepers_lock
;
static
void
wakeup
(
struct
proc
*
p
)
{
{
initlock
(
&
cv
->
lock
,
n
);
LIST_REMOVE
(
p
,
cv_waiters
);
cv
->
waiters
=
0
;
p
->
oncv
=
0
;
addrun
(
p
);
p
->
state
=
RUNNABLE
;
}
}
void
void
cv_sleep
(
struct
condvar
*
cv
,
struct
spinlock
*
lk
)
cv_tick
(
void
)
{
struct
proc
*
p
,
*
tmp
;
int
again
;
u64
now
;
acquire
(
&
tickslock
);
ticks
++
;
cv_wakeup
(
&
cv_ticks
);
release
(
&
tickslock
);
now
=
nsectime
();
again
=
0
;
do
{
acquire
(
&
sleepers_lock
);
LIST_FOREACH_SAFE
(
p
,
&
sleepers
,
cv_sleep
,
tmp
)
{
if
(
p
->
cv_wakeup
<=
now
)
{
if
(
tryacquire
(
&
p
->
lock
))
{
if
(
tryacquire
(
&
p
->
oncv
->
lock
))
{
LIST_REMOVE
(
p
,
cv_sleep
);
p
->
cv_wakeup
=
0
;
wakeup
(
p
);
release
(
&
p
->
lock
);
release
(
&
p
->
oncv
->
lock
);
continue
;
}
else
{
release
(
&
p
->
lock
);
}
}
again
=
1
;
}
}
release
(
&
sleepers_lock
);
}
while
(
again
);
}
void
cv_sleepto
(
struct
condvar
*
cv
,
struct
spinlock
*
lk
,
u64
timeout
)
{
{
if
(
myproc
()
==
0
)
if
(
myproc
()
==
0
)
panic
(
"sleep"
);
panic
(
"sleep"
);
...
@@ -31,44 +76,61 @@ cv_sleep(struct condvar *cv, struct spinlock *lk)
...
@@ -31,44 +76,61 @@ cv_sleep(struct condvar *cv, struct spinlock *lk)
acquire
(
&
myproc
()
->
lock
);
acquire
(
&
myproc
()
->
lock
);
if
(
myproc
()
->
cv_next
||
myproc
()
->
oncv
)
if
(
myproc
()
->
oncv
)
panic
(
"cv_sleep cv_next"
);
panic
(
"cv_sleep oncv"
);
myproc
()
->
cv_next
=
cv
->
waiters
;
cv
->
waiters
=
myproc
();
LIST_INSERT_HEAD
(
&
cv
->
waiters
,
myproc
(),
cv_waiters
);
myproc
()
->
state
=
SLEEPING
;
myproc
()
->
oncv
=
cv
;
myproc
()
->
oncv
=
cv
;
myproc
()
->
state
=
SLEEPING
;
if
(
timeout
)
{
acquire
(
&
sleepers_lock
);
myproc
()
->
cv_wakeup
=
timeout
;
LIST_INSERT_HEAD
(
&
sleepers
,
myproc
(),
cv_sleep
);
release
(
&
sleepers_lock
);
}
release
(
&
cv
->
lock
);
release
(
&
cv
->
lock
);
sched
();
sched
();
release
(
&
myproc
()
->
lock
);
release
(
&
myproc
()
->
lock
);
// Reacquire original lock.
// Reacquire original lock.
acquire
(
lk
);
acquire
(
lk
);
}
}
void
cv_sleep
(
struct
condvar
*
cv
,
struct
spinlock
*
lk
)
{
cv_sleepto
(
cv
,
lk
,
0
);
}
// Wake up all processes sleeping on this condvar.
// Wake up all processes sleeping on this condvar.
void
void
cv_wakeup
(
struct
condvar
*
cv
)
cv_wakeup
(
struct
condvar
*
cv
)
{
{
// XXX race with cv_sleep()
struct
proc
*
p
,
*
tmp
;
// if (!cv->waiters)
// return;
acquire
(
&
cv
->
lock
);
acquire
(
&
cv
->
lock
);
while
(
cv
->
waiters
)
{
LIST_FOREACH_SAFE
(
p
,
&
cv
->
waiters
,
cv_waiters
,
tmp
)
{
struct
proc
*
p
=
cv
->
waiters
;
acquire
(
&
p
->
lock
);
acquire
(
&
p
->
lock
);
if
(
p
->
state
!=
SLEEPING
||
p
->
oncv
!=
cv
)
if
(
p
->
state
!=
SLEEPING
||
p
->
oncv
!=
cv
)
panic
(
"cv_wakeup"
);
panic
(
"cv_wakeup"
);
struct
proc
*
nxt
=
p
->
cv_next
;
if
(
p
->
cv_wakeup
)
{
p
->
cv_next
=
0
;
acquire
(
&
sleepers_lock
);
p
->
oncv
=
0
;
LIST_REMOVE
(
p
,
cv_sleep
);
addrun
(
p
);
p
->
cv_wakeup
=
0
;
p
->
state
=
RUNNABLE
;
release
(
&
sleepers_lock
);
}
wakeup
(
p
);
release
(
&
p
->
lock
);
release
(
&
p
->
lock
);
cv
->
waiters
=
nxt
;
}
}
release
(
&
cv
->
lock
);
release
(
&
cv
->
lock
);
}
}
void
initcondvar
(
struct
condvar
*
cv
,
char
*
n
)
{
initlock
(
&
cv
->
lock
,
n
);
LIST_INIT
(
&
cv
->
waiters
);
}
condvar.h
浏览文件 @
69db41a0
#include "queue.h"
struct
condvar
{
struct
condvar
{
struct
spinlock
lock
;
struct
spinlock
lock
;
struct
proc
*
waiters
;
LIST_HEAD
(
waiters
,
proc
)
waiters
;
};
};
kernel.h
浏览文件 @
69db41a0
...
@@ -55,9 +55,14 @@ void tree_test(void);
...
@@ -55,9 +55,14 @@ void tree_test(void);
void
cgaputc
(
int
c
);
void
cgaputc
(
int
c
);
// condvar.c
// condvar.c
extern
u64
ticks
;
extern
struct
spinlock
tickslock
;
extern
struct
condvar
cv_ticks
;
void
initcondvar
(
struct
condvar
*
,
char
*
);
void
initcondvar
(
struct
condvar
*
,
char
*
);
void
cv_sleep
(
struct
condvar
*
cv
,
struct
spinlock
*
);
void
cv_sleep
(
struct
condvar
*
cv
,
struct
spinlock
*
);
void
cv_sleepto
(
struct
condvar
*
cv
,
struct
spinlock
*
,
u64
);
void
cv_wakeup
(
struct
condvar
*
cv
);
void
cv_wakeup
(
struct
condvar
*
cv
);
void
cv_tick
(
void
);
// console.c
// console.c
void
cprintf
(
const
char
*
,
...);
void
cprintf
(
const
char
*
,
...);
...
@@ -279,9 +284,6 @@ void swtch(struct context**, struct context*);
...
@@ -279,9 +284,6 @@ void swtch(struct context**, struct context*);
// trap.c
// trap.c
extern
struct
segdesc
bootgdt
[
NSEGS
];
extern
struct
segdesc
bootgdt
[
NSEGS
];
extern
u64
ticks
;
extern
struct
spinlock
tickslock
;
extern
struct
condvar
cv_ticks
;
// uart.c
// uart.c
void
uartputc
(
char
c
);
void
uartputc
(
char
c
);
...
...
proc.h
浏览文件 @
69db41a0
...
@@ -42,8 +42,6 @@ struct proc {
...
@@ -42,8 +42,6 @@ struct proc {
struct
proc
*
parent
;
// Parent process
struct
proc
*
parent
;
// Parent process
struct
trapframe
*
tf
;
// Trap frame for current syscall
struct
trapframe
*
tf
;
// Trap frame for current syscall
struct
context
*
context
;
// swtch() here to run process
struct
context
*
context
;
// swtch() here to run process
struct
condvar
*
oncv
;
// Where it is sleeping, for kill()
struct
proc
*
cv_next
;
// Linked list of processes waiting for oncv
int
killed
;
// If non-zero, have been killed
int
killed
;
// If non-zero, have been killed
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
inode
*
cwd
;
// Current directory
struct
inode
*
cwd
;
// Current directory
...
@@ -66,6 +64,11 @@ struct proc {
...
@@ -66,6 +64,11 @@ struct proc {
struct
runq
*
runq
;
struct
runq
*
runq
;
struct
wqframe
wqframe
;
struct
wqframe
wqframe
;
STAILQ_ENTRY
(
proc
)
runqlink
;
STAILQ_ENTRY
(
proc
)
runqlink
;
struct
condvar
*
oncv
;
// Where it is sleeping, for kill()
u64
cv_wakeup
;
// Wakeup time for this process
LIST_ENTRY
(
proc
)
cv_waiters
;
// Linked list of processes waiting for oncv
LIST_ENTRY
(
proc
)
cv_sleep
;
// Linked list of processes sleeping on a cv
};
};
extern
struct
ns
*
nspid
;
extern
struct
ns
*
nspid
;
trap.c
浏览文件 @
69db41a0
...
@@ -11,11 +11,6 @@
...
@@ -11,11 +11,6 @@
#include "kmtrace.h"
#include "kmtrace.h"
#include "bits.h"
#include "bits.h"
u64
ticks
__mpalign__
;
struct
spinlock
tickslock
__mpalign__
;
struct
condvar
cv_ticks
__mpalign__
;
struct
segdesc
__attribute__
((
aligned
(
16
)))
bootgdt
[
NSEGS
]
=
{
struct
segdesc
__attribute__
((
aligned
(
16
)))
bootgdt
[
NSEGS
]
=
{
// null
// null
[
0
]
=
SEGDESC
(
0
,
0
,
0
),
[
0
]
=
SEGDESC
(
0
,
0
,
0
),
...
@@ -76,12 +71,8 @@ trap(struct trapframe *tf)
...
@@ -76,12 +71,8 @@ trap(struct trapframe *tf)
switch
(
tf
->
trapno
){
switch
(
tf
->
trapno
){
case
T_IRQ0
+
IRQ_TIMER
:
case
T_IRQ0
+
IRQ_TIMER
:
if
(
mycpu
()
->
id
==
0
){
if
(
mycpu
()
->
id
==
0
)
acquire
(
&
tickslock
);
cv_tick
();
ticks
++
;
cv_wakeup
(
&
cv_ticks
);
release
(
&
tickslock
);
}
lapiceoi
();
lapiceoi
();
break
;
break
;
case
T_IRQ0
+
IRQ_IDE
:
case
T_IRQ0
+
IRQ_IDE
:
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论