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 35 int read_fun(int ID) 36 { 37 printf("read the board, data=%d \n", data); 38 return 0; 39 } 40 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 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 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 108 int main(void) 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