1 /* 2 * Copyright (C) 2010 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 29 /* This program is used to test that sem_post() will wake up all 30 * threads that are waiting on a single semaphore, and not all of 31 * them. 32 */ 33 34 #include <pthread.h> 35 #include <semaphore.h> 36 #include <stdio.h> 37 #include <errno.h> 38 #include <string.h> 39 #include <unistd.h> 40 41 static sem_t semaphore; 42 43 /* Thread function, just wait for the semaphore */ 44 static void* 45 thread_func(void* arg) 46 { 47 sem_t *psem = (sem_t *)arg; 48 void *me = (void *)pthread_self(); 49 printf("thread %p waiting\n", me); 50 sem_wait(psem); 51 printf("thread %p exiting\n", me); 52 return me; 53 } 54 55 #define MAX_THREADS 50 56 57 int main(void) 58 { 59 pthread_t t[MAX_THREADS]; 60 int nn, value; 61 62 /* Initialize to 1, first thread will exit immediately. 63 * this is used to exercize more of the semaphore code path */ 64 if ( sem_init( &semaphore, 0, 1 ) < 0 ) { 65 printf( "Could not initialize semaphore: %s\n", strerror(errno) ); 66 return 1; 67 } 68 69 for ( nn = 0; nn < MAX_THREADS; nn++ ) { 70 if ( pthread_create( &t[nn], NULL, thread_func, &semaphore ) < 0 ) { 71 printf("Could not create thread %d: %s\n", nn+1, strerror(errno) ); 72 return 2; 73 } 74 } 75 sleep( 1 ); 76 77 for (nn = 0; nn < MAX_THREADS; nn++) { 78 sem_post(&semaphore); 79 } 80 81 for ( nn = 0; nn < MAX_THREADS; nn++) { 82 void* result; 83 pthread_join(t[nn], &result); 84 if (result != (void*)t[nn]) { 85 printf("Thread %p joined but returned %p\n", (void*)t[nn], result); 86 } 87 } 88 89 if (sem_getvalue(&semaphore, &value) < 0) { 90 printf("Could not get semaphore value: %s\n", strerror(errno)); 91 return 3; 92 } 93 if (value != 1) { 94 printf("Error: Semaphore value = %d\n", value); 95 return 4; 96 } 97 return 0; 98 } 99