xv6解析-- 多处理器操作
阅读原文时间:2023年07月15日阅读:1

xv6可以运行多cpu的计算机上,这个os使用mycpu函数来标识初当前的cpu,使用struct cpu结构体来记录当前的CPU状态。使用cpus这些状态存放于cpus数组中,使用ncpu来标志cpu的个数。

1 // Per-CPU state
2 struct cpu {
3 uchar apicid; // Local APIC ID 每个cpu都有一个唯一硬件ID,这个ID可以lapicid()函数进行获取,然后存放于这个字段中。
4 struct context *scheduler; // swtch() here to enter scheduler
5 struct taskstate ts; // Used by x86 to find stack for interrupt
6 struct segdesc gdt[NSEGS]; // x86 global descriptor table
7 volatile uint started; // Has the CPU started?
8 int ncli; // Depth of pushcli nesting.
9 int intena; // Were interrupts enabled before pushcli?
10 struct proc *proc; // The process running on this cpu or null
11 };
12
13 extern struct cpu cpus[NCPU]; //当前系统中存在的CPU
14 extern int ncpu;

以下函数主要功能是获取 运行当前代码的cpu对应的ID,然后通过这个ID在cpus数组中进行匹配,得到当前CPU信息(这个cpu信息是已经事先通过程序获取的)

35 // Must be called with interrupts disabled to avoid the caller being
36 // rescheduled between reading lapicid and running through the loop.
37 struct cpu*
38 mycpu(void)
39 {
40 int apicid, i;
41
42 if(readeflags()&FL_IF)
43 panic("mycpu called with interrupts enabled\n");
44
45 apicid = lapicid();
46 // APIC IDs are not guaranteed to be contiguous. Maybe we should have
47 // a reverse map, or reserve a register to store &cpus[i].
48 for (i = 0; i < ncpu; ++i) {
49 if (cpus[i].apicid == apicid)
50 return &cpus[i];
51 }
52 panic("unknown apicid\n");
53 }