Back to index

glibc  2.9
tst-tls4.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Jakub Jelinek <jakub@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 <stdio.h>
00024 #include <stdlib.h>
00025 #include <unistd.h>
00026 #include <tls.h>
00027 
00028 #if HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE
00029 
00030 #define N 3
00031 
00032 void (*test1) (void), (*test2) (void);
00033 
00034 pthread_barrier_t b2, b3;
00035 
00036 static void *
00037 tf (void *arg)
00038 {
00039   int i;
00040 
00041   for (i = 0; i <= (uintptr_t) arg; ++i)
00042     {
00043       int r = pthread_barrier_wait (&b3);
00044       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00045        {
00046          puts ("tf: barrier_wait failed");
00047          exit (1);
00048        }
00049     }
00050 
00051   test1 ();
00052 
00053   for (i = 0; i < 3; ++i)
00054     {
00055       int r = pthread_barrier_wait (&b3);
00056       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00057        {
00058          puts ("tf: barrier_wait failed");
00059          exit (1);
00060        }
00061     }
00062 
00063   test2 ();
00064 
00065   for (i = 0; i < 3 - (uintptr_t) arg; ++i)
00066     {
00067       int r = pthread_barrier_wait (&b3);
00068       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00069        {
00070          puts ("tf: barrier_wait failed");
00071          exit (1);
00072        }
00073     }
00074 
00075   return NULL;
00076 }
00077 
00078 static void *
00079 tf2 (void *arg)
00080 {
00081   int r = pthread_barrier_wait (&b2);
00082   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00083     {
00084       puts ("tf2: barrier_wait failed");
00085       exit (1);
00086     }
00087 
00088   int i;
00089   for (i = 0; i < N; ++i)
00090     tf (arg);
00091   return NULL;
00092 }
00093 
00094 int
00095 do_test (void)
00096 {
00097   pthread_t th[2];
00098   const char *modules[N]
00099     = { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" };
00100 
00101   if (pthread_barrier_init (&b2, NULL, 2) != 0)
00102     {
00103       puts ("barrier_init failed");
00104       return 1;
00105     }
00106 
00107   if (pthread_barrier_init (&b3, NULL, 3) != 0)
00108     {
00109       puts ("barrier_init failed");
00110       return 1;
00111     }
00112 
00113   if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1))
00114     {
00115       puts ("pthread_create failed");
00116       return 1;
00117     }
00118 
00119   int r = pthread_barrier_wait (&b2);
00120   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00121     {
00122       puts ("barrier_wait failed");
00123       return 1;
00124     }
00125 
00126   int i;
00127   for (i = 0; i < N; ++i)
00128     {
00129       void *h = dlopen (modules[i], RTLD_LAZY);
00130       if (h == NULL)
00131        {
00132          printf ("dlopen failed %s\n", dlerror ());
00133          return 1;
00134        }
00135 
00136       test1 = dlsym (h, "test1");
00137       if (test1 == NULL)
00138        {
00139          printf ("dlsym for test1 failed %s\n", dlerror ());
00140          return 1;
00141        }
00142 
00143       test2 = dlsym (h, "test2");
00144       if (test2 == NULL)
00145        {
00146          printf ("dlsym for test2 failed %s\n", dlerror ());
00147          return 1;
00148        }
00149 
00150       if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2))
00151        {
00152          puts ("pthread_create failed");
00153          return 1;
00154        }
00155 
00156       tf ((void *) (uintptr_t) 0);
00157 
00158       if (pthread_join (th[1], NULL) != 0)
00159        {
00160          puts ("join failed");
00161          return 1;
00162        }
00163 
00164       if (dlclose (h))
00165        {
00166          puts ("dlclose failed");
00167          return 1;
00168        }
00169 
00170       printf ("test %d with %s succeeded\n", i, modules[i]);
00171     }
00172 
00173   if (pthread_join (th[0], NULL) != 0)
00174     {
00175       puts ("join failed");
00176       return 1;
00177     }
00178 
00179   return 0;
00180 }
00181 
00182 #define TIMEOUT 5
00183 #define TEST_FUNCTION do_test ()
00184 
00185 #else
00186 
00187 #define TEST_FUNCTION 0
00188 
00189 #endif
00190 
00191 #include "../test-skeleton.c"