Back to index

glibc  2.9
tst-cond4.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026 #include <sys/mman.h>
00027 #include <sys/wait.h>
00028 
00029 
00030 int *condition;
00031 
00032 static int
00033 do_test (void)
00034 {
00035   size_t ps = sysconf (_SC_PAGESIZE);
00036   char tmpfname[] = "/tmp/tst-cond4.XXXXXX";
00037   char data[ps];
00038   void *mem;
00039   int fd;
00040   pthread_mutexattr_t ma;
00041   pthread_mutex_t *mut1;
00042   pthread_mutex_t *mut2;
00043   pthread_condattr_t ca;
00044   pthread_cond_t *cond;
00045   pid_t pid;
00046   int result = 0;
00047   int p;
00048 
00049   fd = mkstemp (tmpfname);
00050   if (fd == -1)
00051     {
00052       printf ("cannot open temporary file: %m\n");
00053       return 1;
00054     }
00055 
00056   /* Make sure it is always removed.  */
00057   unlink (tmpfname);
00058 
00059   /* Create one page of data.  */
00060   memset (data, '\0', ps);
00061 
00062   /* Write the data to the file.  */
00063   if (write (fd, data, ps) != (ssize_t) ps)
00064     {
00065       puts ("short write");
00066       return 1;
00067     }
00068 
00069   mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
00070   if (mem == MAP_FAILED)
00071     {
00072       printf ("mmap failed: %m\n");
00073       return 1;
00074     }
00075 
00076   mut1 = (pthread_mutex_t *) (((uintptr_t) mem
00077                             + __alignof (pthread_mutex_t))
00078                            & ~(__alignof (pthread_mutex_t) - 1));
00079   mut2 = mut1 + 1;
00080 
00081   cond = (pthread_cond_t *) (((uintptr_t) (mut2 + 1)
00082                            + __alignof (pthread_cond_t))
00083                           & ~(__alignof (pthread_cond_t) - 1));
00084 
00085   condition = (int *) (((uintptr_t) (cond + 1) + __alignof (int))
00086                      & ~(__alignof (int) - 1));
00087 
00088   if (pthread_mutexattr_init (&ma) != 0)
00089     {
00090       puts ("mutexattr_init failed");
00091       return 1;
00092     }
00093 
00094   if (pthread_mutexattr_getpshared (&ma, &p) != 0)
00095     {
00096       puts ("1st mutexattr_getpshared failed");
00097       return 1;
00098     }
00099 
00100   if (p != PTHREAD_PROCESS_PRIVATE)
00101     {
00102       puts ("default pshared value wrong");
00103       return 1;
00104     }
00105 
00106   if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0)
00107     {
00108       puts ("mutexattr_setpshared failed");
00109       return 1;
00110     }
00111 
00112   if (pthread_mutexattr_getpshared (&ma, &p) != 0)
00113     {
00114       puts ("2nd mutexattr_getpshared failed");
00115       return 1;
00116     }
00117 
00118   if (p != PTHREAD_PROCESS_SHARED)
00119     {
00120       puts ("pshared value after setpshared call wrong");
00121       return 1;
00122     }
00123 
00124   if (pthread_mutex_init (mut1, &ma) != 0)
00125     {
00126       puts ("1st mutex_init failed");
00127       return 1;
00128     }
00129 
00130   if (pthread_mutex_init (mut2, &ma) != 0)
00131     {
00132       puts ("2nd mutex_init failed");
00133       return 1;
00134     }
00135 
00136   if (pthread_condattr_init (&ca) != 0)
00137     {
00138       puts ("condattr_init failed");
00139       return 1;
00140     }
00141 
00142   if (pthread_condattr_getpshared (&ca, &p) != 0)
00143     {
00144       puts ("1st condattr_getpshared failed");
00145       return 1;
00146     }
00147 
00148   if (p != PTHREAD_PROCESS_PRIVATE)
00149     {
00150       puts ("default value for pshared in condattr wrong");
00151       return 1;
00152     }
00153 
00154   if (pthread_condattr_setpshared (&ca, PTHREAD_PROCESS_SHARED) != 0)
00155     {
00156       puts ("condattr_setpshared failed");
00157       return 1;
00158     }
00159 
00160   if (pthread_condattr_getpshared (&ca, &p) != 0)
00161     {
00162       puts ("2nd condattr_getpshared failed");
00163       return 1;
00164     }
00165 
00166   if (p != PTHREAD_PROCESS_SHARED)
00167     {
00168       puts ("pshared condattr still not set");
00169       return 1;
00170     }
00171 
00172   if (pthread_cond_init (cond, &ca) != 0)
00173     {
00174       puts ("cond_init failed");
00175       return 1;
00176     }
00177 
00178   if (pthread_mutex_lock (mut1) != 0)
00179     {
00180       puts ("parent: 1st mutex_lock failed");
00181       return 1;
00182     }
00183 
00184   puts ("going to fork now");
00185   pid = fork ();
00186   if (pid == -1)
00187     {
00188       puts ("fork failed");
00189       return 1;
00190     }
00191   else if (pid == 0)
00192     {
00193       if (pthread_mutex_lock (mut2) != 0)
00194        {
00195          puts ("child: mutex_lock failed");
00196          return 1;
00197        }
00198 
00199       if (pthread_mutex_unlock (mut1) != 0)
00200        {
00201          puts ("child: 1st mutex_unlock failed");
00202          return 1;
00203        }
00204 
00205       do
00206        if (pthread_cond_wait (cond, mut2) != 0)
00207          {
00208            puts ("child: cond_wait failed");
00209            return 1;
00210          }
00211       while (*condition == 0);
00212 
00213       if (pthread_mutex_unlock (mut2) != 0)
00214        {
00215          puts ("child: 2nd mutex_unlock failed");
00216          return 1;
00217        }
00218 
00219       puts ("child done");
00220     }
00221   else
00222     {
00223       int status;
00224 
00225       if (pthread_mutex_lock (mut1) != 0)
00226        {
00227          puts ("parent: 2nd mutex_lock failed");
00228          return 1;
00229        }
00230 
00231       if (pthread_mutex_lock (mut2) != 0)
00232        {
00233          puts ("parent: 3rd mutex_lock failed");
00234          return 1;
00235        }
00236 
00237       if (pthread_cond_signal (cond) != 0)
00238        {
00239          puts ("parent: cond_signal failed");
00240          return 1;
00241        }
00242 
00243       *condition = 1;
00244 
00245       if (pthread_mutex_unlock (mut2) != 0)
00246        {
00247          puts ("parent: mutex_unlock failed");
00248          return 1;
00249        }
00250 
00251       puts ("waiting for child");
00252 
00253       waitpid (pid, &status, 0);
00254       result |= status;
00255 
00256       puts ("parent done");
00257     }
00258 
00259  return result;
00260 }
00261 
00262 #define TEST_FUNCTION do_test ()
00263 #include "../test-skeleton.c"