Ejemplo n.º 1
0
/*
  PROGRAM: Symposium
  This program executes a "symposium" for a number of philosophers, by spawning
  a process per philosopher.
 */
int Symposium(int argl, void* args)
{
    int bites;			/* Bites (mpoykies) per philosopher */
    Pid_t pid;
    int i;

    assert(argl == sizeof(int[2]));
    N = ((int*)args)[0];		/* get the arguments */
    bites = ((int*)args)[1];

    /* Initialize structures */
    state = (PHIL*) malloc(sizeof(PHIL)*N);
    hungry = (CondVar*) malloc(sizeof(CondVar)*N);
    for(i=0; i<N; i++) {
        state[i] = NOTHERE;
        Cond_Init(&(hungry[i]));
    }

    /* Execute philosophers */
    for(i=0; i<N; i++) {
        int Arg[2];
        Arg[0] = i;
        Arg[1] = bites;
        pid = Exec(Philosopher, sizeof(Arg), Arg);
    }

    /* Wait for philosophers to exit */
    for(i=0; i<N; i++) {
        pid = WaitChild(NOPROC, NULL);
    }
    free(state);
    free(hungry);
    return 0;
}
Ejemplo n.º 2
0
int boot_task(int argl, void* args)
{
    /* Just start task Symposium */
    Exec(Symposium, argl, args);

    while( WaitChild(NOPROC, NULL)!=NOPROC ); /* Wait for all children */

    return 0;
}
Ejemplo n.º 3
0
/*
 * This is the initial task, which starts all the other tasks (except for the idle task). 
 */
int boot_task(int argl, void* args)
{
  int i,ntasks,ncalls;
  int status;
  long msg;
  Message m;
  Pid_t pid;
  Pid_t printer;
  Pid_t* pids;
  
  ntasks = ((int*)args)[0];
  ncalls = ((int*)args)[1];

  pids = malloc(sizeof(Pid_t)*ntasks);
  
  /* Launch child processes */
  printer = Exec(printer_task,0,NULL);
  ReceivePort(&msg,1);		/* Wait until it is ready to print */

  for(i=0; i<ntasks; i++) {
    pids[i] = pid = Exec(fibodriver_task,sizeof(ncalls),&ncalls);
    printf("boot_task: executed fibodriver %d   pid=%d\n",i+1,pid);
  }

  /* Wait for child processes */
  for(i=0;i<ntasks;i++) {
    Pid_t pid = WaitChild(NOPROC, &status);
    printf("boot_task: Process %d exited with exit value %d.\n",pid,status);
  }
 
  /* Tell printer to exit */
  m.type = PRINTER_QUIT;
  m.data = NULL;
  m.len = 0;
  SendMail("printer",&m);
  
  /* Loop until all children have exited  */
  while(WaitChild(NOPROC,NULL) != NOPROC)
    printf("boot_task: child exited.\n");

  printf("boot_task: exiting!\n");

  return 0;
}
Ejemplo n.º 4
0
/*
  PROGRAM: fibodriver_task

  This program creates a fibo_task child and then sends to it a number of values to
  process.
*/
int fibodriver_task(int argl, void* args)
{
  int work;
  Pid_t child;

  assert(argl == sizeof(int));
  work = *((int*)args) ;

  child = Exec(fibo_task, 0, NULL);
  while(work>0) {
    SendPort(child, fiborand());
    work --;
  }
  SendPort(child, -1);
  
  WaitChild(child,NULL);
  return 0;
}
Ejemplo n.º 5
0
// Run the command specified by the argv array and kill it after timeout
// seconds.
static void SpawnCommand(char *const *argv, double timeout_secs) {
  CHECK_CALL(global_child_pid = fork());
  if (global_child_pid == 0) {
    // In child.
    CHECK_CALL(setsid());
    ClearSignalMask();

    // Force umask to include read and execute for everyone, to make
    // output permissions predictable.
    umask(022);

    // Does not return unless something went wrong.
    execvp(argv[0], argv);
    err(EXIT_FAILURE, "execvp(\"%s\", ...)", argv[0]);
  } else {
    // In parent.

    // Set up a signal handler which kills all subprocesses when the given
    // signal is triggered.
    HandleSignal(SIGALRM, OnSignal);
    HandleSignal(SIGTERM, OnSignal);
    HandleSignal(SIGINT, OnSignal);
    SetTimeout(timeout_secs);

    int status = WaitChild(global_child_pid, argv[0]);

    // The child is done for, but may have grandchildren that we still have to
    // kill.
    kill(-global_child_pid, SIGKILL);

    if (global_signal > 0) {
      // Don't trust the exit code if we got a timeout or signal.
      UnHandle(global_signal);
      raise(global_signal);
    } else if (WIFEXITED(status)) {
      exit(WEXITSTATUS(status));
    } else {
      int sig = WTERMSIG(status);
      UnHandle(sig);
      raise(sig);
    }
  }
}
Ejemplo n.º 6
0
// Usage: process-wrapper
//            <timeout_sec> <kill_delay_sec> <stdout file> <stderr file>
//            [cmdline]
int main(int argc, char *argv[]) {
  if (argc <= 5) {
    DIE("Not enough cmd line arguments to process-wrapper");
  }

  // Parse the cmdline args to get the timeout and redirect files.
  argv++;
  double timeout;
  if (sscanf(*argv++, "%lf", &timeout) != 1) {
    DIE("timeout_sec is not a real number.");
  }
  if (sscanf(*argv++, "%lf", &global_kill_delay) != 1) {
    DIE("kill_delay_sec is not a real number.");
  }
  char *stdout_path = *argv++;
  char *stderr_path = *argv++;

  if (strcmp(stdout_path, "-")) {
    // Redirect stdout and stderr.
    int fd_out = open(stdout_path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
    if (fd_out == -1) {
      DIE("Could not open %s for stdout", stdout_path);
    }
    if (dup2(fd_out, STDOUT_FILENO) == -1) {
      DIE("dup2 failed for stdout");
    }
    CHECK_CALL(close(fd_out));
  }

  if (strcmp(stderr_path, "-")) {
    int fd_err = open(stderr_path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
    if (fd_err == -1) {
      DIE("Could not open %s for stderr", stderr_path);
    }
    if (dup2(fd_err, STDERR_FILENO) == -1) {
      DIE("dup2 failed for stderr");
    }
    CHECK_CALL(close(fd_err));
  }

  global_pid = fork();
  if (global_pid < 0) {
    DIE("Fork failed");
  } else if (global_pid == 0) {
    // In child.
    if (setsid() == -1) {
      DIE("Could not setsid from child");
    }
    ClearSignalMask();
    // Force umask to include read and execute for everyone, to make
    // output permissions predictable.
    umask(022);

    execvp(argv[0], argv);  // Does not return.
    DIE("execvpe %s failed", argv[0]);
  } else {
    // In parent.
    InstallSignalHandler(SIGALRM);
    InstallSignalHandler(SIGTERM);
    InstallSignalHandler(SIGINT);
    EnableAlarm(timeout);

    int status = WaitChild(global_pid, argv[0]);

    // The child is done, but may have grandchildren.
    kill(-global_pid, SIGKILL);
    if (global_signal > 0) {
      // Don't trust the exit code if we got a timeout or signal.
      UnHandle(global_signal);
      raise(global_signal);
    } else if (WIFEXITED(status)) {
      exit(WEXITSTATUS(status));
    } else {
      int sig = WTERMSIG(status);
      UnHandle(sig);
      raise(sig);
    }
  }
}