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