fork-plus-threads.c revision 1.1.1.5
1275970Scy/* This testcase is part of GDB, the GNU debugger.
2275970Scy
3275970Scy   Copyright 2015-2020 Free Software Foundation, Inc.
4275970Scy
5275970Scy   This program is free software; you can redistribute it and/or modify
6275970Scy   it under the terms of the GNU General Public License as published by
7275970Scy   the Free Software Foundation; either version 3 of the License, or
8275970Scy   (at your option) any later version.
9275970Scy
10275970Scy   This program is distributed in the hope that it will be useful,
11275970Scy   but WITHOUT ANY WARRANTY; without even the implied warranty of
12275970Scy   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13275970Scy   GNU General Public License for more details.
14275970Scy
15275970Scy   You should have received a copy of the GNU General Public License
16275970Scy   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17275970Scy
18275970Scy#include <assert.h>
19275970Scy#include <pthread.h>
20275970Scy#include <unistd.h>
21275970Scy#include <stdio.h>
22275970Scy#include <sys/types.h>
23275970Scy#include <sys/wait.h>
24275970Scy
25275970Scy
26275970Scy/* Number of times the main process forks.  */
27275970Scy#define NFORKS 10
28275970Scy
29275970Scy/* Number of threads by each fork child.  */
30275970Scy#define NTHREADS 10
31275970Scy
32275970Scystatic void *
33275970Scythread_func (void *arg)
34275970Scy{
35275970Scy  /* Empty.  */
36275970Scy  return NULL;
37275970Scy}
38275970Scy
39275970Scystatic void
40275970Scyfork_child (void)
41275970Scy{
42275970Scy  pthread_t threads[NTHREADS];
43275970Scy  int i;
44275970Scy  int ret;
45275970Scy
46275970Scy  for (i = 0; i < NTHREADS; i++)
47275970Scy    {
48275970Scy      ret = pthread_create (&threads[i], NULL, thread_func, NULL);
49275970Scy      assert (ret == 0);
50275970Scy    }
51275970Scy
52275970Scy  for (i = 0; i < NTHREADS; i++)
53275970Scy    {
54275970Scy      ret = pthread_join (threads[i], NULL);
55275970Scy      assert (ret == 0);
56275970Scy    }
57275970Scy}
58275970Scy
59275970Scyint
60275970Scymain (void)
61275970Scy{
62275970Scy  pid_t childs[NFORKS];
63275970Scy  int i;
64275970Scy  int status;
65275970Scy  int num_exited = 0;
66275970Scy
67275970Scy  /* Don't run forever if the wait loop below gets stuck.  */
68275970Scy  alarm (180);
69275970Scy
70275970Scy  for (i = 0; i < NFORKS; i++)
71275970Scy    {
72275970Scy      pid_t pid;
73275970Scy
74275970Scy      pid = fork ();
75275970Scy
76275970Scy      if (pid > 0)
77275970Scy	{
78275970Scy	  /* Parent.  */
79275970Scy	  childs[i] = pid;
80275970Scy	}
81275970Scy      else if (pid == 0)
82275970Scy	{
83275970Scy	  /* Child.  */
84275970Scy	  fork_child ();
85275970Scy	  return 0;
86275970Scy	}
87275970Scy      else
88275970Scy	{
89275970Scy	  perror ("fork");
90275970Scy	  return 1;
91275970Scy	}
92275970Scy    }
93275970Scy
94275970Scy  while (num_exited != NFORKS)
95275970Scy    {
96275970Scy      pid_t pid = wait (&status);
97275970Scy
98275970Scy      if (pid == -1)
99275970Scy	{
100275970Scy	  perror ("wait");
101275970Scy	  return 1;
102275970Scy	}
103275970Scy
104275970Scy      if (WIFEXITED (status))
105275970Scy	{
106275970Scy	  num_exited++;
107275970Scy	}
108275970Scy      else
109275970Scy	{
110275970Scy	  printf ("Hmm, unexpected wait status 0x%x from child %d\n", status,
111275970Scy		  pid);
112275970Scy	}
113275970Scy    }
114275970Scy
115275970Scy  return 0;
116275970Scy}
117275970Scy