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

   Copyright 2014-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>

pthread_t main_thread;
pthread_attr_t detached_attr;
pthread_attr_t joinable_attr;

/* Number of threads we'll create of each variant
   (joinable/detached).  */
int n_threads = 50;

/* Mutex used to hold creating detached threads.  */
pthread_mutex_t dthrds_create_mutex;

/* Wrapper for pthread_create.   */

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

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

void
break_fn (void)
{
}

/* Data passed to joinable threads on creation.  This is allocated on
   the heap and ownership transferred from parent to child.  (We do
   this because it's not portable to cast pthread_t to pointer.)  */

struct thread_arg
{
  pthread_t parent;
};

/* Entry point for joinable threads.  These threads first join their
   parent before spawning a new child (and exiting).  The parent's tid
   is passed as pthread_create argument, encapsulated in a struct
   thread_arg object.  */

void *
joinable_fn (void *arg)
{
  struct thread_arg *p = arg;

  pthread_setname_np (pthread_self (), "joinable");

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

  p->parent = pthread_self ();

  create_thread (&joinable_attr, joinable_fn, p);

  break_fn ();

  return NULL;
}

/* Entry point for detached threads.  */

void *
detached_fn (void *arg)
{
  pthread_setname_np (pthread_self (), "detached");

  /* This should throttle threads a bit in case we manage to spawn
     threads faster than they exit.  */
  pthread_mutex_lock (&dthrds_create_mutex);

  create_thread (&detached_attr, detached_fn, NULL);

  /* Note this is called before the mutex is unlocked otherwise in
     non-stop mode, when the breakpoint is hit we'd keep spawning more
     threads forever while the old threads stay alive (stopped in the
     breakpoint).  */
  break_fn ();

  pthread_mutex_unlock (&dthrds_create_mutex);

  return NULL;
}

/* Allow for as much timeout as DejaGnu wants, plus a bit of
   slack.  */
#define SECONDS (TIMEOUT + 20)

/* We'll exit after this many seconds.  */
unsigned int seconds_left = SECONDS;

/* GDB sets this whenever it's about to start a new detach/attach
   sequence.  We react by resetting the seconds left counter.  */
volatile int again = 0;

int
main (int argc, char *argv[])
{
  int i;

  if (argc > 1)
    n_threads = atoi (argv[1]);

  pthread_mutex_init (&dthrds_create_mutex, NULL);

  pthread_attr_init (&detached_attr);
  pthread_attr_setdetachstate (&detached_attr, PTHREAD_CREATE_DETACHED);
  pthread_attr_init (&joinable_attr);
  pthread_attr_setdetachstate (&joinable_attr, PTHREAD_CREATE_JOINABLE);

  main_thread = pthread_self ();

  /* Spawn the initial set of test threads.  Some threads are
     joinable, others are detached.  This exercises different code
     paths in the runtime.  */
  for (i = 0; i < n_threads; ++i)
    {
      struct thread_arg *p;

      p = malloc (sizeof *p);
      p->parent = main_thread;
      create_thread (&joinable_attr, joinable_fn, p);

      create_thread (&detached_attr, detached_fn, NULL);
    }

  /* Exit after a while if GDB is gone/crashes.  But wait long enough
     for one attach/detach sequence done by the .exp file.  */
  while (--seconds_left > 0)
    {
      sleep (1);

      if (again)
	{
	  /* GDB should be reattaching soon.  Restart the timer.  */
	  again = 0;
	  seconds_left = SECONDS;
	}
    }

  printf ("timeout, exiting\n");
  return 0;
}
