#include #include #include #include #include #include #include #include "as5.h" #define NUM_READERS 4 #define NUM_WRITERS 3 void randStartProcs(SysSemaphores *pStart) { int started[NUM_READERS+NUM_WRITERS]; int count = 0; int index; srand((unsigned)time(NULL)); for (int i = 0; i < NUM_READERS+NUM_WRITERS; ++i) started[i] = 0; while (count < NUM_READERS+NUM_WRITERS) { index = rand() % (NUM_READERS+NUM_WRITERS); if (!started[index]) { count++; pStart->Signal(index); started[index] = 1; milliSleep(5); } } } void orderedStartProcs(SysSemaphores *pStart) { //Order: W,R,R,R,W,R,W pStart->Signal(6); milliSleep(5); pStart->Signal(0); milliSleep(5); pStart->Signal(1); milliSleep(5); pStart->Signal(2); milliSleep(5); pStart->Signal(5); milliSleep(5); pStart->Signal(3); milliSleep(5); pStart->Signal(4); } int StartProcs(SysSemaphores *pStart, int argc, char **argv) { int rand = 0; for (int i = 1; i < argc; ++i) if (strcmp(argv[i], "-r")) { printf("Usage:\r\n\t%s [-r]\r\n\t\t-r\tRandomly start readers/writers\r\n\t\t\tOtherwise, ordered starting: W,R,R,R,W,R,W\r\n\r\n", argv[0]); return -1; } else rand = 1; if (rand) randStartProcs(pStart); else orderedStartProcs(pStart); return 0; } struct timeval startTime; int main(int argc, char **argv) { int Pid; int Status; void *ShmPtr; SysSemaphores sems(3, 0666 | IPC_CREAT); SysSemaphores startProc(NUM_READERS+NUM_WRITERS, 0666 | IPC_CREAT); SysSharedMem shm(SHM_SIZE, 0666 | IPC_CREAT); ERROR("SetVal", sems.SetVal(SEM_QUEUE, 1)); ERROR("SetVal", sems.SetVal(SEM_MUTEX, 1)); ERROR("SetVal", sems.SetVal(SEM_WRITE, 1)); for (int i = 0; i < NUM_READERS+NUM_WRITERS; ++i) ERROR("SetVal", startProc.SetVal(i, 0)); gettimeofday(&startTime, NULL); for (int i = 1; i <= NUM_READERS; ++i) //make some readers { Pid=fork(); if (Pid==0) // child { //attach shared memory to process ShmPtr = shm.Attach(SHM_R); startProc.Wait(i-1); ReaderFunction(&sems, (char*)ShmPtr); shm.Detach(ShmPtr); exit(0); } } for (int i = 1; i <= NUM_WRITERS; ++i) // make some writers { Pid=fork(); if (Pid==0) // child { //attach shared memory to process ShmPtr = shm.Attach(SHM_W); startProc.Wait(i+NUM_READERS-1); WriterFunction(&sems, (char*)ShmPtr); shm.Detach(ShmPtr); exit(0); } } if (StartProcs(&startProc, argc, argv) == -1) { killpg(0, SIGKILL); } //Wait for children to finish for (int i = 0; i < NUM_READERS+NUM_WRITERS; ++i) wait(&Status); return 0; } void milliSleep(int millisecs) { usleep(millisecs*1000); } long getTime() { struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec - startTime.tv_sec) * 1000000 + (tv.tv_usec - startTime.tv_usec); }