/////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2004-2006 Intel Corporation // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// // Demonstrates the use of Pthreads condition variable. #include #include #include "pthread.h" #define BLOCK_SIZE 100 #define BUF_SIZE 1000000 size_t bytesRead; typedef struct { pthread_mutex_t mutex; // the mutex pthread_cond_t cv; // the condition variable int data; // the data item used as a flag. } flag; flag ourFlag = { // default initialization PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 }; // data item set to 0 pthread_t hThread1, hThread2; // the waiting threads void* PrintCountRead ( void* ); // the thread function int main ( int argc, char *argv[] ) { FILE *infile; char *inbuf; int status; if ( argc != 2 ) { printf ( "Usage GetSetEvents filename\n" ); return ( -1 ); } infile = fopen ( argv[1], "r+b" ); if ( infile == NULL ) { printf ( "Error opening %s\n", argv[1] ); return ( -1 ); } inbuf = (char*) malloc ( BUF_SIZE ); if ( inbuf == NULL ) { printf ( "Could not allocate read buffer\n" ); return ( -1 ); } // now start up two threads pthread_create ( &hThread1, NULL, PrintCountRead, (void *) NULL ); pthread_create ( &hThread2, NULL, PrintCountRead, (void *) NULL ); bytesRead = fread ( inbuf, 1, BLOCK_SIZE, infile ); if ( bytesRead < BLOCK_SIZE ) { printf ( "Need a file longer than %d bytes\n", BLOCK_SIZE ); return ( -1 ); } else // now we tell the waiting thread(s) { // first, lock the mutex status = pthread_mutex_lock ( &ourFlag.mutex ); if ( status != 0 ) { printf ( "error locking mutex in main function\n" ); exit ( -1 ); } ourFlag.data = 1; // change the data item (our flag) // then broadcast the change status = pthread_cond_broadcast ( &ourFlag.cv ) ; if ( status != 0 ) { printf ( "error broadcasting condition variable\n" ); exit ( -1 ); } // unlock the mutex status = pthread_mutex_unlock ( &ourFlag.mutex ); if ( status != 0 ) { printf ( "error unlocking mutex in waiting function\n" ); exit ( -1 ); } } while ( !feof ( infile ) && bytesRead < BUF_SIZE - BLOCK_SIZE ) bytesRead += fread ( inbuf, 1, BLOCK_SIZE, infile ); printf ( "Read a total of %d bytes\n", (int) bytesRead ); return ( 0 ); } // the thread function, which waits on the condition variable void *PrintCountRead ( void* pv ) { int status; // lock the mutex status = pthread_mutex_lock ( &ourFlag.mutex ); if ( status != 0 ) { printf ( "error locking mutex in waiting function\n" ); exit ( -1 ); } // now wait on the condition variable (loop should spin once only) while ( ourFlag.data == 0 ) { status = pthread_cond_wait ( &ourFlag.cv, &ourFlag.mutex ); if ( status != 0 ) { printf ( "error waiting on condition variable\n" ); exit ( -1 ); } } if ( ourFlag.data != 0 ) { printf ( "Condition was signaled. " "Main thread has read %06d bytes\n", (int) bytesRead ); } // unlock the mutex status = pthread_mutex_unlock ( &ourFlag.mutex ); if ( status != 0 ) { printf ( "error unlocking mutex in waiting function\n" ); exit ( -1 ); } return ( pv ); }