Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
504828a0
提交
504828a0
4月 29, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Primitive partitioned memory allocater (no stealing)
Primitive partitioned proc table, per core runq, and non-scalable stealing Panics on two cores, but i should make more frequent checkpoints
上级
a5579e26
显示空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
182 行增加
和
38 行删除
+182
-38
console.c
console.c
+1
-1
defs.h
defs.h
+1
-0
exec.c
exec.c
+1
-1
ide.c
ide.c
+2
-2
kalloc.c
kalloc.c
+40
-19
main.c
main.c
+2
-1
param.h
param.h
+2
-1
proc.c
proc.c
+124
-11
proc.h
proc.h
+5
-0
vm.c
vm.c
+4
-2
没有找到文件。
console.c
浏览文件 @
504828a0
...
...
@@ -190,7 +190,7 @@ consoleintr(int (*getc)(void))
while
((
c
=
getc
())
>=
0
){
switch
(
c
){
case
C
(
'P'
):
// Process listing.
procdump
(
cpunum
()
);
procdump
all
(
);
break
;
case
C
(
'U'
):
// Kill line.
while
(
input
.
e
!=
input
.
w
&&
...
...
defs.h
浏览文件 @
504828a0
...
...
@@ -100,6 +100,7 @@ int growproc(int);
int
kill
(
int
);
void
pinit
(
void
);
void
procdump
(
int
);
void
procdumpall
(
void
);
void
scheduler
(
void
)
__attribute__
((
noreturn
));
void
sched
(
void
);
void
sleep
(
void
*
,
struct
spinlock
*
);
...
...
exec.c
浏览文件 @
504828a0
...
...
@@ -19,7 +19,7 @@ exec(char *path, char **argv)
pde_t
*
pgdir
,
*
oldpgdir
;
cprintf
(
"%d: exec %s
\n
"
,
cpunum
(),
path
);
procdump
(
cpunum
()
);
procdump
all
(
);
if
((
ip
=
namei
(
path
))
==
0
)
return
-
1
;
...
...
ide.c
浏览文件 @
504828a0
...
...
@@ -48,8 +48,8 @@ ideinit(void)
initlock
(
&
idelock
,
"ide"
);
picenable
(
IRQ_IDE
);
ioapicenable
(
IRQ_IDE
,
ncpu
-
1
);
//
ioapicenable(IRQ_IDE, 0);
//
ioapicenable(IRQ_IDE, ncpu - 1);
ioapicenable
(
IRQ_IDE
,
0
);
idewait
(
0
);
// Check if disk 1 is present
...
...
kalloc.c
浏览文件 @
504828a0
...
...
@@ -7,15 +7,10 @@
#include "param.h"
#include "mmu.h"
#include "spinlock.h"
#include "proc.h"
#include "kalloc.h"
struct
run
{
struct
run
*
next
;
};
struct
{
struct
spinlock
lock
;
struct
run
*
freelist
;
}
kmem
;
struct
kmem
kmems
[
NCPU
];
extern
char
end
[];
// first address after kernel loaded from ELF file
...
...
@@ -23,12 +18,35 @@ extern char end[]; // first address after kernel loaded from ELF file
void
kinit
(
void
)
{
struct
run
*
r
;
char
*
p
;
int
c
;
int
n
;
int
i
;
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
kmems
[
c
].
name
[
0
]
=
(
char
)
c
;
safestrcpy
(
kmems
[
c
].
name
+
1
,
"kmem"
,
MAXNAME
-
1
);
initlock
(
&
kmems
[
c
].
lock
,
kmems
[
c
].
name
);
}
initlock
(
&
kmem
.
lock
,
"kmem"
);
p
=
(
char
*
)
PGROUNDUP
((
uint
)
end
);
for
(;
p
+
PGSIZE
<=
(
char
*
)
PHYSTOP
;
p
+=
PGSIZE
)
kfree
(
p
);
n
=
(
char
*
)
PHYSTOP
-
p
;
cprintf
(
"n = %d
\n
"
,
n
);
n
=
n
/
PGSIZE
;
cprintf
(
"n = %d
\n
"
,
n
);
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
,
p
+=
PGSIZE
)
{
memset
(
p
,
1
,
PGSIZE
);
r
=
(
struct
run
*
)
p
;
r
->
next
=
kmems
[
c
].
freelist
;
kmems
[
c
].
freelist
=
r
;
}
}
}
//PAGEBREAK: 21
...
...
@@ -47,11 +65,11 @@ kfree(char *v)
// Fill with junk to catch dangling refs.
memset
(
v
,
1
,
PGSIZE
);
acquire
(
&
kmem
.
lock
);
acquire
(
&
kmem
->
lock
);
r
=
(
struct
run
*
)
v
;
r
->
next
=
kmem
.
freelist
;
kmem
.
freelist
=
r
;
release
(
&
kmem
.
lock
);
r
->
next
=
kmem
->
freelist
;
kmem
->
freelist
=
r
;
release
(
&
kmem
->
lock
);
}
// Allocate one 4096-byte page of physical memory.
...
...
@@ -62,11 +80,14 @@ kalloc(void)
{
struct
run
*
r
;
acquire
(
&
kmem
.
lock
);
r
=
kmem
.
freelist
;
cprintf
(
"%d: kalloc
\n
"
,
cpunum
());
acquire
(
&
kmem
->
lock
);
r
=
kmem
->
freelist
;
if
(
r
)
kmem
.
freelist
=
r
->
next
;
release
(
&
kmem
.
lock
);
kmem
->
freelist
=
r
->
next
;
release
(
&
kmem
->
lock
);
if
(
r
==
0
)
cprintf
(
"%d: kalloc out
\n
"
,
cpunum
());
return
(
char
*
)
r
;
}
main.c
浏览文件 @
504828a0
...
...
@@ -58,7 +58,6 @@ mainc(void)
timerinit
();
// uniprocessor timer
userinit
();
// first user process
bootothers
();
// start other processors
// Finish setting up this processor in mpmain.
mpmain
();
}
...
...
@@ -75,8 +74,10 @@ mpmain(void)
}
vmenable
();
// turn on paging
cprintf
(
"cpu%d: starting
\n
"
,
cpu
->
id
);
procdumpall
();
idtinit
();
// load idt register
xchg
(
&
cpu
->
booted
,
1
);
// tell bootothers() we're up
procdumpall
();
scheduler
();
// start running processes
}
...
...
param.h
浏览文件 @
504828a0
#define NPROC 64 // maximum number of processes
#define KSTACKSIZE 4096 // size of per-process kernel stack
#define NCPU
8
// maximum number of CPUs
#define NCPU
2
// maximum number of CPUs
#define NOFILE 16 // open files per process
#define NFILE 100 // open files per system
#define NBUF 10 // size of disk block cache
...
...
@@ -10,3 +10,4 @@
#define USERTOP 0xA0000 // end of user address space
#define PHYSTOP 0x1000000 // use phys mem up to here as free pool
#define MAXARG 32 // max exec arguments
#define MAXNAME 16 // max string names
proc.c
浏览文件 @
504828a0
...
...
@@ -18,7 +18,12 @@ static void wakeup1(void *chan);
void
pinit
(
void
)
{
initlock
(
&
ptable
->
lock
,
"ptable"
);
int
c
;
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
ptables
[
c
].
name
[
0
]
=
(
char
)
c
;
safestrcpy
(
ptables
[
c
].
name
+
1
,
"ptable"
,
MAXNAME
-
1
);
initlock
(
&
ptables
[
c
].
lock
,
ptables
[
c
].
name
);
}
}
//PAGEBREAK: 32
...
...
@@ -41,7 +46,7 @@ allocproc(void)
found:
p
->
state
=
EMBRYO
;
p
->
pid
=
nextpid
++
;
p
->
pid
=
nextpid
++
;
// XXX global var!
release
(
&
ptable
->
lock
);
// Allocate kernel stack if possible.
...
...
@@ -68,6 +73,63 @@ found:
return
p
;
}
static
void
addrun1
(
struct
proc
*
p
)
{
struct
proc
*
q
;
cprintf
(
"%d: add to run %d
\n
"
,
cpu
->
id
,
p
->
pid
);
for
(
q
=
ptable
->
runq
;
q
!=
0
;
q
=
q
->
next
)
{
if
(
q
==
p
)
{
cprintf
(
"allready on q
\n
"
);
p
->
state
=
RUNNABLE
;
return
;
}
}
p
->
state
=
RUNNABLE
;
// race?
p
->
next
=
ptable
->
runq
;
ptable
->
runq
=
p
;
}
static
void
addrun
(
struct
proc
*
p
)
{
acquire
(
&
ptable
->
lock
);
addrun1
(
p
);
release
(
&
ptable
->
lock
);
procdumpall
();
}
static
void
delrun1
(
struct
ptable
*
pt
,
struct
proc
*
proc
)
{
struct
proc
*
p
=
0
;
struct
proc
*
n
;
n
=
pt
->
runq
;
while
(
n
!=
0
)
{
if
(
n
==
proc
)
{
if
(
p
==
0
)
{
pt
->
runq
=
n
->
next
;
}
else
{
p
->
next
=
n
->
next
;
}
n
->
next
=
0
;
return
;
}
else
{
p
=
n
;
n
=
n
->
next
;
}
}
}
void
delrun
(
struct
proc
*
proc
)
{
acquire
(
&
ptable
->
lock
);
delrun1
(
ptable
,
proc
);
release
(
&
ptable
->
lock
);
}
//PAGEBREAK: 32
// Set up first user process.
void
...
...
@@ -93,8 +155,7 @@ userinit(void)
safestrcpy
(
p
->
name
,
"initcode"
,
sizeof
(
p
->
name
));
p
->
cwd
=
namei
(
"/"
);
p
->
state
=
RUNNABLE
;
addrun
(
p
);
}
// Grow current process's memory by n bytes.
...
...
@@ -152,7 +213,7 @@ fork(void)
np
->
cwd
=
idup
(
proc
->
cwd
);
pid
=
np
->
pid
;
np
->
state
=
RUNNABLE
;
addrun
(
np
)
;
safestrcpy
(
np
->
name
,
proc
->
name
,
sizeof
(
proc
->
name
));
return
pid
;
}
...
...
@@ -180,8 +241,12 @@ exit(void)
iput
(
proc
->
cwd
);
proc
->
cwd
=
0
;
cprintf
(
"%d: exit %s
\n
"
,
cpunum
(),
proc
->
name
);
acquire
(
&
ptable
->
lock
);
delrun1
(
ptable
,
proc
);
// Parent might be sleeping in wait().
wakeup1
(
proc
->
parent
);
...
...
@@ -243,6 +308,34 @@ wait(void)
}
}
void
steal
(
void
)
{
int
c
;
struct
proc
*
p
;
int
r
=
0
;
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
if
(
c
==
cpunum
())
continue
;
acquire
(
&
ptables
[
c
].
lock
);
for
(
p
=
ptables
[
c
].
runq
;
p
!=
0
;
p
=
p
->
next
)
{
if
(
p
->
state
==
RUNNABLE
)
{
cprintf
(
"%d: steal %d from %d
\n
"
,
cpunum
(),
p
->
pid
,
c
);
delrun1
(
&
ptables
[
c
],
p
);
addrun
(
p
);
r
=
1
;
break
;
}
}
release
(
&
ptables
[
c
].
lock
);
if
(
r
)
{
procdumpall
();
return
;
}
}
}
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
...
...
@@ -262,7 +355,7 @@ scheduler(void)
// Loop over process table looking for process to run.
acquire
(
&
ptable
->
lock
);
for
(
p
=
ptable
->
proc
;
p
<
&
ptable
->
proc
[
NPROC
];
p
++
)
{
for
(
p
=
ptable
->
runq
;
p
!=
0
;
p
=
p
->
next
)
{
if
(
p
->
state
!=
RUNNABLE
)
continue
;
...
...
@@ -272,6 +365,7 @@ scheduler(void)
proc
=
p
;
switchuvm
(
p
);
p
->
state
=
RUNNING
;
cprintf
(
"%d: running %d
\n
"
,
cpu
->
id
,
p
->
pid
);
swtch
(
&
cpu
->
scheduler
,
proc
->
context
);
switchkvm
();
...
...
@@ -280,7 +374,7 @@ scheduler(void)
proc
=
0
;
}
release
(
&
ptable
->
lock
);
steal
();
}
}
...
...
@@ -309,7 +403,7 @@ void
yield
(
void
)
{
acquire
(
&
ptable
->
lock
);
//DOC: yieldlock
proc
->
state
=
RUNNABLE
;
proc
->
state
=
RUNNABLE
;
// race? stays in runqueue
sched
();
release
(
&
ptable
->
lock
);
}
...
...
@@ -350,6 +444,7 @@ sleep(void *chan, struct spinlock *lk)
// Go to sleep.
proc
->
chan
=
chan
;
proc
->
state
=
SLEEPING
;
delrun1
(
ptable
,
proc
);
sched
();
// Tidy up.
...
...
@@ -372,13 +467,14 @@ wakeup1(void *chan)
for
(
p
=
ptable
->
proc
;
p
<
&
ptable
->
proc
[
NPROC
];
p
++
)
if
(
p
->
state
==
SLEEPING
&&
p
->
chan
==
chan
)
p
->
state
=
RUNNABLE
;
addrun1
(
p
)
;
}
// Wake up all processes sleeping on chan.
void
wakeup
(
void
*
chan
)
{
// XXX should go through all proctables
acquire
(
&
ptable
->
lock
);
wakeup1
(
chan
);
release
(
&
ptable
->
lock
);
...
...
@@ -398,7 +494,7 @@ kill(int pid)
p
->
killed
=
1
;
// Wake process from sleep if necessary.
if
(
p
->
state
==
SLEEPING
)
p
->
state
=
RUNNABLE
;
addrun1
(
p
)
;
release
(
&
ptable
->
lock
);
return
0
;
}
...
...
@@ -424,6 +520,7 @@ procdump(int c)
};
int
i
;
struct
proc
*
p
;
struct
proc
*
q
;
char
*
state
;
uint
pc
[
10
];
...
...
@@ -443,6 +540,22 @@ procdump(int c)
}
cprintf
(
"
\n
"
);
}
cprintf
(
"runq: "
);
for
(
q
=
ptables
[
c
].
runq
;
q
!=
0
;
q
=
q
->
next
)
{
if
(
q
->
state
>=
0
&&
q
->
state
<
NELEM
(
states
)
&&
states
[
q
->
state
])
state
=
states
[
q
->
state
];
else
state
=
"???"
;
cprintf
(
"%d %s %s, "
,
q
->
pid
,
state
,
q
->
name
);
}
cprintf
(
"
\n
"
);
}
void
procdumpall
(
void
)
{
int
c
;
for
(
c
=
0
;
c
<
NCPU
;
c
++
)
{
procdump
(
c
);
}
}
proc.h
浏览文件 @
504828a0
...
...
@@ -45,6 +45,7 @@ struct proc {
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
inode
*
cwd
;
// Current directory
char
name
[
16
];
// Process name (debugging)
struct
proc
*
next
;
};
// Process memory is laid out contiguously, low addresses first:
...
...
@@ -67,11 +68,14 @@ struct cpu {
struct
cpu
*
cpu
;
struct
proc
*
proc
;
// The currently-running process.
struct
ptable
*
ptable
;
// The per-core proc table
struct
kmem
*
kmem
;
// The per-core proc table
};
struct
ptable
{
char
name
[
MAXNAME
];
struct
spinlock
lock
;
struct
proc
proc
[
NPROC
];
struct
proc
*
runq
;
};
extern
struct
ptable
ptables
[
NCPU
];
...
...
@@ -89,3 +93,4 @@ extern int ncpu;
extern
struct
cpu
*
cpu
asm
(
"%gs:0"
);
// &cpus[cpunum()]
extern
struct
proc
*
proc
asm
(
"%gs:4"
);
// cpus[cpunum()].proc
extern
struct
ptable
*
ptable
asm
(
"%gs:8"
);
// &ptables[cpunum()]
extern
struct
kmem
*
kmem
asm
(
"%gs:12"
);
// &kmems[cpunum()]
vm.c
浏览文件 @
504828a0
...
...
@@ -6,6 +6,7 @@
#include "spinlock.h"
#include "proc.h"
#include "elf.h"
#include "kalloc.h"
extern
char
data
[];
// defined in data.S
...
...
@@ -36,8 +37,8 @@ seginit(void)
c
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
DPL_USER
);
// Map cpu, curproc,
and ptable
c
->
gdt
[
SEG_KCPU
]
=
SEG
(
STA_W
,
&
c
->
cpu
,
1
2
,
0
);
// Map cpu, curproc,
ptable, kmem
c
->
gdt
[
SEG_KCPU
]
=
SEG
(
STA_W
,
&
c
->
cpu
,
1
6
,
0
);
lgdt
(
c
->
gdt
,
sizeof
(
c
->
gdt
));
loadgs
(
SEG_KCPU
<<
3
);
...
...
@@ -46,6 +47,7 @@ seginit(void)
cpu
=
c
;
proc
=
0
;
ptable
=
&
ptables
[
cpunum
()];
kmem
=
&
kmems
[
cpunum
()];
}
// Return the address of the PTE in page table pgdir
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论