Home | History | Annotate | Download | only in semaphores
      1 
      2 /*
      3  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      4  * Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
      5  * This file is licensed under the GPL license.  For the full content
      6  * of this license, see the COPYING file at the top level of this
      7  * source tree.
      8  *
      9  * This is a test about producer and consumer. Producer sends data
     10  * to a buffer. Consumer keeps reading data from the buffer.
     11  */
     12 
     13 #include <stdio.h>
     14 #include <unistd.h>
     15 #include <fcntl.h>
     16 #include <stdlib.h>
     17 #include <sys/wait.h>
     18 #include <sys/mman.h>
     19 #include <string.h>
     20 #include <errno.h>
     21 #include <pthread.h>
     22 #include <semaphore.h>
     23 
     24 #include "posixtest.h"
     25 
     26 #define BUF_SIZE	5
     27 #define Max_Num		10
     28 
     29 typedef struct {
     30 	int buffer[BUF_SIZE];
     31 	sem_t occupied;
     32 	sem_t empty;
     33 	sem_t lock;
     34 } buf_t;
     35 
     36 int in, out;
     37 
     38 int *producer(buf_t * buf)
     39 {
     40 	int data;
     41 	int i;
     42 
     43 	for (i = 0; i < Max_Num; i++) {
     44 		if (-1 == sem_wait(&buf->occupied)) {
     45 			perror("sem_wait didn't return success \n");
     46 			pthread_exit((void *)1);
     47 		}
     48 		if (-1 == sem_wait(&buf->lock)) {
     49 			perror("sem_wait didn't return success \n");
     50 			pthread_exit((void *)1);
     51 		}
     52 		data = 100 * i;
     53 		buf->buffer[in] = data;
     54 		printf("producer has added %d to the buffer[%d] \n", data, in);
     55 		in = (in + 1) % BUF_SIZE;
     56 		if (-1 == sem_post(&buf->lock)) {
     57 			perror("sem_wait didn't return success \n");
     58 			pthread_exit((void *)1);
     59 		}
     60 		if (-1 == sem_post(&buf->empty)) {
     61 			perror("sem_wait didn't return success \n");
     62 			pthread_exit((void *)1);
     63 		}
     64 	}
     65 	pthread_exit(NULL);
     66 }
     67 
     68 int *consumer(buf_t * buf)
     69 {
     70 	int data;
     71 	int i;
     72 
     73 	for (i = 0; i < Max_Num; i++) {
     74 		if (-1 == sem_wait(&buf->empty)) {
     75 			perror("sem_wait didn't return success \n");
     76 			pthread_exit((void *)1);
     77 		}
     78 		if (-1 == sem_wait(&buf->lock)) {
     79 			perror("sem_wait didn't return success \n");
     80 			pthread_exit((void *)1);
     81 		}
     82 		data = buf->buffer[out];
     83 		printf("consumer has taken %d from buffer[%d] \n", data, out);
     84 		out = (out + 1) % BUF_SIZE;
     85 		if (-1 == sem_post(&buf->lock)) {
     86 			perror("sem_wait didn't return success \n");
     87 			pthread_exit((void *)1);
     88 		}
     89 		if (-1 == sem_post(&buf->occupied)) {
     90 			perror("sem_wait didn't return success \n");
     91 			pthread_exit((void *)1);
     92 		}
     93 	}
     94 	pthread_exit(0);
     95 }
     96 
     97 int main(int argc, char *argv[])
     98 {
     99 	int shared = 1;
    100 	int occupied_value = BUF_SIZE;
    101 	int empty_value = 0;
    102 	int lock_value = 1;
    103 	buf_t buf;
    104 	pthread_t con, pro;
    105 
    106 #ifndef  _POSIX_SEMAPHORES
    107 	printf("_POSIX_SEMAPHORES is not defined \n");
    108 	return PTS_UNRESOLVED;
    109 #endif
    110 	if (-1 == sem_init(&buf.occupied, shared, occupied_value)) {
    111 		perror("sem_init didn't return success \n");
    112 		return PTS_UNRESOLVED;
    113 	}
    114 	if (-1 == sem_init(&buf.empty, shared, empty_value)) {
    115 		perror("sem_init didn't return success \n");
    116 		return PTS_UNRESOLVED;
    117 	}
    118 	if (-1 == sem_init(&buf.lock, shared, lock_value)) {
    119 		perror("sem_init didn't return success \n");
    120 		return PTS_UNRESOLVED;
    121 	}
    122 	in = out = 0;
    123 
    124 	pthread_create(&con, NULL, (void *)consumer, &buf);
    125 	pthread_create(&pro, NULL, (void *)producer, &buf);
    126 	pthread_join(con, NULL);
    127 	pthread_join(pro, NULL);
    128 	sem_destroy(&buf.occupied);
    129 	sem_destroy(&buf.empty);
    130 	return PTS_PASS;
    131 }
    132