Home | History | Annotate | Download | only in semaphores
      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(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