183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner/* 283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * Copyright (C) 2010 The Android Open Source Project 383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * All rights reserved. 483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * 583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * Redistribution and use in source and binary forms, with or without 683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * modification, are permitted provided that the following conditions 783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * are met: 883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * * Redistributions of source code must retain the above copyright 983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * notice, this list of conditions and the following disclaimer. 1083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * * Redistributions in binary form must reproduce the above copyright 1183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * notice, this list of conditions and the following disclaimer in 1283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * the documentation and/or other materials provided with the 1383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * distribution. 1483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * 1583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * SUCH DAMAGE. 2783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner */ 2883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 2983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner/* This program is used to test that sem_post() will wake up all 3083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * threads that are waiting on a single semaphore, and not all of 3183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * them. 3283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner */ 3383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 3483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <pthread.h> 3583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <semaphore.h> 3683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <stdio.h> 3783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <errno.h> 3883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <string.h> 3983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <unistd.h> 4083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 4183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turnerstatic sem_t semaphore; 4283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 4383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner/* Thread function, just wait for the semaphore */ 4483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turnerstatic void* 4583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turnerthread_func(void* arg) 4683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner{ 4783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner sem_t *psem = (sem_t *)arg; 4883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner void *me = (void *)pthread_self(); 4983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("thread %p waiting\n", me); 5083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner sem_wait(psem); 5183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("thread %p exiting\n", me); 5283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return me; 5383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner} 5483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 5583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#define MAX_THREADS 50 5683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 5783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turnerint main(void) 5883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner{ 5983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner pthread_t t[MAX_THREADS]; 6083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner int nn, value; 6183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 6283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner /* Initialize to 1, first thread will exit immediately. 6383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * this is used to exercize more of the semaphore code path */ 6483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if ( sem_init( &semaphore, 0, 1 ) < 0 ) { 6583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf( "Could not initialize semaphore: %s\n", strerror(errno) ); 6683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 1; 6783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 6883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 6983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner for ( nn = 0; nn < MAX_THREADS; nn++ ) { 7083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if ( pthread_create( &t[nn], NULL, thread_func, &semaphore ) < 0 ) { 7183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("Could not create thread %d: %s\n", nn+1, strerror(errno) ); 7283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 2; 7383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 7483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 7583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner sleep( 1 ); 7683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 7783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner for (nn = 0; nn < MAX_THREADS; nn++) { 7883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner sem_post(&semaphore); 7983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 8083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 8183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner for ( nn = 0; nn < MAX_THREADS; nn++) { 8283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner void* result; 8383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner pthread_join(t[nn], &result); 8483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (result != (void*)t[nn]) { 8583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("Thread %p joined but returned %p\n", (void*)t[nn], result); 8683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 8783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 8883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 8983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (sem_getvalue(&semaphore, &value) < 0) { 9083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("Could not get semaphore value: %s\n", strerror(errno)); 9183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 3; 9283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 9383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (value != 1) { 9483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner printf("Error: Semaphore value = %d\n", value); 9583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 4; 9683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 9783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 0; 9883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner} 99