Esempio n. 1
0
// Acquire the lock.
// Loops (spins) until the lock is acquired.
// (Because contention is handled by spinning, must not
// go to sleep holding any locks.)
void
acquire(struct spinlock *lock)
{
  if(holding(lock))
    panic("acquire");

  if(cpus[cpu()].nlock == 0)
    cli();
  cpus[cpu()].nlock++;

  while(cmpxchg(0, 1, &lock->locked) == 1)
    ;

  // Serialize instructions: now that lock is acquired, make sure 
  // we wait for all pending writes from other processors.
  cpuid(0, 0, 0, 0, 0);  // memory barrier (see Ch 7, IA-32 manual vol 3)
  
  // Record info about lock acquisition for debugging.
  // The +10 is only so that we can tell the difference
  // between forgetting to initialize lock->cpu
  // and holding a lock on cpu 0.
  lock->cpu = cpu() + 10;
  getcallerpcs(&lock, lock->pcs);
}
Esempio n. 2
0
// Exit the current process.  Does not return.
// An exited process remains in the zombie state
// until its parent calls wait() to find out it exited.
void
exit(void)
{
    struct proc *p;
    int fd;
    int rmBrothers=0;

    if(!is_main_thread(proc)) {
        // Kill main thread
        proc->parent->killed=1;
        if(proc->parent->state==SLEEPING)
            proc->parent->state=RUNNABLE;
        //clear_thread(proc);
        rmBrothers=1;
        //return;
    }

    if(proc == initproc)
        panic("init exiting");

    cprintf("#");
    //release(&ptable.lock);
    if(!holding(&ptable.lock)) {
        cprintf("[ex%d]", proc->pid);
        acquire(&ptable.lock);
    }
    cprintf("%");

    // Pass abandoned proc children to init &
    // kill all threads beneath (children who are not procs)
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
        if(p->parent == proc) {
            if(is_main_thread(p) && rmBrothers==0) {
                p->parent = initproc;
                if(p->state == ZOMBIE)
                    wakeup1(initproc);
            } else {
                clear_thread(p);
            }
        }
    }

    if(rmBrothers)
        goto end;

    // Close all open files.
    for(fd = 0; fd < NOFILE; fd++) {
        if(proc->ofile[fd]) {
            fileclose(proc->ofile[fd]);
            proc->ofile[fd] = 0;
        }
    }

    iput(proc->cwd);
    proc->cwd = 0;

end:
    // Parent might be sleeping in wait().
    wakeup1(proc->parent);

    // Jump into the scheduler, never to return.
    proc->state = ZOMBIE;
    sched();
    panic("zombie exit");
}
Esempio n. 3
0
File: proc.c Progetto: Minjun-Li/xv6
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
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);

#ifndef __ORIGINAL_SCHED__
    p = pdequeue();
    if(p){
#else
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;
#endif

      // For debug, checking the scheduled process priority
      cprintf("cpu %d get process %s, process prio = %d\n",cpunum(),p->name,p->priority);

      // 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);
  }
}

// Enter scheduler.  Must hold only ptable.lock
// and have changed proc->state.
void
sched(void)
{
  int intena;

  if(!holding(&ptable.lock))
    panic("sched ptable.lock");
  if(cpu->ncli != 1)
    panic("sched locks");
  if(proc->state == RUNNING)
    panic("sched running");
  if(readeflags()&FL_IF)
    panic("sched interruptible");
  intena = cpu->intena;
  swtch(&proc->context, cpu->scheduler);
  cpu->intena = intena;
}