proc.c
static struct proc*
allocproc(void)
{
  struct proc *p;
  char *sp;

  acquire(&ptable.lock);

  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
    if(p->state == UNUSED)
      goto found;

  release(&ptable.lock);
  return 0;

found:
  p->state = EMBRYO;
  p->pid = nextpid++;
  p->priority = 2;

  release(&ptable.lock);

  // Allocate kernel stack.
  if((p->kstack = kalloc()) == 0){
    p->state = UNUSED;
    return 0;
  }
  sp = p->kstack + KSTACKSIZE;

  // Leave room for trap frame.
  sp -= sizeof *p->tf;
  p->tf = (struct trapframe*)sp;

  // Set up new context to start executing at forkret,
  // which returns to trapret.
  sp -= 4;
  *(uint*)sp = (uint)trapret;

  sp -= sizeof *p->context;
  p->context = (struct context*)sp;
  memset(p->context, 0, sizeof *p->context);
  p->context->eip = (uint)forkret;

  p->ctime = ticks;

  return p;
}
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
// state required to run in the kernel.
// Otherwise return 0.
32
Look in the process table for an UNUSED proc.
If found, change state to EMBRYO and initialize
state required to run in the kernel.
Otherwise return 0.
32 Look in the process table for an UNUSED proc . If found change state to EMBRYO and initialize state required to run in the kernel . Otherwise return 0 .
static struct proc*
allocproc(void)
{
  struct proc *p;
  char *sp;
  acquire(&ptable.lock);
  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
    if(p->state == UNUSED)
      goto found;
  release(&ptable.lock);
  return 0;
found:
  p->state = EMBRYO;
  p->pid = nextpid++;
  p->priority = 2;
  release(&ptable.lock);
  if((p->kstack = kalloc()) == 0){
    p->state = UNUSED;
    return 0;
  }
  sp = p->kstack + KSTACKSIZE;
  sp -= sizeof *p->tf;
  p->tf = (struct trapframe*)sp;
  sp -= 4;
  *(uint*)sp = (uint)trapret;
  sp -= sizeof *p->context;
  p->context = (struct context*)sp;
  memset(p->context, 0, sizeof *p->context);
  p->context->eip = (uint)forkret;
  p->ctime = ticks;
  return p;
}
static struct proc * allocproc ( void ) { struct proc * p ; char * sp ; acquire ( & ptable . lock ) ; for ( p = ptable . proc ; p < & ptable . proc [ NPROC ] ; p ++ ) if ( p -> state == UNUSED ) goto found ; release ( & ptable . lock ) ; return 0 ; found : p -> state = EMBRYO ; p -> pid = nextpid ++ ; p -> priority = 2 ; release ( & ptable . lock ) ; if ( ( p -> kstack = kalloc ( ) ) == 0 ) { p -> state = UNUSED ; return 0 ; } sp = p -> kstack + KSTACKSIZE ; sp -= sizeof * p -> tf ; p -> tf = ( struct trapframe * ) sp ; sp -= 4 ; * ( uint * ) sp = ( uint ) trapret ; sp -= sizeof * p -> context ; p -> context = ( struct context * ) sp ; memset ( p -> context , 0 , sizeof * p -> context ) ; p -> context -> eip = ( uint ) forkret ; p -> ctime = ticks ; return p ; }
PAGEBREAK: 32
Look in the process table for an UNUSED proc.
PAGEBREAK : 32 Look in the process table for an UNUSED proc .
// Allocate kernel stack. // Leave room for trap frame. // Set up new context to start executing at forkret, // which returns to trapret.