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 
producer(buf_t * buf)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 
consumer(buf_t * buf)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 
main(void)97 int main(void)
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