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