/**********************************************************************
*
* ProcReaders.c
*
* Module for the Readers / Writers problem which favors readers using
* processes.
*
* Author: Nick DiZazzo, April 2007
* CS305 Programming Assignment 3 - Readers / Writers Problem
*
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include "Constants.h"
#include "Processes.h"
#include "ProcReaders.h"
#include "ReadWrite.h"
#include "Sem.h"
/* Global Variables - absolutely nessecary, shared between processes. */
int readCount;
/**********************************************************************
* pr_readersWriters()
*
* This function creates the specified number of reader processes, and
* the specified number of writers processes, then has each new
* process execute its associated reader/writer algorithm. This version
* favors readers.
*
* It is nearly impossible to have a perfect outcome every time
* demonstrating the solution clearly, but there are some techniques that
* improve the demonstration. Interleaving the process creation helps this
* slightly, but there are still too many factors to create a perfect
* demonstration.
*
* By creating two child processes which in turn create readers and
* writers, we achieve pseudo-process interleaving, naturally
* generated by the OS process scheduler. This sharing of CPU time between
* the two launcher children is what achieves this effect.
*
* Parameters: readers - The number of reader processes to create.
* writers - The number of writer processes to create.
*
* Output: None.
* Pre-Conditions: None.
* Post-Conditions: None.
* Other: This function modifies globals:
* readCount
* C_W_XSEM
* C_W_RSEM
*********************************************************************/
void pr_readersWriters(int readers, int writers)
{
pid_t pPID; // parent manages semiphores
pid_t c1PID; // c1 launches readers
pid_t c2PID; // c2 launches writers
key_t semkey;
int semid;
readCount = 0;
// Create semaphores
semkey = ftok(C_KEYFILE, C_KEYCHAR);
semid = semget(semkey, C_R_NUMSEMS, 0666 | IPC_CREAT);
// Initialize semaphores
sem_init(semid, C_R_XSEM); // Initialize XSEM
sem_init(semid, C_R_WSEM); // Initialize WSEM
// Create child processes
pPID = getpid(); // Store parent PID
c1PID = fork(); // Create child
if (pPID == getpid())
{
c2PID = fork();
if (c2PID == (pid_t)C_CHILD)
c1PID = C_STOPFLG; // C2 -> Mark C1 PID
}
else if (c1PID == (pid_t)C_CHILD)
{
c2PID = C_STOPFLG; // C1 -> Mark C2 PID
}
else
{
printf("%s\n", C_EM_FORKERR);
exit(1);
}
// C1 Spawns readers, C2 Spawns writers
if (c1PID == (pid_t)C_CHILD)
{
if (readers > 0)
{
createProcesses(readers-1); // Create # of readers
rreader(semid); // start read routene
}
exit(0); // Children do no more
}
else if (c2PID == (pid_t)C_CHILD)