blob: 423b2fe9019f1685e02cfa709b75a61552438164 [file] [log] [blame]
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: crystal.xiong REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
*
* Test the well-known sleeping barber problem.
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include "posixtest.h"
#define CHAIR_NUM 5
#define CUS_NUM 10
#define LOOP_NUM 30
sem_t customer;
sem_t barber;
sem_t lock;
sem_t print;
int waiting = 0;
#ifdef __GNUC__
#define my_printf(x...) do { \
sem_wait(&print); \
printf(x); \
sem_post(&print); \
} while (0)
#else
#define my_printf printf
#endif
void mdelay(unsigned msecs)
{
struct timespec req;
req.tv_sec = msecs / 1000;
req.tv_nsec = (msecs % 1000) * 1000000;
nanosleep(&req, NULL);
}
void *barbers(void *unused)
{
int i;
for (i = 0; i < LOOP_NUM; i++) {
if (-1 == sem_wait(&lock)) {
perror("sem_wait(&lock) didn't return success");
pthread_exit((void *)1);
}
if (waiting == 0) {
my_printf
("There are no more customers waiting, barber will sleep.\n");
}
if (-1 == sem_post(&lock)) {
perror("sem_post(&lock) didn't return success");
pthread_exit((void *)1);
}
if (-1 == sem_wait(&customer)) {
perror("sem_wait(&customer) didn't return success");
pthread_exit((void *)1);
}
if (-1 == sem_wait(&lock)) {
perror("sem_wait(&lock) didn't return success");
pthread_exit((void *)1);
}
if (waiting >= 1)
waiting--;
my_printf
("A customer sits in the barber's chair and get a hair cut. %d customers left waiting.\n",
waiting);
if (-1 == sem_post(&lock)) {
perror("sem_post(&lock) didn't return success");
pthread_exit((void *)1);
}
if (-1 == sem_post(&barber)) {
perror("sem_post(&barber) didn't return success");
pthread_exit((void *)1);
}
}
return NULL;
}
void *customers(void *ID)
{
int CusID;
CusID = *(int *)ID;
if (CusID == 8)
mdelay(10);
my_printf("customer %d enters the room.\n", CusID);
if (-1 == sem_wait(&lock)) {
perror("sem_wait(&lock) didn't return success");
pthread_exit((void *)1);
}
if (waiting < CHAIR_NUM) {
waiting = waiting + 1;
if (-1 == sem_post(&customer)) {
perror("sem_post(&customer) didn't return success");
pthread_exit((void *)1);
}
my_printf
("Customer %d sits down, now %d customers are waiting.\n",
CusID, waiting);
if (-1 == sem_post(&lock)) {
perror("sem_post(&lock) didn't return success");
pthread_exit((void *)1);
}
if (-1 == sem_wait(&barber)) {
perror("sem_wait(&barber) didn't return success");
pthread_exit((void *)1);
}
my_printf("Customer %d leaves with nice hair.\n", CusID);
} else {
my_printf
("No chairs available, customer %d leaves without a haircut.\n",
CusID);
if (-1 == sem_post(&lock)) {
perror("sem_post(&lock) didn't return success");
pthread_exit((void *)1);
}
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t bar, cus[CUS_NUM];
int shared = 0;
int barber_value = 0;
int customer_value = 0;
int lock_value = 1;
int i, ID[CUS_NUM];
if (-1 == sem_init(&print, shared, 1)) {
perror("sem_init(&print) didn't return success");
return PTS_UNRESOLVED;
}
#ifndef _POSIX_SEMAPHORES
my_printf("_POSIX_SEMAPHORES is not defined\n");
return PTS_UNRESOLVED;
#endif
if (-1 == sem_init(&customer, shared, customer_value)) {
perror("sem_init(&customer) didn't return success");
return PTS_UNRESOLVED;
}
if (-1 == sem_init(&barber, shared, barber_value)) {
perror("sem_init(&barber) didn't return success");
return PTS_UNRESOLVED;
}
if (-1 == sem_init(&lock, shared, lock_value)) {
perror("sem_init(&lock) didn't return success");
return PTS_UNRESOLVED;
}
for (i = 0; i < CUS_NUM; i++) {
ID[i] = i;
pthread_create(&cus[i], NULL, customers, (void *)&ID[i]);
}
pthread_create(&bar, NULL, barbers, NULL);
for (i = 0; i < CUS_NUM; i++)
pthread_join(cus[i], NULL);
return PTS_PASS;
}