(root)/
glibc-2.38/
sysdeps/
pthread/
tst-pt-tls1.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 <pthread.h>
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <stdint.h>
      22  #include <inttypes.h>
      23  #include <support/support.h>
      24  #include <support/check.h>
      25  #include <support/xthread.h>
      26  
      27  struct test_s
      28  {
      29    __attribute__ ((aligned(0x20))) int a;
      30    __attribute__ ((aligned(0x200))) int b;
      31  };
      32  
      33  #define INIT_A 1
      34  #define INIT_B 42
      35  /* Deliberately not static.  */
      36  __thread struct test_s s __attribute__ ((tls_model ("initial-exec"))) =
      37  {
      38    .a = INIT_A,
      39    .b = INIT_B
      40  };
      41  
      42  /* Use noinline in combination with not static to ensure that the
      43     alignment check is really done.  Otherwise it was optimized out!  */
      44  __attribute__ ((noinline)) void
      45  check_alignment (const char *thr_name, const char *ptr_name,
      46  		 int *ptr, int alignment)
      47  {
      48    uintptr_t offset_aligment = ((uintptr_t) ptr) & (alignment - 1);
      49    if (offset_aligment)
      50      {
      51        FAIL_EXIT1 ("%s (%p) is not 0x%x-byte aligned in %s thread\n",
      52  		  ptr_name, ptr, alignment, thr_name);
      53      }
      54  }
      55  
      56  static void
      57  check_s (const char *thr_name)
      58  {
      59    if (s.a != INIT_A || s.b != INIT_B)
      60      FAIL_EXIT1 ("initial value of s in %s thread wrong\n", thr_name);
      61  
      62    check_alignment (thr_name, "s.a", &s.a, 0x20);
      63    check_alignment (thr_name, "s.b", &s.b, 0x200);
      64  }
      65  
      66  static void *
      67  tf (void *arg)
      68  {
      69    check_s ("child");
      70  
      71    ++s.a;
      72  
      73    return NULL;
      74  }
      75  
      76  
      77  int
      78  do_test (void)
      79  {
      80    check_s ("main");
      81  
      82    pthread_attr_t a;
      83  
      84    xpthread_attr_init (&a);
      85  
      86  #define STACK_SIZE (1 * 1024 * 1024)
      87    xpthread_attr_setstacksize (&a, STACK_SIZE);
      88  
      89  #define N 10
      90    int i;
      91    for (i = 0; i < N; ++i)
      92      {
      93  #define M 10
      94        pthread_t th[M];
      95        int j;
      96        for (j = 0; j < M; ++j, ++s.a)
      97  	th[j] = xpthread_create (&a, tf, NULL);
      98  
      99        for (j = 0; j < M; ++j)
     100  	xpthread_join (th[j]);
     101      }
     102  
     103    /* Also check the alignment of the tls variables if a misaligned stack is
     104       specified.  */
     105    pthread_t th;
     106    void *thr_stack = NULL;
     107    thr_stack = xposix_memalign (0x200, STACK_SIZE + 1);
     108    xpthread_attr_setstack (&a, thr_stack + 1, STACK_SIZE);
     109    th = xpthread_create (&a, tf, NULL);
     110    xpthread_join (th);
     111    free (thr_stack);
     112  
     113    xpthread_attr_destroy (&a);
     114  
     115    return 0;
     116  }
     117  
     118  #include <support/test-driver.c>