Пример #1
0
static void ps_print_level(int level, proc_p p) {
  /* pid ppid envid pgrp session   xstat stat flag nxch */
#define MAXLEVEL 4
  int i;
  int epilogue_count, yield_count;
#if 0
  char state[] = "XIRSHZ";
#endif
  if (level == -1) {
    printf("PID ");
    for (i = 0; i < MAXLEVEL; i++) printf("  ");

#if 0    
    printf("PPID  PG SES "); 
    printf("sta xst flag  nx ");
    printf("ticks ctxcnt eip      name\n");
#else
    printf ("    TICKS\tCTXCNT\tEIP\t\tNAME\t\tEID\n\n");
#endif
    return;
  }
  if (level > MAXLEVEL) level = MAXLEVEL;
  for (i = 0; i < level; i++) printf("  ");

  if (p == NULL) {printf(" null proc entry\n");return;}

  printf("%-3d",p->p_pid);
  for (i = level; i <= MAXLEVEL; i++) printf("  ");
#if 0
  printf("%3d ",(p->p_pptr) ? p->p_pptr->p_pid : -1);
  printf("%3d ",(p->p_pgrp) ? p->p_pgrp->pg_id : -1);
  printf("%3d ",(p->p_session->s_leader) ? p->p_session->s_leader->p_pid : -1);
  printf("%c %3d %4s %3d ",
	   state[p->p_stat], p->p_xstat, ps_get_flags(p->p_flag), p->nxchildren);
#endif
  epilogue_count = 0;
  yield_count = 0;
  get_counts(p->envid, &epilogue_count, &yield_count);
  printf("\t%5d\t%6d\t%08x\t%.10s",
	 __envs[envidx(p->envid)].env_ticks,
	 __envs[envidx(p->envid)].env_ctxcnt, /*  epilogue_count, */
	 (p->envid == __envid || p->p_stat == SZOMB) ? 0 : get_eip(p->envid),
	 ps_get_comm(p->envid,1));
  if (strlen (ps_get_comm (p->envid,1)) < 8)
    printf ("\t\t");
  else
    printf ("\t");
  printf ("%d\n", p->envid);
  for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
    ps_print_level(level+1,p);
  }

}
Пример #2
0
static unsigned int get_eip (u_int envid) {
  unsigned int esp;
  unsigned int eip = 0;

  struct Env *e = (struct Env *)&__envs[envidx (envid)];
  esp = e->env_tf.tf_esp + 44;

  /* check if pid is saving its fpu state */ 
  { 
    struct Uenv cu;
    int ret;
    if ((ret = sys_rdu(CAP_ROOT,e->env_id,&cu)) >= 0) {
      if (cu.u_fpu) esp += FPU_SAVE_SZ; 
    }
    /* if this fails, read_write_memory will fail too. */
  }
  eip = read_write_memory (PT_READ_D, envid, esp, 0);

  return (eip);
}
Пример #3
0
void 
ae_eth_init()
{
    int i,fid;
    extern void print_physical(int page);

    if (envidx(__envid) == 1) {
      AllocAshShareRegion();
      ASN.nfree = 0;
      for (i = 0; i < NENTRY; i++) {
	ASN.ae_packets[i].recv.r[0].data = &asn.ash_pkt_data[i * MAXPKT];
	ASN.ae_packets[i].recv.r[0].sz = MAXPKT;
	ASN.ae_packets[i].recv.n = 1;
	ASN.nfree++;
	ae_ash_append_pkt(&asn.ash_alloc_pkt, &ASN.ae_packets[i]);
      }
      for (fid = 0; fid < DPF_MAXFILT; fid++) {
	FID_HEAD_QUEUE = 0;
	FID_TAIL_QUEUE = 0;
      }
    }
}
Пример #4
0
/* everything is based on this exec, we have an extra flag
   (_EXEC_EXECONLY) to differentiate between the exec and fork_exec
   families.  the difference is that the latter forks and then execs
   the process thereby returning in the parent
   */
