From 2177f0712fb47a95b2970c6838a4a4d978174b3b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Fri, 24 Nov 2017 18:12:18 -0500 Subject: CS3871/assignments/sync: Initial Commit --- sync/assign.rst | 41 ++++++++++++++++++++++++++++++++++++++ sync/reader.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sync/sync.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sync/writer.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 sync/assign.rst create mode 100644 sync/reader.c create mode 100644 sync/sync.c create mode 100644 sync/writer.c diff --git a/sync/assign.rst b/sync/assign.rst new file mode 100644 index 0000000..ea4a566 --- /dev/null +++ b/sync/assign.rst @@ -0,0 +1,41 @@ +================ +Syncronization 1 +================ + +Write a program that uses semaphores to implement a readers/writers solution. Your program should: + + - be written in C and use the standard kernel IPC mechanisms (semget,semop,shmget etc) + - be written as a single top level source file compiled as: gcc –o myprog myprog.c + - take two arguments on the command line: myprog NR NW where NR,NW are each integers specifying the number of reader/writer processes respectively + - use fork/exec to create the readers/writers + +The shared memory segment should be 16k bytes in size, with all bytes initialized to 0x30 + +Reader: + +.. code :: + + open a file (for append) named reader.N, where N is the reader number + while (1) { + for (i=0; i<16k; i++) { + read the next byte of the shared memory segment + write that byte to the file + flush the file + } + sleep a random number of seconds, between 0 and N inclusive + } + +Writer: + +.. code :: + + while (1) { + for (i=0; i<16k; i++) + shared memory segment[i] = N + 0x30; + sleep a random number of seconds between 0 and 2*N inclusive + } + +readers and writers should be mutually exclusive +multiple concurrent readers are allowed +writers have priority over readers +writers are mutually exclusive relative to each other diff --git a/sync/reader.c b/sync/reader.c new file mode 100644 index 0000000..edecf56 --- /dev/null +++ b/sync/reader.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + + +int main(argc, argv) +int argc; +char **argv; +{ + int shmid, i, pid, id; + char *mem, filename[50]; + FILE fd; + timeval *s; + + if (argc != 1) { + printf("usage: reader [id]\n"); + exit(1); + } + + id = atoi(argv[1]); + + if (argc < 2) { + printf("usage: sync [number readers] [number writers]\n"); + exit(1); + } + + if ((shmid = shmget(52, 1<<14, IPC_CREAT | 0666)) == -1){ + perror("shmget: shmget failed"); + exit(1); + } + + if ((mem = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + sprintf(filename, "reader.%d", id); + + fd = fopen(filename, "a"); + + if (!fd) { + perror("fopen: "); + exit(1); + } + srand(time(NULL)); + + while (1) { + s->tv_sec = rand() % id; + for (i = 0; i < 1<<14; i++) { + fprintf(fd, "%c", *(mem + i)); + fflush(fd); + } + + select(0, NULL, NULL, NULL, s); + } +} diff --git a/sync/sync.c b/sync/sync.c new file mode 100644 index 0000000..e1fbc4c --- /dev/null +++ b/sync/sync.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include + + +int main(argc, argv) +int argc; +char **argv; +{ + int shmid, i, pid, n_read, n_write; + char *mem, **arg_r, **arg_w; + + if (argc < 2) { + printf("usage: sync [number readers] [number writers]\n"); + exit(1); + } + n_read = atoi(argv[1]); + n_write = atoi(argv[2]); + + if ((shmid = shmget(52, 1<<14, IPC_CREAT | 0666)) == -1){ + perror("shmget: shmget failed"); + exit(1); + } + + if ((mem = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + for (i = 0; i < 1<<14; i++) { + *(mem + i) = 0x30; + } + + arg_r = malloc(sizeof(char*) * 2); + arg_w = malloc(sizeof(char*) * 2); + + *(arg_r + 1) = NULL; + *(arg_w + 1) = NULL; + + for (i = 0; i < n_read; i++){ + sprintf(*arg_r, "%d", i); + if (pid = fork()) { + printf("starting reader %d...\n", i); + } else { + execvp("./reader", arg_r); + } + } + + for (i = 0; i < n_write; i++) { + sprintf(*arg_w, "%d", i); + if (pid = fork()) { + printf("starting writer %d...\n", i); + } else { + execvp("./writer", arg_w); + } + + } +} diff --git a/sync/writer.c b/sync/writer.c new file mode 100644 index 0000000..0a7a1fe --- /dev/null +++ b/sync/writer.c @@ -0,0 +1,51 @@ + +#include +#include +#include +#include +#include +#include +#include + + +int main(argc, argv) +int argc; +char **argv; +{ + int shmid, i, pid, id; + char *mem; + timeval *s; + + if (argc != 1) { + printf("usage: reader [id]\n"); + exit(1); + } + + id = atoi(argv[1]); + + if (argc < 2) { + printf("usage: sync [number readers] [number writers]\n"); + exit(1); + } + + if ((shmid = shmget(52, 1<<14, IPC_CREAT | 0666)) == -1){ + perror("shmget: shmget failed"); + exit(1); + } + + if ((mem = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + srand(time(NULL)); + + + while (1) { + s->tv_sec = rand() % (id * 2; + for (i = 0; i < 1<<14; i++) { + mem[i]= 0x30 + id; + select(0, NULL, NULL, NULL, s); + } + } +} -- cgit v1.1