예제 #1
0
/* Start threads. */
int
start_threads (size_t option_P, guestfs_h *options_handle, work_fn work)
{
  const int trace = options_handle ? guestfs_get_trace (options_handle) : 0;
  const int verbose = options_handle ? guestfs_get_verbose (options_handle) : 0;
  size_t i, nr_threads;
  int err, errors;
  void *status;
  CLEANUP_FREE struct thread_data *thread_data = NULL;
  CLEANUP_FREE pthread_t *threads = NULL;

  if (nr_domains == 0)          /* Nothing to do. */
    return 0;

  /* If the user selected the -P option, then we use up to that many threads. */
  if (option_P > 0)
    nr_threads = MIN (nr_domains, option_P);
  else
    nr_threads = MIN (nr_domains, MIN (MAX_THREADS, estimate_max_threads ()));

  if (verbose)
    fprintf (stderr, "parallel: creating %zu threads\n", nr_threads);

  thread_data = malloc (sizeof (struct thread_data) * nr_threads);
  threads = malloc (sizeof (pthread_t) * nr_threads);
  if (thread_data == NULL || threads == NULL)
    error (EXIT_FAILURE, errno, "malloc");

  for (i = 0; i < nr_threads; ++i) {
    thread_data[i].thread_num = i;
    thread_data[i].trace = trace;
    thread_data[i].verbose = verbose;
    thread_data[i].work = work;
  }

  /* Start the worker threads. */
  for (i = 0; i < nr_threads; ++i) {
    err = pthread_create (&threads[i], NULL, worker_thread, &thread_data[i]);
    if (err != 0)
      error (EXIT_FAILURE, err, "pthread_create [%zu]", i);
  }

  /* Wait for the threads to exit. */
  errors = 0;
  for (i = 0; i < nr_threads; ++i) {
    err = pthread_join (threads[i], &status);
    if (err != 0) {
      error (0, err, "pthread_join [%zu]", i);
      errors++;
    }
    if (*(int *)status == -1)
      errors++;
  }

  return errors == 0 ? 0 : -1;
}
예제 #2
0
int
main (int argc, char *argv[])
{
  enum { HELP_OPTION = CHAR_MAX + 1 };
  static const char *options = "in:P:vx";
  static const struct option long_options[] = {
    { "help", 0, 0, HELP_OPTION },
    { "ignore", 0, 0, 'i' },
    { "number", 1, 0, 'n' },
    { "processes", 1, 0, 'P' },
    { "trace", 0, 0, 'x' },
    { "verbose", 0, 0, 'v' },
    { 0, 0, 0, 0 }
  };
  size_t P = 0, i, errors;
  int c, option_index;
  int err;
  void *status;

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:
      /* Options which are long only. */
      fprintf (stderr, "%s: unknown long option: %s (%d)\n",
               guestfs_int_program_name, long_options[option_index].name, option_index);
      exit (EXIT_FAILURE);

    case 'i':
      ignore_errors = 1;
      break;

    case 'n':
      if (sscanf (optarg, "%zu", &n) != 1 || n == 0) {
        fprintf (stderr, "%s: -n option not numeric and greater than 0\n",
                 guestfs_int_program_name);
        exit (EXIT_FAILURE);
      }
      break;

    case 'P':
      if (sscanf (optarg, "%zu", &P) != 1) {
        fprintf (stderr, "%s: -P option not numeric\n", guestfs_int_program_name);
        exit (EXIT_FAILURE);
      }
      break;

    case 'v':
      verbose = 1;
      break;

    case 'x':
      trace = 1;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  if (n == 0) {
    fprintf (stderr,
             "%s: must specify number of processes to run (-n option)\n",
             guestfs_int_program_name);
    exit (EXIT_FAILURE);
  }

  if (optind != argc) {
    fprintf (stderr, "%s: extra arguments found on the command line\n",
             guestfs_int_program_name);
    exit (EXIT_FAILURE);
  }

  /* Calculate the number of threads to use. */
  if (P > 0)
    P = MIN (n, P);
  else
    P = MIN (n, MIN (MAX_THREADS, estimate_max_threads ()));

  /* Start the worker threads. */
  struct thread_data thread_data[P];
  pthread_t threads[P];

  for (i = 0; i < P; ++i) {
    thread_data[i].thread_num = i;
    err = pthread_create (&threads[i], NULL, start_thread, &thread_data[i]);
    if (err != 0) {
      fprintf (stderr, "%s: pthread_create[%zu]: %s\n",
               guestfs_int_program_name, i, strerror (err));
      exit (EXIT_FAILURE);
    }
  }

  /* Wait for the threads to exit. */
  errors = 0;
  for (i = 0; i < P; ++i) {
    err = pthread_join (threads[i], &status);
    if (err != 0) {
      fprintf (stderr, "%s: pthread_join[%zu]: %s\n",
               guestfs_int_program_name, i, strerror (err));
      errors++;
    }
    if (*(int *)status == -1)
      errors++;
  }

  exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #3
0
int
main (int argc, char *argv[])
{
  enum { HELP_OPTION = CHAR_MAX + 1 };
  static const char *options = "in:P:vx";
  static const struct option long_options[] = {
    { "help", 0, 0, HELP_OPTION },
    { "ignore", 0, 0, 'i' },
    { "log", 1, 0, 0 },
    { "number", 1, 0, 'n' },
    { "processes", 1, 0, 'P' },
    { "trace", 0, 0, 'x' },
    { "verbose", 0, 0, 'v' },
    { 0, 0, 0, 0 }
  };
  size_t P = 0, i;
  int c, option_index;

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:
      /* Options which are long only. */
      if (STREQ (long_options[option_index].name, "log")) {
        log_template = optarg;
        log_file_size = strlen (log_template);
        for (i = 0; i < strlen (log_template); ++i) {
          if (log_template[i] == '%')
            log_file_size += 64;
        }
      }
      else
        error (EXIT_FAILURE, 0,
               "unknown long option: %s (%d)",
               long_options[option_index].name, option_index);
      break;

    case 'i':
      ignore_errors = 1;
      break;

    case 'n':
      if (sscanf (optarg, "%zu", &n) != 1 || n == 0)
        error (EXIT_FAILURE, 0, "-n option not numeric and greater than 0");
      break;

    case 'P':
      if (sscanf (optarg, "%zu", &P) != 1)
        error (EXIT_FAILURE, 0, "-P option not numeric");
      break;

    case 'v':
      verbose = 1;
      break;

    case 'x':
      trace = 1;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  if (n == 0)
    error (EXIT_FAILURE, 0,
           "must specify number of processes to run (-n option)");

  if (optind != argc)
    error (EXIT_FAILURE, 0,
           "extra arguments found on the command line");

  /* Calculate the number of threads to use. */
  if (P > 0)
    P = MIN (n, P);
  else
    P = MIN (n, MIN (MAX_THREADS, estimate_max_threads ()));

  run_test (P);
  exit (EXIT_SUCCESS);
}