static void *
outer_thread (void *closure)
{
  pthread_t *threads = xcalloc (sizeof (*threads), inner_thread_count);
  while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
    {
      pthread_barrier_t barrier;
      xpthread_barrier_init (&barrier, NULL, inner_thread_count + 1);
      for (int i = 0; i < inner_thread_count; ++i)
        {
          void *(*func) (void *);
          if ((i  % 2) == 0)
            func = malloc_first_thread;
          else
            func = wait_first_thread;
          threads[i] = xpthread_create (NULL, func, &barrier);
        }
      xpthread_barrier_wait (&barrier);
      for (int i = 0; i < inner_thread_count; ++i)
        xpthread_join (threads[i]);
      xpthread_barrier_destroy (&barrier);
    }

  free (threads);

  return NULL;
}
Exemple #2
0
int
do_test (void)
{
  xpthread_rwlockattr_init (&mylock_attr);
  xpthread_rwlockattr_setkind_np (&mylock_attr,
				  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
  xpthread_rwlock_init (&mylock, &mylock_attr);

  for (int n = 0; n < LOOPS; n++)
    {
      pthread_t tids[NTHREADS];
      do_exit = 0;
      for (int i = 0; i < NTHREADS; i++)
	tids[i] = xpthread_create (NULL, run_loop, NULL);
      /* Let the threads run for some time.  */
      sleep (1);
      printf ("Exiting...");
      fflush (stdout);
      do_exit = 1;
      for (int i = 0; i < NTHREADS; i++)
	xpthread_join (tids[i]);
      printf ("done.\n");
    }
  pthread_rwlock_destroy (&mylock);
  pthread_rwlockattr_destroy (&mylock_attr);
  return 0;
}
Exemple #3
0
static void join_workers(struct worker_info *data, int thnum)
{
	int i;

	for (i = 0; i < thnum; i++)
		xpthread_join(data[i].tid);
}
static int
do_test (void)
{
  /* Limit the size of the process, so that memory allocation will
     fail without impacting the entire system.  */
  {
    struct rlimit limit;
    if (getrlimit (RLIMIT_AS, &limit) != 0)
      {
        printf ("FAIL: getrlimit (RLIMIT_AS) failed: %m\n");
        return 1;
      }
    /* This limit, 800MB, is just a heuristic. Any value can be
       picked.  */
    long target = 800 * 1024 * 1024;
    if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
      {
        limit.rlim_cur = target;
        if (setrlimit (RLIMIT_AS, &limit) != 0)
          {
            printf ("FAIL: setrlimit (RLIMIT_AS) failed: %m\n");
            return 1;
          }
      }
  }

  xpthread_attr_init (&detached);

  xpthread_attr_setdetachstate (&detached, PTHREAD_CREATE_DETACHED);

  /* A large thread stack seems beneficial for reproducing a race
     condition in detached thread creation.  The goal is to reach the
     limit of the runtime thread stack cache such that the detached
     thread's stack is unmapped after exit and causes a segfault when
     the parent reads the thread descriptor data stored on the the
     unmapped stack.  */
  xpthread_attr_setstacksize (&detached, 16 * 1024 * 1024);

  xpthread_barrier_init (&barrier, NULL, creator_threads);

  pthread_t threads[creator_threads];

  for (int i = 0; i < creator_threads; ++i)
    threads[i] = xpthread_create (NULL, creator_thread, NULL);

  for (int i = 0; i < creator_threads; ++i)
    xpthread_join (threads[i]);

  xpthread_attr_destroy (&detached);

  xpthread_barrier_destroy (&barrier);

  return 0;
}
Exemple #5
0
static void
test_benchmark(struct ovs_cmdl_context *ctx)
{
    struct thread_aux *threads;
    long long start;
    unsigned i;

    fatal_signal_init();

    /* Parse arguments */
    n_threads = strtoul(ctx->argv[1], NULL, 0);
    if (!n_threads) {
        ovs_fatal(0, "n_threads must be at least one");
    }
    n_pkts = strtoul(ctx->argv[2], NULL, 0);
    batch_size = strtoul(ctx->argv[3], NULL, 0);
    if (batch_size == 0 || batch_size > NETDEV_MAX_BURST) {
        ovs_fatal(0, "batch_size must be between 1 and NETDEV_MAX_BURST(%u)",
                  NETDEV_MAX_BURST);
    }
    if (ctx->argc > 4) {
        change_conn = strtoul(ctx->argv[4], NULL, 0);
    }

    threads = xcalloc(n_threads, sizeof *threads);
    ovs_barrier_init(&barrier, n_threads + 1);
    ct = conntrack_init();

    /* Create threads */
    for (i = 0; i < n_threads; i++) {
        threads[i].tid = i;
        threads[i].thread = ovs_thread_create("ct_thread", ct_thread_main,
                                              &threads[i]);
    }
    /* Starts the work inside the threads */
    ovs_barrier_block(&barrier);
    start = time_msec();

    /* Wait for the threads to finish the work */
    ovs_barrier_block(&barrier);
    printf("conntrack:  %5lld ms\n", time_msec() - start);

    for (i = 0; i < n_threads; i++) {
        xpthread_join(threads[i].thread, NULL);
    }

    conntrack_destroy(ct);
    ovs_barrier_destroy(&barrier);
    free(threads);
}
Exemple #6
0
static void
benchmark_ccmap(void)
{
    struct ccmap ccmap;
    struct timeval start;
    pthread_t *threads;
    struct ccmap_aux aux;
    size_t i;

    /* Insertions. */
    xgettimeofday(&start);
    ccmap_init(&ccmap);
    for (i = 0; i < n_elems; i++) {
        ccmap_inc(&ccmap, hash_int(i, 0));
    }
    printf("ccmap insert:  %5d ms\n", elapsed(&start));

    /* Search and mutation. */
    xgettimeofday(&start);
    aux.ccmap = &ccmap;
    ovs_mutex_init(&aux.mutex);
    threads = xmalloc(n_threads * sizeof *threads);
    for (i = 0; i < n_threads; i++) {
        threads[i] = ovs_thread_create("search", search_ccmap, &aux);
    }
    for (i = 0; i < n_threads; i++) {
        xpthread_join(threads[i], NULL);
    }
    free(threads);
    printf("ccmap search:  %5d ms\n", elapsed(&start));

    /* Destruction. */
    xgettimeofday(&start);
    for (i = 0; i < n_elems; i++) {
        uint32_t hash = hash_int(i, 0);

        if (ccmap_find(&ccmap, hash)) {
            /* Also remove any colliding hashes. */
            while (ccmap_dec(&ccmap, hash)) {
                ;
            }
        }
    }
    ccmap_destroy(&ccmap);
    printf("ccmap destroy: %5d ms\n", elapsed(&start));
}
Exemple #7
0
/* ====================================================================
 *
 * @brief pe_crew_destory() 
 *        Free all the memory and kill the specified work crew.
 *
 * @param0 <old_crew>       - I/O
 *         pointer to the crew structure that is to be destroyed
 * @return <status>         - O
 *         0 if sucessful, else the return from the pthread calls.
 *               
 **/
void pe_crew_destroy() 
{
    static char mod[] = "pe_crew_destroy";
    rb_cond_vars_t *cond_list;
    int crew_index = 0;

    DBUG_ENTER(mod);
    VLOG_DBG("%s: -->", mod);

    pe_set_crew_quit_status(true);
    rb_broadcast_cond_variables(); //signal threads to wake up and die

    VLOG_DBG("%s: Broadcast for termination.", mod);

    for (crew_index = 0; crew_index < crew.size; crew_index++)
        xpthread_join(crew.worker[crew_index]->thread, NULL);

    ovs_rwlock_destroy(&crew.rwlock);

    DBUG_LEAVE;

}
Exemple #8
0
static int
do_test (void)
{
  xpthread_barrier_init (&barrier, NULL, thread_count + 1);

  pthread_t threads[thread_count];
  for (size_t i = 0; i < array_length (threads); ++i)
    threads[i] = xpthread_create (NULL, allocation_thread_function, NULL);

  xpthread_barrier_wait (&barrier);
  puts ("info: After allocation:");
  malloc_info (0, stdout);

  xpthread_barrier_wait (&barrier);
  for (size_t i = 0; i < array_length (threads); ++i)
    xpthread_join (threads[i]);

  puts ("\ninfo: After deallocation:");
  malloc_info (0, stdout);

  return 0;
}
Exemple #9
0
static int
do_test (void)
{
  unsigned int i;
  printf ("Starting %d threads to run %lld iterations.\n",
	  thread_count, iteration_count);

  pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t));
  xpthread_barrier_init (&barrier, NULL, thread_count);
  xpthread_mutex_init (&mutex, NULL);

  for (i = 0; i < thread_count; i++)
    threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i);

  for (i = 0; i < thread_count; i++)
    xpthread_join (threads[i]);

  xpthread_barrier_destroy (&barrier);
  free (threads);

  return EXIT_SUCCESS;
}
Exemple #10
0
static int
do_test (void)
{
  /* The number of threads should be smaller than the number of
     arenas, so that there will be some free arenas to add to the
     arena free list.  */
  enum { outer_thread_count = 2 };
  if (mallopt (M_ARENA_MAX, 8) == 0)
    {
      printf ("error: mallopt (M_ARENA_MAX) failed\n");
      return 1;
    }

  /* Leave some room for shutting down all threads gracefully.  */
  int timeout = 3;
  if (timeout > DEFAULT_TIMEOUT)
    timeout = DEFAULT_TIMEOUT - 1;

  pthread_t *threads = xcalloc (sizeof (*threads), outer_thread_count);
  for (long i = 0; i < outer_thread_count; ++i)
    threads[i] = xpthread_create (NULL, outer_thread, NULL);

  struct timespec ts = {timeout, 0};
  if (nanosleep (&ts, NULL))
    {
      printf ("error: error: nanosleep: %m\n");
      abort ();
    }

  __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);

  for (long i = 0; i < outer_thread_count; ++i)
    xpthread_join (threads[i]);
  free (threads);

  return 0;
}
Exemple #11
0
static void
sl (void)
{
  FILE *f = fopen (pidfile, "w");
  if (f == NULL)
    exit (1);

  fprintf (f, "%lld\n", (long long) getpid ());
  fflush (f);

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 1
    };
  if (fcntl (fileno (f), F_SETLK, &fl) != 0)
    exit (1);

  sigset_t ss;
  sigfillset (&ss);
  sigsuspend (&ss);
  exit (0);
}


