Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
7b2ffeaf
提交
7b2ffeaf
3月 19, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Some rough kernel code to start WQ workers on demand.
Missing code to cleanup worker state.
上级
f91ddbe4
隐藏空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
222 行增加
和
89 行删除
+222
-89
wqtest.cc
bin/wqtest.cc
+0
-1
hwvm.hh
include/hwvm.hh
+1
-1
kern_c.h
include/kern_c.h
+1
-0
memlayout.h
include/memlayout.h
+1
-0
proc.hh
include/proc.hh
+3
-0
syscall.h
include/syscall.h
+2
-1
uwq.hh
include/uwq.hh
+18
-5
vm.hh
include/vm.hh
+1
-2
wquser.hh
include/wquser.hh
+17
-30
bootdata.c
kernel/bootdata.c
+1
-1
exec.cc
kernel/exec.cc
+14
-6
hwvm.cc
kernel/hwvm.cc
+12
-0
idle.cc
kernel/idle.cc
+4
-0
proc.cc
kernel/proc.cc
+3
-1
trap.cc
kernel/trap.cc
+1
-0
uwq.cc
kernel/uwq.cc
+135
-22
vm.cc
kernel/vm.cc
+6
-19
usys.S
lib/usys.S
+1
-0
param.h
param.h
+1
-0
没有找到文件。
bin/wqtest.cc
浏览文件 @
7b2ffeaf
...
@@ -43,7 +43,6 @@ int
...
@@ -43,7 +43,6 @@ int
main
(
int
ac
,
char
**
av
)
main
(
int
ac
,
char
**
av
)
{
{
initwq
();
initwq
();
sleep
(
5
);
test
();
test
();
exitwq
();
exitwq
();
printf
(
"all done!
\n
"
);
printf
(
"all done!
\n
"
);
...
...
include/hwvm.hh
浏览文件 @
7b2ffeaf
...
@@ -10,7 +10,7 @@ extern pgmap kpml4;
...
@@ -10,7 +10,7 @@ extern pgmap kpml4;
void
freevm
(
pgmap
*
pml4
);
void
freevm
(
pgmap
*
pml4
);
pgmap
*
setupkvm
(
void
);
pgmap
*
setupkvm
(
void
);
int
setupuvm
(
pgmap
*
pml4
,
char
*
kshared
,
char
*
uwq
);
int
mapkva
(
pgmap
*
pml4
,
char
*
kva
,
uptr
uva
,
size_t
size
);
std
::
atomic
<
pme_t
>*
walkpgdir
(
pgmap
*
pml4
,
u64
,
int
);
std
::
atomic
<
pme_t
>*
walkpgdir
(
pgmap
*
pml4
,
u64
,
int
);
void
tlbflush
(
void
);
void
tlbflush
(
void
);
...
...
include/kern_c.h
浏览文件 @
7b2ffeaf
...
@@ -51,6 +51,7 @@ long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
...
@@ -51,6 +51,7 @@ long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long
sys_async
(
int
,
size_t
,
off_t
,
u32
,
u32
);
long
sys_async
(
int
,
size_t
,
off_t
,
u32
,
u32
);
long
sys_script
(
void
*
addr
,
u64
len
,
u64
chunk
);
long
sys_script
(
void
*
addr
,
u64
len
,
u64
chunk
);
long
sys_setfs
(
u64
base
);
long
sys_setfs
(
u64
base
);
long
sys_wqwait
(
void
);
extern
long
(
*
syscalls
[])(
u64
,
u64
,
u64
,
u64
,
u64
);
extern
long
(
*
syscalls
[])(
u64
,
u64
,
u64
,
u64
,
u64
);
// other exported/imported functions
// other exported/imported functions
...
...
include/memlayout.h
浏览文件 @
7b2ffeaf
...
@@ -3,3 +3,4 @@
...
@@ -3,3 +3,4 @@
#define KSHARED 0xFFFFF00000000000ull
#define KSHARED 0xFFFFF00000000000ull
#define USERWQ 0xFFFFF00100000000ull
#define USERWQ 0xFFFFF00100000000ull
#define USERTOP 0x0000800000000000ull
#define USERTOP 0x0000800000000000ull
#define UWQSTACK 0x0000700000000000ull
include/proc.hh
浏览文件 @
7b2ffeaf
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
#include "file.hh"
#include "file.hh"
#include "filetable.hh"
#include "filetable.hh"
class
uwq
;
// Saved registers for kernel context switches.
// Saved registers for kernel context switches.
// (also implicitly defined in swtch.S)
// (also implicitly defined in swtch.S)
struct
context
{
struct
context
{
...
@@ -43,6 +45,7 @@ enum procstate { EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
...
@@ -43,6 +45,7 @@ enum procstate { EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state
// Per-process state
struct
proc
:
public
rcu_freed
{
struct
proc
:
public
rcu_freed
{
struct
vmap
*
vmap
;
// va -> vma
struct
vmap
*
vmap
;
// va -> vma
uwq
*
uwq
;
char
*
kstack
;
// Bottom of kernel stack for this process
char
*
kstack
;
// Bottom of kernel stack for this process
volatile
int
pid
;
// Process ID
volatile
int
pid
;
// Process ID
struct
proc
*
parent
;
// Parent process
struct
proc
*
parent
;
// Parent process
...
...
include/syscall.h
浏览文件 @
7b2ffeaf
...
@@ -31,4 +31,5 @@
...
@@ -31,4 +31,5 @@
#define SYS_async 30
#define SYS_async 30
#define SYS_script 31
#define SYS_script 31
#define SYS_setfs 32
#define SYS_setfs 32
#define SYS_ncount 33
/* total number of system calls */
#define SYS_wqwait 33
#define SYS_ncount 34
/* total number of system calls */
include/uwq.hh
浏览文件 @
7b2ffeaf
...
@@ -6,27 +6,40 @@ struct padded_length {
...
@@ -6,27 +6,40 @@ struct padded_length {
};
};
#if defined (XV6_KERNEL)
#if defined (XV6_KERNEL)
struct
uwq
{
struct
uwq
:
public
referenced
,
public
rcu_freed
{
uwq
(
vmap
*
vmap
,
padded_length
*
len
);
static
uwq
*
alloc
(
vmap
*
vmap
,
filetable
*
ftable
);
~
uwq
();
bool
haswork
();
bool
haswork
();
int
trywork
();
int
trywork
();
void
*
buffer
();
void
*
buffer
();
void
setuentry
(
uptr
uentry
);
virtual
void
do_gc
(
void
)
{
delete
this
;
}
protected
:
virtual
void
onzero
()
const
{
gc_delayed
((
uwq
*
)
this
);
}
private
:
private
:
uwq
(
vmap
*
vmap
,
filetable
*
ftable
,
padded_length
*
len
);
~
uwq
();
uwq
&
operator
=
(
const
uwq
&
);
uwq
&
operator
=
(
const
uwq
&
);
uwq
(
const
uwq
&
x
);
uwq
(
const
uwq
&
x
);
proc
*
getworker
();
proc
*
getworker
();
proc
*
allocworker
();
void
finishworkers
();
NEW_DELETE_OPS
(
uwq
);
struct
spinlock
lock_
;
struct
spinlock
lock_
;
vmap
*
vmap_
;
vmap
*
vmap_
;
filetable
*
ftable_
;
padded_length
*
len_
;
padded_length
*
len_
;
uptr
uentry_
;
uptr
ustack_
;
struct
worker
{
struct
worker
{
int
running
;
bool
running
;
proc
*
proc
;
proc
*
proc
;
};
};
worker
worker_
[
NCPU
];
worker
worker_
[
NCPU
];
};
};
...
...
include/vm.hh
浏览文件 @
7b2ffeaf
...
@@ -81,7 +81,7 @@ struct vmap : public rcu_freed {
...
@@ -81,7 +81,7 @@ struct vmap : public rcu_freed {
bool
replace_vma
(
vma
*
a
,
vma
*
b
);
bool
replace_vma
(
vma
*
a
,
vma
*
b
);
void
decref
();
void
decref
();
bool
tryinc
();
void
incref
();
vmap
*
copy
(
int
share
);
vmap
*
copy
(
int
share
);
vma
*
lookup
(
uptr
start
,
uptr
len
);
vma
*
lookup
(
uptr
start
,
uptr
len
);
...
@@ -94,7 +94,6 @@ struct vmap : public rcu_freed {
...
@@ -94,7 +94,6 @@ struct vmap : public rcu_freed {
virtual
void
do_gc
(
void
)
{
delete
this
;
}
virtual
void
do_gc
(
void
)
{
delete
this
;
}
uptr
brk_
;
// Top of heap
uptr
brk_
;
// Top of heap
uwq
uwq_
;
private
:
private
:
vmap
();
vmap
();
...
...
include/wquser.hh
浏览文件 @
7b2ffeaf
...
@@ -5,17 +5,17 @@
...
@@ -5,17 +5,17 @@
#include "wq.hh"
#include "wq.hh"
#include "pthread.h"
#include "pthread.h"
#include "memlayout.h"
#include "memlayout.h"
#include "uwq.hh"
#include "atomic.hh"
#include "lib.h"
#include "elf.hh"
typedef
struct
uspinlock
wqlock_t
;
typedef
struct
uspinlock
wqlock_t
;
static
pthread_key_t
idkey
;
static
pthread_key_t
idkey
;
static
std
::
atomic
<
int
>
nextid
;
static
volatile
int
exiting
;
static
volatile
int
exiting
;
struct
padded_length
{
volatile
u64
v_
__mpalign__
;;
__padout__
;
};
int
int
mycpuid
(
void
)
mycpuid
(
void
)
{
{
...
@@ -64,42 +64,29 @@ wqlock_init(wqlock_t *lock)
...
@@ -64,42 +64,29 @@ wqlock_init(wqlock_t *lock)
initlock
(
lock
);
initlock
(
lock
);
}
}
static
void
extern
"C"
long
wqwait
(
void
);
setaffinity
(
int
c
)
{
// XXX(sbw)
}
static
void
*
static
void
__attribute__
((
used
))
workerth
(
void
*
x
)
initworker
(
void
)
{
{
u64
c
=
(
u64
)
x
;
int
id
;
forkt_setup
(
0
);
setaffinity
(
c
)
;
id
=
nextid
++
;
pthread_setspecific
(
idkey
,
(
void
*
)
c
);
pthread_setspecific
(
idkey
,
(
void
*
)
(
u64
)
id
);
while
(
!
exiting
)
while
(
1
)
{
wq_trywork
();
if
(
!
wq_trywork
())
wqwait
();
return
0
;
}
}
}
DEFINE_XV6_ADDRNOTE
(
xnote
,
XV6_ADDR_ID_WQ
,
&
initworker
);
static
inline
void
static
inline
void
wqarch_init
(
void
)
wqarch_init
(
void
)
{
{
pthread_t
th
;
int
r
;
if
(
pthread_key_create
(
&
idkey
,
0
))
if
(
pthread_key_create
(
&
idkey
,
0
))
die
(
"wqarch_init: pthread_key_create"
);
die
(
"wqarch_init: pthread_key_create"
);
pthread_setspecific
(
idkey
,
0
);
pthread_setspecific
(
idkey
,
0
);
setaffinity
(
0
);
for
(
int
i
=
1
;
i
<
NCPU
;
i
++
)
{
r
=
pthread_create
(
&
th
,
0
,
workerth
,
(
void
*
)(
u64
)
i
);
if
(
r
<
0
)
die
(
"wqarch_init: pthread_create"
);
}
}
}
static
inline
void
static
inline
void
...
...
kernel/bootdata.c
浏览文件 @
7b2ffeaf
...
@@ -61,5 +61,5 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
...
@@ -61,5 +61,5 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL
(
async
),
SYSCALL
(
async
),
SYSCALL
(
script
),
SYSCALL
(
script
),
SYSCALL
(
setfs
),
SYSCALL
(
setfs
),
SYSCALL
(
wqwait
),
};
};
kernel/exec.cc
浏览文件 @
7b2ffeaf
...
@@ -27,7 +27,7 @@ struct eargs {
...
@@ -27,7 +27,7 @@ struct eargs {
};
};
static
int
static
int
donotes
(
struct
inode
*
ip
,
vmap
*
vmap
,
u64
off
)
donotes
(
struct
inode
*
ip
,
uwq
*
uwq
,
u64
off
)
{
{
struct
proghdr
ph
;
struct
proghdr
ph
;
struct
elfnote
note
;
struct
elfnote
note
;
...
@@ -49,7 +49,7 @@ donotes(struct inode *ip, vmap *vmap, u64 off)
...
@@ -49,7 +49,7 @@ donotes(struct inode *ip, vmap *vmap, u64 off)
return
-
1
;
return
-
1
;
if
(
desc
.
id
==
XV6_ADDR_ID_WQ
)
{
if
(
desc
.
id
==
XV6_ADDR_ID_WQ
)
{
vmap
->
uwq_
.
setuentry
(
desc
.
vaddr
);
uwq
->
setuentry
(
desc
.
vaddr
);
return
0
;
return
0
;
}
}
}
}
...
@@ -179,12 +179,13 @@ exec(const char *path, char **argv)
...
@@ -179,12 +179,13 @@ exec(const char *path, char **argv)
{
{
struct
inode
*
ip
=
nullptr
;
struct
inode
*
ip
=
nullptr
;
struct
vmap
*
vmp
=
nullptr
;
struct
vmap
*
vmp
=
nullptr
;
uwq
*
uwq
=
nullptr
;
struct
elfhdr
elf
;
struct
elfhdr
elf
;
struct
proghdr
ph
;
struct
proghdr
ph
;
u64
off
;
u64
off
;
int
i
;
int
i
;
struct
vmap
*
oldvmap
;
struct
vmap
*
oldvmap
;
if
((
ip
=
namei
(
myproc
()
->
cwd
,
path
))
==
0
)
if
((
ip
=
namei
(
myproc
()
->
cwd
,
path
))
==
0
)
return
-
1
;
return
-
1
;
...
@@ -201,6 +202,9 @@ exec(const char *path, char **argv)
...
@@ -201,6 +202,9 @@ exec(const char *path, char **argv)
if
((
vmp
=
vmap
::
alloc
())
==
0
)
if
((
vmp
=
vmap
::
alloc
())
==
0
)
goto
bad
;
goto
bad
;
if
((
uwq
=
uwq
::
alloc
(
vmp
,
myproc
()
->
ftable
))
==
0
)
goto
bad
;
// Arguments for work queue
// Arguments for work queue
struct
eargs
args
;
struct
eargs
args
;
args
.
proc
=
myproc
();
args
.
proc
=
myproc
();
...
@@ -217,7 +221,7 @@ exec(const char *path, char **argv)
...
@@ -217,7 +221,7 @@ exec(const char *path, char **argv)
sizeof
(
type
))
!=
sizeof
(
type
))
sizeof
(
type
))
!=
sizeof
(
type
))
goto
bad
;
goto
bad
;
if
(
type
==
ELF_PROG_NOTE
)
{
if
(
type
==
ELF_PROG_NOTE
)
{
if
(
donotes
(
ip
,
vmp
,
off
)
<
0
)
{
if
(
donotes
(
ip
,
uwq
,
off
)
<
0
)
{
cilk_abort
(
-
1
);
cilk_abort
(
-
1
);
break
;
break
;
}
}
...
@@ -238,7 +242,10 @@ exec(const char *path, char **argv)
...
@@ -238,7 +242,10 @@ exec(const char *path, char **argv)
// Commit to the user image.
// Commit to the user image.
oldvmap
=
myproc
()
->
vmap
;
oldvmap
=
myproc
()
->
vmap
;
myproc
()
->
vmap
=
vmp
;
myproc
()
->
vmap
=
vmp
;
myproc
()
->
tf
->
rip
=
elf
.
entry
;
// main
if
(
myproc
()
->
uwq
!=
nullptr
)
myproc
()
->
uwq
->
dec
();
myproc
()
->
uwq
=
uwq
;
myproc
()
->
tf
->
rip
=
elf
.
entry
;
switchvm
(
myproc
());
switchvm
(
myproc
());
oldvmap
->
decref
();
oldvmap
->
decref
();
...
@@ -250,7 +257,8 @@ exec(const char *path, char **argv)
...
@@ -250,7 +257,8 @@ exec(const char *path, char **argv)
cprintf
(
"exec failed
\n
"
);
cprintf
(
"exec failed
\n
"
);
if
(
vmp
)
if
(
vmp
)
vmp
->
decref
();
vmp
->
decref
();
if
(
uwq
)
uwq
->
dec
();
gc_end_epoch
();
gc_end_epoch
();
return
0
;
return
0
;
}
}
kernel/hwvm.cc
浏览文件 @
7b2ffeaf
...
@@ -93,6 +93,18 @@ setupkvm(void)
...
@@ -93,6 +93,18 @@ setupkvm(void)
}
}
int
int
mapkva
(
pgmap
*
pml4
,
char
*
kva
,
uptr
uva
,
size_t
size
)
{
for
(
u64
off
=
0
;
off
<
size
;
off
+=
4096
)
{
atomic
<
pme_t
>
*
pte
=
walkpgdir
(
pml4
,
(
u64
)
(
uva
+
off
),
1
);
if
(
pte
==
nullptr
)
return
-
1
;
*
pte
=
v2p
(
kva
+
off
)
|
PTE_P
|
PTE_U
|
PTE_W
;
}
return
0
;
}
int
setupuvm
(
pgmap
*
pml4
,
char
*
kshared
,
char
*
uwq
)
setupuvm
(
pgmap
*
pml4
,
char
*
kshared
,
char
*
uwq
)
{
{
struct
todo
{
struct
todo
{
...
...
kernel/idle.cc
浏览文件 @
7b2ffeaf
...
@@ -120,6 +120,10 @@ idleloop(void)
...
@@ -120,6 +120,10 @@ idleloop(void)
// XXX(sbw)
// XXX(sbw)
worked
=
uwq_trywork
();
worked
=
uwq_trywork
();
if
(
worked
==
1
)
{
cprintf
(
"did some work..
\n
"
);
break
;
}
worked
=
wq_trywork
();
worked
=
wq_trywork
();
// If we are no longer the idle thread, exit
// If we are no longer the idle thread, exit
...
...
kernel/proc.cc
浏览文件 @
7b2ffeaf
...
@@ -36,7 +36,7 @@ struct kstack_tag kstack_tag[NCPU];
...
@@ -36,7 +36,7 @@ struct kstack_tag kstack_tag[NCPU];
enum
{
sched_debug
=
0
};
enum
{
sched_debug
=
0
};
proc
::
proc
(
int
npid
)
:
proc
::
proc
(
int
npid
)
:
rcu_freed
(
"proc"
),
vmap
(
0
),
kstack
(
0
),
rcu_freed
(
"proc"
),
vmap
(
0
),
uwq
(
0
),
kstack
(
0
),
pid
(
npid
),
parent
(
0
),
tf
(
0
),
context
(
0
),
killed
(
0
),
pid
(
npid
),
parent
(
0
),
tf
(
0
),
context
(
0
),
killed
(
0
),
ftable
(
0
),
cwd
(
0
),
tsc
(
0
),
curcycles
(
0
),
cpuid
(
0
),
epoch
(
0
),
ftable
(
0
),
cwd
(
0
),
tsc
(
0
),
curcycles
(
0
),
cpuid
(
0
),
epoch
(
0
),
on_runq
(
-
1
),
cpu_pin
(
0
),
runq
(
0
),
oncv
(
0
),
cv_wakeup
(
0
),
on_runq
(
-
1
),
cpu_pin
(
0
),
runq
(
0
),
oncv
(
0
),
cv_wakeup
(
0
),
...
@@ -376,6 +376,8 @@ finishproc(struct proc *p)
...
@@ -376,6 +376,8 @@ finishproc(struct proc *p)
{
{
if
(
p
->
vmap
!=
nullptr
)
if
(
p
->
vmap
!=
nullptr
)
p
->
vmap
->
decref
();
p
->
vmap
->
decref
();
if
(
p
->
uwq
!=
nullptr
)
p
->
uwq
->
dec
();
ksfree
(
slab_stack
,
p
->
kstack
);
ksfree
(
slab_stack
,
p
->
kstack
);
p
->
kstack
=
0
;
p
->
kstack
=
0
;
if
(
!
xnspid
->
remove
(
p
->
pid
,
&
p
))
if
(
!
xnspid
->
remove
(
p
->
pid
,
&
p
))
...
...
kernel/trap.cc
浏览文件 @
7b2ffeaf
...
@@ -158,6 +158,7 @@ trap(struct trapframe *tf)
...
@@ -158,6 +158,7 @@ trap(struct trapframe *tf)
#endif
#endif
return
;
return
;
}
}
cprintf
(
"pagefault: failed
\n
"
);
cli
();
cli
();
}
}
...
...
kernel/uwq.cc
浏览文件 @
7b2ffeaf
//
// XXX
// - vmap doesn't need to be rcu_freed anymore
// - workers should have a uwq
// - pin workers
#include "types.h"
#include "types.h"
#include "amd64.h"
#include "amd64.h"
#include "kernel.hh"
#include "kernel.hh"
...
@@ -6,10 +12,14 @@
...
@@ -6,10 +12,14 @@
#include "percpu.hh"
#include "percpu.hh"
#include "spinlock.h"
#include "spinlock.h"
#include "condvar.h"
#include "condvar.h"
#include "uwq.hh"
#include "proc.hh"
#include "proc.hh"
#include "uwq.hh"
#include "vm.hh"
#include "vm.hh"
#include "kalloc.hh"
#include "kalloc.hh"
#include "bits.hh"
extern
"C"
{
#include "kern_c.h"
}
int
int
uwq_trywork
(
void
)
uwq_trywork
(
void
)
...
@@ -28,12 +38,13 @@ uwq_trywork(void)
...
@@ -28,12 +38,13 @@ uwq_trywork(void)
scoped_gc_epoch
xgc
();
scoped_gc_epoch
xgc
();
barrier
();
barrier
();
struct
proc
*
p
=
c
->
proc
;
struct
proc
*
p
=
c
->
proc
;
if
(
p
==
nullptr
||
p
->
vmap
==
nullptr
)
if
(
p
==
nullptr
||
p
->
uwq
==
nullptr
)
continue
;
continue
;
uwq
*
uwq
=
&
p
->
vmap
->
uwq_
;
uwq
*
uwq
=
p
->
uwq
;
if
(
uwq
->
haswork
())
{
if
(
uwq
->
haswork
())
{
uwq
->
trywork
();
if
(
uwq
->
trywork
()
==
1
)
return
1
;
// XXX(sbw) start a worker thread..
// XXX(sbw) start a worker thread..
break
;
break
;
}
}
...
@@ -42,19 +53,56 @@ uwq_trywork(void)
...
@@ -42,19 +53,56 @@ uwq_trywork(void)
return
0
;
return
0
;
}
}
long
sys_wqwait
(
void
)
{
return
0
;
}
//
//
// uwq
// uwq
//
//
uwq
::
uwq
(
vmap
*
vmap
,
padded_length
*
len
)
uwq
*
:
vmap_
(
vmap
),
len_
(
len
)
uwq
::
alloc
(
vmap
*
vmap
,
filetable
*
ftable
)
{
{
if
(
len_
!=
nullptr
)
{
padded_length
*
len
;
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
uwq
*
u
;
len_
[
i
].
v_
=
0
;
}
else
{
len
=
(
padded_length
*
)
ksalloc
(
slab_userwq
);
cprintf
(
"uwq::uwq: nullptr len
\n
"
);
if
(
len
==
nullptr
)
return
nullptr
;
ftable
->
incref
();
vmap
->
incref
();
u
=
new
uwq
(
vmap
,
ftable
,
len
);
if
(
u
==
nullptr
)
{
ftable
->
decref
();
vmap
->
decref
();
ksfree
(
slab_userwq
,
len
);
return
nullptr
;
}
u
->
inc
();
if
(
mapkva
(
vmap
->
pml4
,
(
char
*
)
len
,
USERWQ
,
USERWQSIZE
))
{
ftable
->
decref
();
vmap
->
decref
();
ksfree
(
slab_userwq
,
len
);
u
->
dec
();
return
nullptr
;
}
}
return
u
;
}
uwq
::
uwq
(
vmap
*
vmap
,
filetable
*
ftable
,
padded_length
*
len
)
:
rcu_freed
(
"uwq"
),
vmap_
(
vmap
),
ftable_
(
ftable
),
len_
(
len
),
uentry_
(
0
),
ustack_
(
UWQSTACK
)
{
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
len_
[
i
].
v_
=
0
;
initlock
(
&
lock_
,
"uwq_lock"
,
0
);
initlock
(
&
lock_
,
"uwq_lock"
,
0
);
memset
(
worker_
,
0
,
sizeof
(
worker_
));
memset
(
worker_
,
0
,
sizeof
(
worker_
));
}
}
...
@@ -63,7 +111,9 @@ uwq::~uwq(void)
...
@@ -63,7 +111,9 @@ uwq::~uwq(void)
{
{
if
(
len_
!=
nullptr
)
if
(
len_
!=
nullptr
)
ksfree
(
slab_userwq
,
len_
);
ksfree
(
slab_userwq
,
len_
);
// XXX(sbw) clean up worker procs
vmap_
->
decref
();
ftable_
->
decref
();
finishworkers
();
}
}
bool
bool
...
@@ -89,13 +139,23 @@ uwq::trywork(void)
...
@@ -89,13 +139,23 @@ uwq::trywork(void)
if
(
p
==
nullptr
)
if
(
p
==
nullptr
)
return
-
1
;
return
-
1
;
if
(
!
vmap_
->
tryinc
())
// XXX(sbw) filetable, etc
return
-
1
;
p
->
cpuid
=
mycpuid
()
;
// XXX(sbw)
acquire
(
&
p
->
lock
);
vmap_
->
decref
();
addrun
(
p
);
panic
(
"XXX"
);
release
(
&
p
->
lock
);
return
0
;
cprintf
(
"trying to run..
\n
"
);
return
1
;
}
void
uwq
::
finishworkers
(
void
)
{
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
if
(
worker_
[
i
].
proc
!=
nullptr
)
panic
(
"uwq::finishworkers"
);
}
}
void
*
void
*
...
@@ -104,6 +164,57 @@ uwq::buffer(void)
...
@@ -104,6 +164,57 @@ uwq::buffer(void)
return
(
void
*
)
len_
;
return
(
void
*
)
len_
;
}
}
void
uwq
::
setuentry
(
uptr
uentry
)
{
uentry_
=
uentry
;
}
proc
*
uwq
::
allocworker
(
void
)
{
uptr
uentry
=
uentry_
;
if
(
uentry
==
0
)
return
nullptr
;
proc
*
p
=
allocproc
();
if
(
p
==
nullptr
)
return
nullptr
;
safestrcpy
(
p
->
name
,
"uwq_worker"
,
sizeof
(
p
->
name
));
vmap_
->
incref
();
ftable_
->
incref
();
// finishproc will drop these refs
p
->
vmap
=
vmap_
;
p
->
ftable
=
ftable_
;
struct
vmnode
*
vmn
;
if
((
vmn
=
new
vmnode
(
UWQSTACKPAGES
))
==
nullptr
)
{
finishproc
(
p
);
return
nullptr
;
}
uptr
stacktop
=
ustack_
+
(
UWQSTACKPAGES
*
PGSIZE
);
if
(
vmap_
->
insert
(
vmn
,
ustack_
,
1
)
<
0
)
{
delete
vmn
;
finishproc
(
p
);
return
nullptr
;
}
ustack_
+=
(
UWQSTACKPAGES
*
PGSIZE
);
p
->
tf
->
rsp
=
stacktop
-
8
;
cprintf
(
"stacktop %lx
\n
"
,
stacktop
);
p
->
tf
->
rip
=
uentry
;
p
->
tf
->
cs
=
UCSEG
|
0x3
;
p
->
tf
->
ds
=
UDSEG
|
0x3
;
p
->
tf
->
ss
=
p
->
tf
->
ds
;
p
->
tf
->
rflags
=
FL_IF
;
return
p
;
}
proc
*
proc
*
uwq
::
getworker
(
void
)
uwq
::
getworker
(
void
)
{
{
...
@@ -112,8 +223,10 @@ uwq::getworker(void)
...
@@ -112,8 +223,10 @@ uwq::getworker(void)
scoped_acquire
lockx
(
&
lock_
);
scoped_acquire
lockx
(
&
lock_
);
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
{
for
(
int
i
=
0
;
i
<
NCPU
;
i
++
)
{
if
(
worker_
[
i
].
running
)
continue
;
if
(
worker_
[
i
].
proc
!=
nullptr
)
{
if
(
worker_
[
i
].
proc
!=
nullptr
)
{
worker_
[
i
].
running
=
1
;
worker_
[
i
].
running
=
true
;
return
worker_
[
i
].
proc
;
return
worker_
[
i
].
proc
;
}
else
if
(
slot
==
-
1
)
{
}
else
if
(
slot
==
-
1
)
{
slot
=
i
;
slot
=
i
;
...
@@ -121,13 +234,13 @@ uwq::getworker(void)
...
@@ -121,13 +234,13 @@ uwq::getworker(void)
}
}
if
(
slot
!=
-
1
)
{
if
(
slot
!=
-
1
)
{
proc
*
p
=
alloc
proc
();
proc
*
p
=
alloc
worker
();
if
(
p
!=
nullptr
)
{
if
(
p
!=
nullptr
)
{
worker_
[
slot
].
proc
=
p
;
worker_
[
slot
].
proc
=
p
;
worker_
[
slot
].
running
=
1
;
worker_
[
slot
].
running
=
true
;
return
worker_
[
slot
].
proc
;
return
worker_
[
slot
].
proc
;
}
}
}
}
return
nullptr
;
return
nullptr
;
}
}
kernel/vm.cc
浏览文件 @
7b2ffeaf
...
@@ -154,7 +154,7 @@ vmap::vmap() :
...
@@ -154,7 +154,7 @@ vmap::vmap() :
rx
(
PGSHIFT
),
rx
(
PGSHIFT
),
#endif
#endif
ref
(
1
),
pml4
(
setupkvm
()),
kshared
((
char
*
)
ksalloc
(
slab_kshared
)),
ref
(
1
),
pml4
(
setupkvm
()),
kshared
((
char
*
)
ksalloc
(
slab_kshared
)),
brk_
(
0
)
,
uwq_
(
this
,
(
padded_length
*
)
ksalloc
(
slab_userwq
))
brk_
(
0
)
{
{
initlock
(
&
brklock_
,
"brk_lock"
,
LOCKSTAT_VM
);
initlock
(
&
brklock_
,
"brk_lock"
,
LOCKSTAT_VM
);
if
(
pml4
==
0
)
{
if
(
pml4
==
0
)
{
...
@@ -167,13 +167,8 @@ vmap::vmap() :
...
@@ -167,13 +167,8 @@ vmap::vmap() :
goto
err
;
goto
err
;
}
}
if
(
uwq_
.
buffer
()
==
nullptr
)
{
if
(
mapkva
(
pml4
,
kshared
,
KSHARED
,
KSHAREDSIZE
))
{
cprintf
(
"vmap::vmap: userwq out of memory
\n
"
);
cprintf
(
"vmap::vmap: mapkva out of memory
\n
"
);
goto
err
;
}
if
(
setupuvm
(
pml4
,
kshared
,
(
char
*
)
uwq_
.
buffer
()))
{
cprintf
(
"vmap::vmap: setupkshared out of memory
\n
"
);
goto
err
;
goto
err
;
}
}
...
@@ -202,18 +197,10 @@ vmap::decref()
...
@@ -202,18 +197,10 @@ vmap::decref()
gc_delayed
(
this
);
gc_delayed
(
this
);
}
}
bool
void
vmap
::
tryinc
()
vmap
::
incref
()
{
{
u64
o
;
++
ref
;
do
{
o
=
ref
.
load
();
if
(
o
==
0
)
return
false
;
}
while
(
!
cmpxch
(
&
ref
,
o
,
o
+
1
));
return
true
;
}
}
bool
bool
...
...
lib/usys.S
浏览文件 @
7b2ffeaf
...
@@ -48,3 +48,4 @@ SYSCALL(pread)
...
@@ -48,3 +48,4 @@ SYSCALL(pread)
SYSCALL(async)
SYSCALL(async)
SYSCALL(script)
SYSCALL(script)
SYSCALL(setfs)
SYSCALL(setfs)
SYSCALL(wqwait)
param.h
浏览文件 @
7b2ffeaf
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#define ALLOC_MEMSET DEBUG
#define ALLOC_MEMSET DEBUG
#define KSHAREDSIZE (32 << 10)
#define KSHAREDSIZE (32 << 10)
#define USERWQSIZE (1 << 14)
#define USERWQSIZE (1 << 14)
#define UWQSTACKPAGES 2
#define WQSHIFT 7
#define WQSHIFT 7
#define CILKENABLE 0
#define CILKENABLE 0
#if defined(HW_josmp)
#if defined(HW_josmp)
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论