All pastes #980860 Raw Edit

Mine

public text v1 · immutable
·published 2008-04-11 10:27 UTC
rendered paste body
/**
 * TI II - Fachpraktikum 2
 * Copyright (C) 2006 ETH Zurich
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>

void* barber_main(void* arg);
void* customer_main(void* arg);
void quit(int sig);
void quitsem(int sig);

/***********************************************/
/* declaration */
/***********************************************/

/*given: */
static int num_barbers = 4;
static int num_customers = 60;
static int max_customers = 20;

int i;

/* number of customers in the shop */
int custom_in_shop=0;
sem_t custom_in_shop_sem;

/* available places on the sofa */
sem_t sofa;

/* barrier hair cut */
sem_t cuthair_custom_ready;
sem_t cuthair_barber_ready;

/* simple barrier to ensure customer
   waits until barber is done */
sem_t cuthair_done;

/* is cash desk free? */
sem_t cash_desk;

/*barrier payment */
sem_t payment_custom_ready;
sem_t payment_barber_ready;

/* threads: each barber and each customer curresponds to one thread */
pthread_t* barbers;
pthread_t* customers;


int main(int argc, char **argv)
{
        /****************************************************/
        /* initialization                                   */
        /****************************************************/
        printf("INIT: start... \n");
        /* prepare threads */
        barbers = malloc(num_barbers * sizeof(pthread_t));
        customers = malloc(num_customers * sizeof(pthread_t));
        if (barbers == NULL || customers == NULL)
                return -1;

        /* initialize semaphore */
        if(sem_init(&custom_in_shop_sem, 0, 1) < 0)
                return -1;
        if(sem_init(&sofa, 0, 4) < 0)
                return -1;
        if(sem_init(&cuthair_custom_ready, 0, 0) < 0)
                return -1;
        if(sem_init(&cuthair_barber_ready, 0, 0) < 0)
                return -1;
        if(sem_init(&cuthair_done, 0, 0) < 0)
                return -1;
        if(sem_init(&cash_desk, 0, 1) < 0)
                return -1;
        if(sem_init(&payment_custom_ready, 0, 0) < 0)
                return -1;
        if(sem_init(&payment_barber_ready, 0, 0) < 0)
                return -1;
        printf("\t ... ended\n");
 
        
        /**************************************************/
        /* start thread                                   */
        /**************************************************/

        /* create barber threads: calls barber_main() */
        for (i = 0; i < num_barbers; i++) 
	{
                pthread_create(&barbers[i], NULL, barber_main, (void*)i);
        }
        /* create customer threads: calls customer_main() */
        for (i = 0; i < num_customers; i++) 
	{
                pthread_create(&customers[i], NULL, customer_main, (void*)i);     
        }
        
        /**************************************************/
        /*let barber to their job                         */
        /**************************************************/

        
        /**************************************************/
        /* clean up shop                                  */
        /**************************************************/

        /* wait for customers to leave the shop */
        for (i = 0; i < num_customers; i++) 
	{
                pthread_join(customers[i], NULL);
        }

        /* no costomers -> kill the barbers */
        for (i = 0; i <num_barbers; i++) 
	{
                pthread_kill(barbers[i], 3);
        }
        for (i = 0; i < num_barbers; i++) 
	{
                pthread_join(barbers[i], NULL);
        }

        /* free the semaphores */
        sem_destroy(&custom_in_shop_sem);
        sem_destroy(&sofa);
        sem_destroy(&cuthair_custom_ready);
        sem_destroy(&cuthair_barber_ready);
        sem_destroy(&cuthair_done);
        sem_destroy(&cash_desk);
        sem_destroy(&payment_custom_ready);
        sem_destroy(&payment_barber_ready);

        return 0;
}

void* barber_main(void* arg)
{
        /* get argument */
        int id = (int)arg;

        printf("Starting barber %d\n", id);
        
        /* declare signal handler:
           - stops the barber thread at the end ... */
        signal(SIGQUIT, quit);
        
        /* do the barber job */
        while(1) 
	{
                /*I want to cut hairs */ 
		sem_post(&cuthair_barber_ready);

                /*I am waiting for a client */
		sem_wait(&cuthair_custom_ready);
                printf("BARB %02i: waiting for customer\n", id);

                /*cut the hair */
                printf("BARB %02i: cutting hair\n", id);
                sleep(3);

                /* tell the customer we're done */
		sem_post(&cuthair_done);


                /*wait for cash desk == free */
		sem_wait(&cash_desk);
                printf("BARB %02i: desk free, waiting for customer to pay\n", id);

                /*make the payment */
		sem_post(&payment_barber_ready);
                sem_wait(&payment_custom_ready);


                /*free cash desk */
		sem_post(&cash_desk);
                printf("BARB %02i: payment done\n", id);
        }
        return NULL;
}



void* customer_main(void* arg)
{
        /* get argument */
        int id = (int)arg;

        printf("Starting customer %d\n", id);
	
	sem_wait(&custom_in_shop_sem);
	if(custom_in_shop<max_customers)
	{
		/*check if the shop is not full */
		custom_in_shop++;
		sem_post(&custom_in_shop_sem);
		printf("CUST %02i: entering Shop (%d) \n", id, custom_in_shop);
		
		
		/* wait to sit down to the sofa */
		sem_wait(&sofa);
		printf("CUST %02i: sitting on the sofa\n", id);
	
	
		/* wait for a barber */
		sem_post(&cuthair_custom_ready);
		sem_wait(&cuthair_barber_ready);
	
	
		/* free sofa */
		sem_post(&sofa);
	
		/* barber cuts my hair */
		printf("CUST %02i: leaving the sofa and cutting hair\n", id);
	
		/* wait until the barber is done.
		Although the code may work properly when going directly
		to the payment barrier, something unwanted may happen instead.
		What may happen and why? This is quite an intrictated problem
		and not at all easy to find out. If you can't find
		the explanation, it doesn't matter either. 
		*/
		sem_wait(&cuthair_done);
	
		/* payment barrier */
		sem_post(&payment_custom_ready);
		sem_wait(&payment_barber_ready);
		printf("CUST %02i: payment done\n", id);
	
		/*leave the shop */
		/*enter critical section */
		sem_wait(&custom_in_shop_sem);
		custom_in_shop--;
		sem_post(&custom_in_shop_sem);
		/* leave critical section */
		
		printf("CUST %02i: leaving the shop (%02i) \n", id,custom_in_shop);
	
		return NULL;
	}
	sem_post(&custom_in_shop_sem);

	return NULL;

}

void quit(int sig)
{
        pthread_exit(NULL);
}