1 1.1 christos /* This testcase is part of GDB, the GNU debugger. 2 1.1 christos 3 1.1.1.6 christos Copyright 2016-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This program is free software; you can redistribute it and/or modify 6 1.1 christos it under the terms of the GNU General Public License as published by 7 1.1 christos the Free Software Foundation; either version 3 of the License, or 8 1.1 christos (at your option) any later version. 9 1.1 christos 10 1.1 christos This program is distributed in the hope that it will be useful, 11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 christos GNU General Public License for more details. 14 1.1 christos 15 1.1 christos You should have received a copy of the GNU General Public License 16 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 1.1 christos 18 1.1 christos #define _GNU_SOURCE 19 1.1 christos #include <stdlib.h> 20 1.1 christos #include <unistd.h> 21 1.1 christos #include <sched.h> 22 1.1.1.5 christos #include <pthread.h> 23 1.1 christos 24 1.1 christos static void 25 1.1 christos marker () 26 1.1 christos {} 27 1.1 christos 28 1.1 christos #define STACK_SIZE 0x1000 29 1.1 christos 30 1.1.1.5 christos /* These are used to signal that the threads have started correctly. The 31 1.1.1.5 christos GLOBAL_THREAD_COUNT is set to the number of threads in main, then 32 1.1.1.5 christos decremented (under a lock) in each new thread. */ 33 1.1.1.5 christos pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; 34 1.1.1.5 christos int global_thread_count = 0; 35 1.1.1.5 christos 36 1.1 christos static int 37 1.1 christos clone_fn (void *unused) 38 1.1 christos { 39 1.1.1.5 christos /* Signal that this thread has started correctly. */ 40 1.1.1.5 christos if (pthread_mutex_lock (&global_lock) != 0) 41 1.1.1.5 christos abort (); 42 1.1.1.5 christos global_thread_count--; 43 1.1.1.5 christos if (pthread_mutex_unlock (&global_lock) != 0) 44 1.1.1.5 christos abort (); 45 1.1.1.5 christos 46 1.1 christos return 0; 47 1.1 christos } 48 1.1 christos 49 1.1 christos int 50 1.1 christos main (void) 51 1.1 christos { 52 1.1 christos int i, pid; 53 1.1 christos unsigned char *stack[6]; 54 1.1 christos 55 1.1.1.5 christos /* Due to bug gdb/19675 the cloned thread _might_ try to reenter main 56 1.1.1.5 christos (this depends on where the displaced instruction is placed for 57 1.1.1.5 christos execution). However, if we do reenter main then lets ensure we fail 58 1.1.1.5 christos hard rather then just silently executing the code below. */ 59 1.1.1.5 christos static int started = 0; 60 1.1.1.5 christos if (!started) 61 1.1.1.5 christos started = 1; 62 1.1.1.5 christos else 63 1.1.1.5 christos abort (); 64 1.1.1.5 christos 65 1.1 christos for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++) 66 1.1 christos stack[i] = malloc (STACK_SIZE); 67 1.1 christos 68 1.1.1.5 christos global_thread_count = (sizeof (stack) / sizeof (stack[0])); 69 1.1.1.5 christos 70 1.1 christos for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++) 71 1.1 christos { 72 1.1 christos pid = clone (clone_fn, stack[i] + STACK_SIZE, CLONE_FILES | CLONE_VM, 73 1.1 christos NULL); 74 1.1 christos } 75 1.1 christos 76 1.1 christos for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++) 77 1.1 christos free (stack[i]); 78 1.1 christos 79 1.1.1.5 christos /* Set an alarm so we don't end up stuck waiting for threads that might 80 1.1.1.5 christos never start correctly. */ 81 1.1.1.5 christos alarm (120); 82 1.1.1.5 christos 83 1.1.1.5 christos /* Now wait for all the threads to start up. */ 84 1.1.1.5 christos while (global_thread_count != 0) 85 1.1.1.5 christos { 86 1.1.1.5 christos /* Force memory barrier so GLOBAL_THREAD_COUNT will be refetched. */ 87 1.1.1.5 christos asm volatile ("" ::: "memory"); 88 1.1.1.5 christos sleep (1); 89 1.1.1.5 christos } 90 1.1.1.5 christos 91 1.1.1.5 christos /* Call marker, this is what GDB is waiting for. */ 92 1.1 christos marker (); 93 1.1 christos } 94