Home | History | Annotate | Line # | Download | only in gdb.threads
      1      1.1  christos /* This testcase is part of GDB, the GNU debugger.
      2      1.1  christos 
      3  1.1.1.4  christos    Copyright 2018-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 #include <stdio.h>
     19      1.1  christos #include <stdlib.h>
     20      1.1  christos #include <pthread.h>
     21      1.1  christos 
     22      1.1  christos /* This defines the number of threads to spawn.  */
     23      1.1  christos #define THREADCOUNT 4
     24      1.1  christos 
     25      1.1  christos /* Global barrier type to control synchronization between threads.  */
     26      1.1  christos static pthread_barrier_t print_barrier;
     27      1.1  christos 
     28      1.1  christos /* Define global thread identifiers.  */
     29      1.1  christos static pthread_t threads[THREADCOUNT];
     30      1.1  christos 
     31      1.1  christos /* Hold values for each thread at the index supplied to the thread
     32      1.1  christos    on creation.  */
     33      1.1  christos static int thread_ids[THREADCOUNT];
     34      1.1  christos 
     35      1.1  christos /* Find the value associated with the calling thread.  */
     36      1.1  christos static int
     37      1.1  christos get_value ()
     38      1.1  christos {
     39      1.1  christos   for (int tid = 0; tid < THREADCOUNT; ++tid)
     40      1.1  christos     {
     41      1.1  christos       if (pthread_equal (threads[tid], pthread_self ()))
     42      1.1  christos 	return thread_ids[tid];
     43      1.1  christos     }
     44      1.1  christos   /* Value for the main thread.  */
     45      1.1  christos   return 1;
     46      1.1  christos }
     47      1.1  christos 
     48      1.1  christos /* Return the nth Fibonacci number.  */
     49      1.1  christos static unsigned long
     50      1.1  christos fast_fib (unsigned int n)
     51      1.1  christos {
     52      1.1  christos   int a = 0;
     53      1.1  christos   int b = 1;
     54      1.1  christos   int t;
     55      1.1  christos   for (unsigned int i = 0; i < n; ++i)
     56      1.1  christos     {
     57      1.1  christos       t = b;
     58      1.1  christos       b = a + b;
     59      1.1  christos       a = t;
     60      1.1  christos     }
     61      1.1  christos   return a;
     62      1.1  christos }
     63      1.1  christos 
     64      1.1  christos /* Encapsulate the synchronization of the threads. Perform a barrier before
     65      1.1  christos    and after the computation.  */
     66      1.1  christos static void *
     67      1.1  christos thread_function (void *args)
     68      1.1  christos {
     69      1.1  christos   int tid = *((int *) args);
     70      1.1  christos   int status = pthread_barrier_wait (&print_barrier);
     71      1.1  christos   if (status == PTHREAD_BARRIER_SERIAL_THREAD)
     72      1.1  christos     printf ("All threads entering compute region\n");
     73      1.1  christos 
     74      1.1  christos   unsigned long result = fast_fib (100); /* testmarker01 */
     75      1.1  christos   status = pthread_barrier_wait (&print_barrier);
     76      1.1  christos   if (status == PTHREAD_BARRIER_SERIAL_THREAD)
     77      1.1  christos     printf ("All threads outputting results\n");
     78      1.1  christos 
     79      1.1  christos   pthread_barrier_wait (&print_barrier);
     80      1.1  christos   printf ("Thread %d Result: %lu\n", tid, result);
     81      1.1  christos }
     82      1.1  christos 
     83      1.1  christos int
     84      1.1  christos main (void)
     85      1.1  christos {
     86      1.1  christos   int err = pthread_barrier_init (&print_barrier, NULL, THREADCOUNT);
     87      1.1  christos   if (err != 0)
     88      1.1  christos     {
     89      1.1  christos       fprintf (stderr, "Barrier creation failed\n");
     90      1.1  christos       return EXIT_FAILURE;
     91      1.1  christos     }
     92      1.1  christos   /* Create the worker threads (main).  */
     93      1.1  christos   printf ("Spawning worker threads\n");
     94      1.1  christos   for (int tid = 0; tid < THREADCOUNT; ++tid)
     95      1.1  christos     {
     96      1.1  christos       /* Add 2 so the value maps to the debugger's thread identifiers.  */
     97      1.1  christos       thread_ids[tid] = tid + 2; /* prethreadcreationmarker */
     98      1.1  christos       err = pthread_create (&threads[tid], NULL, thread_function,
     99      1.1  christos 			    (void *) &thread_ids[tid]);
    100      1.1  christos       if (err != 0)
    101      1.1  christos 	{
    102      1.1  christos 	  fprintf (stderr, "Thread creation failed\n");
    103      1.1  christos 	  return EXIT_FAILURE;
    104      1.1  christos 	}
    105      1.1  christos     }
    106      1.1  christos   /* Wait for the threads to complete then exit.  */
    107      1.1  christos   for (int tid = 0; tid < THREADCOUNT; ++tid)
    108      1.1  christos     pthread_join (threads[tid], NULL);
    109      1.1  christos 
    110      1.1  christos   return EXIT_SUCCESS;
    111      1.1  christos }
    112