static int
fork_execve0(const char *path, char *const argv[], char * const envptr[],
	     int fd, u_int flags)
{
  u_int k = 0;
  int target_cpu = 0;
  struct Uenv cu;
  int NewPid = 0;
  int envid = 0; /* XXX -- init to supress warning */
  char **old_argv = (char **)argv;
  int r, exec_format;
  struct Env e;

  OSCALLENTER(OSCALL_execve);
  /* verify executable permission */
  if (!(flags & _EXEC_USE_FD) && access(path, X_OK) == -1) {
    /* access will set errno */
    r = -errno;
    goto err;
  }

  if (!(envid = sys_env_alloc (0, &r))) {
    fprintf(stderr,"could not sys_env_alloc\n");
    r = -ENOEXEC;
    goto err;
  }

  e = __envs[envidx(envid)];
  if ((exec_format = fork_execve0_part2(path, argv, envptr, &e, fd, flags)) < 0)
    goto err_env_free;

  /* write environment */
  if ((r = sys_wrenv (k, envid, &e)) < 0) {
    kprintf ("sys_wrenv failed\n");
    r = -ENOEXEC;
    goto err;
  }

  if (ExecuteOnExecHandlers(k, envid, flags & _EXEC_EXECONLY) == -1) {
    fprintf(stderr,"cleanup code not done yet\n");
    assert(-1);
  }

#ifdef PROCESS_TABLE
  if (flags & _EXEC_EXECONLY) {
    /* because true exec */
    NewPid = getpid();
  
    dlockputs(__PROCD_LD,"fork_execve0 get lock ");
    EXOS_LOCK(PROCINFO_LOCK);
    dlockputs(__PROCD_LD,"... got lock\n");
    EnterCritical (); 

    ProcChangeEnv(NewPid,envid);
    
    EXOS_UNLOCK(PROCINFO_LOCK);
    dlockputs(__PROCD_LD,"fork_execve0 release lock\n");
    ExitCritical (); 

  } else {
    /* because we are forking */
    NewPid = AllocateFreePid (envid);
  }

  cu = UAREA;
  if (!execonly) {
    AddProcEntry (&cu, (char *)path, (char **)argv, NewPid, UAREA.pid);
    if ((cu.parent_slot = GetChildSlot (NewPid)) < 0) {
      r = -ENOEXEC;
      goto err_env_free;
    }
  } else {
    /* TO TOM: what do we do this for?
    strncpy (UAREA.name, (char*)(((u_int)argv[0]) + ARGV_START_LOCAL - ARGV_START),
	     U_NAMEMAX-1);
    UAREA.name[U_NAMEMAX-1] = '\0'; */
  }
  /* XXX -- on an exec we'll forget to unref our children's pids */
  /* TO TOM: shouldnt this clearchildinfo be at the top */
  ClearChildInfo (&cu);
#else
#ifdef PROCD
  if (flags & _EXEC_EXECONLY) 
  {
    NewPid = getpid();
    /* only register us if we are of the right format */ 
    if (exec_format == EXEC_EXOS_AOUT)
      proc_exec(envid);
  } else {
    NewPid = proc_fork(envid);
  }
  cu = UAREA;
  //kprintf("NewPid %d envid: %d %s proc_%s: (%d) -> %d\n",
	    //NewPid,__envid,execonly ? "exec" : "fork",path,envid,NewPid);
#else
  NewPid = envid;
#endif /* PROCD */
#endif /* PROCESS_TABLE */

  strncpy (cu.name, path, U_NAMEMAX-1);
  cu.name[U_NAMEMAX-1] = '\0';
  cu.u_fpu = 0;
  cu.u_in_critical = 0;
  cu.u_status = U_RUN;
  cu.u_entprologue = e.env_tf.tf_eip;
  cu.u_entepilogue = e.env_tf.tf_eip;
  cu.u_entfault = 0;
  cu.u_entipc1 = 0;
  cu.u_entipc2 = 0;
  cu.u_ppc = 0;
#ifdef PROCESS_TABLE
  cu.u_chld_state_chng = 0;
#endif /* PROCESS_TABLE */
  cu.u_next_timeout = 0;
  cu.u_in_pfault = 0;
  cu.u_donate = -1;
  cu.u_yield_count = 0;
  cu.u_epilogue_count = 0;
  cu.u_epilogue_abort_count = 0;

  STOPP(misc,step7);
  ISTART(misc,step8);

  cu.u_start_kern_call_counting = 0;

  if ((r = sys_wru (0, envid, &cu)) < 0) {
    fprintf (stderr,"sys_wru failed\n");
    r = -ENOEXEC;
    goto err_env_free;
  }

  target_cpu = 0;

#ifdef __SMP__
  if (strncmp(path,"_cpu",4)==0 && strlen(path)>4) 
  {
    target_cpu = path[4]-'0';
    if (target_cpu<0 || target_cpu>sys_get_num_cpus()-1) 
      target_cpu = 0;
  }
#endif

  /* we can't do this until all the child state is setup */
  if ((r = sys_quantum_alloc (k, -1, target_cpu, envid)) < 0) {
    fprintf (stderr,"could not alloc quantum\n");
    r = -ENOEXEC;
    goto err_env_free;
  }

  /* if we're doing a true unix exec and not a combined fork/spawn
     we need to destroy ourselves since our child should have
     replaced us. */

  if (flags & _EXEC_EXECONLY) 
  {
    /* if not an exos format, should not expect normal child behaviors, so we
     * just quit from procd to avoid any hanging...
     */
    if (exec_format == EXEC_SIMPLE)
      proc_exit(0);

    /* we die anyways, so free quantum and env */
    ProcessFreeQuanta(__envid);
    sys_env_free (0, __envid);
  }

  if (old_argv != argv) __free((char**)argv);
  OSCALLEXIT(OSCALL_execve);
  return (NewPid);

err_env_free:
  ProcessFreeQuanta(__envid);
  sys_env_free (k, envid);

err:
  if (old_argv != argv) __free((char**)argv);
  errno = -r;
  OSCALLEXIT(OSCALL_execve);
  return -1;
}
Пример #5
0
/* could implement tsleep in terms of following tsleep_pred */
int tsleep (void *chan, int pri, char *wmesg, int ticks) {
#define PREDSZ 32
  struct wk_term t[PREDSZ];
  int sz = 0;
  int sig = 0;
  int catch = pri & PCATCH;
  void **wchan;
  int ret, i, CriticalLevels;
  unsigned long long dest_ticks = ticks;
retry:
  sz = 0;
  d0printf("%d tsleep chan: %p, catch: %d, ticks: %d (lbolt? %d)\n",
	  getpid(),chan, catch ?1:0, ticks, chan == &lbolt);

  global_ftable->counter0++;
  if (chan == &lbolt)   global_ftable->counter2++;

  wchan = &synch_table->wchan[envidx(__envid)];
  *wchan = chan;

  /* for timeout */
  if (dest_ticks) {
    dest_ticks += __sysinfo.si_system_ticks; 
    sz += wk_mksleep_pred(t, dest_ticks); /* t is fine since it is first */
    sz = wk_mkop(sz, t, WK_OR);
  }
  /* for channel */
  if (chan != &lbolt) {
    sz = wk_mkvar (sz, t, wk_phys (wchan), 0);
    sz = wk_mkimm (sz, t, 0);
    sz = wk_mkop (sz, t, WK_EQ);
  } else {
    /* sleep for 0.5 seconds */
    sz += wk_mksleep_pred(&t[sz],(500000/__sysinfo.si_rate) +
			  __sysinfo.si_system_ticks);
  }
  /* for signals */
  if (catch) {
    //kprintf("%d tsleep interruptible (sigready? %d)\n",getpid(),__issigready());

    if ((sig = __issigready())) goto resume;
    sz = wk_mkop(sz, t, WK_OR);
    sz += wk_mksig_pred(&t[sz]);
  }

  assert(sz <= PREDSZ);
  /* make sure when sleeping on lbolt => no ticks */
  assert(!(chan == &lbolt && dest_ticks != 0)); 

  /* Leave and then Enter Critical Region */
  i = CriticalLevels = CriticalNesting();  assert(i >= 0);
  while (i-- > 0) ExitCritical(); assert(CriticalNesting() == 0);
  
  wk_waitfor_pred (t, sz);

  i = 0; while (i++ < CriticalLevels) EnterCritical();
  assert(CriticalLevels == CriticalNesting());

resume:
  ret = 0;
  if (catch && (sig != 0 || (sig = __issigready()))) {
    /* there is a signal ready */
    //kprintf("%d tsleep interrupted by a signal: %d (%s)\n",getpid(),sig,sys_signame[sig]);
    if (__issigstopping(sig)) {
      __signal_stop_process(sig);
      goto retry;
    }
    if (__issigrestart(sig)) ret = ERESTART;
    else ret = EINTR;
    goto done;
  }
  if (chan != &lbolt && dest_ticks && __sysinfo.si_system_ticks > dest_ticks) {
    ret = EWOULDBLOCK;
  }
done:
  d0printf("%d tsleep ret: %d chan: %p, catch: %d, dest_ticks: %qu (lbolt? %d) -> %d\n",
	  getpid(),ret,chan, catch ?1:0, dest_ticks, chan == &lbolt, ret);
  /* clear waiting channel */
  *wchan = 0;
  return ret;
}