#include #include #include

Report 6 Downloads 274 Views
#include <stdlib.h> #include <semaphore.h> #include #include <stdio.h> #include #include "buffer.h" #define MAX_SLEEP_TIME_FOR_THREADS 2 #define MAX_RAND_NUM 100 /* Global variables */ // buffer buffer_item buffer[BUFFER_SIZE]; int start_of_buffer = 1; int end_of_buffer = 0; // semaphores sem_t empty; sem_t full; // mutex pthread_mutex_t mutex;

/* prototypes */ int initializeBuffer(); void *producer( void *param ); void *consumer( void *param ); int insertitem( buffer_item item ); int removeitem( buffer_item *item );

int main( int argc, char *argv[] ) { int sleepTime; int numProducer; int numConsumer; int i; // random number seed srand( (unsigned)time( NULL ) );

pthread_t tid; /* the thread identifier */ /* If no 3 inputs were entered, quit */ if ( argc != 4 ) { printf( "You need to input 3 integers\n" ); return -1; } /* 1. Get command line arguments argv[1],argv[2],argv[3] */ sleepTime = atoi( argv[1] ); numProducer = atoi( argv[2] ); numConsumer = atoi( argv[3] ); /* 2. Initialize buffer */ if ( initializeBuffer() != 0 ) { // error is reported inside the function return -1; } /* 3. Create producer thread(s) */ for ( i = 0; i < numProducer; i++ ) { if ( pthread_create( &tid, NULL, producer, &sleepTime ) != 0 ) { printf( "A producer thread creation failed.\n" ); } } /* 4. Create consumer thread(s) */ for ( i = 0; i < numConsumer; i ++ ) { if ( pthread_create( &tid, NULL, consumer, &sleepTime ) ) { printf( "A consumer thread creation failed.\n" ); } } /* 5. Sleep */

sleep( sleepTime ); /* 6. Exit */ return 0; }

int initializeBuffer() { sem_init( &empty, 0, 4 ); sem_init( &full, 0, 0 ); if ( pthread_mutex_init( &mutex, NULL ) != 0 ) { printf( "Mutex initialization failed.\n" ); return -1; } return 0; } /* insert item into buffer return 0 if successful, otherwise return -1 indicating an error condition */ int insert_item( buffer_item item ) { int sem_value_for_debugging; sem_wait( &empty ); if ( pthread_mutex_lock( &mutex ) != 0 ) { return -1; }

// lock operaton failed

// Do I need to check if it overflows? I don't think so... if ( start_of_buffer == end_of_buffer ) { return -1; } else

{ /* critical seciton */ buffer[start_of_buffer] = item; start_of_buffer = ( start_of_buffer + 1 ) % BUFFER_SIZE; } /* printf( "producer produced %d\n", item ); // debugging purpose sem_getvalue( &full, &sem_value_for_debugging ); // good for understanding the semaphore printf( "full: %d\n", sem_value_for_debugging+1 ); sem_getvalue( &empty, &sem_value_for_debugging ); printf( "empty: %d\n", sem_value_for_debugging ); */ if ( pthread_mutex_unlock( &mutex ) != 0 ) { return -1; }

// unlock operation failed

sem_post( &full ); return 0; } /* remove an object from buffer placing it in item variable return 0 if successful, otherwise return -1 indicating an error condition */ int remove_item( buffer_item *item ) { int sem_value_for_debugging; sem_wait( &full ); if ( pthread_mutex_lock( &mutex ) != 0 ) { return -1; } // Do I need to check if it underflows?

// lock operation failed

if ( end_of_buffer + 1 == start_of_buffer ) { return -1; } else { /* critical seciton */ end_of_buffer = ( end_of_buffer + 1 ) % BUFFER_SIZE; *item = buffer[end_of_buffer]; } /* printf( "consumer consumed %d\n", *item ); // debugging purpose sem_getvalue( &full, &sem_value_for_debugging ); // good for understanding semaphore printf( "full: %d\n", sem_value_for_debugging ); sem_getvalue( &empty, &sem_value_for_debugging ); printf( "empty: %d\n", sem_value_for_debugging+1 ); */ if ( pthread_mutex_unlock( &mutex ) != 0 ) { return -1; }

// unlock opeartion failed

sem_post( &empty ); return 0; } void *producer( void *param ) { buffer_item item; while ( 1 ) { /* sleep for a random period of time */ sleep( rand() % MAX_SLEEP_TIME_FOR_THREADS ); /* generate a random number */ item = rand() % MAX_RAND_NUM; if ( insert_item( item ) )

{ printf( "Producer failed to insert item.\n" ); } else { printf( "producer produced %d\n", item ); } } } void *consumer( void *param ) { buffer_item item; while ( 1 ) { /* sleep for a random period of time */ sleep( rand() % MAX_SLEEP_TIME_FOR_THREADS ); if ( remove_item( &item ) ) { printf( "Consumer failed to remove item.\n" ); } else { printf( "consumer consumed %d\n", item ); } } }