static void
do_prepare (int argc, char *argv[])
{
  if (command == NULL)
    command = argv[0];

  if (pidfile)
    sl ();

  int fd = mkstemp (pidfilename);
  if (fd == -1)
    {
      puts ("mkstemp failed");
      exit (1);
    }

  write (fd, " ", 1);
  close (fd);
}


static int
do_test (void)
{
  pthread_t th;
  if (pthread_create (&th, NULL, tf, NULL) != 0)
    {
      puts ("pthread_create failed");
      return 1;
    }

  do
    sleep (1);
  while (access (pidfilename, R_OK) != 0);

  xpthread_cancel (th);
  void *r = xpthread_join (th);

  sleep (1);

  FILE *f = fopen (pidfilename, "r+");
  if (f == NULL)
    {
      puts ("no pidfile");
      return 1;
    }

  long long ll;
  if (fscanf (f, "%lld\n", &ll) != 1)
    {
      puts ("could not read pid");
      unlink (pidfilename);
      return 1;
    }

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 1
    };
  if (fcntl (fileno (f), F_GETLK, &fl) != 0)
    {
      puts ("F_GETLK failed");
      unlink (pidfilename);
      return 1;
    }

  if (fl.l_type != F_UNLCK)
    {
      printf ("child %lld still running\n", (long long) fl.l_pid);
      if (fl.l_pid == ll)
	kill (fl.l_pid, SIGKILL);

      unlink (pidfilename);
      return 1;
    }

  fclose (f);

  unlink (pidfilename);

  return r != PTHREAD_CANCELED;
}

