/* This testcase is part of GDB, the GNU debugger.

   Copyright 2021 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#define _GNU_SOURCE
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define THREADS 20

static volatile unsigned int global_var = 123;

/* Wrapper around pthread_create.   */

static void
create_thread (pthread_t *child,
	       void *(*start_routine) (void *), void *arg)
{
  int rc;

  while ((rc = pthread_create (child, NULL, start_routine, arg)) != 0)
    {
      fprintf (stderr, "unexpected error from pthread_create: %s (%d)\n",
	       strerror (rc), rc);
      sleep (1);
    }
}

/* Data passed to threads on creation.  This is allocated on the heap
   and ownership transferred from parent to child.  */

struct thread_arg
{
  /* The thread's parent.  */
  pthread_t parent;

  /* Whether to call pthread_join on the parent.  */
  int join_parent;
};

/* Entry point for threads.  */

static void *
thread_fn (void *arg)
{
  struct thread_arg *p = arg;

  /* Passing no argument makes the thread exit immediately.  */
  if (p == NULL)
    return NULL;

  if (p->join_parent)
    assert (pthread_join (p->parent, NULL) == 0);

  /* Spawn a number of threads that exit immediately, and then join
     them.  The idea is to maximize the time window when we mostly
     have threads exiting.  */
  {
    pthread_t child[THREADS];
    int i;

    /* Passing no argument makes the thread exit immediately.  */
    for (i = 0; i < THREADS; i++)
      create_thread (&child[i], thread_fn, NULL);

    for (i = 0; i < THREADS; i++)
      pthread_join (child[i], NULL);
  }

  /* Spawn a new thread that joins us, and exit.  The idea here is to
     not have any thread that stays around forever.  */
  {
    pthread_t child;

    p->parent = pthread_self ();
    p->join_parent = 1;
    create_thread (&child, thread_fn, p);
  }

  return NULL;
}

int
main (void)
{
  int i;

  for (i = 0; i < 4; i++)
    {
      struct thread_arg *p;
      pthread_t child;

      p = malloc (sizeof *p);
      p->parent = pthread_self ();
      /* Only join the parent once.  */
      if (i == 0)
	p->join_parent = 1;
      else
	p->join_parent = 0;
      create_thread (&child, thread_fn, p);
    }

  /* Exit the leader to make sure that we can access memory with the
     leader gone.  */
  pthread_exit (NULL);
}
