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 <getopt.h>
21#include <errno.h>
22#include <pthread.h>
23#include <semaphore.h>
24
25#include "posixtest.h"
26
27#define BUF_SIZE	5
28#define Max_Num		10
29
30typedef struct {
31	int buffer[BUF_SIZE];
32	sem_t occupied;
33	sem_t empty;
34	sem_t lock;
35}buf_t;
36
37int in, out;
38
39int *producer(buf_t *buf)
40{
41	int data;
42	int i;
43
44	for (i = 0; i< Max_Num; i++) {
45		if (-1 == sem_wait(&buf->occupied)) {
46			perror("sem_wait didn't return success \n");
47			pthread_exit((void *)1);
48		}
49		if (-1 == sem_wait(&buf->lock)) {
50			perror("sem_wait didn't return success \n");
51			pthread_exit((void *)1);
52		}
53		data = 100*i;
54		buf->buffer[in] = data;
55		printf("producer has added %d to the buffer[%d] \n", data, in);
56		in = (in + 1) % BUF_SIZE;
57		if (-1 == sem_post(&buf->lock)) {
58			perror("sem_wait didn't return success \n");
59			pthread_exit((void *)1);
60		}
61		if (-1 == sem_post(&buf->empty)) {
62			perror("sem_wait didn't return success \n");
63			pthread_exit((void *)1);
64		}
65	}
66	pthread_exit((void *)0);
67}
68int *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}
96int main(int argc, char *argv[])
97{
98	int shared = 1;
99	int occupied_value = BUF_SIZE;
100	int empty_value = 0;
101	int lock_value=1;
102	buf_t *buf;
103	pthread_t con, pro;
104	buf = (buf_t *)malloc(sizeof(buf_t));
105
106
107#ifndef  _POSIX_SEMAPHORES
108	printf("_POSIX_SEMAPHORES is not defined \n");
109	return PTS_UNRESOLVED;
110#endif
111	if (-1 == sem_init(&(buf->occupied), shared, occupied_value)) {
112		perror("sem_init didn't return success \n");
113		printf("hello \n");
114		return PTS_UNRESOLVED;
115	}
116	if (-1 == sem_init(&buf->empty, shared, empty_value)) {
117		perror("sem_init didn't return success \n");
118		return PTS_UNRESOLVED;
119	}
120	if (-1 == sem_init(&buf->lock, shared, lock_value)) {
121		perror("sem_init didn't return success \n");
122		return PTS_UNRESOLVED;
123	}
124	in = out = 0;
125
126	pthread_create(&con, NULL, (void *)consumer, (void *)buf);
127	pthread_create(&pro, NULL, (void *)producer, (void *)buf);
128	pthread_join(con, NULL);
129	pthread_join(pro, NULL);
130	sem_destroy(&buf->occupied);
131	sem_destroy(&buf->empty);
132	return PTS_PASS;
133}
134