static void
do_cleanup (void)
{
  FILE *f = fopen (pidfilename, "r+");
  long long ll;

  if (f != NULL && fscanf (f, "%lld\n", &ll) == 1)
    {
      struct flock fl =
	{
	  .l_type = F_WRLCK,
	  .l_start = 0,
	  .l_whence = SEEK_SET,
	  .l_len = 1
	};
      if (fcntl (fileno (f), F_GETLK, &fl) == 0 && fl.l_type != F_UNLCK
	  && fl.l_pid == ll)
	kill (fl.l_pid, SIGKILL);

      fclose (f);
    }

  unlink (pidfilename);
}

#define OPT_COMMAND	10000
#define OPT_PIDFILE	10001
#define CMDLINE_OPTIONS \
  { "command", required_argument, NULL, OPT_COMMAND },	\
  { "pidfile", required_argument, NULL, OPT_PIDFILE },
static void
cmdline_process (int c)
{
  switch (c)
    {
    case OPT_COMMAND:
      command = optarg;
      break;
    case OPT_PIDFILE:
      pidfile = optarg;
      break;
    }
}
Exemple #12
0
static int
do_test (void)
{
    /* The test basically pipe a 'echo $$' created by a thread with a
       cancellation pending.  It then checks if the thread is not cancelled,
       the process is created and if the output is the expected one.  */

    if (pipe (pipefd) != 0)
    {
        puts ("error: pipe failed");
        exit (1);
    }

    /* Not interested in knowing when the pipe is closed.  */
    if (sigignore (SIGPIPE) != 0)
    {
        puts ("error: sigignore failed");
        exit (1);
    }

    /* To synchronize with the thread.  */
    if (pthread_barrier_init (&b, NULL, 2) != 0)
    {
        puts ("error: pthread_barrier_init failed");
        exit (1);
    }

    pthread_t th = xpthread_create (NULL, &tf, NULL);

    if (pthread_cancel (th) != 0)
    {
        puts ("error: pthread_cancel failed");
        return 1;
    }

    xpthread_barrier_wait (&b);

    if (xpthread_join (th) == PTHREAD_CANCELED)
    {
        puts ("error: thread cancelled");
        exit (1);
    }

    close (pipefd[1]);

    /* The global 'pid' should be set by thread posix_spawn calling.  Check
       below if it was executed correctly and with expected output.  */

    char buf[64];
    ssize_t n;
    bool seen_pid = false;
    while (TEMP_FAILURE_RETRY ((n = read (pipefd[0], buf, sizeof (buf)))) > 0)
    {
        /* We only expect to read the PID.  */
        char *endp;
        long int rpid = strtol (buf, &endp, 10);

        if (*endp != '\n')
        {
            printf ("error: didn't parse whole line: \"%s\"\n", buf);
            exit (1);
        }
        if (endp == buf)
        {
            puts ("error: read empty line");
            exit (1);
        }

        if (rpid != pid)
        {
            printf ("error: found \"%s\", expected PID %ld\n", buf,
                    (long int) pid);
            exit (1);
        }

        if (seen_pid)
        {
            puts ("error: found more than one PID line");
            exit (1);
        }

        seen_pid = true;
    }

    close (pipefd[0]);

    int status;
    int err = waitpid (pid, &status, 0);
    if (err != pid)
    {
        puts ("errnor: waitpid failed");
        exit (1);
    }

    if (!seen_pid)
    {
        puts ("error: didn't get PID");
        exit (1);
    }

    return 0;
}