Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
a9331f63
提交
a9331f63
3月 04, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
More c++ifying wq
上级
e1748848
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
145 行增加
和
97 行删除
+145
-97
kalloc.hh
include/kalloc.hh
+1
-1
percpu.hh
include/percpu.hh
+7
-7
user.h
include/user.h
+1
-0
wq.hh
include/wq.hh
+43
-6
kalloc.cc
kernel/kalloc.cc
+5
-0
proc.cc
kernel/proc.cc
+6
-0
wq.cc
lib/wq.cc
+82
-83
没有找到文件。
include/kalloc.hh
浏览文件 @
a9331f63
...
...
@@ -62,9 +62,9 @@ enum {
slab_stack
,
slab_perf
,
slab_kshared
,
slab_wq
,
slab_type_max
};
extern
struct
kmem
kmems
[
NCPU
];
extern
struct
kmem
slabmem
[
slab_type_max
][
NCPU
];
include/percpu.hh
浏览文件 @
a9331f63
#pragma once
extern
int
mycpuid
(
void
);
template
<
typename
T
>
struct
percpu
{
int
myid
()
{
return
mycpu
()
->
id
;
}
const
T
*
operator
->
()
const
{
return
cpu
(
myid
());
return
cpu
(
my
cpu
id
());
}
T
*
operator
->
()
{
return
cpu
(
myid
());
return
cpu
(
my
cpu
id
());
}
T
&
operator
*
()
{
return
*
cpu
(
myid
());
return
*
cpu
(
my
cpu
id
());
}
T
&
operator
[](
int
id
)
{
...
...
include/user.h
浏览文件 @
a9331f63
...
...
@@ -57,4 +57,5 @@ void printf(const char*, ...);
void
fprintf
(
int
,
const
char
*
,
...);
void
snprintf
(
char
*
buf
,
unsigned
int
n
,
const
char
*
fmt
,
...);
void
die
(
const
char
*
errstr
,
...)
__attribute__
((
noreturn
));
#define assert(c) if (!(c)) { fprintf(2, "%s:%d: ", __FILE__, __LINE__); die("assertion failure"); }
END_DECLS
include/wq.hh
浏览文件 @
a9331f63
#ifdef XV6_KERNEL
typedef
struct
spinlock
wqlock_t
;
#else
typedef
int
wqlock_t
;
#endif
#include "percpu.hh"
#define NSLOTS (1 << WQSHIFT)
struct
work
{
virtual
void
run
()
=
0
;
};
class
wq
{
public
:
wq
();
int
push
(
work
*
w
);
int
trywork
();
void
dump
();
static
void
*
operator
new
(
unsigned
long
);
private
:
work
*
steal
(
int
c
);
work
*
pop
(
int
c
);
struct
wqueue
{
work
*
w
[
NSLOTS
];
volatile
int
head
__mpalign__
;
volatile
int
tail
;
wqlock_t
lock
;
};
struct
stat
{
u64
push
;
u64
full
;
u64
pop
;
u64
steal
;
};
percpu
<
wqueue
>
q_
;
percpu
<
stat
>
stat_
;
};
struct
cwork
:
public
work
{
virtual
void
run
();
...
...
@@ -17,17 +58,13 @@ struct cwork : public work{
void
*
arg4
;
};
struct
run_work
{
virtual
void
run
()
=
0
;
};
void
initwq
(
void
);
struct
work
*
allocwork
(
void
);
void
freework
(
struct
work
*
w
);
int
wq_push
(
work
*
w
);
template
<
typename
IT
,
typename
BODY
>
struct
for_work
:
public
run_
work
{
struct
for_work
:
public
work
{
for_work
(
IT
&
it
,
BODY
body
)
:
it_
(
it
),
body_
(
body
)
{}
virtual
void
run
()
{
printf
(
"hi %s
\n
"
,
*
it_
);
}
...
...
@@ -38,7 +75,7 @@ struct for_work : public run_work {
};
static
inline
void
wq_push_cpp
(
struct
run_
work
*
w
)
wq_push_cpp
(
work
*
w
)
{
w
->
run
();
}
...
...
kernel/kalloc.cc
浏览文件 @
a9331f63
...
...
@@ -11,6 +11,7 @@
#include "mtrace.h"
#include "cpu.hh"
#include "multiboot.hh"
#include "wq.hh"
static
struct
Mbmem
mem
[
128
];
static
u64
nmem
;
...
...
@@ -273,6 +274,10 @@ initkalloc(u64 mbaddr)
slabmem
[
slab_kshared
][
c
].
size
=
KSHAREDSIZE
;
slabmem
[
slab_kshared
][
c
].
ninit
=
CPUKSTACKS
;
strncpy
(
slabmem
[
slab_wq
][
c
].
name
,
" wq"
,
MAXNAME
);
slabmem
[
slab_wq
][
c
].
size
=
PGROUNDUP
(
sizeof
(
wq
));
slabmem
[
slab_wq
][
c
].
ninit
=
NCPU
;
for
(
int
i
=
0
;
i
<
slab_type_max
;
i
++
)
{
slabmem
[
i
][
c
].
name
[
0
]
=
(
char
)
c
+
'0'
;
slabinit
(
&
slabmem
[
i
][
c
],
&
p
,
&
k
);
...
...
kernel/proc.cc
浏览文件 @
a9331f63
...
...
@@ -20,6 +20,12 @@ proc_hash(const u32 &p)
return
p
;
}
int
mycpuid
(
void
)
{
return
mycpu
()
->
id
;
}
xns
<
u32
,
proc
*
,
proc_hash
>
*
xnspid
__mpalign__
;
static
struct
proc
*
bootproc
__mpalign__
;
...
...
kernel
/wq.cc
→
lib
/wq.cc
浏览文件 @
a9331f63
...
...
@@ -4,119 +4,134 @@
#include "amd64.h"
#include "cpu.hh"
#include "wq.hh"
#include "kalloc.hh"
#define NSLOTS (1 << WQSHIFT)
static
wq
*
wq_
;
struct
wqueue
{
work
*
w
[
NSLOTS
];
int
wq_push
(
work
*
w
)
{
return
wq_
->
push
(
w
);
}
volatile
int
head
__mpalign__
;
volatile
int
tail
;
struct
spinlock
lock
;
__padout__
;
}
__mpalign__
;;
int
wq_trywork
(
void
)
{
return
wq_
->
trywork
()
;
}
struct
wqstat
{
u64
push
;
u64
full
;
u64
pop
;
u64
steal
;
__padout__
;
}
__mpalign__
;
void
wq_dump
(
void
)
{
return
wq_
->
dump
();
}
struct
wqueue
queue
[
NCPU
]
__mpalign__
;
struct
wqstat
stat
[
NCPU
]
__mpalign__
;
void
initwq
(
void
)
{
wq_
=
new
wq
();
}
static
inline
struct
wqueue
*
getwq
(
void
)
//
// wq
//
void
*
wq
::
operator
new
(
unsigned
long
nbytes
)
{
pushcli
(
);
return
&
queue
[
mycpu
()
->
id
]
;
assert
(
nbytes
==
sizeof
(
wq
)
);
return
ksalloc
(
slab_wq
)
;
}
static
inline
void
putwq
(
struct
wqueue
*
wq
)
wq
::
wq
(
void
)
{
popcli
();
int
i
;
for
(
i
=
0
;
i
<
NCPU
;
i
++
)
initlock
(
&
q_
[
i
].
lock
,
"wq lock"
,
LOCKSTAT_WQ
);
}
static
inline
struct
wqstat
*
wq
_stat
(
void
)
void
wq
::
dump
(
void
)
{
return
&
stat
[
mycpu
()
->
id
];
int
i
;
for
(
i
=
0
;
i
<
NCPU
;
i
++
)
cprintf
(
"push %lu full %lu pop %lu steal %lu
\n
"
,
stat_
[
i
].
push
,
stat_
[
i
].
full
,
stat_
[
i
].
pop
,
stat_
[
i
].
steal
);
}
int
wq
_
push
(
work
*
w
)
wq
::
push
(
work
*
w
)
{
int
i
;
struct
wqueue
*
wq
=
getwq
();
i
=
wq
->
head
;
if
((
i
-
wq
->
tail
)
==
NSLOTS
)
{
wq_stat
()
->
full
++
;
pushcli
();
i
=
q_
->
head
;
if
((
i
-
q_
->
tail
)
==
NSLOTS
)
{
stat_
->
full
++
;
popcli
();
return
-
1
;
}
i
=
i
&
(
NSLOTS
-
1
);
wq
->
w
[
i
]
=
w
;
q_
->
w
[
i
]
=
w
;
barrier
();
wq
->
head
++
;
wq_stat
()
->
push
++
;
p
utwq
(
wq
);
q_
->
head
++
;
stat_
->
push
++
;
p
opcli
(
);
return
0
;
}
static
inline
work
*
__wq_
pop
(
int
c
)
inline
work
*
wq
::
pop
(
int
c
)
{
struct
wqueue
*
wq
=
&
queue
[
c
];
struct
wqueue
*
q
=
&
q_
[
c
];
work
*
w
;
int
i
;
i
=
w
q
->
head
;
if
((
i
-
w
q
->
tail
)
==
0
)
i
=
q
->
head
;
if
((
i
-
q
->
tail
)
==
0
)
return
0
;
acquire
(
&
w
q
->
lock
);
i
=
w
q
->
head
;
if
((
i
-
w
q
->
tail
)
==
0
)
{
release
(
&
w
q
->
lock
);
acquire
(
&
q
->
lock
);
i
=
q
->
head
;
if
((
i
-
q
->
tail
)
==
0
)
{
release
(
&
q
->
lock
);
return
0
;
}
i
=
(
i
-
1
)
&
(
NSLOTS
-
1
);
w
=
w
q
->
w
[
i
];
w
q
->
head
--
;
release
(
&
w
q
->
lock
);
w
=
q
->
w
[
i
];
q
->
head
--
;
release
(
&
q
->
lock
);
wq_stat
()
->
pop
++
;
stat_
->
pop
++
;
return
w
;
}
static
inline
work
*
__wq_
steal
(
int
c
)
inline
work
*
wq
::
steal
(
int
c
)
{
struct
wqueue
*
wq
=
&
queue
[
c
];
struct
wqueue
*
q
=
&
q_
[
c
];
work
*
w
;
int
i
;
if
(
tryacquire
(
&
w
q
->
lock
)
==
0
)
if
(
tryacquire
(
&
q
->
lock
)
==
0
)
return
0
;
i
=
w
q
->
tail
;
if
((
i
-
w
q
->
head
)
==
0
)
{
release
(
&
w
q
->
lock
);
i
=
q
->
tail
;
if
((
i
-
q
->
head
)
==
0
)
{
release
(
&
q
->
lock
);
return
0
;
}
i
=
i
&
(
NSLOTS
-
1
);
w
=
w
q
->
w
[
i
];
w
q
->
tail
++
;
release
(
&
w
q
->
lock
);
w
=
q
->
w
[
i
];
q
->
tail
++
;
release
(
&
q
->
lock
);
wq_stat
()
->
steal
++
;
stat_
->
steal
++
;
return
w
;
}
int
wq
_
trywork
(
void
)
wq
::
trywork
(
void
)
{
work
*
w
;
u64
i
,
k
;
...
...
@@ -124,7 +139,7 @@ wq_trywork(void)
// A "random" victim CPU
k
=
rdtsc
();
w
=
__wq_pop
(
mycpu
()
->
id
);
w
=
pop
(
mycpuid
()
);
if
(
w
!=
nullptr
)
{
w
->
run
();
return
1
;
...
...
@@ -133,10 +148,10 @@ wq_trywork(void)
for
(
i
=
0
;
i
<
NCPU
;
i
++
)
{
u64
j
=
(
i
+
k
)
%
NCPU
;
if
(
j
==
mycpu
()
->
id
)
if
(
j
==
mycpu
id
()
)
continue
;
w
=
__wq_
steal
(
j
);
w
=
steal
(
j
);
if
(
w
!=
nullptr
)
{
w
->
run
();
return
1
;
...
...
@@ -146,24 +161,9 @@ wq_trywork(void)
return
0
;
}
void
wq_dump
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NCPU
;
i
++
)
cprintf
(
"push %lu full %lu pop %lu steal %lu
\n
"
,
stat
[
i
].
push
,
stat
[
i
].
full
,
stat
[
i
].
pop
,
stat
[
i
].
steal
);
}
void
initwq
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NCPU
;
i
++
)
initlock
(
&
queue
[
i
].
lock
,
"wq lock"
,
LOCKSTAT_WQ
);
}
//
// cwork
//
void
cwork
::
run
(
void
)
{
...
...
@@ -192,4 +192,3 @@ cwork::operator delete(void *p)
{
kmfree
(
p
,
sizeof
(
cwork
));
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论