Exemplo n.º 1
0
static void cleanup() {
    debug("Cleaning up...");
    process_cleanup();
    comm_cleanup();
    protocol_cleanup();
    injectable_cleanup();
    debug("Cleanup complete.");
}
Exemplo n.º 2
0
/*
 * Tears down the process, removing it from the pid table.
 * Frees ALL associated memory and structures.
 */
void
process_destroy(pid_t pid)
{
    rw_wlock(pidt_rw);
    struct process *p = pid_table[pid];
    
    KASSERT(p->ps_thread == NULL);
    
    pid_table[pid] = NULL;
    rw_wdone(pidt_rw);
    
    // orphan all children if not already done in process_finish()
    // (this is important because kill_curthread() calls
    // process_destroy() on a process that has not properly exited.)
    if (!pid_set_empty(p->ps_children)) {
        int x = splhigh();
        pid_set_map(p->ps_children, process_orphan);
        splx(x);
    }
    
    process_cleanup(p);
}
Exemplo n.º 3
0
Arquivo: runner.c Projeto: Isszul/node
int run_test(const char* test,
             int timeout,
             int benchmark_output,
             int test_count) {
  char errmsg[1024] = "no error";
  process_info_t processes[1024];
  process_info_t *main_proc;
  task_entry_t* task;
  int process_count;
  int result;
  int status;
  int i;

  status = 255;
  main_proc = NULL;
  process_count = 0;

#ifndef _WIN32
  /* Clean up stale socket from previous run. */
  remove(TEST_PIPENAME);
#endif

  /* If it's a helper the user asks for, start it directly. */
  for (task = TASKS; task->main; task++) {
    if (task->is_helper && strcmp(test, task->process_name) == 0) {
      return task->main();
    }
  }

  /* Start the helpers first. */
  for (task = TASKS; task->main; task++) {
    if (strcmp(test, task->task_name) != 0) {
      continue;
    }

    /* Skip the test itself. */
    if (!task->is_helper) {
      continue;
    }

    if (process_start(task->task_name,
                      task->process_name,
                      &processes[process_count],
                      1 /* is_helper */) == -1) {
      snprintf(errmsg,
               sizeof errmsg,
               "Process `%s` failed to start.",
               task->process_name);
      goto out;
    }

    process_count++;
  }

  /* Give the helpers time to settle. Race-y, fix this. */
  uv_sleep(250);

  /* Now start the test itself. */
  for (task = TASKS; task->main; task++) {
    if (strcmp(test, task->task_name) != 0) {
      continue;
    }

    if (task->is_helper) {
      continue;
    }

    if (process_start(task->task_name,
                      task->process_name,
                      &processes[process_count],
                      0 /* !is_helper */) == -1) {
      snprintf(errmsg,
               sizeof errmsg,
               "Process `%s` failed to start.",
               task->process_name);
      goto out;
    }

    main_proc = &processes[process_count];
    process_count++;
    break;
  }

  if (main_proc == NULL) {
    snprintf(errmsg,
             sizeof errmsg,
             "No test with that name: %s",
             test);
    goto out;
  }

  result = process_wait(main_proc, 1, timeout);
  if (result == -1) {
    FATAL("process_wait failed");
  } else if (result == -2) {
    /* Don't have to clean up the process, process_wait() has killed it. */
    snprintf(errmsg,
             sizeof errmsg,
             "timeout");
    goto out;
  }

  status = process_reap(main_proc);
  if (status != 0) {
    snprintf(errmsg,
             sizeof errmsg,
             "exit code %d",
             status);
    goto out;
  }

  if (benchmark_output) {
    /* Give the helpers time to clean up their act. */
    uv_sleep(1000);
  }

out:
  /* Reap running processes except the main process, it's already dead. */
  for (i = 0; i < process_count - 1; i++) {
    process_terminate(&processes[i]);
  }

  if (process_count > 0 &&
      process_wait(processes, process_count - 1, -1) < 0) {
    FATAL("process_wait failed");
  }

  /* Show error and output from processes if the test failed. */
  if (status != 0 || task->show_output) {
    if (tap_output) {
      LOGF("not ok %d - %s\n#", test_count, test);
    } else if (status != 0) {
      LOGF("\n`%s` failed: %s\n", test, errmsg);
    } else {
      LOGF("\n");
    }

    for (i = 0; i < process_count; i++) {
      switch (process_output_size(&processes[i])) {
       case -1:
        LOGF("Output from process `%s`: (unavailable)\n",
             process_get_name(&processes[i]));
        break;

       case 0:
        LOGF("Output from process `%s`: (no output)\n",
             process_get_name(&processes[i]));
        break;

       default:
        LOGF("Output from process `%s`:\n", process_get_name(&processes[i]));
        process_copy_output(&processes[i], fileno(stderr));
        break;
      }
    }

    if (!tap_output) {
      LOG("=============================================================\n");
    }

  /* In benchmark mode show concise output from the main process. */
  } else if (benchmark_output) {
    switch (process_output_size(main_proc)) {
     case -1:
      LOGF("%s: (unavailable)\n", test);
      break;

     case 0:
      LOGF("%s: (no output)\n", test);
      break;

     default:
      for (i = 0; i < process_count; i++) {
        process_copy_output(&processes[i], fileno(stderr));
      }
      break;
    }
  } else if (tap_output) {
    LOGF("ok %d - %s\n", test_count, test);
  }

  /* Clean up all process handles. */
  for (i = 0; i < process_count; i++) {
    process_cleanup(&processes[i]);
  }

  return status;
}
Exemplo n.º 4
0
/*
 * Load program and start running it in usermode
 * in a new thread.
 * This is essentially an amalgam of fork() and execv().
 */
