#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;
}