1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #include <pthread.h> 29 #include <semaphore.h> 30 #include <errno.h> 31 #include <stdio.h> 32 #include <time.h> 33 #include <string.h> 34 #include <unistd.h> 35 36 /* a simple semaphore test, using three threads 37 * 38 * a semaphore is initialized with a value of 1 39 * 40 * Thread 1, 2 and 3 start at the same time 41 * 42 * Thread 1 takes the semaphore, then sleeps for 2 seconds, then post the semaphore 43 * Thread 2 sleeps for 1 second, then waits the semaphore, sleeps for 2 seconds, then post the semaphoe 44 * Thread 3 sleeps 3 seconds, waits for the semaphore 45 */ 46 47 static sem_t semaphore; 48 49 static void* 50 _thread1( void* unused ) 51 { 52 printf( "thread 1: waiting for semaphore\n" ); 53 if ( sem_wait( &semaphore ) < 0 ) { 54 printf( "thread 1: could not wait for semaphore: %s\n", strerror(errno) ); 55 return NULL; 56 } 57 printf( "thread 1: got the semaphore ! sleeping for 2 seconds\n" ); 58 sleep( 2 ); 59 printf( "thread 1: awake !! posting semaphore\n" ); 60 if ( sem_post( &semaphore ) < 0 ) { 61 printf( "thread 2: could not post semaphore: %s\n", strerror(errno) ); 62 } 63 printf( "thread 1: quitting\n" ); 64 return NULL; 65 } 66 67 static void* 68 _thread2( void* unused ) 69 { 70 printf( "thread 2: sleeping for 1 second\n" ); 71 sleep(1); 72 printf( "thread 2: awake !! waiting for semaphore\n" ); 73 if ( sem_wait( &semaphore ) < 0 ) { 74 printf( "thread 2: could not wait for semaphore: %s\n", strerror(errno) ); 75 return NULL; 76 } 77 printf( "thread 2: got the semaphore ! sleeping for 2 seconds\n" ); 78 sleep( 2 ); 79 printf( "thread 2: awake !! posting semaphore\n" ); 80 if ( sem_post( &semaphore ) < 0 ) { 81 printf( "thread 2: could not post semaphore: %s\n", strerror(errno) ); 82 } 83 printf( "thread 2: quitting\n" ); 84 return NULL; 85 } 86 87 88 static void* 89 _thread3( void* unused ) 90 { 91 printf( "thread 3: sleeping for 3 seconds\n" ); 92 sleep(3); 93 printf( "thread 3: awake !! waiting for semaphore\n" ); 94 if ( sem_wait( &semaphore ) < 0 ) { 95 printf( "thread 3: could not wait for semaphore: %s\n", strerror(errno) ); 96 return NULL; 97 } 98 printf( "thread 3: got semaphore. quitting\n" ); 99 return NULL; 100 } 101 102 typedef void* (*thread_func)(void*); 103 104 static const thread_func thread_routines[] = 105 { 106 &_thread1, 107 &_thread2, 108 &_thread3 109 }; 110 111 int main( void ) 112 { 113 pthread_t t[3]; 114 int nn; 115 116 if ( sem_init( &semaphore, 0, 1 ) < 0 ) { 117 printf( "could not initialize semaphore: %s\n", strerror(errno) ); 118 return -1; 119 } 120 121 for ( nn = 0; nn < 3; nn++ ) { 122 if ( pthread_create( &t[nn], NULL, thread_routines[nn], NULL ) < 0 ) { 123 printf("could not create thread %d: %s\n", nn+1, strerror(errno) ); 124 return -2; 125 } 126 } 127 sleep( 5 ); 128 return 0; 129 } 130