本文整理汇总了C++中cpunum函数的典型用法代码示例。如果您正苦于以下问题:C++ cpunum函数的具体用法?C++ cpunum怎么用?C++ cpunum使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了cpunum函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: trap_init_percpu
// Initialize and load the per-CPU TSS and IDT
void
trap_init_percpu(void)
{
// The example code here sets up the Task State Segment (TSS) and
// the TSS descriptor for CPU 0. But it is incorrect if we are
// running on other CPUs because each CPU has its own kernel stack.
// Fix the code so that it works for all CPUs.
//
// Hints:
// - The macro "thiscpu" always refers to the current CPU's
// struct CpuInfo;
// - The ID of the current CPU is given by cpunum() or
// thiscpu->cpu_id;
// - Use "thiscpu->cpu_ts" as the TSS for the current CPU,
// rather than the global "ts" variable;
// - Use gdt[(GD_TSS0 >> 3) + i] for CPU i's TSS descriptor;
// - You mapped the per-CPU kernel stacks in mem_init_mp()
//
// ltr sets a 'busy' flag in the TSS selector, so if you
// accidentally load the same TSS on more than one CPU, you'll
// get a triple fault. If you set up an individual CPU's TSS
// wrong, you may not get a fault until you try to return from
// user space on that CPU.
//
// LAB 4: Your code here:
// Setup a TSS so that we get the right stack
// when we trap to the kernel.
thiscpu->cpu_ts.ts_esp0 = KSTACKTOP-cpunum()*(KSTKSIZE+KSTKGAP);
thiscpu->cpu_ts.ts_ss0 = GD_KD;
thiscpu->cpu_ts.ts_eflags = 0;
thiscpu->cpu_ts.ts_iomb = 0;
// Initialize the TSS slot of the gdt.
gdt[(GD_TSS0 >> 3)+cpunum()] = SEG16(STS_T32A, (uint32_t)(&(thiscpu->cpu_ts)),
sizeof(struct Taskstate) - 1, 0);
gdt[(GD_TSS0 >> 3)+cpunum()].sd_s = 0;
ltr(GD_TSS0+cpunum()*sizeof(struct Segdesc));
/* thiscpu->cpu_ts.ts_esp0 = KSTACKTOP-cpunum()*(KSTKSIZE+KSTKGAP);
thiscpu->cpu_ts.ts_ss0 = GD_KD;
gdt[(GD_TSS0 >> 3) + cpunum()]= SEG16(STS_T32A, (uint32_t)thiscpu,
sizeof(struct Taskstate) - 1, 0);
gdt[(GD_TSS0 >> 3) + cpunum()].sd_s = 0;
// Load the TSS selector (like other segment selectors, the
// bottom three bits are special; we leave them 0)
ltr(GD_TSS0+cpunum()*sizeof(struct Segdesc));*/
// Load the IDT
lidt(&idt_pd);
}
示例2: main
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
// doing some setup required for memory allocator to work.
int
main(void)
{
kinit1(end, P2V(4*1024*1024)); // phys page allocator
kvmalloc(); // kernel page table
mpinit(); // detect other processors
lapicinit(); // interrupt controller
seginit(); // segment descriptors
cprintf("\ncpu%d: starting xv6\n\n", cpunum());
picinit(); // another interrupt controller
ioapicinit(); // another interrupt controller
consoleinit(); // console hardware
uartinit(); // serial port
pinit(); // process table
tvinit(); // trap vectors
binit(); // buffer cache
fileinit(); // file table
ideinit(); // disk
if(!ismp)
timerinit(); // uniprocessor timer
startothers(); // start other processors
kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
userinit(); // first user process
mpmain(); // finish this processor's setup
init_semaphores_on_boot();
}
示例3: print_trapframe
void
print_trapframe(struct Trapframe *tf)
{
cprintf("TRAP frame at %p from CPU %d\n", tf, cpunum());
print_regs(&tf->tf_regs);
cprintf(" es 0x----%04x\n", tf->tf_es);
cprintf(" ds 0x----%04x\n", tf->tf_ds);
cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
// If this trap was a page fault that just happened
// (so %cr2 is meaningful), print the faulting linear address.
if (tf == last_tf && tf->tf_trapno == T_PGFLT)
cprintf(" cr2 0x%08x\n", rcr2());
cprintf(" err 0x%08x", tf->tf_err);
// For page faults, print decoded fault error code:
// U/K=fault occurred in user/kernel mode
// W/R=a write/read caused the fault
// PR=a protection violation caused the fault (NP=page not present).
if (tf->tf_trapno == T_PGFLT)
cprintf(" [%s, %s, %s]\n",
tf->tf_err & 4 ? "user" : "kernel",
tf->tf_err & 2 ? "write" : "read",
tf->tf_err & 1 ? "protection" : "not-present");
else
cprintf("\n");
cprintf(" eip 0x%08x\n", tf->tf_eip);
cprintf(" cs 0x----%04x\n", tf->tf_cs);
cprintf(" flag 0x%08x\n", tf->tf_eflags);
if ((tf->tf_cs & 3) != 0) {
cprintf(" esp 0x%08x\n", tf->tf_esp);
cprintf(" ss 0x----%04x\n", tf->tf_ss);
}
}
示例4: bootothers
static void
bootothers(void)
{
extern uchar _binary_bootother_start[], _binary_bootother_size[];
uchar *code;
struct cpu *c;
char *stack;
// Write bootstrap code to unused memory at 0x7000.
code = (uchar*)0x7000;
memmove(code, _binary_bootother_start, (uint)_binary_bootother_size);
for(c = cpus; c < cpus+ncpu; c++){
if(c == cpus+cpunum()) // We've started already.
continue;
// Fill in %esp, %eip and start code on cpu.
stack = kalloc(KSTACKSIZE);
*(void**)(code-4) = stack + KSTACKSIZE;
*(void**)(code-8) = mpmain;
lapicstartap(c->id, (uint)code);
// Wait for cpu to get through bootstrap.
while(c->booted == 0)
;
}
}
示例5: mp_main
// Setup code for APs
void
mp_main(void)
{
// We are in high EIP now, safe to switch to kern_pgdir
lcr3(PADDR(kern_pgdir));
cprintf("SMP: CPU %d starting\n", cpunum());
lapic_init();
env_init_percpu();
trap_init_percpu();
xchg(&thiscpu->cpu_status, CPU_STARTED); // tell boot_aps() we're up
#ifdef USE_TICKET_SPIN_LOCK
spinlock_test();
#endif
// Now that we have finished some basic setup, call sched_yield()
// to start running processes on this CPU. But make sure that
// only one CPU can enter the scheduler at a time!
//
// Your code here:
lock_kernel();
sched_yield();
// Remove this after you finish Exercise 4
//for (;;);
}
示例6: mpmain
// Bootstrap processor gets here after setting up the hardware.
// Additional processors start here.
static void
mpmain(void)
{
if(cpunum() != mpbcpu())
lapicinit(cpunum());
ksegment();
cprintf("cpu%d: mpmain\n", cpu->id);
idtinit();
cpu->dir = kernel_dir;
enable_page(cpu->dir);
cprintf("-- mpmain -- cpu%d enable paging dir: %x \n", cpu->id, cpu->dir);
xchg(&cpu->booted, 1);
cprintf("cpu%d: scheduling\n", cpu->id);
scheduler();
}
示例7: seginit
// Set up CPU's kernel segment descriptors.
// Run once at boot time on each CPU.
void
seginit(void)
{
struct cpu *c;
// Map virtual addresses to linear addresses using identity map.
// 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[cpunum()];
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);
// Map cpu, and curproc
c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0);
lgdt(c->gdt, sizeof(c->gdt));
loadgs(SEG_KCPU << 3);
// Initialize cpu-local storage.
cpu = c;
proc = 0;
}
示例8: startothers
// Start the non-boot (AP) processors.
static void
startothers(void)
{
extern uchar _binary_entryother_start[], _binary_entryother_size[];
uchar *code;
struct cpu *c;
char *stack;
// Write entry code to unused memory at 0x7000.
// The linker has placed the image of entryother.S in
// _binary_entryother_start.
code = p2v(0x7000);
memmove(code, _binary_entryother_start, (uint)_binary_entryother_size);
for(c = cpus; c < cpus+ncpu; c++){
if(c == cpus+cpunum()) // We've started already.
continue;
// Tell entryother.S what stack to use, where to enter, and what
// pgdir to use. We cannot use kpgdir yet, because the AP processor
// is running in low memory, so we use entrypgdir for the APs too.
stack = kalloc();
*(void**)(code-4) = stack + KSTACKSIZE;
*(void**)(code-8) = mpenter;
*(int**)(code-12) = (void *) v2p(entrypgdir);
lapicstartap(c->id, v2p(code));
// wait for cpu to finish mpmain()
while(c->started == 0)
;
}
}
示例9: boot_aps
// Start the non-boot (AP) processors.
static void
boot_aps(void)
{
extern unsigned char mpentry_start[], mpentry_end[];
void *code;
struct CpuInfo *c;
// Write entry code to unused memory at MPENTRY_PADDR
code = KADDR(MPENTRY_PADDR);
memmove(code, mpentry_start, mpentry_end - mpentry_start);
// Boot each AP one at a time
for (c = cpus; c < cpus + ncpu; c++) {
if (c == cpus + cpunum()) // We've started already.
continue;
// Tell mpentry.S what stack to use
mpentry_kstack = percpu_kstacks[c - cpus] + KSTKSIZE;
// Start the CPU at mpentry_start
lapic_startap(c->cpu_id, PADDR(code));
// Wait for the CPU to finish some basic setup in mp_main()
while(c->cpu_status != CPU_STARTED)
;
}
}
示例10: mpenter
// Other CPUs jump here from entryother.S.
static void
mpenter(void)
{
switchkvm();
seginit();
lapicinit(cpunum());
mpmain();
}
示例11: mpmain
// Common CPU setup code.
static void
mpmain(void)
{
cprintf("cpu%d: starting\n", cpunum());
idtinit(); // load idt register
xchg(&cpu->started, 1); // tell startothers() we're up
scheduler(); // start running processes
}
示例12: sched_yield
// Choose a user environment to run and run it.
void
sched_yield(void)
{
struct Env *idle;
int i;
// Implement simple round-robin scheduling.
//
// Search through 'envs' for an ENV_RUNNABLE environment in
// circular fashion starting just after the env this CPU was
// last running. Switch to the first such environment found.
//
// If no envs are runnable, but the environment previously
// running on this CPU is still ENV_RUNNING, it's okay to
// choose that environment.
//
// Never choose an environment that's currently running on
// another CPU (env_status == ENV_RUNNING) and never choose an
// idle environment (env_type == ENV_TYPE_IDLE). If there are
// no runnable environments, simply drop through to the code
// below to switch to this CPU's idle environment.
// LAB 4: Your code here.
// For debugging and testing purposes, if there are no
// runnable environments other than the idle environments,
// drop into the kernel monitor.
for (i = 0; i < NENV; i++) {
if (envs[i].env_type != ENV_TYPE_IDLE &&
(envs[i].env_status == ENV_RUNNABLE ||
envs[i].env_status == ENV_RUNNING))
break;
}
if (i == NENV) {
cprintf("No more runnable environments!\n");
while (1)
monitor(NULL);
}
// Run this CPU's idle environment when nothing else is runnable.
idle = &envs[cpunum()];
if (!(idle->env_status == ENV_RUNNABLE || idle->env_status == ENV_RUNNING))
panic("CPU %d: No idle environment!", cpunum());
env_run(idle);
}
示例13: spinlock_test
void spinlock_test()
{
int i;
volatile int interval = 0;
/* BSP give APs some time to reach this point */
if (cpunum() == 0) {
while (interval++ < 10000)
asm volatile("pause");
}
for (i=0; i<100; i++) {
lock_kernel();
if (test_ctr % 10000 != 0)
panic("ticket spinlock test fail: I saw a middle value\n");
interval = 0;
while (interval++ < 10000)
test_ctr++;
unlock_kernel();
}
lock_kernel();
cprintf("spinlock_test() succeeded on CPU %d!\n", cpunum());
unlock_kernel();
}
示例14: ksegment
// Set up CPU's kernel segment descriptors.
// Run once at boot time on each CPU.
void
ksegment(void)
{
struct cpu *c;
c = &cpus[cpunum()];
c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0);
c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0);
lgdt(c->gdt, sizeof(c->gdt));
loadgs(SEG_KCPU << 3);
// Initialize cpu-local storage.
cpu = c;
proc = 0;
}
示例15: spin_unlock
// Release the lock.
void
spin_unlock(struct spinlock *lk)
{
#ifdef DEBUG_SPINLOCK
if (!holding(lk)) {
int i;
uint32_t pcs[10];
// Nab the acquiring EIP chain before it gets released
memmove(pcs, lk->pcs, sizeof pcs);
#ifdef bug_017
if(lk->cpu == 0)
{
cprintf("Total lock_cnt:%d\n",lock_cnt);
panic("here\n");
}
#endif
cprintf("CPU %d cannot release %s: held by CPU %d\nAcquired at:",
cpunum(), lk->name, lk->cpu->cpu_id);
for (i = 0; i < 10 && pcs[i]; i++) {
struct Eipdebuginfo info;
if (debuginfo_eip(pcs[i], &info) >= 0)
cprintf(" %08x %s:%d: %.*s+%x\n", pcs[i],
info.eip_file, info.eip_line,
info.eip_fn_namelen, info.eip_fn_name,
pcs[i] - info.eip_fn_addr);
else
cprintf(" %08x\n", pcs[i]);
}
panic("spin_unlock");
}
lk->pcs[0] = 0;
lk->cpu = 0;
#endif
// The xchg serializes, so that reads before release are
// not reordered after it. The 1996 PentiumPro manual (Volume 3,
// 7.2) says reads can be carried out speculatively and in
// any order, which implies we need to serialize here.
// But the 2007 Intel 64 Architecture Memory Ordering White
// Paper says that Intel 64 and IA-32 will not move a load
// after a store. So lock->locked = 0 would work here.
// The xchg being asm volatile ensures gcc emits it after
// the above assignments (and after the critical section).
xchg(&lk->locked, 0);
}