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 31sem_t r_lock, w_lock; 32int reader_count = 0; 33int data = 0; 34 35int read_fun(int ID) 36{ 37 printf("read the board, data=%d \n", data); 38 return 0; 39} 40 41int write_fun(int ID) 42{ 43 data = 100 * ID + ID; 44 printf("write the board, data=%d \n", data); 45 return 0; 46} 47 48int *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 89int *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 108int 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