Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
a2c48700
提交
a2c48700
11月 13, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Try to parallelize exec.c with the work queue.
上级
3bc0f1e2
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
208 行增加
和
7 行删除
+208
-7
exec.c
exec.c
+178
-1
kernel.h
kernel.h
+13
-0
main.c
main.c
+2
-0
param.h
param.h
+1
-0
proc.c
proc.c
+8
-3
wq.c
wq.c
+6
-3
没有找到文件。
exec.c
浏览文件 @
a2c48700
...
@@ -15,6 +15,59 @@
...
@@ -15,6 +15,59 @@
#include "vm.h"
#include "vm.h"
#define USTACKPAGES 2
#define USTACKPAGES 2
#define BRK (USERTOP >> 1)
static
const
int
odp
=
1
;
struct
eargs
{
struct
inode
*
ip
;
struct
vmap
*
vmap
;
};
static
void
dosegment
(
uptr
a0
,
u64
a1
)
{
struct
eargs
*
args
=
(
void
*
)
a0
;
u64
off
=
a1
;
struct
vmnode
*
vmn
=
NULL
;
struct
proghdr
ph
;
if
(
readi
(
args
->
ip
,
(
char
*
)
&
ph
,
off
,
sizeof
(
ph
))
!=
sizeof
(
ph
))
goto
bad
;
if
(
ph
.
type
!=
ELF_PROG_LOAD
)
{
return
;
}
if
(
ph
.
memsz
<
ph
.
filesz
)
goto
bad
;
// XXX(sbw) vaddr doesn't have to be page aligned..
if
(
ph
.
vaddr
%
PGSIZE
)
{
cprintf
(
"unaligned ph.va
\n
"
);
goto
bad
;
}
uptr
va_start
=
PGROUNDDOWN
(
ph
.
vaddr
);
uptr
va_end
=
PGROUNDUP
(
ph
.
vaddr
+
ph
.
memsz
);
int
npg
=
(
va_end
-
va_start
)
/
PGSIZE
;
if
(
odp
)
{
if
((
vmn
=
vmn_alloc
(
npg
,
ONDEMAND
))
==
0
)
goto
bad
;
}
else
{
if
((
vmn
=
vmn_allocpg
(
npg
))
==
0
)
goto
bad
;
}
if
(
vmn_load
(
vmn
,
args
->
ip
,
ph
.
offset
,
ph
.
filesz
)
<
0
)
goto
bad
;
if
(
vmap_insert
(
args
->
vmap
,
vmn
,
ph
.
vaddr
)
<
0
)
goto
bad
;
return
;
bad:
panic
(
"dosegment: Oops"
);
}
int
int
exec
(
char
*
path
,
char
**
argv
)
exec
(
char
*
path
,
char
**
argv
)
...
@@ -25,7 +78,127 @@ exec(char *path, char **argv)
...
@@ -25,7 +78,127 @@ exec(char *path, char **argv)
struct
elfhdr
elf
;
struct
elfhdr
elf
;
struct
proghdr
ph
;
struct
proghdr
ph
;
uptr
brk
=
0
;
uptr
brk
=
0
;
int
odp
=
1
;
u64
off
;
int
i
;
uptr
sp
;
int
argc
;
uptr
ustack
[
1
+
MAXARG
+
1
];
char
*
s
,
*
last
;
struct
vmap
*
oldvmap
;
if
((
ip
=
namei
(
path
))
==
0
)
return
-
1
;
rcu_begin_read
();
// Check ELF header
if
(
ip
->
type
!=
T_FILE
)
goto
bad
;
if
(
readi
(
ip
,
(
char
*
)
&
elf
,
0
,
sizeof
(
elf
))
<
sizeof
(
elf
))
goto
bad
;
if
(
elf
.
magic
!=
ELF_MAGIC
)
goto
bad
;
if
((
vmap
=
vmap_alloc
())
==
0
)
goto
bad
;
struct
eargs
args
;
args
.
ip
=
ip
;
args
.
vmap
=
vmap
;
wq_start
();
for
(
i
=
0
,
off
=
elf
.
phoff
;
i
<
elf
.
phnum
;
i
++
,
off
+=
sizeof
(
ph
)){
wq_push
(
dosegment
,
(
uptr
)
&
args
,
(
uptr
)
off
);
}
if
(
odp
)
{
// iunlock(ip);
}
else
{
// iunlockput(ip);
iput
(
ip
);
ip
=
0
;
}
brk
=
BRK
;
// Allocate a vmnode for the heap.
// XXX pre-allocate 32 pages..
if
((
vmn
=
vmn_allocpg
(
32
))
==
0
)
goto
bad
;
if
(
vmap_insert
(
vmap
,
vmn
,
brk
)
<
0
)
goto
bad
;
vmn
=
0
;
// Allocate a one-page stack at the top of the (user) address space
if
((
vmn
=
vmn_allocpg
(
USTACKPAGES
))
==
0
)
goto
bad
;
if
(
vmap_insert
(
vmap
,
vmn
,
USERTOP
-
(
USTACKPAGES
*
PGSIZE
))
<
0
)
goto
bad
;
vmn
=
0
;
wq_end
();
// Push argument strings, prepare rest of stack in ustack.
sp
=
USERTOP
;
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
{
if
(
argc
>=
MAXARG
)
goto
bad
;
sp
-=
strlen
(
argv
[
argc
])
+
1
;
sp
&=
~
7
;
if
(
copyout
(
vmap
,
sp
,
argv
[
argc
],
strlen
(
argv
[
argc
])
+
1
)
<
0
)
goto
bad
;
ustack
[
1
+
argc
]
=
sp
;
}
ustack
[
1
+
argc
]
=
0
;
ustack
[
0
]
=
0xffffffffffffffffull
;
// fake return PC
myproc
()
->
tf
->
rdi
=
argc
;
myproc
()
->
tf
->
rsi
=
sp
-
(
argc
+
1
)
*
8
;
sp
-=
(
1
+
argc
+
1
)
*
8
;
if
(
copyout
(
vmap
,
sp
,
ustack
,
(
1
+
argc
+
1
)
*
8
)
<
0
)
goto
bad
;
// Save program name for debugging.
for
(
last
=
s
=
path
;
*
s
;
s
++
)
if
(
*
s
==
'/'
)
last
=
s
+
1
;
safestrcpy
(
myproc
()
->
name
,
last
,
sizeof
(
myproc
()
->
name
));
// Commit to the user image.
oldvmap
=
myproc
()
->
vmap
;
myproc
()
->
vmap
=
vmap
;
myproc
()
->
brk
=
brk
+
8
;
// XXX so that brk-1 points within heap vma..
myproc
()
->
tf
->
rip
=
elf
.
entry
;
// main
myproc
()
->
tf
->
rsp
=
sp
;
switchuvm
(
myproc
());
vmap_decref
(
oldvmap
);
migrate
(
myproc
());
rcu_end_read
();
return
0
;
bad:
cprintf
(
"exec failed
\n
"
);
if
(
vmap
)
vmap_decref
(
vmap
);
if
(
vmn
)
vmn_free
(
vmn
);
rcu_end_read
();
return
0
;
}
#if 0
int
exec(char *path, char **argv)
{
struct inode *ip = NULL;
struct vmap *vmap = NULL;
struct vmnode *vmn = NULL;
struct elfhdr elf;
struct proghdr ph;
uptr brk = 0;
u64 off;
u64 off;
int i;
int i;
uptr sp;
uptr sp;
...
@@ -84,6 +257,7 @@ exec(char *path, char **argv)
...
@@ -84,6 +257,7 @@ exec(char *path, char **argv)
goto bad;
goto bad;
vmn = 0;
vmn = 0;
}
}
if (odp) {
if (odp) {
// iunlock(ip);
// iunlock(ip);
} else {
} else {
...
@@ -92,6 +266,8 @@ exec(char *path, char **argv)
...
@@ -92,6 +266,8 @@ exec(char *path, char **argv)
ip = 0;
ip = 0;
}
}
brk = BRK;
// Allocate a vmnode for the heap.
// Allocate a vmnode for the heap.
// XXX pre-allocate 32 pages..
// XXX pre-allocate 32 pages..
if((vmn = vmn_allocpg(32)) == 0)
if((vmn = vmn_allocpg(32)) == 0)
...
@@ -159,3 +335,4 @@ exec(char *path, char **argv)
...
@@ -159,3 +335,4 @@ exec(char *path, char **argv)
return 0;
return 0;
}
}
#endif
kernel.h
浏览文件 @
a2c48700
...
@@ -274,8 +274,21 @@ void updatepages(pml4e_t*, void*, void*, int);
...
@@ -274,8 +274,21 @@ void updatepages(pml4e_t*, void*, void*, int);
struct
vmap
*
vmap_copy
(
struct
vmap
*
,
int
);
struct
vmap
*
vmap_copy
(
struct
vmap
*
,
int
);
// wq.c
// wq.c
#if WQENABLE
void
wq_push
(
void
*
rip
,
u64
arg0
,
u64
arg1
);
void
wq_push
(
void
*
rip
,
u64
arg0
,
u64
arg1
);
void
wq_start
(
void
);
void
wq_start
(
void
);
void
wq_end
(
void
);
void
wq_end
(
void
);
void
wq_dump
(
void
);
void
wq_dump
(
void
);
int
wq_trywork
(
void
);
void
initwqframe
(
struct
wqframe
*
wq
);
void
initwqframe
(
struct
wqframe
*
wq
);
#else
#define wq_push(rip, arg0, arg1) do { \
void (*fn)(uptr, uptr) = rip; \
fn(arg0, arg1); \
} while(0)
#define wq_start() do { } while(0)
#define wq_end() do { } while(0)
#define wq_dump() do { } while(0)
#define wq_trywork() 0
#define initwqframe(x) do { } while (0)
#endif
main.c
浏览文件 @
a2c48700
...
@@ -96,7 +96,9 @@ cmain(void)
...
@@ -96,7 +96,9 @@ cmain(void)
initbio
();
// buffer cache
initbio
();
// buffer cache
initinode
();
// inode cache
initinode
();
// inode cache
initdisk
();
// disk
initdisk
();
// disk
#if WQENABLE
initwq
();
// work queues
initwq
();
// work queues
#endif
cprintf
(
"ncpu %d %lu MHz
\n
"
,
ncpu
,
cpuhz
/
1000000
);
cprintf
(
"ncpu %d %lu MHz
\n
"
,
ncpu
,
cpuhz
/
1000000
);
...
...
param.h
浏览文件 @
a2c48700
...
@@ -18,3 +18,4 @@
...
@@ -18,3 +18,4 @@
#define CPUKSTACKS (NPROC + NCPU)
#define CPUKSTACKS (NPROC + NCPU)
#define QUANTUN 10 // scheduling time quantum and tick length (in msec)
#define QUANTUN 10 // scheduling time quantum and tick length (in msec)
#define WQSHIFT 4 // 2^WORKSHIFT work queue slots
#define WQSHIFT 4 // 2^WORKSHIFT work queue slots
#define WQENABLE 0 // Enable work queue
proc.c
浏览文件 @
a2c48700
...
@@ -316,8 +316,8 @@ scheduler(void)
...
@@ -316,8 +316,8 @@ scheduler(void)
myproc
()
->
cpu_pin
=
1
;
myproc
()
->
cpu_pin
=
1
;
// Test the work queue
// Test the work queue
extern
void
testwq
(
void
);
//
extern void testwq(void);
testwq
();
//
testwq();
// Enabling mtrace calls in scheduler generates many mtrace_call_entrys.
// Enabling mtrace calls in scheduler generates many mtrace_call_entrys.
// mtrace_call_set(1, cpu->id);
// mtrace_call_set(1, cpu->id);
...
@@ -381,8 +381,13 @@ scheduler(void)
...
@@ -381,8 +381,13 @@ scheduler(void)
}
}
if
(
idle
[
mycpu
()
->
id
])
{
if
(
idle
[
mycpu
()
->
id
])
{
int
worked
;
do
{
worked
=
wq_trywork
();
}
while
(
worked
);
sti
();
sti
();
hlt
();
if
(
!
WQENABLE
)
hlt
();
}
}
}
}
}
}
...
...
wq.c
浏览文件 @
a2c48700
#if WQENABLE
#include "types.h"
#include "types.h"
#include "kernel.h"
#include "kernel.h"
#include "param.h"
#include "amd64.h"
#include "amd64.h"
#include "cpu.h"
#include "cpu.h"
#include "bits.h"
#include "bits.h"
...
@@ -119,6 +119,7 @@ __wq_run(struct wqthread *th)
...
@@ -119,6 +119,7 @@ __wq_run(struct wqthread *th)
void
(
*
fn
)(
uptr
arg0
,
uptr
arg1
)
=
(
void
*
)
th
->
rip
;
void
(
*
fn
)(
uptr
arg0
,
uptr
arg1
)
=
(
void
*
)
th
->
rip
;
fn
(
th
->
arg0
,
th
->
arg1
);
fn
(
th
->
arg0
,
th
->
arg1
);
subfetch
(
th
->
ref
,
1
);
subfetch
(
th
->
ref
,
1
);
kfree
(
th
);
}
}
// Add the (rip, arg0, arg1) work to the local work queue.
// Add the (rip, arg0, arg1) work to the local work queue.
...
@@ -140,9 +141,10 @@ wq_push(void *rip, u64 arg0, u64 arg1)
...
@@ -140,9 +141,10 @@ wq_push(void *rip, u64 arg0, u64 arg1)
th
->
arg1
=
arg1
;
th
->
arg1
=
arg1
;
th
->
ref
=
&
wq_frame
()
->
ref
;
th
->
ref
=
&
wq_frame
()
->
ref
;
if
(
__wq_push
(
wq_cur
(),
th
))
if
(
__wq_push
(
wq_cur
(),
th
))
{
kfree
(
th
);
fn
(
arg0
,
arg1
);
fn
(
arg0
,
arg1
);
else
}
else
fetchadd
(
&
wq_frame
()
->
ref
,
1
);
fetchadd
(
&
wq_frame
()
->
ref
,
1
);
}
}
...
@@ -265,3 +267,4 @@ initwq(void)
...
@@ -265,3 +267,4 @@ initwq(void)
initlock
(
&
queue
[
i
].
lock
,
"queue lock"
);
initlock
(
&
queue
[
i
].
lock
,
"queue lock"
);
}
}
}
}
#endif // WQENABLE
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论