diff options
Diffstat (limited to 'CS3871/sync')
-rw-r--r-- | CS3871/sync/assign.rst | 41 | ||||
-rw-r--r-- | CS3871/sync/makefile | 5 | ||||
-rw-r--r-- | CS3871/sync/reader.c | 86 | ||||
-rw-r--r-- | CS3871/sync/sync.c | 118 | ||||
-rw-r--r-- | CS3871/sync/writer.c | 76 |
5 files changed, 326 insertions, 0 deletions
diff --git a/CS3871/sync/assign.rst b/CS3871/sync/assign.rst new file mode 100644 index 0000000..ea4a566 --- /dev/null +++ b/CS3871/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/CS3871/sync/makefile b/CS3871/sync/makefile new file mode 100644 index 0000000..dd9c463 --- /dev/null +++ b/CS3871/sync/makefile @@ -0,0 +1,5 @@ +sync: sync.c reader.c writer.c + cc -o sync sync.c + cc -o reader reader.c + cc -o writer writer.c + diff --git a/CS3871/sync/reader.c b/CS3871/sync/reader.c new file mode 100644 index 0000000..929eba1 --- /dev/null +++ b/CS3871/sync/reader.c @@ -0,0 +1,86 @@ +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ipc.h> +#include <sys/select.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#define NSEM 3 +#define KEY 52 + +char *mem; + +void quit(signum) +int signum; +{ + shmdt(mem); + exit(1); +} + +int main(argc, argv) +int argc; +char **argv; +{ + int shmid, semid, i, pid, id; + char filename[50]; + FILE *fd; + struct sembuf sb; + + if (argc < 2) { + printf("usage: reader [id]\n"); + exit(1); + } + + id = atoi(argv[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); + } + + if ((semid = semget(shmid, NSEM, 0)) == -1) { + perror("Rsemget: "); + exit(1); + } + + signal(SIGQUIT, quit); + + sprintf(filename, "reader.%d", id); + + fd = fopen(filename, "a"); + + if (!fd) { + perror("fopen: "); + exit(1); + } + srand(time(NULL)); + + while (1) { + sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = 0; + semop(semid, &sb, 1); + + for (i = 0; i < 1<<14; i++) { + fprintf(fd, "%c", *(mem + i)); + fflush(fd); + } + fprintf(fd, "\n"); + fflush(fd); + + sb.sem_op = 1; + semop(semid, &sb, 1); + + + sleep(rand() % (id + 1)); + } +} diff --git a/CS3871/sync/sync.c b/CS3871/sync/sync.c new file mode 100644 index 0000000..23d6ba1 --- /dev/null +++ b/CS3871/sync/sync.c @@ -0,0 +1,118 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#define NSEM 3 + +union semun { + int val; + struct semid_ds *buf; + ushort *array; +}; + + +int shmid, semid; + +void quit(signum) +int signum; +{ + shmctl(shmid, IPC_RMID, NULL); + semctl(semid, IPC_RMID, 0); +} + + +int main(argc, argv) +int argc; +char **argv; +{ + int i, pid, n_read, n_write, w; + char *mem, **arg_r, **arg_w; + union semun semarg; + + 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); + } +printf("Sshmid: %x\n", shmid); + signal(SIGQUIT, quit); + + for (i = 0; i < 1<<14; i++) { + *(mem + i) = 0x30; + } + + if ((semid = semget(shmid, NSEM, 0666 | IPC_CREAT)) == -1) { + perror("Ssemget: "); + exit(1); + } + + semarg.val = 1; + for (i = 0; i < NSEM; i++) { + if ((semctl(semid, i, SETVAL, semarg)) == -1) { + perror("semctl: "); + exit(1); + } + } + + + arg_r = malloc(sizeof(char*) * 3); + arg_w = malloc(sizeof(char*) * 3); + *arg_r = malloc(sizeof(char) * 10); + *arg_w = malloc(sizeof(char) * 10); + + *(arg_r + 1) = malloc(sizeof(char) * 50); + *(arg_w + 1) = malloc(sizeof(char) * 50); + + *arg_r = "reader"; + *arg_w = "writer"; + + *(arg_r + 2) = NULL; + *(arg_w + 2) = NULL; + + for (i = 0; i < n_read; i++){ + sprintf(*(arg_r + 1), "%d", i); + if (pid = fork()) { + /* printf("starting reader %d...\n", i); */ + } else { + int ret = execv("./reader", arg_r); + printf("exec retern %d", ret); + } + } + + for (i = 0; i < n_write; i++) { + sprintf(*(arg_w + 1), "%d", i); + if (pid = fork()) { + /* printf("starting writer %d...\n", i); */ + } else { + execvp("./writer", arg_w); + } + + } + + shmdt(mem); +printf("sync done...\n"); +/* TODO + * why is this returning 8 + */ + for (i = 0; i < (n_write + n_read); i++) { + wait(&w); + printf("\nReturned with code:%d\n", WEXITSTATUS(w)); + } + quit(); +} diff --git a/CS3871/sync/writer.c b/CS3871/sync/writer.c new file mode 100644 index 0000000..d38dd70 --- /dev/null +++ b/CS3871/sync/writer.c @@ -0,0 +1,76 @@ +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ipc.h> +#include <sys/select.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <sys/types.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#define NSEM 3 + +char *mem; + +void quit(signum) +int signum; +{ + shmdt(mem); + exit(1); +} + +int main(argc, argv) +int argc; +char **argv; +{ + int shmid, semid, i, pid, id; + char *mem; + struct sembuf sb; + + if (argc < 2) { + printf("usage: writer [id]\n"); + exit(1); + } + + id = atoi(argv[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); + } +printf("Wshmid: %x\n", shmid); + + if ((semid = semget(shmid, NSEM, 0)) == -1) { + perror("Wsemget: "); + exit(1); + } + + signal(SIGQUIT, quit); + + srand(time(NULL)); + + while (1) { + rand() % id; + + sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = 0; + semop(semid, &sb, 1); + + for (i = 0; i < 1<<14; i++) { + mem[i]= 0x30 + id; + } + + sb.sem_op = 1; + semop(semid, &sb, 1); + + sleep(rand() % ((id * 2) + 1)); + } +} |