#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "Syscalls.h"
#define TRACE 0
/************************************************************************/
/* */
/* This is the test program for CSC415, PJ2, Spring 2001. It generates */
/* semaphore activities. Initially, it creates N semaphores : */
/* key, key+1, ..., key+N-1, then it repeatedly does waitSem() or */
/* signalSem() on each of the N semaphores. */
/* */
/* This program can be executed many times to create multiple clients. */
/* There are exactly six input arguments : */
/* */
/* argv[0] = program name */
/* argv[1] = first key value */
/* argv[2] = number of semaphores, between 1 to 5 */
/* argv[3] = init value. Set this value for all semaphores */
/* argv[4] = # of loops for semWait() or semSignal() */
/* argv[5] = 1 do semWait(), 0 do semSignal() */
/* */
/* Example : a.out 777 2 0 10 1 */
/* This create two semaphores with key = 777 & 778 */
/* Initial value of each semaphore is set to 0 */
/* Repeat semWait() on each semaphore 10 times */
/* */
/* Note : you may modify this program to create more options */
/* if you want to see more trace output, set the above TRACE 1 */
/* */
/************************************************************************/
/* Global variables */
int id[5], flag, key, init, numLoops,numSemaphores;
/* process input arguments */
void GetArguments(int argc, char *argv[])
{
if ( argc != 6 ) {
printf("PID=%d : Error! argc=%d != 6, cannot run this program!\n",
getpid(), argc);
printf("Usage : progName key numSemaphores initValue numLoops flag\n");
exit(-1);
}
/* get parameters */
key = atoi(argv[1]);
numSemaphores = atoi(argv[2]);
init = atoi(argv[3]);
numLoops = atoi(argv[4]);
flag = atoi(argv[5]);
#if TRACE
printf("--------------------------------\n");
printf("Key = %d\n",key);
printf("numSemaphores = %d\n",numSemaphores);
printf("initial value = %d\n",init);
printf("numLoops = %d\n",numLoops);
printf("flag = %d\n",flag);
printf("--------------------------------\n");
#endif
/* simple argumenty error checking. There may be more */
if ( (numSemaphores < 1) || (numSemaphores > 5) ||
(init < 0) || (numLoops < 1) ||
(flag < 0) || (flag > 1 )) {
printf("PID=%d : Error in input parameters, program exits!\n");
exit(-1);
}
}
/* This function uses getSem() to get all semaphores */
void DoGetAllSemaphores()
{
int i, tmpKey;
tmpKey = key;
#if TRACE
printf("\nIn DoGetAllSemaphores: pid=%d : numSemaphores=%d"
" : key=%d : init=%d \n",
getpid(), numSemaphores, key, init);
#endif
for (i=0; i<numSemaphores; i++) {
if (getSem(tmpKey, init, &id[i]) == -1) {
printf("PID=%d : Error in getSem(%d,%d,--), loop=%d\n",
getpid(), tmpKey,init,i);
exit(-1);
} else {
printf("PID=%d : OK in getSem(%d,%d,--), loop=%d, get semid=%d\n",
getpid(),tmpKey,init,i,id[i]);
tmpKey++;
}
}
}
/* This function does waitSem() numLoops times on each semaphore */
void DoWaitAllSemaphores()
{
int i,j;
#if TRACE
printf("\n\tIn DoWaitAllSemaphores : pid=%d : numLoops=%d \n",
getpid(), numLoops);
#endif
/* do numLoops times */
for (j=0; j<numLoops; j++) {
/* do for each created semaphore */
for (i=0; i<numSemaphores; i++) {
printf("\tPID=%d : try waitSem(%d), loop=%d\n", getpid(),id[i],j);
if (waitSem(id[i]) == -1) {
printf("\tPID=%d : Error in waitSem(%d), loop=%d\n",
getpid(),id[i],j);
exit(0);
} else {
printf("\tPID=%d : OK waitSem(%d), loop=%d\n",
getpid(),id[i], j);
}
}
}
}
/* This function does signalSem() numLoops times on each semaphore */
void DoSignalAllSemaphores()
{
int i,j;
#if TRACE
printf("\n\t\tIn DoSignalAllSemaphores : pid=%d : numLoops=%d \n",
getpid(), numLoops);
#endif
/* do numLoops times */
for (j=0; j<numLoops; j++) {
/* do for each created semaphore */
for (i=0; i<numSemaphores; i++) {
printf("\t\tPID=%d : try signalSem(%d), loop=%d\n",
getpid(),id[i], j);
if (signalSem(id[i]) == -1) {
printf("\t\tPID=%d : Error in signalSem(%d), loop=%d\n",
getpid(),id[i],j);
exit(0);
} else {
printf("\t\tPID=%d : OK signalSem(%d), loop=%d\n",
getpid(),id[i], j);
sleep(5); /* delay signalSem operations */
}
}
}
}
/* This function releases all semaphores */
void DoReleaseAllSemaphores() {
int i;
#if TRACE
printf("\n\t\t\tIn DoReleaseAllSemaphores : pid=%d : numSemaphores=%d \n",
getpid(), numSemaphores);
#endif
for (i=0; i<numSemaphores; i++) {
if (releaseSem(id[i]) == -1) {
printf("\t\t\tPID=%d : Error in releaseSem(%d), loop=%d\n",
getpid(),id[i],i);
exit(0);
} else {
printf("\t\t\tPID=%d : OK in releaseSem(%d), loop=%d\n",
getpid(),id[i],i);
}
}
}
/************************************************************************/
/* */
/* This main function uses above functions to generate semaphores */
/* activities. The user can create 1 to 5 semaphores, input key word, */
/* set initial value. The user has an option to do waitSem() only or */
/* signalSem() only. */
/* */
/* This program can be used to create multiple client processes. */
/* */
/* Example : Two processs share a semaphore, name = MySem, initial */
/* value is 0, the 1st process does semSignal() 10 times, and */
/* the 2nd process does semWait() 10 times. */
/* */
/* a.out MySem 1 0 10 0 */
/* a.out MySem 1 0 10 1 */
/* */
/************************************************************************/
main(int argc, char *argv[])
{
vsinit(&argc, argv);
GetArguments(argc, argv);
/* get all semaphores */
DoGetAllSemaphores();
sleep(10); /* allow other processes to start */
/* do waitSem() or signalSem() */
if (flag)
DoWaitAllSemaphores();
else
DoSignalAllSemaphores();
/* release all semaphores */
DoReleaseAllSemaphores();
vsexit();
}