Home | History | Annotate | Download | only in semaphores
      1 /*
      2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      3  * Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
      4  * This file is licensed under the GPL license.  For the full content
      5  * of this license, see the COPYING file at the top level of this
      6  * source tree.
      7  *
      8  * Test the well-known sleeping barber problem.
      9  */
     10 
     11 #include <stdio.h>
     12 #include <unistd.h>
     13 #include <fcntl.h>
     14 #include <stdlib.h>
     15 #include <sys/wait.h>
     16 #include <sys/mman.h>
     17 #include <string.h>
     18 #include <errno.h>
     19 #include <pthread.h>
     20 #include <semaphore.h>
     21 #include <time.h>
     22 
     23 #include "posixtest.h"
     24 #define CHAIR_NUM	5
     25 #define CUS_NUM		10
     26 #define LOOP_NUM	30
     27 
     28 sem_t customer;
     29 sem_t barber;
     30 sem_t lock;
     31 sem_t print;
     32 
     33 int waiting = 0;
     34 
     35 #ifdef __GNUC__
     36 #define my_printf(x...) do { \
     37 	sem_wait(&print); \
     38 	printf(x); \
     39 	sem_post(&print); \
     40 } while (0)
     41 #else
     42 #define my_printf printf
     43 #endif
     44 
     45 void mdelay(unsigned msecs)
     46 {
     47 	struct timespec req;
     48 	req.tv_sec = msecs / 1000;
     49 	req.tv_nsec = (msecs % 1000) * 1000000;
     50 	nanosleep(&req, NULL);
     51 }
     52 
     53 void *barbers(void *unused)
     54 {
     55 	int i;
     56 	for (i = 0; i < LOOP_NUM; i++) {
     57 		if (-1 == sem_wait(&lock)) {
     58 			perror("sem_wait(&lock) didn't return success");
     59 			pthread_exit((void *)1);
     60 		}
     61 		if (waiting == 0) {
     62 			my_printf
     63 			    ("There are no more customers waiting, barber will sleep.\n");
     64 		}
     65 		if (-1 == sem_post(&lock)) {
     66 			perror("sem_post(&lock) didn't return success");
     67 			pthread_exit((void *)1);
     68 		}
     69 		if (-1 == sem_wait(&customer)) {
     70 			perror("sem_wait(&customer) didn't return success");
     71 			pthread_exit((void *)1);
     72 		}
     73 		if (-1 == sem_wait(&lock)) {
     74 			perror("sem_wait(&lock) didn't return success");
     75 			pthread_exit((void *)1);
     76 		}
     77 		if (waiting >= 1)
     78 			waiting--;
     79 		my_printf
     80 		    ("A customer sits in the barber's chair and get a hair cut.  %d customers left waiting.\n",
     81 		     waiting);
     82 		if (-1 == sem_post(&lock)) {
     83 			perror("sem_post(&lock) didn't return success");
     84 			pthread_exit((void *)1);
     85 		}
     86 		if (-1 == sem_post(&barber)) {
     87 			perror("sem_post(&barber) didn't return success");
     88 			pthread_exit((void *)1);
     89 		}
     90 
     91 	}
     92 	return NULL;
     93 }
     94 
     95 void *customers(void *ID)
     96 {
     97 	int CusID;
     98 	CusID = *(int *)ID;
     99 
    100 	if (CusID == 8)
    101 		mdelay(10);
    102 
    103 	my_printf("customer %d enters the room.\n", CusID);
    104 	if (-1 == sem_wait(&lock)) {
    105 		perror("sem_wait(&lock) didn't return success");
    106 		pthread_exit((void *)1);
    107 	}
    108 	if (waiting < CHAIR_NUM) {
    109 		waiting = waiting + 1;
    110 		if (-1 == sem_post(&customer)) {
    111 			perror("sem_post(&customer) didn't return success");
    112 			pthread_exit((void *)1);
    113 		}
    114 		my_printf
    115 		    ("Customer %d sits down, now %d customers are waiting.\n",
    116 		     CusID, waiting);
    117 		if (-1 == sem_post(&lock)) {
    118 			perror("sem_post(&lock) didn't return success");
    119 			pthread_exit((void *)1);
    120 		}
    121 		if (-1 == sem_wait(&barber)) {
    122 			perror("sem_wait(&barber) didn't return success");
    123 			pthread_exit((void *)1);
    124 		}
    125 		my_printf("Customer %d leaves with nice hair.\n", CusID);
    126 	} else {
    127 		my_printf
    128 		    ("No chairs available, customer %d leaves without a haircut.\n",
    129 		     CusID);
    130 		if (-1 == sem_post(&lock)) {
    131 			perror("sem_post(&lock) didn't return success");
    132 			pthread_exit((void *)1);
    133 		}
    134 	}
    135 	return NULL;
    136 }
    137 
    138 int main(int argc, char *argv[])
    139 {
    140 	pthread_t bar, cus[CUS_NUM];
    141 	int shared = 0;
    142 	int barber_value = 0;
    143 	int customer_value = 0;
    144 	int lock_value = 1;
    145 	int i, ID[CUS_NUM];
    146 
    147 	if (-1 == sem_init(&print, shared, 1)) {
    148 		perror("sem_init(&print) didn't return success");
    149 		return PTS_UNRESOLVED;
    150 	}
    151 #ifndef  _POSIX_SEMAPHORES
    152 	my_printf("_POSIX_SEMAPHORES is not defined\n");
    153 	return PTS_UNRESOLVED;
    154 #endif
    155 	if (-1 == sem_init(&customer, shared, customer_value)) {
    156 		perror("sem_init(&customer) didn't return success");
    157 		return PTS_UNRESOLVED;
    158 	}
    159 	if (-1 == sem_init(&barber, shared, barber_value)) {
    160 		perror("sem_init(&barber) didn't return success");
    161 		return PTS_UNRESOLVED;
    162 	}
    163 	if (-1 == sem_init(&lock, shared, lock_value)) {
    164 		perror("sem_init(&lock) didn't return success");
    165 		return PTS_UNRESOLVED;
    166 	}
    167 	for (i = 0; i < CUS_NUM; i++) {
    168 		ID[i] = i;
    169 		pthread_create(&cus[i], NULL, customers, (void *)&ID[i]);
    170 	}
    171 	pthread_create(&bar, NULL, barbers, NULL);
    172 	for (i = 0; i < CUS_NUM; i++)
    173 		pthread_join(cus[i], NULL);
    174 
    175 	return PTS_PASS;
    176 }
    177