Saket Soni


back to readerwriter
back to home


#include
#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 incWriterCount();
void decWriterCount();
int  getWriterCount();
void getWriterLock();
void releaseWriterLock();

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

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

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

	printf ( "Getting id of semaphore set with key 0x20...\n" );
	semid = semget ( 32, 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;

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

		getWriterLock();

			// writing data ...
			printf ( "    Writing Data ...    DataChangeCount : %d\n", ++(*ptrDataChangeCount) );
			printf ( "  unlocking WriterLock ...\n" );
			#ifndef DEBUG
			int fd = open ( "abc.dat", O_RDWR | O_CREAT, 0666);
			for ( int i = 0 ; i < bufSize ; i++ )	{
				buf[i] = (char) ( (rand()/(float)RAND_MAX)*('z'-'A'+1) + 'A');
				printf ( "%c", buf[i] );
			}
			if ( write ( fd, buf, bufSize ) != bufSize )	{
				perror ( "Error in writing to the file " );
				exit(1);
			}
			printf ( "\n" );
			close (fd);
			#endif

		releaseWriterLock();

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

void getWriterLock()
{
	#ifdef DEBUG
	printf ( "  locking WriterCountLock ...\n" );
	#endif
	lock ( WriterCountLock );
		#ifdef DEBUG
		printf ( "  Incrementing writer count\n" );
		#endif
		incWriterCount();
		#ifdef DEBUG
		printf ( "  WriterCount = %d\n", getWriterCount() );
		printf ( "  unlocking WriterCountLock ...\n" );
		#endif
	unlock ( WriterCountLock );
	#ifdef DEBUG
	printf ( "  locking WriterLock ...\n" );
	#endif
	lock ( WriterLock );
}
void releaseWriterLock()
{
	unlock ( WriterLock );
	#ifdef DEBUG
	printf ( "  locking WriterCountLock ...\n" );		
	#endif
	lock ( WriterCountLock );
		#ifdef DEBUG
		printf ( "  Decrementing writer count\n" );
		#endif
		decWriterCount();
		#ifdef DEBUG
		printf ( "  WriterCount = %d\n", getWriterCount() );
		printf ( "  unlocking WriterCountLock ...\n" );
		#endif
	unlock ( WriterCountLock );
}
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 acquiring lock " );
		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 releasing lock " );
		exit(1);
	}
}
void incWriterCount()
{
	sop.sem_num = WriterCountSema;
	sop.sem_op 	= 1;
	sop.sem_flg = SEM_UNDO;
	if ( semop(semid,&sop,1) == -1 )	{
		perror ( "Error while inceasing writer count " );
		exit(1);
	}
}
void decWriterCount()
{
	sop.sem_num = WriterCountSema;
	sop.sem_op  = -1;
	sop.sem_flg = SEM_UNDO;
	if ( semop(semid,&sop,1) == -1 )	{
		perror ( "Error while decreasing writer count " );
		exit(1);
	}
}
int getWriterCount()
{
	int writerCount = semctl(semid, WriterCountSema, GETVAL, 0);
	if ( writerCount == -1 )	{
		perror ( "Error while getting writer count " );
		exit(1);
	}
	return writerCount;
}



back to readerwriter
back to home

Locations of visitors to this page 1