Saket Soni


back to readerwriter
back to home


#include
#include
#include
#include
#include
#include
#include
#include

//#define DEBUG

enum	{
	WriterLock      = 0,
	ReaderCountLock = 1,
	WriterCountLock = 2,
	WriterCountSema = 3
	};

int semid = -1;;
int shmid = -1;
struct sembuf sop;
int * ptrReaderCount     = NULL;
int * ptrDataChangeCount = NULL;

void lock   ( int i );
void unlock ( int i );
void waitTillNoWriter();
void getReaderLock();
void releaseReaderLock();

#ifndef DEBUG
const int  bufSize = 20;
char buf[bufSize];
#endif

int main ( int argc, char * argv[] )
{
	int iCount = 0;
	int waitTime = 1;
	int stat = -1;

	if ( argc > 2 )	{
		printf ( "Syntax Error : more than one arguments specified !!\n" );
		exit(1);
	}
	if ( argc == 2 )	{
		waitTime = atoi ( argv[1] );
	}
	else
		waitTime = 5;	

	printf ( "Getting id of semaphore set with key 0x20...\n" );
	semid = semget ( 0x20, 4, IPC_CREAT|0666);
	if ( semid == -1 )	{
		perror ( "semaphore id retreival failed " );
		exit(1);
	}
	printf ( "Semaphore semid is : %d\n", semid );
	
	key_t shKey = 0x1000;
	shmid = shmget ( shKey, sizeof(int)*2, IPC_CREAT|0666 );
	if ( shmid == -1 )	{
		perror ( "cannot allocated shared memory " );
		printf ( "\ndeleting the semaphore set id : %d\n", semid );
		int stat = semctl ( semid, 0, IPC_RMID, 0 );
		if ( stat == -1 )	{
			perror ( "semaphore deletion failed " );
			exit ( 1 );
		}
		printf ( "semaphore set with id : %d deleted!!\n", semid );			
		exit(1);
	}
	int * ptr = (int *) shmat ( shmid, 0, 0 );
	ptrReaderCount     = ptr;
	ptrDataChangeCount = ptr+1;

	while ( 1 )
	{
		printf ( "Iteration : %d\n",iCount++);

		getReaderLock();

			// reading data ...
			printf ( "    Reading Data ... DataChangeCount : %d\n", *ptrDataChangeCount);
			#ifndef DEBUG
			int fd = open ( "abc.dat", O_RDONLY );
			if ( fd == -1 )	{
				perror ( "cannot open file for reading " );
				exit(1);
			}
			read ( fd, buf, bufSize );
			for ( int i = 0 ; i < bufSize ; i++ )
				printf ( "%c", buf[i] );
			printf ( "\n" );
			close (fd);
			#endif

		releaseReaderLock();

		printf ( "  sleeping for %d seconds, before attempting to read again ...\n", waitTime);
		sleep ( waitTime );
	}
}

void getReaderLock()
{
	#ifdef DEBUG
	printf ( "  waiting till no writer ...\n" );
	#endif
	waitTillNoWriter();
	#ifdef DEBUG
	printf ( "  locking ReaderCountLock ...\n" );
	#endif
	lock ( ReaderCountLock );
		if ( *ptrReaderCount == 0 )	{
			#ifdef DEBUG
			printf ( "  I am the First Reader hence locking WriterLock ...\n" );
			#endif
			lock ( WriterLock );
		}
		#ifdef DEBUG
		printf ( "  Incrementing reader count ...\n" );
		#endif
		(*ptrReaderCount)++;
		#ifdef DEBUG
		printf ( "  Now ReaderCount = %d\n", *ptrReaderCount );
		printf ( "  unlocking ReaderCountLock ...\n" );
		#endif
	unlock ( ReaderCountLock );
}
void releaseReaderLock()
{
	#ifdef DEBUG
	printf ( "  locking ReaderCountLock ...\n" );
	#endif
	lock ( ReaderCountLock );
		#ifdef DEBUG
		printf ( "  Decrementing reader count\n" );
		#endif
		(*ptrReaderCount)--;
		#ifdef DEBUG
		printf ( "  Now ReaderCount = %d\n", *ptrReaderCount );
		#endif
		if ( *ptrReaderCount == 0 )	{
			#ifdef DEBUG
			printf ( "  I am the Last Reader hence unlocking WriterLock ...\n" );
			#endif
			unlock ( WriterLock );
		}
		#ifdef DEBUG
		printf ( "  unlocking ReaderCountLock ...\n" );
		#endif
	unlock ( ReaderCountLock );
}
void lock ( int i )
{
	sop.sem_num = i;
	sop.sem_op  = -1;
	sop.sem_flg = SEM_UNDO;
	if ( semop(semid,&sop,1) == -1 )	{
		perror ( "Error while decrementing semaphore " );
		exit(1);
	}
}
void unlock ( int i )
{
	sop.sem_num = i;
	sop.sem_op  = 1;
	sop.sem_flg = SEM_UNDO;
	if ( semop(semid,&sop,1) == -1 )	{
		perror ( "Error while incrementing semaphore " );
		exit(1);
	}
}
void waitTillNoWriter()
{
	sop.sem_num = 3;
	sop.sem_op  = 0;
	sop.sem_flg = SEM_UNDO;
	if ( semop(semid,&sop,1) == -1 )	{
		perror ( "Error while waiting on semaphore " );
		exit(1);
	} 
}



back to readerwriter
back to home

Locations of visitors to this page 1