Back to index

glibc  2.9
ex13.c
Go to the documentation of this file.
00001 /* Test for Pthreads/mutexes.
00002    Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Kurt Garloff <garloff@suse.de>, 2000.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public License as
00008    published by the Free Software Foundation; either version 2.1 of the
00009    License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; see the file COPYING.LIB.  If not,
00018    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.  */
00020 
00021 #include <errno.h>
00022 #include <pthread.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 
00028 static void *thread_start (void *ptr) __attribute__ ((__noreturn__));
00029 
00030 
00031 struct thr_ctrl
00032 {
00033   pthread_mutex_t mutex;
00034   pthread_cond_t cond;
00035   int retval;
00036 };
00037 
00038 static void
00039 dump_mut (pthread_mutex_t * mut)
00040 {
00041   size_t i;
00042   for (i = 0; i < sizeof (*mut); i++)
00043     printf (" %02x", *((unsigned char *) mut + i));
00044   printf ("\n");
00045 };
00046 
00047 /* Helper, the opposite of pthread_cond_wait (cond, mut).  */
00048 static void
00049 pthr_cond_signal_mutex (pthread_cond_t * cond, pthread_mutex_t * mut)
00050 {
00051   int err;
00052   err = pthread_mutex_lock (mut);
00053   if (err)
00054     printf ("mutex_lock  : %s\n", strerror (err));
00055   err = pthread_cond_signal (cond);
00056   if (err)
00057     printf ("cond_signal : %s\n", strerror (err));
00058   err = pthread_mutex_unlock (mut);
00059   if (err)
00060     printf ("mutex_unlock: %s\n", strerror (err));
00061 }
00062 
00063 static void *
00064 thread_start (void *ptr)
00065 {
00066   struct thr_ctrl *tc = ptr;
00067   /* Do initialization.  */
00068   /* ... */
00069   /* Signal that we are ready.  */
00070   pthr_cond_signal_mutex (&tc->cond, &tc->mutex);
00071   sleep (2);
00072   pthr_cond_signal_mutex (&tc->cond, &tc->mutex);
00073   tc->retval = 0;
00074   pthread_exit (&tc->retval);
00075 }
00076 
00077 int
00078 main (void)
00079 {
00080   struct thr_ctrl threadctrl;
00081   pthread_t thread;
00082   int err;
00083   void *res = &threadctrl.retval;
00084   pthread_mutexattr_t mutattr;
00085   pthread_mutexattr_init (&mutattr);
00086   pthread_mutex_init (&threadctrl.mutex, &mutattr);
00087   pthread_cond_init (&threadctrl.cond, NULL);
00088   err = pthread_mutex_lock (&threadctrl.mutex);
00089   if (err)
00090     printf ("mutex_lock : %s\n", strerror (err));
00091   dump_mut (&threadctrl.mutex);
00092   pthread_create (&thread, NULL, thread_start, &threadctrl);
00093   /* Wait until it's ready.  */
00094   err = pthread_cond_wait (&threadctrl.cond, &threadctrl.mutex);
00095   if (err)
00096     printf ("cond_wait  : %s\n", strerror (err));
00097   /* Now, we should have acquired the mutex again!  */
00098   dump_mut (&threadctrl.mutex);
00099   sleep (1);
00100   dump_mut (&threadctrl.mutex);
00101   err = pthread_cond_wait (&threadctrl.cond, &threadctrl.mutex);
00102   if (err)
00103     {
00104       printf ("cond_wait  : %s\n", strerror (err));
00105       printf ("ERROR\n");
00106       abort ();
00107     };
00108   dump_mut (&threadctrl.mutex);
00109   pthread_join (thread, &res);
00110   printf ("OK\n");
00111   return 0;
00112 }