XV6:ptable 初始化
Posted
技术标签:
【中文标题】XV6:ptable 初始化【英文标题】:XV6: ptable initialization 【发布时间】:2015-06-09 11:43:22 【问题描述】:我说的是:
struct
struct spinlock lock;
struct proc proc[NPROC];
ptable;
位于 proc.c 文件中。
有人能解释一下它是在哪里初始化的吗? 因为,在 proc.c 中,我从未见过向其中添加某些东西(进程)。
更准确地说,假设我正在查看调度程序代码:
void
scheduler(void)
struct proc *p;
for(;;)
// Enable interrupts on this processor.
sti();
// Loop over process table looking for process to run.
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p−>state != RUNNABLE)
continue;
// Switch to chosen process. It is the process’s job
// to release ptable.lock and then reacquire it
// before jumping back to us.
proc = p;
switchuvm(p);
p−>state = RUNNING;
swtch(&cpu−>scheduler, proc−>context);
switchkvm();
// Process is done running for now.
// It should have changed its p−>state before coming back.
proc = 0;
release(&ptable.lock);
在:
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
你可以看到我们正在循环遍历 ptable 中的每个进程。我的问题是,他们是如何到达那里的? 谢谢!
【问题讨论】:
由于ptable
没有在您发布的代码中声明,并且它不是函数的参数,我不得不得出结论它是一个全局变量。它在哪里声明?也许它是静态初始化的?也许隐式初始化为零,作为一个全局变量?
这就是重点,我找不到初始化它的代码。我不确定它是否是全球性的,但我会听从您的建议并在其他文件中检查ptable
的初始化。谢谢。
【参考方案1】:
您不会在 xv6 的代码中找到初始化。原因如下。
C 将 proc 的 int 和 enum 变量初始化为 0。当ptable
实现时,struct proc proc[NPROC];
创建一个包含 64 个进程的数组,其字段被语言初始化为 0。 0 恰好是 UNUSED 枚举的值。
allocproc 循环通过 ptable.proc 寻找 state=UNUSED,然后将它找到的第一个初始化为所有需要的值。所以不需要显式初始化数组中的结构。
【讨论】:
宏被声明为#define NPROC 64 // 最大进程数。源代码位于 [github.com/mit-pdos/xv6-public]【参考方案2】:已初始化。
struct
struct spinlock lock;
struct proc proc[NPROC];
ptable;
上面的代码定义了一个结构体(没有名字)并将ptable
初始化为这种类型的结构体。
也许你对这种语法感到困惑:
struct ptable
struct spinlock lock;
struct proc proc[NPROC];
;
这里我们只定义了一个结构名ptable
,并没有初始化。
【讨论】:
【参考方案3】:struct
struct spinlock lock;
struct proc proc[NPROC];
ptable;
它在堆栈上分配并自动初始化。这里的诀窍是它是用 GCC 方式编写的,也称为匿名结构。
【讨论】:
【参考方案4】:ptable
结构体是一个全局变量,在 xv6 内核启动期间作为bootmain()
调用的一部分被加载到内存中。由于它是全局的,因此会初始化默认值。
现在来了解它们如何实际用于存储进程以及何时修改条目。
userinit()
创建,它选择一个未使用的条目并将其用于设置自己的 PCB。
在内核生成手工制作的 initproc 之后,会发生对调度程序的第一次调用,这就是您在此处所指的内容。
由于调度程序将选择一个 RUNNABLE 进程,而我们现在唯一的一个就是 initproc 本身,它就是开始运行的那个。
它调用fork()
以生成一个shell,该shell 在每次调用时调用allocproc()
从ptable 获取另一个未使用的条目并将其分配给进程。
这是在 fork 期间填充 ptable 的方式,并帮助 xv6 记录活动进程。
【讨论】:
以上是关于XV6:ptable 初始化的主要内容,如果未能解决你的问题,请参考以下文章