int
runprogram(int nargs, char **args, struct process **created_proc)
{
    if (nargs > ARGNUM_MAX)
        return E2BIG;
    
	struct vnode *v;
	int result;
    struct process *proc;
    
    // copy the string, since vfs_open() will modify it
    char *progname = kstrdup(args[0]);
    if (progname == NULL)
        return ENOMEM;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
    
    // We no longer need the duplicate program name
    kfree(progname);

    // set up new process structure
    proc = process_create(args[0]);
    if (proc == NULL)
    {
        vfs_close(v);
        return ENOMEM;
    }
    
    // Get a PID for the process.  ENPROC is
    // the error code for "no more processes allowed
    // in the system."
    pid_t pid = process_identify(proc);
    if (pid == 0)
    {
        process_cleanup(proc);
        vfs_close(v);
        return ENPROC;
    }
    
    // Create a new file descriptor table
    proc->ps_fdt = fdt_create();
    if (proc->ps_fdt == NULL)
    {
        process_destroy(pid);
        vfs_close(v);
        return ENOMEM;
    }
    
    // Open FDs for stdin, stdout, and stderr
    result = setup_inouterr(proc->ps_fdt);
    if (result)
    {
        process_destroy(pid);
        vfs_close(v);
        return result;
    }
    
	// Create a new address space
	proc->ps_addrspace = as_create();
	if (proc->ps_addrspace==NULL) {
        process_destroy(pid);
		vfs_close(v);
		return ENOMEM;
	}
    
    struct new_process_context *ctxt = kmalloc(sizeof(struct new_process_context));
    if (ctxt == NULL)
    {
        as_activate(NULL);
        process_destroy(pid);
        return ENOMEM;
    }
    ctxt->nargs = nargs;
    ctxt->args = args;
    ctxt->proc = proc;
    ctxt->executable = v;

	// Start a new thread to warp to user mode
    result = thread_fork("user process",
                         run_process,
                         ctxt, 0, NULL);
    if (result)
    {
        kfree(ctxt);
        as_activate(NULL);
        process_destroy(pid);
        return result;
    }
    
    // pass process to caller and return
    *created_proc = proc;
	return 0;
}
Exemplo n.º 5
0
Arquivo: runner.c Projeto: BrettQ/node
/*
 * Runs all processes associated with a particular test or benchmark.
 * It returns 1 if the test succeeded, 0 if it failed.
 * If the test fails it prints diagnostic information.
 * If benchmark_output is nonzero, the output from the main process is
 * always shown.
 */
