Back to index

glibc  2.9
tst-tls3.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <dlfcn.h>
00021 #include <errno.h>
00022 #include <pthread.h>
00023 #include <signal.h>
00024 #include <semaphore.h>
00025 #include <stdint.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <pthreaddef.h>
00030 
00031 #define THE_SIG SIGUSR1
00032 
00033 
00034 #define N 10
00035 static pthread_t th[N];
00036 
00037 
00038 #define CB(n) \
00039 static void                                                          \
00040 cb##n (void)                                                         \
00041 {                                                                    \
00042   if (th[n] != pthread_self ())                                             \
00043     {                                                                \
00044       write (STDOUT_FILENO, "wrong callback\n", 15);                        \
00045       _exit (1);                                                     \
00046     }                                                                \
00047 }
00048 CB (0)
00049 CB (1)
00050 CB (2)
00051 CB (3)
00052 CB (4)
00053 CB (5)
00054 CB (6)
00055 CB (7)
00056 CB (8)
00057 CB (9)
00058 static void (*cbs[]) (void) =
00059 {
00060   cb0, cb1, cb2, cb3, cb4, cb5, cb6, cb7, cb8, cb9
00061 };
00062 
00063 
00064 sem_t s;
00065 
00066 
00067 pthread_barrier_t b;
00068 
00069 #define TOTAL_SIGS 1000
00070 int nsigs;
00071 
00072 
00073 int
00074 do_test (void)
00075 {
00076 #if !HAVE___THREAD
00077 
00078   puts ("No __thread support in compiler, test skipped.");
00079 
00080   return 0;
00081 #else
00082 
00083   if ((uintptr_t) pthread_self () & (TCB_ALIGNMENT - 1))
00084     {
00085       puts ("initial thread's struct pthread not aligned enough");
00086       exit (1);
00087     }
00088 
00089   if (pthread_barrier_init (&b, NULL, N + 1) != 0)
00090     {
00091       puts ("barrier_init failed");
00092       exit (1);
00093     }
00094 
00095   if (sem_init (&s, 0, 0) != 0)
00096     {
00097       puts ("sem_init failed");
00098       exit (1);
00099     }
00100 
00101   void *h = dlopen ("tst-tls3mod.so", RTLD_LAZY);
00102   if (h == NULL)
00103     {
00104       puts ("dlopen failed");
00105       exit (1);
00106     }
00107 
00108   void *(*tf) (void *) = dlsym (h, "tf");
00109   if (tf == NULL)
00110     {
00111       puts ("dlsym for tf failed");
00112       exit (1);
00113     }
00114 
00115   struct sigaction sa;
00116   sa.sa_handler = dlsym (h, "handler");
00117   if (sa.sa_handler == NULL)
00118     {
00119       puts ("dlsym for handler failed");
00120       exit (1);
00121     }
00122   sigemptyset (&sa.sa_mask);
00123   sa.sa_flags = 0;
00124   if (sigaction (THE_SIG, &sa, NULL) != 0)
00125     {
00126       puts ("sigaction failed");
00127       exit (1);
00128     }
00129 
00130   pthread_attr_t a;
00131 
00132   if (pthread_attr_init (&a) != 0)
00133     {
00134       puts ("attr_init failed");
00135       exit (1);
00136     }
00137 
00138   if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
00139     {
00140       puts ("attr_setstacksize failed");
00141       return 1;
00142     }
00143 
00144   int r;
00145   for (r = 0; r < 10; ++r)
00146     {
00147       int i;
00148       for (i = 0; i < N; ++i)
00149        if (pthread_create (&th[i], &a, tf, cbs[i]) != 0)
00150          {
00151            puts ("pthread_create failed");
00152            exit (1);
00153          }
00154 
00155       nsigs = 0;
00156 
00157       pthread_barrier_wait (&b);
00158 
00159       sigset_t ss;
00160       sigemptyset (&ss);
00161       sigaddset (&ss, THE_SIG);
00162       if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
00163        {
00164          puts ("pthread_sigmask failed");
00165          exit (1);
00166        }
00167 
00168       /* Start sending signals.  */
00169       for (i = 0; i < TOTAL_SIGS; ++i)
00170        {
00171          if (kill (getpid (), THE_SIG) != 0)
00172            {
00173              puts ("kill failed");
00174              exit (1);
00175            }
00176 
00177          if (TEMP_FAILURE_RETRY (sem_wait (&s)) != 0)
00178            {
00179              puts ("sem_wait failed");
00180              exit (1);
00181            }
00182 
00183          ++nsigs;
00184        }
00185 
00186       pthread_barrier_wait (&b);
00187 
00188       if (pthread_sigmask (SIG_UNBLOCK, &ss, NULL) != 0)
00189        {
00190          puts ("pthread_sigmask failed");
00191          exit (1);
00192        }
00193 
00194       for (i = 0; i < N; ++i)
00195        if (pthread_join (th[i], NULL) != 0)
00196          {
00197            puts ("join failed");
00198            exit (1);
00199          }
00200     }
00201 
00202   if (pthread_attr_destroy (&a) != 0)
00203     {
00204       puts ("attr_destroy failed");
00205       exit (1);
00206     }
00207 
00208   return 0;
00209 #endif
00210 }
00211 
00212 
00213 #define TIMEOUT 5
00214 #define TEST_FUNCTION do_test ()
00215 #include "../test-skeleton.c"