• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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