int run_task(task_entry_t *test, int timeout, int benchmark_output) {
  int i, result, success;
  char errmsg[256];
  task_entry_t *helper;
  int process_count;
  process_info_t processes[MAX_PROCESSES];
  process_info_t *main_process;

  success = 0;

  process_count = 0;

  /* Start all helpers for this test first. */
  for (helper = (task_entry_t*)&TASKS; helper->main; helper++) {
    if (helper->is_helper &&
        strcmp(test->task_name, helper->task_name) == 0) {
      if (process_start(helper->process_name, &processes[process_count]) == -1) {
        snprintf((char*)&errmsg,
                 sizeof(errmsg),
                 "process `%s` failed to start.",
                 helper->process_name);
        goto finalize;
      }
      process_count++;
    }
  }

  /* Wait a little bit to allow servers to start. Racy. */
  uv_sleep(50);

  /* Start the main test process. */
  if (process_start(test->process_name, &processes[process_count]) == -1) {
    snprintf((char*)&errmsg, sizeof(errmsg), "process `%s` failed to start.",
        test->process_name);
    goto finalize;
  }
  main_process = &processes[process_count];
  process_count++;

  /* Wait for the main process to terminate. */
  result = process_wait(main_process, 1, timeout);
  if (result == -1) {
    FATAL("process_wait failed");
  } else if (result == -2) {
    snprintf((char*)&errmsg, sizeof(errmsg), "timeout.");
    goto finalize;
  }

  /* Reap the main process. */
  result = process_reap(main_process);
  if (result != 0) {
    snprintf((char*)&errmsg, sizeof(errmsg), "exit code %d.", result);
    goto finalize;
  }

  /* Yes! did it. */
  success = 1;

finalize:
  /* Kill all (helper) processes that are still running. */
  for (i = 0; i < process_count; i++) {
    /* If terminate fails the process is probably already closed. */
    process_terminate(&processes[i]);
  }

  /* Wait until all processes have really terminated. */
  if (process_wait((process_info_t*)&processes, process_count, -1) < 0) {
    FATAL("process_wait failed");
  }

  /* Show error and output from processes if the test failed. */
  if (!success) {
    LOGF("\n`%s` failed: %s\n", test->task_name, errmsg);

    for (i = 0; i < process_count; i++) {
      switch (process_output_size(&processes[i])) {
       case -1:
        LOGF("Output from process `%s`: (unavailable)\n",
             process_get_name(&processes[i]));
        break;

       case 0:
        LOGF("Output from process `%s`: (no output)\n",
             process_get_name(&processes[i]));
        break;

       default:
        LOGF("Output from process `%s`:\n", process_get_name(&processes[i]));
        process_copy_output(&processes[i], fileno(stderr));
        break;
      }
    }
    LOG("=============================================================\n");

  /* In benchmark mode show concise output from the main process. */
  } else if (benchmark_output) {
    switch (process_output_size(main_process)) {
     case -1:
      LOGF("%s: (unavailabe)\n", test->task_name);
      break;

     case 0:
      LOGF("%s: (no output)\n", test->task_name);
      break;

     default:
      //LOGF("%s: ", test->task_name);
      process_copy_output(main_process, fileno(stderr));
      break;
    }
  }

  /* Clean up all process handles. */
  for (i = 0; i < process_count; i++) {
    process_cleanup(&processes[i]);
  }

  return success;
}
Exemplo n.º 6
0
int main(int argc, char *argv[])
{
	const char client_name[] = "SteelSeries Sound Illuminator";
	const char *client_name_real;
	jack_status_t status;
	J2STL j2stl;
	int ret;

	/* Memory initialization */
	memset(&j2stl, 0, sizeof(j2stl));
	pthread_mutex_init(&j2stl.memsync.mutex, NULL);
	pthread_cond_init(&j2stl.memsync.cond, NULL);
	j2stl.status.progname = basename(argv[0]);

	/* Options parsing */
	opt_parse(argc, argv, &j2stl.status);
	if (j2stl.status.verbose)
		opt_dump(&j2stl.status);


	/* Stlseries init */
	if (stlseries_open(&j2stl.kbd.stlseries)) {
		fprintf(stderr, "Unable to open steelseries keyboard.\n");
		exit(EXIT_FAILURE);
	}

	/* Jack init */
	j2stl.jack.client = jack_client_open(client_name, JackNoStartServer,
					   &status, NULL);
	if (j2stl.jack.client == NULL) {
		fprintf(stderr, "Unable to create jack client, status = "
				"0x%2.0x<\n", status);
		if (status & JackServerFailed)
			fprintf(stderr, "Unable to establish a connection to "
					"the server\n");
		exit(EXIT_FAILURE);
	}
	if (status & JackNameNotUnique) {
		client_name_real = jack_get_client_name(j2stl.jack.client);
		fprintf(stderr, "Name assigned to the client: %s\n",
			client_name_real);
	} else {
		client_name_real = client_name;
		if (j2stl.status.verbose)
			fprintf(stderr, "Jack client name: %s\n",
				client_name_real);
	}

	/* Set jack callbacks */
	jack_set_process_callback(j2stl.jack.client, jack_process, &j2stl);
	jack_on_shutdown(j2stl.jack.client, jack_shutdown, NULL);

	/* Retrieve audio format from jack */
	j2stl.audio.sample_rate = jack_get_sample_rate(j2stl.jack.client);
	j2stl.audio.size = lrint((j2stl.status.sampling / 1000.0) *
				 j2stl.audio.sample_rate);
	j2stl.audio.data = malloc(sizeof(jack_default_audio_sample_t) *
				  j2stl.audio.size);
	if (j2stl.audio.data == NULL) {
		fprintf(stderr, "Unable to allocate memory for sound buffers: "
				"%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	if (j2stl.status.verbose)
		fprintf(stderr, "Jack sample rate: %u\n",
			j2stl.audio.sample_rate);

	/* jack: port creation */
	j2stl.jack.input_port = jack_port_register(j2stl.jack.client, "input",
					     JACK_DEFAULT_AUDIO_TYPE,
					     JackPortIsInput, 0);
	if (j2stl.jack.input_port == NULL) {
		fprintf(stderr, "No port available.\n");
		exit(EXIT_FAILURE);
	}

	/* Threads launch */
	if ((ret = pthread_create(&j2stl.status.fftw_thread, NULL,
				  fftw_thread, &j2stl))) {
		fprintf(stderr, "Unable to spawn fftw thread: %s\n",
			strerror(ret));
		exit(EXIT_FAILURE);
	}

	if (jack_activate(j2stl.jack.client) != 0) {
		fprintf(stderr, "Unable to activate client\n");
		exit(EXIT_FAILURE);
	}
	if (j2stl.status.verbose)
		fprintf(stderr, "Jack client thread launched\n");

	if (j2stl.status.timeout)
		sleep(j2stl.status.timeout);
	else
		for(;;);

	process_cleanup(&j2stl);

	return EXIT_SUCCESS;
}
Exemplo n.º 7
0
void jack_shutdown(void *arg)
{
	process_cleanup((J2STL *)arg);

	exit(EXIT_FAILURE);
}
Exemplo n.º 8
0
static void syscall_exit (int status)
{
  process_cleanup (status);
  syscall_release_files ();
  thread_exit ();
}
Exemplo n.º 9
0
bool __TI_process_descriptors(_Unwind_Phase        phase, 
			      _Unwind_Exception   *uexcep, 
			      _Unwind_Context     *context, 
			      _Unwind_PR_Kind      pr_kind, 
			      _UINT32             *descr_ptr, 
			      _Unwind_Reason_Code *reason, 
			      bool                *ph2_call_unexpected)
{

    bool reason_code_valid = false;

    #ifdef DEBUG_PR
    printf("PD: descriptor @ %p\n", descr_ptr);
    #endif /* DEBUG_PR */

    /*-------------------------------------------------------------------*/
    /* Process each descriptor. The descriptor list is terminated by a   */
    /* 0 word (first word of a valid descriptor, length, is never 0)     */
    /*-------------------------------------------------------------------*/
    while (*descr_ptr)
    {
	_UINT32 length; 
	_UINT32 offset;

	/*---------------------------------------------------------------*/
	/* Based of PR kind, read in length and offset (16/32 bit)       */
	/*---------------------------------------------------------------*/
	switch (pr_kind)
	{
	    case _UPK_Su16: 
	    case _UPK_Lu16: 
	    case _UPK_PR3:
	    case _UPK_PR4:
		length = ((_PR_Scope16 *)descr_ptr)->length;
		offset = ((_PR_Scope16 *)descr_ptr)->offset;
		descr_ptr += sizeof(_PR_Scope16)/sizeof(_UINT32);
		break;

	    case _UPK_Lu32:
		length = ((_PR_Scope32 *)descr_ptr)->length;
		offset = ((_PR_Scope32 *)descr_ptr)->offset;
		descr_ptr += sizeof(_PR_Scope32)/sizeof(_UINT32);
		break;

	    default:
		*reason = _URC_FAILURE;
		reason_code_valid = true;
		break;
	}

	/*---------------------------------------------------------------*/
	/* Use LSB of length and offset to determine descriptor type     */
	/* 0,0 => cleanup, 0,1 => func espec, 1,0 => catch               */
	/*---------------------------------------------------------------*/
	switch (((length & 1) << 1) | (offset & 1))
	{
	    case 0:	    /* Process a Cleanup Descriptor*/
	    {
		if (process_cleanup(uexcep, phase, context,&descr_ptr,
				    length, offset))
		{
		    *reason = _URC_INSTALL_CONTEXT;
		    reason_code_valid = true;
		}
		break;
	    }
	    case 1:	    /* Process a Function Exception Spec Descriptor */
	    {
		offset -= 1; /* Clear LSB */
		if (process_fespec(uexcep, phase, context,&descr_ptr,
				    length, offset, reason, 
				    ph2_call_unexpected))
		    reason_code_valid = true;
		break;
	    }
	    case 2:	    /* Process a Catch Descriptor*/
	    {
		length -= 1; /* Clear LSB */
		if (process_catch(uexcep, phase, context,&descr_ptr,
				  length, offset, reason))
		    reason_code_valid = true;
		break;
	    }
	    default:
		*reason = _URC_FAILURE;
		reason_code_valid = true;
		break;
	}

	if (reason_code_valid == true) break;
    }
	
    return reason_code_valid;
}
Exemplo n.º 10
0
pid_t
sys_fork(const struct trapframe *parent_tf, int *err)
{
    struct process *parent = curthread->t_proc;
    
    // set up new process structure
    struct process *child = process_create(parent->ps_name);
    if (child == NULL)
    {
        *err = ENOMEM;
        return -1;
    }
    
    // Get a PID for the child.  ENPROC is
    // the error code for "no more processes allowed
    // in the system."
    pid_t child_pid = process_identify(child);
    if (child_pid == 0)
    {
        *err = ENPROC;
        process_cleanup(child);
        return -1;
    }
    
    // copy the file descriptor table of the parent
    child->ps_fdt = fdt_copy(parent->ps_fdt);
    if (child->ps_fdt == NULL)
    {
        *err = ENOMEM;
        process_destroy(child_pid);
        return -1;
    }
    
    // copy the address space of the parent
    *err = as_copy(parent->ps_addrspace,
                   &child->ps_addrspace);
    if (*err)
    {
        process_destroy(child_pid);
        return -1;
    }
    
    // add PID to children now.  That way, if we fail to
    // allocate memory, we have not yet forked a thread
    *err = pid_set_add(parent->ps_children, child_pid);
    if (*err)
    {
        process_destroy(child_pid);
        return -1;
    }
    
    // allocate space for child trapframe in the kernel heap
    struct trapframe *child_tf = kmalloc(sizeof(struct trapframe));
    if (child_tf == NULL)
    {
        process_destroy(child_pid);
        pid_set_remove(parent->ps_children, child_pid);
        *err = ENOMEM;
        return -1;
    }
    
    // copy trapframe
    memcpy(child_tf, parent_tf, sizeof(struct trapframe));
    
    // abuse child_tf->TF_RET (which will be set to 0)
    // to pass the process struct to the child thread
    // this cast and assignment will always work,
    // as pointers always fit in machine registers
    child_tf->TF_RET = (uintptr_t)child;
    
    // child thread sets up child return value
    // and ps_thread/t_proc
    *err = thread_fork("user process",
                       enter_forked_process,
                       child_tf, 0,
                       NULL);
    if (*err)
    {
        process_destroy(child_pid);
        kfree(child_tf);
        pid_set_remove(parent->ps_children, child_pid);
        return -1;
    }
    
    return child_pid;
}