Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
ed396c06
提交
ed396c06
2月 01, 2017
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Eliminate code for gs trick to track per-cpu state. We rely on lapiccpunum()
to find a per-cpu id with which we locate a cpu's cpu struct.
上级
fbb4c094
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
32 行增加
和
66 行删除
+32
-66
defs.h
defs.h
+1
-0
lapic.c
lapic.c
+2
-12
main.c
main.c
+1
-1
mmu.h
mmu.h
+4
-5
proc.c
proc.c
+22
-10
proc.h
proc.h
+1
-29
trapasm.S
trapasm.S
+0
-3
vm.c
vm.c
+1
-6
没有找到文件。
defs.h
浏览文件 @
ed396c06
...
...
@@ -108,6 +108,7 @@ void exit(void);
int
fork
(
void
);
int
growproc
(
int
);
int
kill
(
int
);
struct
cpu
*
mycpu
(
void
);
struct
proc
*
myproc
();
void
pinit
(
void
);
void
procdump
(
void
);
...
...
lapic.c
浏览文件 @
ed396c06
...
...
@@ -98,23 +98,13 @@ lapicinit(void)
lapicw
(
TPR
,
0
);
}
// Should be called with interrupts disabled: the calling thread shouldn't be
// rescheduled between reading lapic[ID] and checking against cpu array.
int
lapiccpunum
(
void
)
{
int
apicid
,
i
;
// Cannot call cpunum when interrupts are enabled:
// result not guaranteed to last long enough to be used!
// Would prefer to panic but even printing is chancy here:
// almost everything, including cprintf and panic, calls cpu,
// often indirectly through acquire and release.
if
(
readeflags
()
&
FL_IF
){
static
int
n
;
if
(
n
++
==
0
)
cprintf
(
"cpunum called from %x with interrupts enabled
\n
"
,
__builtin_return_address
(
0
));
}
if
(
!
lapic
)
return
0
;
...
...
main.c
浏览文件 @
ed396c06
...
...
@@ -53,7 +53,7 @@ mpenter(void)
static
void
mpmain
(
void
)
{
cprintf
(
"cpu%d: starting %d
\n
"
,
cpuid
(),
lapiccpunum
());
cprintf
(
"cpu%d: starting %d
\n
"
,
cpuid
(),
cpuid
());
idtinit
();
// load idt register
xchg
(
&
(
mycpu
()
->
started
),
1
);
// tell startothers() we're up
scheduler
();
// start running processes
...
...
mmu.h
浏览文件 @
ed396c06
...
...
@@ -42,13 +42,12 @@
// various segment selectors.
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_UCODE 4 // user code
#define SEG_UDATA 5 // user data+stack
#define SEG_TSS 6 // this process's task state
#define SEG_UCODE 3 // user code
#define SEG_UDATA 4 // user data+stack
#define SEG_TSS 5 // this process's task state
// cpu->gdt[NSEGS] holds the above segments.
#define NSEGS
7
#define NSEGS
6
//PAGEBREAK!
#ifndef __ASSEMBLER__
...
...
proc.c
浏览文件 @
ed396c06
...
...
@@ -26,12 +26,29 @@ pinit(void)
initlock
(
&
ptable
.
lock
,
"ptable"
);
}
//
XXX get rid off?
//
Must be called with interrupts disabled
int
cpuid
()
{
return
mycpu
()
-
cpus
;
}
// Must be called with interrupts disabled
struct
cpu
*
mycpu
(
void
)
{
// Would prefer to panic but even printing is chancy here: almost everything,
// including cprintf and panic, calls mycpu(), often indirectly through
// acquire and release.
if
(
readeflags
()
&
FL_IF
){
static
int
n
;
if
(
n
++
==
0
)
cprintf
(
"mycpu called from %x with interrupts enabled
\n
"
,
__builtin_return_address
(
0
));
}
return
&
cpus
[
lapiccpunum
()];
}
// Disable interrupts so that we are not rescheduled
// while reading proc from the cpu structure
struct
proc
*
...
...
@@ -304,6 +321,7 @@ scheduler(void)
{
struct
proc
*
p
;
struct
cpu
*
c
=
mycpu
();
c
->
proc
=
0
;
for
(;;){
// Enable interrupts on this processor.
...
...
@@ -321,15 +339,13 @@ scheduler(void)
c
->
proc
=
p
;
switchuvm
(
p
);
p
->
state
=
RUNNING
;
p
->
cpu
=
c
;
// cprintf("%d: switch to %d\n", c-cpus, p->pid);
swtch
(
&
(
p
->
cpu
->
scheduler
),
p
->
context
);
swtch
(
&
(
c
->
scheduler
),
p
->
context
);
switchkvm
();
// Process is done running for now.
// It should have changed its p->state before coming back.
c
->
proc
=
0
;
p
->
cpu
=
0
;
}
release
(
&
ptable
.
lock
);
...
...
@@ -358,9 +374,7 @@ sched(void)
if
(
readeflags
()
&
FL_IF
)
panic
(
"sched interruptible"
);
intena
=
mycpu
()
->
intena
;
// cprintf("%d: before swtch %d %x\n", p->cpu-cpus, p->pid, * (int *) 0x1d);
swtch
(
&
p
->
context
,
p
->
cpu
->
scheduler
);
// cprintf("%d/%d: after swtch %d %x\n", cpuid(), p->cpu-cpus, p->pid, * (int *) 0x1d);
swtch
(
&
p
->
context
,
mycpu
()
->
scheduler
);
mycpu
()
->
intena
=
intena
;
}
...
...
@@ -422,8 +436,6 @@ sleep(void *chan, struct spinlock *lk)
p
->
chan
=
chan
;
p
->
state
=
SLEEPING
;
// cprintf("sleep %d\n", p->pid);
sched
();
// Tidy up.
...
...
proc.h
浏览文件 @
ed396c06
...
...
@@ -7,39 +7,12 @@ struct cpu {
volatile
uint
started
;
// Has the CPU started?
int
ncli
;
// Depth of pushcli nesting.
int
intena
;
// Were interrupts enabled before pushcli?
// Per-CPU variables, holding pointers to the current cpu and to the current
// process (see cpu() and proc() in proc.c)
struct
cpu
*
cpu
;
// On cpu 0, cpu = &cpus[0]; on cpu 1, cpu=&cpus[1], etc.
struct
proc
*
proc
;
// The currently-running process on this cpu
struct
proc
*
proc
;
// The process running on this cpu or null
};
extern
struct
cpu
cpus
[
NCPU
];
extern
int
ncpu
;
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// and "%gs:4" to refer to proc. seginit sets up the
// %gs segment register so that %gs refers to the memory
// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
static
inline
struct
cpu
*
mycpu
(
void
)
{
struct
cpu
*
cpu
;
asm
(
"movl %%gs:0, %0"
:
"=r"
(
cpu
));
return
cpu
;
}
#if 0
static inline struct proc*
myproc(void) {
struct proc *proc;
asm("movl %%gs:4, %0" : "=r"(proc));
return proc;
}
#endif
//PAGEBREAK: 17
// Saved registers for kernel context switches.
// Don't need to save all the segment registers (%cs, etc),
...
...
@@ -76,7 +49,6 @@ struct proc {
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
inode
*
cwd
;
// Current directory
char
name
[
16
];
// Process name (debugging)
struct
cpu
*
cpu
;
// If running, which cpu.
};
// Process memory is laid out contiguously, low addresses first:
...
...
trapasm.S
浏览文件 @
ed396c06
...
...
@@ -14,9 +14,6 @@ alltraps:
movw $(SEG_KDATA<<3), %ax
movw %ax, %ds
movw %ax, %es
movw $(SEG_KCPU<<3), %ax
movw %ax, %fs
movw %ax, %gs
# Call trap(tf), where tf=%esp
pushl %esp
...
...
vm.c
浏览文件 @
ed396c06
...
...
@@ -21,17 +21,12 @@ seginit(void)
// Cannot share a CODE descriptor for both kernel and user
// because it would have to have DPL_USR, but the CPU forbids
// an interrupt from CPL=0 to DPL=3.
c
=
&
cpus
[
lapiccpunum
()];
c
=
&
cpus
[
cpuid
()];
c
->
gdt
[
SEG_KCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_KDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
DPL_USER
);
c
->
cpu
=
c
;
c
->
proc
=
0
;
// Map cpu and proc -- these are private per cpu.
c
->
gdt
[
SEG_KCPU
]
=
SEG
(
STA_W
,
&
c
->
cpu
,
4
,
0
);
lgdt
(
c
->
gdt
,
sizeof
(
c
->
gdt
));
loadgs
(
SEG_KCPU
<<
3
);
}
// Return the address of the PTE in page table pgdir
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论