// ===========================================================
// File: Syscalls.c
//
// Implementation of the Syscalls system call functions.
// Theses are system calls requesting for semaphore resource
// in the Server. System calls provide means for
// synchronization of concurrent processes. Each system call
// will peform 4 specific task:
//
// 1) Prepare outgoing message m2
// 2) Send message to Server via pipe 2
// 3) Wait for reply message m3
// 4) Return information to caller
// ===========================================================
#include <stdlib.h>
#include <time.h>
#include <time.h>
#include <unistd.h>
#include "Message.h"
// ===========================================================
// Global variables
// ===========================================================
int inPd; // read in pipe descriptor
int outPd; // write out pipe descriptor
// ===========================================================
// Identifier: vsinit(int*, char*[])
//
// Comments: Pipe descriptors are recorded onto global
// variables, inPd, outPd. The last two
// entries of argv are removed and the argc
// count is updated.
// ===========================================================
void vsinit(int *argcPt, char *argv[])
{
outPd = atoi(argv[*argcPt-1]);
inPd = atoi(argv[*argcPt-2]);
argv[*argcPt-1] = NULL;
argv[*argcPt-2] = NULL;
*argcPt -= 2;
}
// ===========================================================
// Identifier: int vsexit(void)
//
// Comments: PID is sent as reply message m3.
//
// Returns: -1 if pipe fail, 0 otherwise
// ===========================================================
int vsexit(void)
{
int retValue = 0;
RequestMsg m2;
m2.timeStamp = time(NULL);
m2.PID = getpid();
m2.purpose = VS_EXIT;
retValue = write(outPd, &m2, sizeof(RequestMsg));
return (retValue == -1 ? -1 :0);
}
// ===========================================================
// Identifier: int getSem(int, int, int*)
//
// Comments: To obtain a semaphore by providing a semKey
// and initial semaphore value. Server will
// return a return value and semId.
//
// Returns: return value of m3.
// ===========================================================
int getSem(int semKey, int semInitialVal, int *semIdPtr)
{
RequestMsg m2;
ReplyMsg m3;
m2.timeStamp = time(NULL);
m2.PID = getpid();
m2.semKey = semKey;
m2.semInitValue = semInitialVal;
m2.purpose = GET_SEM;
write(outPd, &m2, sizeof(RequestMsg));
read(inPd, &m3, sizeof(ReplyMsg));
*semIdPtr = m3.semId;
return m3.returnValue;
}
// ===========================================================
// Identifier: int signalSem(int)
//
// Comments: Increments the semValue of a semaphore. Server
// will return a return value. This operation
// may wake up a waiting process.
//
// Returns: return value of m3.
// ===========================================================
int signalSem(int semId)
{
RequestMsg m2;
ReplyMsg m3;
m2.timeStamp = time(NULL);
m2.PID = getpid();
m2.semId = semId;
m2.purpose = SIGNAL_SEM;
write(outPd, &m2, sizeof(RequestMsg));
read(inPd, &m3, sizeof(ReplyMsg));
return m3.returnValue;
}
// ===========================================================
// Identifier: waitSem(int)
//
// Comments: Decrements the semValue of a semaphore. Server
// will return a return value. A process must
// wait if resulted semValue is < 0.
//
// Returns: return value of m3.
// ===========================================================
int waitSem(int semId)
{
RequestMsg m2;
ReplyMsg m3;
m2.timeStamp = time(NULL);
m2.PID = getpid();
m2.semId = semId;
m2.purpose = WAIT_SEM;
write(outPd, &m2, sizeof(RequestMsg));
read(inPd, &m3, sizeof(ReplyMsg));
return m3.returnValue;
}
// ===========================================================
// Identifier: releaseSem(int)
//
// Comments: Cancels the right of using a semaphore.
// Server will return a return value.
//
// Returns: return value of m3.
// ===========================================================
int releaseSem(int semId)
{
RequestMsg m2;
ReplyMsg m3;
m2.timeStamp = time(NULL);
m2.PID = getpid();
m2.semId = semId;
m2.purpose = RELEASE_SEM;
write(outPd, &m2, sizeof(RequestMsg));
read(inPd, &m3, sizeof(ReplyMsg));
return m3.returnValue;
}