Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
25fa822b
提交
25fa822b
4月 07, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A sys_futex implementation
上级
d13a7df9
隐藏空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
249 行增加
和
2 行删除
+249
-2
Makefrag
bin/Makefrag
+2
-1
futexbench.cc
bin/futexbench.cc
+50
-0
errno.h
include/errno.h
+2
-0
futex.h
include/futex.h
+2
-0
kern_c.h
include/kern_c.h
+1
-0
kernel.hh
include/kernel.hh
+6
-0
lockstat.h
include/lockstat.h
+1
-0
proc.hh
include/proc.hh
+1
-0
syscall.h
include/syscall.h
+2
-1
user.h
include/user.h
+1
-0
Makefrag
kernel/Makefrag
+1
-0
bootdata.c
kernel/bootdata.c
+1
-0
futex.cc
kernel/futex.cc
+157
-0
main.cc
kernel/main.cc
+2
-0
sysproc.cc
kernel/sysproc.cc
+19
-0
usys.S
lib/usys.S
+1
-0
没有找到文件。
bin/Makefrag
浏览文件 @
25fa822b
...
...
@@ -36,7 +36,8 @@ UPROGS= \
xdu \
wqtest \
rm \
avar
avar \
futexbench
ifeq ($(HAVE_LWIP),y)
UPROGS += \
...
...
bin/futexbench.cc
0 → 100644
浏览文件 @
25fa822b
#include "types.h"
#include "user.h"
#include "amd64.h"
#include "pthread.h"
#include "futex.h"
#include "errno.h"
static
volatile
u64
ftx
;
static
int
iters
;
static
void
*
worker
(
void
*
arg
)
{
long
r
;
for
(
int
i
=
0
;
i
<
iters
;
i
++
)
{
r
=
futex
((
u64
*
)
&
ftx
,
FUTEX_WAIT
,
0
,
0
);
if
(
r
<
0
&&
r
!=
-
EWOULDBLOCK
)
die
(
"FUTEX_WAIT: %d"
,
r
);
ftx
=
0
;
r
=
futex
((
u64
*
)
&
ftx
,
FUTEX_WAKE
,
1
,
0
);
}
return
nullptr
;
}
int
main
(
int
ac
,
char
**
av
)
{
pthread_t
th
;
long
r
;
if
(
ac
<
2
)
die
(
"usage: %s iters"
,
av
[
0
]);
iters
=
atoi
(
av
[
1
]);
pthread_create
(
&
th
,
0
,
&
worker
,
0
);
for
(
int
i
=
0
;
i
<
iters
;
i
++
)
{
ftx
=
1
;
r
=
futex
((
u64
*
)
&
ftx
,
FUTEX_WAKE
,
1
,
0
);
assert
(
r
==
0
);
r
=
futex
((
u64
*
)
&
ftx
,
FUTEX_WAIT
,
1
,
0
);
if
(
r
<
0
&&
r
!=
-
EWOULDBLOCK
)
die
(
"FUTEX_WAIT: %d"
,
r
);
}
wait
();
printf
(
"done
\n
"
);
return
0
;
}
include/errno.h
0 → 100644
浏览文件 @
25fa822b
#define EAGAIN 11
/* Try again */
#define EWOULDBLOCK EAGAIN
/* Operation would block */
include/futex.h
0 → 100644
浏览文件 @
25fa822b
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
include/kern_c.h
浏览文件 @
25fa822b
...
...
@@ -53,6 +53,7 @@ long sys_script(void *addr, u64 len, u64 chunk);
long
sys_setfs
(
u64
base
);
long
sys_wqwait
(
void
);
long
sys_setaffinity
(
int
cpu
);
long
sys_futex
(
const
u64
*
addr
,
int
op
,
u64
val
,
u64
timer
);
extern
long
(
*
syscalls
[])(
u64
,
u64
,
u64
,
u64
,
u64
);
// other exported/imported functions
...
...
include/kernel.hh
浏览文件 @
25fa822b
...
...
@@ -102,6 +102,12 @@ int dirlink(struct inode*, const char*, u32);
void
dir_init
(
struct
inode
*
dp
);
void
dir_flush
(
struct
inode
*
dp
);
// futex.cc
typedef
u64
*
futexkey_t
;
int
futexkey
(
const
u64
*
useraddr
,
vmap
*
vmap
,
futexkey_t
*
key
);
long
futexwait
(
futexkey_t
key
,
u64
val
,
u64
timer
);
long
futexwake
(
futexkey_t
key
,
u64
nwake
);
// hz.c
void
microdelay
(
u64
);
void
inithz
(
void
);
...
...
include/lockstat.h
浏览文件 @
25fa822b
...
...
@@ -47,6 +47,7 @@ struct klockstat;
#define LOCKSTAT_CONSOLE 1
#define LOCKSTAT_CRANGE 1
#define LOCKSTAT_FS 1
#define LOCKSTAT_FUTEX 1
#define LOCKSTAT_GC 1
#define LOCKSTAT_IDLE 1
#define LOCKSTAT_KALLOC 1
...
...
include/proc.hh
浏览文件 @
25fa822b
...
...
@@ -77,6 +77,7 @@ struct proc : public rcu_freed, public sched_link {
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
LIST_ENTRY
(
proc
)
futex_link
;
u64
user_fs_
;
u64
unmap_tlbreq_
;
int
exec_cpuid_
;
...
...
include/syscall.h
浏览文件 @
25fa822b
...
...
@@ -33,4 +33,5 @@
#define SYS_setfs 32
#define SYS_wqwait 33
#define SYS_setaffinity 34
#define SYS_ncount 35
/* total number of system calls */
#define SYS_futex 35
#define SYS_ncount 36
/* total number of system calls */
include/user.h
浏览文件 @
25fa822b
...
...
@@ -35,6 +35,7 @@ int async(int, size_t, off_t, u32, u32);
int
script
(
void
*
addr
,
u64
len
,
u64
chunk
);
int
setfs
(
u64
base
);
int
setaffinity
(
int
cpu
);
long
futex
(
const
u64
*
addr
,
int
op
,
u64
val
,
u64
timer
);
// ulib.c
int
stat
(
char
*
,
struct
stat
*
);
...
...
kernel/Makefrag
浏览文件 @
25fa822b
...
...
@@ -12,6 +12,7 @@ OBJS = \
file.o \
fmt.o \
fs.o \
futex.o \
idle.o \
ioapic.o \
lapic.o \
...
...
kernel/bootdata.c
浏览文件 @
25fa822b
...
...
@@ -63,4 +63,5 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL
(
setfs
),
SYSCALL
(
wqwait
),
SYSCALL
(
setaffinity
),
SYSCALL
(
futex
),
};
kernel/futex.cc
0 → 100644
浏览文件 @
25fa822b
#include "types.h"
#include "kernel.hh"
#include "spinlock.h"
#include "cpputil.hh"
#include "ns.hh"
#include "errno.h"
#include "condvar.h"
#include "proc.hh"
#include "cpu.hh"
//
// futexkey
//
// XXX(sbw) this uses kernel addresses as keys and probably
// isn't complete. For example, a user thread might wait
// on a user address, then another thread might unmap that
// address.
typedef
u64
*
futexkey_t
;
u64
futexkey_hash
(
futexkey_t
const
&
key
)
{
return
(
u64
)
key
;
}
u64
futexkey_val
(
futexkey_t
const
&
key
)
{
return
*
key
;
}
int
futexkey
(
const
u64
*
useraddr
,
vmap
*
vmap
,
futexkey_t
*
key
)
{
u64
*
kaddr
;
kaddr
=
(
u64
*
)
pagelookup
(
vmap
,
(
uptr
)
useraddr
);
if
(
kaddr
==
nullptr
)
{
cprintf
(
"futexkey: pagelookup failed
\n
"
);
return
-
1
;
}
*
key
=
kaddr
;
return
0
;
}
//
// futexaddr
//
struct
futexaddr
:
public
referenced
,
public
rcu_freed
{
futexaddr
(
u64
*
kaddr
);
virtual
void
do_gc
();
virtual
void
onzero
()
const
;
futexkey_t
key_
;
bool
inserted_
;
struct
spinlock
lock_
;
LIST_HEAD
(
proclist
,
proc
)
list_
;
NEW_DELETE_OPS
(
futexaddr
);
};
xns
<
futexkey_t
,
futexaddr
*
,
futexkey_hash
>
*
nsfutex
__mpalign__
;
futexaddr
::
futexaddr
(
futexkey_t
key
)
:
rcu_freed
(
"futexaddr"
),
key_
(
key
),
inserted_
(
false
)
{
initlock
(
&
lock_
,
"futexaddr::lock_"
,
LOCKSTAT_FUTEX
);
LIST_INIT
(
&
list_
);
}
void
futexaddr
::
do_gc
(
void
)
{
delete
this
;
}
void
futexaddr
::
onzero
(
void
)
const
{
if
(
inserted_
)
assert
(
nsfutex
->
remove
(
key_
,
nullptr
));
gc_delayed
((
futexaddr
*
)
this
);
}
long
futexwait
(
futexkey_t
key
,
u64
val
,
u64
timer
)
{
futexaddr
*
fa
;
{
scoped_gc_epoch
gc
;
again
:
fa
=
nsfutex
->
lookup
(
key
);
if
(
fa
==
nullptr
)
{
fa
=
new
futexaddr
(
key
);
if
(
nsfutex
->
insert
(
key
,
fa
)
<
0
)
{
fa
->
dec
();
goto
again
;
}
fa
->
inserted_
=
true
;
}
else
{
if
(
!
fa
->
tryinc
())
{
goto
again
;
}
}
}
assert
(
fa
->
key_
==
key
);
acquire
(
&
fa
->
lock_
);
auto
cleanup
=
scoped_cleanup
([
&
fa
](){
release
(
&
fa
->
lock_
);
fa
->
dec
();
});
if
(
futexkey_val
(
fa
->
key_
)
!=
val
)
return
-
EWOULDBLOCK
;
LIST_INSERT_HEAD
(
&
fa
->
list_
,
myproc
(),
futex_link
);
u64
nsecto
=
timer
==
0
?
0
:
timer
+
nsectime
();
cv_sleepto
(
&
myproc
()
->
cv
,
&
fa
->
lock_
,
nsecto
);
LIST_REMOVE
(
myproc
(),
futex_link
);
return
0
;
}
long
futexwake
(
u64
*
kaddr
,
u64
nwake
)
{
futexaddr
*
fa
;
u64
nwoke
=
0
;
proc
*
p
;
scoped_gc_epoch
gc
;
fa
=
nsfutex
->
lookup
(
kaddr
);
if
(
fa
==
nullptr
)
return
0
;
acquire
(
&
fa
->
lock_
);
LIST_FOREACH
(
p
,
&
fa
->
list_
,
futex_link
)
{
if
(
nwoke
>=
nwake
)
break
;
cv_wakeup
(
&
p
->
cv
);
nwoke
++
;
}
release
(
&
fa
->
lock_
);
return
0
;
}
void
initfutex
(
void
)
{
nsfutex
=
new
xns
<
futexkey_t
,
futexaddr
*
,
futexkey_hash
>
(
false
);
if
(
nsfutex
==
0
)
panic
(
"initfutex"
);
}
kernel/main.cc
浏览文件 @
25fa822b
...
...
@@ -38,6 +38,7 @@ void initwq(void);
void
initsperf
(
void
);
void
initidle
(
void
);
void
initcpprt
(
void
);
void
initfutex
(
void
);
void
idleloop
(
void
);
static
volatile
int
bstate
;
...
...
@@ -119,6 +120,7 @@ cmain(u64 mbmagic, u64 mbaddr)
initdisk
();
// disk
initconsole
();
initwq
();
initfutex
();
initsamp
();
initlockstat
();
initpci
();
...
...
kernel/sysproc.cc
浏览文件 @
25fa822b
...
...
@@ -10,6 +10,7 @@
#include "vm.hh"
#include "sperf.hh"
#include "kmtrace.hh"
#include "futex.h"
long
sys_fork
(
int
flags
)
...
...
@@ -158,3 +159,21 @@ sys_setaffinity(int cpu)
{
return
myproc
()
->
set_cpu_pin
(
cpu
);
}
long
sys_futex
(
const
u64
*
addr
,
int
op
,
u64
val
,
u64
timer
)
{
futexkey_t
key
;
if
(
futexkey
(
addr
,
myproc
()
->
vmap
,
&
key
)
<
0
)
return
-
1
;
switch
(
op
)
{
case
FUTEX_WAIT
:
return
futexwait
(
key
,
val
,
timer
);
case
FUTEX_WAKE
:
return
futexwake
(
key
,
val
);
default:
return
-
1
;
}
}
lib/usys.S
浏览文件 @
25fa822b
...
...
@@ -50,3 +50,4 @@ SYSCALL(script)
SYSCALL(setfs)
SYSCALL(wqwait)
SYSCALL(setaffinity)
SYSCALL(futex)
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论