(root)/
glibc-2.38/
sysdeps/
pthread/
tst-pt-tls4.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <dlfcn.h>
      19  #include <errno.h>
      20  #include <pthread.h>
      21  #include <stdint.h>
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <unistd.h>
      25  
      26  #define N 3
      27  
      28  void (*test1) (void), (*test2) (void);
      29  
      30  pthread_barrier_t b2, b3;
      31  
      32  static void *
      33  tf (void *arg)
      34  {
      35    int i;
      36  
      37    for (i = 0; i <= (uintptr_t) arg; ++i)
      38      {
      39        int r = pthread_barrier_wait (&b3);
      40        if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      41  	{
      42  	  puts ("tf: barrier_wait failed");
      43  	  exit (1);
      44  	}
      45      }
      46  
      47    test1 ();
      48  
      49    for (i = 0; i < 3; ++i)
      50      {
      51        int r = pthread_barrier_wait (&b3);
      52        if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      53  	{
      54  	  puts ("tf: barrier_wait failed");
      55  	  exit (1);
      56  	}
      57      }
      58  
      59    test2 ();
      60  
      61    for (i = 0; i < 3 - (uintptr_t) arg; ++i)
      62      {
      63        int r = pthread_barrier_wait (&b3);
      64        if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      65  	{
      66  	  puts ("tf: barrier_wait failed");
      67  	  exit (1);
      68  	}
      69      }
      70  
      71    return NULL;
      72  }
      73  
      74  static void *
      75  tf2 (void *arg)
      76  {
      77    int r = pthread_barrier_wait (&b2);
      78    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      79      {
      80        puts ("tf2: barrier_wait failed");
      81        exit (1);
      82      }
      83  
      84    int i;
      85    for (i = 0; i < N; ++i)
      86      tf (arg);
      87    return NULL;
      88  }
      89  
      90  int
      91  do_test (void)
      92  {
      93    pthread_t th[2];
      94    const char *modules[N]
      95      = { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" };
      96  
      97    if (pthread_barrier_init (&b2, NULL, 2) != 0)
      98      {
      99        puts ("barrier_init failed");
     100        return 1;
     101      }
     102  
     103    if (pthread_barrier_init (&b3, NULL, 3) != 0)
     104      {
     105        puts ("barrier_init failed");
     106        return 1;
     107      }
     108  
     109    if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1))
     110      {
     111        puts ("pthread_create failed");
     112        return 1;
     113      }
     114  
     115    int r = pthread_barrier_wait (&b2);
     116    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
     117      {
     118        puts ("barrier_wait failed");
     119        return 1;
     120      }
     121  
     122    int i;
     123    for (i = 0; i < N; ++i)
     124      {
     125        void *h = dlopen (modules[i], RTLD_LAZY);
     126        if (h == NULL)
     127  	{
     128  	  printf ("dlopen failed %s\n", dlerror ());
     129  	  return 1;
     130  	}
     131  
     132        test1 = dlsym (h, "test1");
     133        if (test1 == NULL)
     134  	{
     135  	  printf ("dlsym for test1 failed %s\n", dlerror ());
     136  	  return 1;
     137  	}
     138  
     139        test2 = dlsym (h, "test2");
     140        if (test2 == NULL)
     141  	{
     142  	  printf ("dlsym for test2 failed %s\n", dlerror ());
     143  	  return 1;
     144  	}
     145  
     146        if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2))
     147  	{
     148  	  puts ("pthread_create failed");
     149  	  return 1;
     150  	}
     151  
     152        tf ((void *) (uintptr_t) 0);
     153  
     154        if (pthread_join (th[1], NULL) != 0)
     155  	{
     156  	  puts ("join failed");
     157  	  return 1;
     158  	}
     159  
     160        if (dlclose (h))
     161  	{
     162  	  puts ("dlclose failed");
     163  	  return 1;
     164  	}
     165  
     166        printf ("test %d with %s succeeded\n", i, modules[i]);
     167      }
     168  
     169    if (pthread_join (th[0], NULL) != 0)
     170      {
     171        puts ("join failed");
     172        return 1;
     173      }
     174  
     175    return 0;
     176  }
     177  
     178  #define TEST_FUNCTION do_test ()
     179  #include "../test-skeleton.c"