1 /*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * Created by: crystal.xiong REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license. For the full content
5 * of this license, see the COPYING file at the top level of this
6 * source tree.
7 *
8 * This test use semaphore to implement reader and writer problem. Some readers
9 * and some writers read/write on one blackboard. Only one writer allow to
10 * write on the board at the same time. Reader and Writer can't use the board
11 * the same time. Reader has higher priority than writer, which means only when
12 * no reader reads the board, the writer can write the board.
13 */
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <sys/wait.h>
19 #include <sys/mman.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <semaphore.h>
23 #include <pthread.h>
24
25 #include "posixtest.h"
26
27 #define SEM_NAME "/tmp/semaphore"
28 #define READ_NUM 10
29 #define WRITE_NUM 15
30
31 sem_t r_lock, w_lock;
32 int reader_count = 0;
33 int data = 0;
34
read_fun(int ID)35 int read_fun(int ID)
36 {
37 printf("read the board, data=%d \n", data);
38 return 0;
39 }
40
write_fun(int ID)41 int write_fun(int ID)
42 {
43 data = 100 * ID + ID;
44 printf("write the board, data=%d \n", data);
45 return 0;
46 }
47
reader(void * ID)48 int *reader(void *ID)
49 {
50 int ThID = *(int *)ID;
51 if (-1 == sem_wait(&r_lock)) {
52 perror("sem_wait didn't return success\n");
53 pthread_exit((void *)1);
54 }
55 reader_count++;
56 printf("Enter into Reader thread, reader_count=%d \n", reader_count);
57 if (reader_count == 1) {
58 if (-1 == sem_wait(&w_lock)) {
59 perror("sem_wait didn't return success \n");
60 pthread_exit((void *)1);
61 }
62 }
63 if (-1 == sem_post(&r_lock)) {
64 perror("sem_post didn't return success \n");
65 pthread_exit((void *)1);
66 }
67 sleep(1);
68 read_fun(ThID);
69 if (-1 == sem_wait(&r_lock)) {
70 perror("sem_wait didn't return success \n");
71 pthread_exit((void *)1);
72 }
73 reader_count--;
74 if (reader_count == 0) {
75 if (-1 == sem_post(&w_lock)) {
76 perror("sem_post didn't return success \n");
77 pthread_exit((void *)1);
78 }
79 }
80 if (-1 == sem_post(&r_lock)) {
81 perror("sem_post didn't return success \n");
82 pthread_exit((void *)1);
83 }
84 printf("Reader Thread [%d] exit...reader_count=%d \n", ThID,
85 reader_count);
86 pthread_exit(NULL);
87 }
88
writer(void * ID)89 int *writer(void *ID)
90 {
91 int ThID = *(int *)ID;
92 /* When ThID is equal to WRITE_NUM/2, sleep 2 second and let reader read the data */
93 if (ThID >= WRITE_NUM / 2)
94 sleep(2);
95 if (-1 == sem_wait(&w_lock)) {
96 perror("sem_wait didn't return success \n");
97 pthread_exit((void *)1);
98 }
99 write_fun(ThID);
100 if (-1 == sem_post(&w_lock)) {
101 perror("sem_post didn't return success \n");
102 pthread_exit((void *)1);
103 }
104 printf("Writer Thread [%d] exit...\n", ThID);
105 pthread_exit(NULL);
106 }
107
main(int argc,char * argv[])108 int main(int argc, char *argv[])
109 {
110 pthread_t rea[READ_NUM], wri[WRITE_NUM];
111 int ReadID[READ_NUM], WriteID[WRITE_NUM];
112 int shared = 1;
113 int r_value = 1;
114 int w_value = 1;
115 int i;
116
117 #ifndef _POSIX_SEMAPHORES
118 printf("_POSIX_SEMAPHORES is not defined \n");
119 return PTS_UNRESOLVED;
120 #endif
121 if (-1 == sem_init(&r_lock, shared, r_value)) {
122 perror("sem_init didn't return success \n");
123 return PTS_UNRESOLVED;
124 }
125 if (-1 == sem_init(&w_lock, shared, w_value)) {
126 perror("sem_init didn't return success \n");
127 return PTS_UNRESOLVED;
128 }
129
130 for (i = 0; i < WRITE_NUM; i++) {
131 WriteID[i] = i;
132 pthread_create(&wri[i], NULL, (void *)writer, &WriteID[i]);
133 }
134 for (i = 0; i < READ_NUM; i++) {
135 ReadID[i] = i;
136 pthread_create(&rea[i], NULL, (void *)reader, &ReadID[i]);
137 }
138
139 for (i = 0; i < READ_NUM; i++)
140 pthread_join(rea[i], NULL);
141 for (i = 0; i < WRITE_NUM; i++)
142 pthread_join(wri[i], NULL);
143
144 if (-1 == sem_destroy(&r_lock)) {
145 perror("sem_destroy didn't return success \n");
146 return PTS_UNRESOLVED;
147 }
148 if (-1 == sem_destroy(&w_lock)) {
149 perror("sem_destroy didn't return success \n");
150 return PTS_UNRESOLVED;
151 }
152 return PTS_PASS;
153 }
154