Back to index

glibc  2.9
tst-kill6.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 <errno.h>
00021 #include <pthread.h>
00022 #include <semaphore.h>
00023 #include <signal.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027 
00028 
00029 static pthread_t receiver;
00030 static sem_t sem;
00031 static pthread_barrier_t b;
00032 
00033 static void
00034 handler (int sig)
00035 {
00036   if (sig != SIGUSR1)
00037     {
00038       write (STDOUT_FILENO, "wrong signal\n", 13);
00039       _exit (1);
00040     }
00041 
00042   if (pthread_self () != receiver)
00043     {
00044       write (STDOUT_FILENO, "not the intended receiver\n", 26);
00045       _exit (1);
00046     }
00047 
00048   if (sem_post (&sem) != 0)
00049     {
00050       write (STDOUT_FILENO, "sem_post failed\n", 16);
00051       _exit (1);
00052     }
00053 }
00054 
00055 
00056 static void *
00057 tf (void *a)
00058 {
00059   int e = pthread_barrier_wait (&b);
00060   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00061     {
00062       puts ("child: barrier_wait failed");
00063       exit (1);
00064     }
00065 
00066   return NULL;
00067 }
00068 
00069 
00070 int
00071 do_test (void)
00072 {
00073   struct sigaction sa;
00074   sigemptyset (&sa.sa_mask);
00075   sa.sa_flags = 0;
00076   sa.sa_handler = handler;
00077   if (sigaction (SIGUSR1, &sa, NULL) != 0)
00078     {
00079       puts ("sigaction failed");
00080       exit (1);
00081     }
00082 
00083 #define N 20
00084 
00085   if (pthread_barrier_init (&b, NULL, N + 1) != 0)
00086     {
00087       puts ("barrier_init failed");
00088       exit (1);
00089     }
00090 
00091   pthread_attr_t a;
00092 
00093   if (pthread_attr_init (&a) != 0)
00094     {
00095       puts ("attr_init failed");
00096       exit (1);
00097     }
00098 
00099   if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
00100     {
00101       puts ("attr_setstacksize failed");
00102       return 1;
00103     }
00104 
00105   pthread_t th[N];
00106   int i;
00107   for (i = 0; i < N; ++i)
00108     if (pthread_create (&th[i], &a, tf, NULL) != 0)
00109       {
00110        puts ("create failed");
00111        exit (1);
00112       }
00113 
00114   if (pthread_attr_destroy (&a) != 0)
00115     {
00116       puts ("attr_destroy failed");
00117       exit (1);
00118     }
00119 
00120   if (sem_init (&sem, 0, 0) != 0)
00121     {
00122       puts ("sem_init failed");
00123       exit (1);
00124     }
00125 
00126   for (i = 0; i < N * 10; ++i)
00127     {
00128       receiver = th[i % N];
00129 
00130       if (pthread_kill (receiver, SIGUSR1) != 0)
00131        {
00132          puts ("kill failed");
00133          exit (1);
00134        }
00135 
00136       if (TEMP_FAILURE_RETRY (sem_wait (&sem)) != 0)
00137        {
00138          puts ("sem_wait failed");
00139          exit (1);
00140        }
00141     }
00142 
00143   int e = pthread_barrier_wait (&b);
00144   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00145     {
00146       puts ("barrier_wait failed");
00147       exit (1);
00148     }
00149 
00150   for (i = 0; i < N; ++i)
00151     if (pthread_join (th[i], NULL) != 0)
00152       {
00153        puts ("join failed");
00154        exit (1);
00155       }
00156 
00157   return 0;
00158 }
00159 
00160 
00161 #define TEST_FUNCTION do_test ()
00162 #include "../test-skeleton.c"