Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
34b8eecf
提交
34b8eecf
2月 06, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
The start of a simple lockstat implementation
上级
52e99f8a
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
270 行增加
和
7 行删除
+270
-7
Makefile
Makefile
+2
-1
file.h
file.h
+1
-0
init.c
init.c
+5
-2
kernel.h
kernel.h
+2
-0
lockstat.c
lockstat.c
+71
-0
lockstat.h
lockstat.h
+22
-0
main.c
main.c
+2
-0
param.h
param.h
+1
-0
proc.c
proc.c
+12
-4
spinlock.c
spinlock.c
+147
-0
spinlock.h
spinlock.h
+5
-0
没有找到文件。
Makefile
浏览文件 @
34b8eecf
...
...
@@ -91,7 +91,8 @@ UPROGS= \
_time
\
_sleep
\
_dirbench
\
_usertests
_usertests
\
_lockstat
UPROGS
:=
$
(
addprefix
$(O)
/,
$(UPROGS)
)
all
:
$(O)/kernel
...
...
file.h
浏览文件 @
34b8eecf
...
...
@@ -51,3 +51,4 @@ extern struct devsw devsw[];
#define CONSOLE 1
#define NETIF 2
#define SAMPLER 3
#define DEVLOCKSTAT 4
init.c
浏览文件 @
34b8eecf
...
...
@@ -44,10 +44,13 @@ main(void)
dup
(
0
);
// stdout
dup
(
0
);
// stderr
if
(
mknod
(
"netif"
,
2
,
1
)
<
0
)
mkdir
(
"dev"
);
if
(
mknod
(
"/dev/netif"
,
2
,
1
)
<
0
)
printf
(
2
,
"init: mknod netif failed
\n
"
);
if
(
mknod
(
"sampler"
,
3
,
1
)
<
0
)
if
(
mknod
(
"
/dev/
sampler"
,
3
,
1
)
<
0
)
printf
(
2
,
"init: mknod sampler failed
\n
"
);
if
(
mknod
(
"/dev/lockstat"
,
4
,
1
)
<
0
)
printf
(
2
,
"init: mknod lockstat failed
\n
"
);
for
(
int
i
=
0
;
i
<
NELEM
(
app_argv
);
i
++
)
startone
(
app_argv
[
i
]);
...
...
kernel.h
浏览文件 @
34b8eecf
...
...
@@ -270,6 +270,8 @@ int tryacquire(struct spinlock*);
int
holding
(
struct
spinlock
*
);
void
initlock
(
struct
spinlock
*
,
const
char
*
);
void
release
(
struct
spinlock
*
);
void
lockstat_init
(
struct
spinlock
*
lk
);
void
lockstat_stop
(
struct
spinlock
*
lk
);
// syscall.c
int
argint64
(
int
,
u64
*
);
...
...
lockstat.c
0 → 100644
浏览文件 @
34b8eecf
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"
#include "amd64.h"
#include "lockstat.h"
static
void
xwrite
(
int
fd
,
char
c
)
{
if
(
write
(
fd
,
&
c
,
1
)
!=
1
)
die
(
"lockstat: write failed"
);
}
static
void
stats
(
void
)
{
static
const
u64
sz
=
sizeof
(
struct
lockstat
);
struct
lockstat
ls
;
int
fd
;
int
r
;
fd
=
open
(
"/dev/lockstat"
,
O_RDONLY
);
if
(
fd
<
0
)
die
(
"lockstat: open failed"
);
printf
(
1
,
"## name cycles acquires
\n
"
);
while
(
1
)
{
r
=
read
(
fd
,
&
ls
,
sz
);
if
(
r
<
0
)
die
(
"lockstat: read failed"
);
if
(
r
==
0
)
break
;
if
(
r
!=
sz
)
die
(
"lockstat: unexpected read"
);
u64
cycles
=
0
,
acquires
=
0
;
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
{
cycles
+=
ls
.
cpu
[
i
].
cycles
;
acquires
+=
ls
.
cpu
[
i
].
acquires
;
}
printf
(
1
,
"%s %lu %lu
\n
"
,
ls
.
name
,
cycles
,
acquires
);
}
}
int
main
(
int
ac
,
char
*
av
[])
{
int
fd
=
open
(
"/dev/lockstat"
,
O_RDWR
);
if
(
fd
<
0
)
die
(
"lockstat: open failed"
);
xwrite
(
fd
,
'2'
);
xwrite
(
fd
,
'3'
);
int
pid
=
fork
(
0
);
if
(
pid
<
0
)
die
(
"lockstat: fork failed"
);
if
(
pid
==
0
)
{
xwrite
(
fd
,
'1'
);
exec
(
av
[
1
],
av
+
1
);
die
(
"lockstat: exec failed"
);
}
wait
();
xwrite
(
fd
,
'2'
);
stats
();
xwrite
(
fd
,
'3'
);
exit
();
}
lockstat.h
0 → 100644
浏览文件 @
34b8eecf
#include "queue.h"
struct
cpulockstat
{
u64
acquires
;
u64
cycles
;
__padout__
;
}
__mpalign__
;
struct
lockstat
{
char
name
[
16
];
struct
cpulockstat
cpu
[
NCPU
]
__mpalign__
;
};
struct
klockstat
{
u8
active
;
LIST_ENTRY
(
klockstat
)
link
;
struct
lockstat
s
;
};
#define LOCKSTAT_START 1
#define LOCKSTAT_STOP 2
#define LOCKSTAT_CLEAR 3
main.c
浏览文件 @
34b8eecf
...
...
@@ -28,6 +28,7 @@ extern void initsamp(void);
extern
void
initpci
(
void
);
extern
void
initnet
(
void
);
extern
void
initsched
(
void
);
extern
void
initlockstat
(
void
);
static
volatile
int
bstate
;
...
...
@@ -106,6 +107,7 @@ cmain(u64 mbmagic, u64 mbaddr)
initwq
();
// work queues
#endif
initsamp
();
initlockstat
();
initpci
();
initnet
();
...
...
param.h
浏览文件 @
34b8eecf
...
...
@@ -17,6 +17,7 @@
#define VICTIMAGE 1000000 // cycles a proc executes before an eligible victim
#define VERBOSE 0 // print kernel diagnostics
#define SPINLOCK_DEBUG 1 // Debug spin locks
#define LOCKSTAT 0
#if defined(HW_josmp)
#define NCPU 16 // maximum number of CPUs
#define MTRACE 0
...
...
proc.c
浏览文件 @
34b8eecf
...
...
@@ -171,6 +171,13 @@ exit(void)
panic
(
"zombie exit"
);
}
static
void
freeproc
(
struct
proc
*
p
)
{
lockstat_stop
(
&
p
->
lock
);
gc_delayed
(
p
,
kmfree
);
}
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
// state required to run in the kernel.
...
...
@@ -198,6 +205,7 @@ allocproc(void)
snprintf
(
p
->
lockname
,
sizeof
(
p
->
lockname
),
"cv:proc:%d"
,
p
->
pid
);
initlock
(
&
p
->
lock
,
p
->
lockname
+
3
);
lockstat_init
(
&
p
->
lock
);
initcondvar
(
&
p
->
cv
,
p
->
lockname
);
initwqframe
(
&
p
->
wqframe
);
...
...
@@ -208,7 +216,7 @@ allocproc(void)
if
((
p
->
kstack
=
ksalloc
(
slab_stack
))
==
0
){
if
(
ns_remove
(
nspid
,
KI
(
p
->
pid
),
p
)
==
0
)
panic
(
"allocproc: ns_remove"
);
gc_delayed
(
p
,
kmfree
);
freeproc
(
p
);
return
0
;
}
sp
=
p
->
kstack
+
KSTACKSIZE
;
...
...
@@ -560,7 +568,7 @@ fork(int flags)
np
->
state
=
UNUSED
;
if
(
ns_remove
(
nspid
,
KI
(
np
->
pid
),
np
)
==
0
)
panic
(
"fork: ns_remove"
);
gc_delayed
(
np
,
kmfree
);
freeproc
(
np
);
return
-
1
;
}
}
else
{
...
...
@@ -626,7 +634,7 @@ wait(void)
p
->
parent
=
0
;
p
->
name
[
0
]
=
0
;
p
->
killed
=
0
;
gc_delayed
(
p
,
kmfree
);
freeproc
(
p
);
return
pid
;
}
release
(
&
p
->
lock
);
...
...
@@ -665,7 +673,7 @@ threadalloc(void (*fn)(void *), void *arg)
p
->
vmap
=
vmap_alloc
();
if
(
p
->
vmap
==
NULL
)
{
gc_delayed
(
p
,
kmfree
);
freeproc
(
p
);
return
NULL
;
}
...
...
spinlock.c
浏览文件 @
34b8eecf
...
...
@@ -7,6 +7,13 @@
#include "bits.h"
#include "spinlock.h"
#include "mtrace.h"
#include "condvar.h"
#include "fs.h"
#include "file.h"
#if LOCKSTAT
static
int
lockstat_enable
;
#endif
static
inline
void
locking
(
struct
spinlock
*
lk
)
...
...
@@ -31,6 +38,12 @@ locked(struct spinlock *lk)
lk
->
cpu
=
mycpu
();
getcallerpcs
(
&
lk
,
lk
->
pcs
,
NELEM
(
lk
->
pcs
));
#endif
#if LOCKSTAT
if
(
lockstat_enable
&&
lk
->
stat
!=
NULL
)
{
lk
->
stat
->
s
.
cpu
[
cpunum
()].
acquires
++
;
}
#endif
}
static
inline
void
...
...
@@ -67,6 +80,9 @@ initlock(struct spinlock *lk, const char *name)
lk
->
name
=
name
;
lk
->
cpu
=
0
;
#endif
#if LOCKSTAT
lk
->
stat
=
NULL
;
#endif
lk
->
locked
=
0
;
}
...
...
@@ -119,3 +135,134 @@ release(struct spinlock *lk)
popcli
();
}
#if LOCKSTAT
LIST_HEAD
(
lockstat_list
,
klockstat
);
static
struct
lockstat_list
lockstat_list
=
LIST_HEAD_INITIALIZER
(
lockstat_list
);
static
struct
spinlock
lockstat_lock
=
{
.
locked
=
0
,
#if SPINLOCK_DEBUG
.
name
=
"lockstat"
,
.
cpu
=
NULL
,
#endif
};
void
lockstat_init
(
struct
spinlock
*
lk
)
{
if
(
lk
->
stat
!=
NULL
)
panic
(
"initlockstat"
);
lk
->
stat
=
kmalloc
(
sizeof
(
*
lk
->
stat
));
if
(
lk
->
stat
==
NULL
)
return
;
memset
(
lk
->
stat
,
0
,
sizeof
(
*
lk
->
stat
));
lk
->
stat
->
active
=
1
;
safestrcpy
(
lk
->
stat
->
s
.
name
,
lk
->
name
,
sizeof
(
lk
->
stat
->
s
.
name
));
acquire
(
&
lockstat_lock
);
LIST_INSERT_HEAD
(
&
lockstat_list
,
lk
->
stat
,
link
);
release
(
&
lockstat_lock
);
}
void
lockstat_stop
(
struct
spinlock
*
lk
)
{
if
(
lk
->
stat
!=
NULL
)
{
lk
->
stat
->
active
=
0
;
lk
->
stat
=
NULL
;
}
}
void
lockstat_clear
(
void
)
{
struct
klockstat
*
stat
,
*
tmp
;
acquire
(
&
lockstat_lock
);
LIST_FOREACH_SAFE
(
stat
,
&
lockstat_list
,
link
,
tmp
)
{
if
(
stat
->
active
==
0
)
{
LIST_REMOVE
(
stat
,
link
);
kmfree
(
stat
);
}
else
{
memset
(
&
stat
->
s
.
cpu
,
0
,
sizeof
(
stat
->
s
.
cpu
));
}
}
release
(
&
lockstat_lock
);
}
static
int
lockstat_read
(
struct
inode
*
ip
,
char
*
dst
,
u32
off
,
u32
n
)
{
static
const
u64
sz
=
sizeof
(
struct
lockstat
);
struct
klockstat
*
stat
;
u32
cur
;
if
(
off
%
sz
||
n
<
sz
)
return
-
1
;
cur
=
0
;
acquire
(
&
lockstat_lock
);
LIST_FOREACH
(
stat
,
&
lockstat_list
,
link
)
{
struct
lockstat
*
ls
=
&
stat
->
s
;
if
(
n
<
sizeof
(
*
ls
))
break
;
if
(
cur
>=
off
)
{
memmove
(
dst
,
ls
,
sz
);
dst
+=
sz
;
n
-=
sz
;
}
cur
+=
sz
;
}
release
(
&
lockstat_lock
);
return
cur
>=
off
?
cur
-
off
:
0
;
}
static
int
lockstat_write
(
struct
inode
*
ip
,
char
*
buf
,
u32
off
,
u32
n
)
{
int
cmd
=
buf
[
0
]
-
'0'
;
switch
(
cmd
)
{
case
LOCKSTAT_START
:
lockstat_enable
=
1
;
break
;
case
LOCKSTAT_STOP
:
lockstat_enable
=
0
;
break
;
case
LOCKSTAT_CLEAR
:
lockstat_clear
();
break
;
default:
return
-
1
;
}
return
n
;
}
void
initlockstat
(
void
)
{
devsw
[
DEVLOCKSTAT
].
write
=
lockstat_write
;
devsw
[
DEVLOCKSTAT
].
read
=
lockstat_read
;
}
#else
void
lockstat_init
(
struct
spinlock
*
lk
)
{
}
void
lockstat_stop
(
struct
spinlock
*
lk
)
{
}
void
initlockstat
(
void
)
{
}
#endif
spinlock.h
浏览文件 @
34b8eecf
#pragma once
#include "lockstat.h"
// Mutual exclusion lock.
struct
spinlock
{
...
...
@@ -11,6 +12,10 @@ struct spinlock {
uptr
pcs
[
10
];
// The call stack (an array of program counters)
// that locked the lock.
#endif
#if LOCKSTAT
struct
klockstat
*
stat
;
#endif
};
#if SPINLOCK_DEBUG
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论