Instructions
Requirements and Specifications
Screenshots of output
Source Code
SEAMAPHORES
#include
#include
#include
int currentproc;
// program counters
int r_pc[3] = {0, 0, 0};
int w_pc[3] = {0, 0};
// semaphores
typedef struct sem
{
int val;
int waiting[5];
int nwaiting;
}semaphore;
semaphore mutex = {1, {0}, 0}; // reader shared mutex
semaphore rsem = {2, {0}, 0}; // semaphore for readers
semaphore wsem = {1, {0}, 0}; // semaphore for writers
// counters
int AR = 0; // active readers
int critical_readers = 0;
int critical_writers = 0;
// panic flag
int panic = 0;
int wait(semaphore *sem)
{
if (sem->val == 0)
{
for (int i = 0; i < sem->nwaiting; i++)
if (sem->waiting[i] == currentproc)
return 0;
sem->waiting[sem->nwaiting++] = currentproc;
return 0;
}
else
{
sem->val--;
return 1;
}
}
void signal(semaphore *sem)
{
if (sem->nwaiting > 0)
{
switch (sem->waiting[0])
{
case 0: r_pc[0]++; break;
case 1: r_pc[1]++; break;
case 2: r_pc[2]++; break;
case 3: w_pc[0]++; break;
case 4: w_pc[1]++; break;
}
sem->nwaiting--;
for (int i = 0; i < sem->nwaiting; i++)
sem->waiting[i] = sem->waiting[i + 1];
}
else
{
sem->val++;
}
}
// Reader
void r(int n)
{
switch(r_pc[n]) // select instruction position
{
case 0: // try to enter critical section start for readers
if (wait(&mutex)) // wait for mutex
r_pc[n]++; // advance to next instruction;
break;
case 1:
AR++; // one more reader
r_pc[n]++; // advance to instruction
break;
case 2:
if (AR == 1) // if first reader
{
r_pc[n]++; // advance to next instruction;
}
else
r_pc[n] += 2; // advance to instruction
break;
case 3:
if (wait(&wsem)) // wait if writer active
r_pc[n]++;
break;
case 4: // free mutex
signal(&mutex); // unlock mutex
r_pc[n]++; // advance to next instruction;
break;
case 5:
if (wait(&rsem)) // wait if readers active
r_pc[n]++;
break;
case 6:
critical_readers++;
r_pc[n]++; // advance to next instruction;
break;
case 7:
if (critical_readers > 2 || critical_writers > 0) // if conditions are not met
panic = 1; // panic
printf("Reader %d in critical section [readers=%d, writers=%d]\n", n, critical_readers, critical_writers);
r_pc[n]++; // advance to next instruction;
break;
case 8:
critical_readers--;
r_pc[n]++; // advance to next instruction;
break;
case 9: // free reader
signal(&rsem); // unlock reader
printf("Reader process %d out of critical section...\n", n);
r_pc[n]++; // advance to next instruction;
break;
case 10: // leave critical section
if (wait(&mutex)) // wait for mutex
r_pc[n]++; // advance to next instruction;
break;
case 11:
AR--; // one less active reader
r_pc[n]++; // advance to instruction
break;
case 12:
if (AR == 0)
{
r_pc[n]++; // advance to next instruction;
}
else
r_pc[n] += 2; // advance to instruction 14
break;
case 13:
signal(&wsem); // ok to write
r_pc[n]++; // advance to next instruction;
break;
case 14: // free mutex
signal(&mutex); // unlock mutex
r_pc[n]++; // advance to next instruction;
break;
case 15:
r_pc[n] = 0; // cycle
break;
}
}
// Writer
void w(int n)
{
switch(w_pc[n]) // select instruction position
{
case 0: // try to enter critical section start for writers
if (wait(&wsem)) // wait for semaphore
w_pc[n]++; // advance to next instruction;
break;
case 1:
critical_writers++;
w_pc[n]++; // advance to next instruction;
break;
case 2:
if (critical_readers > 0 || critical_writers > 1) // if conditions are not met
panic = 1; // panic
printf("Writer %d in critical section [readers=%d, writers=%d]\n", n, critical_readers, critical_writers);
w_pc[n]++; // advance to next instruction;
break;
case 3:
critical_writers--;
w_pc[n]++; // advance to next instruction;
break;
case 4:
signal(&wsem); // ok to write
printf("Writer process %d out of critical section...\n", n);
w_pc[n]++; // advance to next instruction;
break;
case 5:
w_pc[n] = 0; // cycle
break;
}
}
int main()
{
srand(time(NULL)); // initialize random generator seed to current time
for (int i = 0; i < 10000; i++)
{
int cointoss = rand() % 5;
currentproc = cointoss;
switch (cointoss)
{
case 0: r(0); break;
case 1: r(1); break;
case 2: r(2); break;
case 3: w(0); break;
case 4: w(1); break;
}
if (panic)
{
printf("Invalid number of writers or readers in critical section!!\n");
printf("Terminating program...\n");
break;
}
}
}
TEST AND SET
#include
#include
#include
// program counters
int r_pc[3] = {0, 0, 0};
int w_pc[3] = {0, 0};
// locks
int lock = 0; // reader shared lock
int rlock = 0; // lock for readers
int wlock = 0; // lock for writers
// counters
int AR = 0; // active readers
int critical_readers = 0;
int critical_writers = 0;
// panic flag
int panic = 0;
int testandset(int *lock)
{
if (*lock == 1)
return 1; // failure
else
{
*lock = 1;
return 0; // success
}
}
// Reader
void r(int n)
{
switch(r_pc[n]) // select instruction position
{
case 0: // try to enter critical section start for readers
if (!testandset(&lock)) // wait for lock
r_pc[n]++; // advance to next instruction;
break;
case 1:
AR++; // one more reader
r_pc[n]++; // advance to instruction
break;
case 2:
if (AR == 1) // if first reader
{
r_pc[n]++; // advance to next instruction;
}
else
r_pc[n] += 2; // advance to instruction
break;
case 3:
if (!testandset(&wlock)) // wait if writer active
r_pc[n]++;
break;
case 4: // free readers lock
lock = 0; // unlock
r_pc[n]++; // advance to next instruction;
break;
case 5:
if (AR <= 2) // wait if readers active
r_pc[n]++;
break;
case 6:
critical_readers++;
r_pc[n]++; // advance to next instruction;
break;
case 7:
if (critical_readers > 2 || critical_writers > 0) // if conditions are not met
panic = 1; // panic
printf("Reader %d in critical section [readers=%d, writers=%d]\n", n, critical_readers, critical_writers);
r_pc[n]++; // advance to next instruction;
break;
case 8:
critical_readers--;
r_pc[n]++; // advance to next instruction;
break;
case 9: // free reader
printf("Reader process %d out of critical section...\n", n);
r_pc[n]++; // advance to next instruction;
break;
case 10: // leave critical section
if (!testandset(&lock)) // wait for mutex
r_pc[n]++; // advance to next instruction;
break;
case 11:
AR--; // one less active reader
r_pc[n]++; // advance to instruction
break;
case 12:
if (AR == 0)
{
r_pc[n]++; // advance to next instruction;
}
else
r_pc[n] += 2; // advance to instruction
break;
case 13:
wlock = 0; // ok to write
r_pc[n]++; // advance to next instruction;
break;
case 14: // free lock
lock = 0; // unlock
r_pc[n]++; // advance to next instruction;
break;
case 15:
r_pc[n] = 0; // cycle
break;
}
}
// Writer
void w(int n)
{
switch(w_pc[n]) // select instruction position
{
case 0: // try to enter critical section start for writers
if (!testandset(&wlock)) // wait for semaphore
w_pc[n]++; // advance to next instruction;
break;
case 1:
critical_writers++;
w_pc[n]++; // advance to next instruction;
break;
case 2:
if (critical_readers > 0 || critical_writers > 1) // if conditions are not met
panic = 1; // panic
printf("Writer %d in critical section [readers=%d, writers=%d]\n", n, critical_readers, critical_writers);
w_pc[n]++; // advance to next instruction;
break;
case 3:
critical_writers--;
w_pc[n]++; // advance to next instruction;
break;
case 4:
wlock = 0; // ok to write
printf("Writer process %d out of critical section...\n", n);
w_pc[n]++; // advance to next instruction;
break;
case 5:
w_pc[n] = 0; // cycle
break;
}
}
int main()
{
srand(time(NULL)); // initialize random generator seed to current time
for (int i = 0; i < 10000; i++)
{
int cointoss = rand() % 5;
switch (cointoss)
{
case 0: r(0); break;
case 1: r(1); break;
case 2: r(2); break;
case 3: w(0); break;
case 4: w(1); break;
}
if (panic)
{
printf("Invalid number of writers or readers in critical section!!\n");
printf("Terminating program...\n");
break;
}
}
}