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