aboutsummaryrefslogtreecommitdiff
path: root/CS3871
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2019-02-18 07:35:54 -0500
committerTucker Evans <tuckerevans24@gmail.com>2019-02-18 07:35:54 -0500
commite8b1808eaf87a49e4c34ebbfb66854baa627418c (patch)
tree8a4bb15321992702b6b26e34bd2ed3a55bb7b0d9 /CS3871
parent6cc5652a8af3361288393718ec2adb2889c9af1e (diff)
Moves assignments to given course folder.
Diffstat (limited to 'CS3871')
-rw-r--r--CS3871/filesystem/README.rst0
-rw-r--r--CS3871/filesystem/disk.h17
-rw-r--r--CS3871/filesystem/disk.obin0 -> 3352 bytes
-rw-r--r--CS3871/filesystem/tfs.c352
-rw-r--r--CS3871/jobScheduler/cpuScheduleTable.c224
-rw-r--r--CS3871/sync/assign.rst41
-rw-r--r--CS3871/sync/makefile5
-rw-r--r--CS3871/sync/reader.c86
-rw-r--r--CS3871/sync/sync.c118
-rw-r--r--CS3871/sync/writer.c76
-rw-r--r--CS3871/timing/client.c133
11 files changed, 1052 insertions, 0 deletions
diff --git a/CS3871/filesystem/README.rst b/CS3871/filesystem/README.rst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/CS3871/filesystem/README.rst
diff --git a/CS3871/filesystem/disk.h b/CS3871/filesystem/disk.h
new file mode 100644
index 0000000..7bf6ad0
--- /dev/null
+++ b/CS3871/filesystem/disk.h
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define TRACKS 128
+#define SECTORS 4096
+
+/* 10ms per track change */
+/* 10ms/SECTORS per unit sector distance > 1 */
+
+void dinit();
+
+void rsector(int t,int s,unsigned char *b);
+
+void wsector(int t,int s,unsigned char *b);
+
+
diff --git a/CS3871/filesystem/disk.o b/CS3871/filesystem/disk.o
new file mode 100644
index 0000000..b1a36f8
--- /dev/null
+++ b/CS3871/filesystem/disk.o
Binary files differ
diff --git a/CS3871/filesystem/tfs.c b/CS3871/filesystem/tfs.c
new file mode 100644
index 0000000..fe2d94c
--- /dev/null
+++ b/CS3871/filesystem/tfs.c
@@ -0,0 +1,352 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include "disk.h"
+
+#define MAX_INODES 1000
+#define INODE_START (TRACKS * SECTORS) / (8 * 512)
+#define MAX_FILES 50
+
+struct block_ptr {
+ char track;
+ short sector;
+};
+struct blockll{
+ struct block_ptr data;
+ struct blockll *next;
+};
+
+struct meta_data{
+ char name[8];
+ int size;
+ int read;
+ int write;
+ int create;
+};
+
+struct inode {
+ struct meta_data info;
+ struct block_ptr data[20];
+};
+
+
+struct inode_list{
+ struct inode *node;
+ struct inode_list *next;
+};
+
+struct file {
+ struct inode *node;
+ int mode;
+ int next_sec;
+ int free;
+};
+
+
+int inode_list_size = 0;
+struct inode_list *root, *end;
+
+char bitmap[TRACKS][SECTORS/8];
+
+struct file files[MAX_FILES];
+int size;
+
+
+
+int check_bitmap(t,s)
+int t,s;
+{
+ char tmp;
+ tmp = bitmap[t][s/8];
+ tmp &= (1 << (s % 8));
+ return (int) tmp;
+}
+
+void set_bitmap(t,s)
+int t,s;
+{
+ bitmap[t][s/8] |= (1 << (s % 8));
+ return;
+}
+
+void print_bitmap()
+{
+ int i,j;
+ for(i = 0; i < 128; i++){
+
+ printf("\n%4d ", i);
+ for (j = 0; j < 4096/8; j++) {
+ printf("%02x", bitmap[i][j]);
+ if (j %31 == 0) {
+ printf("\n%4d ",i);
+ }
+ }
+ }
+}
+
+
+/* TODO
+ * Implement inode table as binary tree to speedup searches
+ */
+struct inode* inode_search(name)
+char *name;
+{
+ if (strcmp(name,"") == 0) {
+ return -1;
+ }
+ int i;
+ struct inode_list *tmp = root;
+
+ for(i = 0; i < MAX_INODES && i < inode_list_size; i++){
+ tmp = tmp->next;
+ if(strcmp(name, tmp->node->info.name) == 0)
+ return tmp->node;
+ }
+ return -2;
+}
+
+struct blockll* get_blocks(size)
+int size;
+{
+ int i, t, s;
+ struct blockll *root, *current = malloc(sizeof(struct blockll));
+ root = current;
+
+ for (i = 0; size > 0 && i < (4096 * 128); i++) {
+ t = i / 4096;
+ s = i % 4096;
+
+ if (!check_bitmap(t, s)) {
+ current->next = malloc(sizeof(struct blockll));
+ current = current->next;
+ current-> next = NULL;
+ current->data.track = (char) t;
+ current->data.sector = (short) s;
+
+ set_bitmap(t,s);
+ size-= 512;
+ }
+ }
+
+ return i <(4096 * 128) ? root : NULL;
+}
+
+struct inode_list* inode_create(name)
+char *name;
+{
+ struct timeval *tmp_time = malloc(sizeof(struct timeval));
+
+ struct inode_list *tmp = malloc(sizeof(struct inode_list));
+ struct inode *tmp_node = malloc(sizeof(struct inode));
+
+
+ tmp->node = tmp_node;
+
+ memcpy(&(tmp->node->info.name), name, strlen(name));
+
+ gettimeofday(tmp_time, NULL);
+
+ tmp->node->info.create = tmp_time->tv_sec;
+ tmp->node->info.read = tmp_time->tv_sec;
+ tmp->node->info.write = tmp_time->tv_sec;
+
+ end->next = tmp;
+ end = tmp;
+ inode_list_size++;
+
+ return tmp;
+}
+
+int inode_init()
+{
+ int n = MAX_INODES / 4;
+ int i;
+ char *ptr;
+ struct inode_list *tmp;
+
+ if (MAX_INODES % 4 > 0)
+ n++;
+
+ char *buf = malloc(512 * n);
+
+ for (i =0; i < n; i++) {
+ rsector(0, i, buf + (512 * i));
+ }
+ ptr = buf;
+
+ tmp = root;
+
+ for(i=0; i< MAX_INODES; i++) {
+ tmp->next = malloc(sizeof(struct inode_list));
+ memcpy(&tmp->node, ptr, 64);
+ ptr += 64;
+ tmp = tmp->next;
+ inode_list_size++;
+ }
+}
+
+/*save inodes to first n sectors on disk*/
+void inode_save()
+{
+ int i, j;
+ char *buf = malloc(512);
+ struct inode_list *tmp = root;
+
+ for (i = 0; i < MAX_INODES && tmp->next;i++) {
+ for (j = 0; j < 4; j++){
+ tmp = tmp->next;
+ memcpy(buf + j, tmp->node, sizeof(struct inode));
+ }
+ wsector(0, INODE_START + i, buf);
+ }
+}
+
+struct inode* inode_from_fd(fd)
+int fd;
+{
+ int i;
+ struct inode_list *tmp = root;
+
+ for (i = 0; i < fd; i++) {
+ tmp = tmp->next;
+ }
+
+ return tmp->node;
+}
+
+int find_fd()
+{
+ int i;
+ for (i = 0; i < size; i++) {
+ if (files[i].free)
+ return i;
+ }
+}
+
+int tfs_init()
+{
+ int i;
+ root = malloc(sizeof(struct inode_list));
+ end = root;
+
+ dinit();
+ /*
+ *
+ * has issue if inodes have not been written to disk i.e. first run
+ inode_init();
+ */
+ for (i = 0; i < MAX_FILES; i++) {
+ files[i].free = 1;
+ }
+}
+
+
+int open(fname, mode)
+char *fname, *mode;
+{
+ struct inode *fnode = inode_search(fname);
+ int fd;
+
+ if (fnode == -1)
+ return -1;
+
+ if (fnode == -2){
+ fnode = inode_create(fname)->node;
+ }
+ fd = find_fd();
+
+ files[fd].node = fnode;
+ files[fd].mode = *mode;
+ files[fd].next_sec = 0;
+ files[fd].free = 0;
+ size++;
+
+ return fd;
+}
+
+int close(fd)
+int fd;
+{
+ if (files[fd].free)
+ return -1;
+
+ files[fd].free = 1;
+ return 1;
+}
+
+int read(fd, buf)
+int fd;
+char *buf;
+{
+ if (files[fd].free || files[fd].mode || (files[fd].next_sec == 20))
+ return -1;
+
+
+ rsector(files[fd].node->data[files[fd].next_sec].track, files[fd].node->data[files[fd].next_sec].sector, buf);
+ files[fd].next_sec++;
+ return 512;
+}
+
+int write(fd, buf)
+int fd;
+char *buf;
+{
+ if ((files[fd].next_sec == 20) || !files[fd].mode)
+ return 0;
+
+ struct blockll *tmp = get_blocks(500);
+ files[fd].node->data[files[fd].next_sec].track = tmp->data.track;
+ files[fd].node->data[files[fd].next_sec].sector = tmp->data.sector;
+
+ wsector(files[fd].node->data[files[fd].next_sec].track, files[fd].node->data[files[fd].next_sec].sector, buf);
+ return 1;
+}
+
+int ulink(fname)
+char *fname;
+{
+ struct inode_list *tmp = root;
+ struct inode *d;
+ int i;
+
+ for(i = 0; i < MAX_INODES && i < inode_list_size; i++){
+ tmp = tmp->next;
+ if(strcmp(fname, tmp->next->node->info.name) == 0)
+ break;;
+ }
+
+ d = tmp->next->node;
+ tmp->next = tmp->next->next;
+ free(d);
+ return 1;
+ }
+
+int main()
+{
+ tfs_init();
+
+ /*
+ *Test Writing
+ */
+ int mode = 1;
+ int fd = open("test", &mode);
+
+ char buf[512];
+ memcpy(&buf, "Hello Filesystem", strlen("Hello Filesystem"));
+
+ int test = write(fd, &buf);
+ close(fd);
+
+ /*
+ *Test reading
+ */
+ mode = 0;
+ fd = open("test", &mode);
+ char buf2[512];
+ read(fd, &buf2);
+ printf("wrote: %s\n", buf);
+
+ printf("read: %s\n", buf2);
+
+}
diff --git a/CS3871/jobScheduler/cpuScheduleTable.c b/CS3871/jobScheduler/cpuScheduleTable.c
new file mode 100644
index 0000000..5d2256a
--- /dev/null
+++ b/CS3871/jobScheduler/cpuScheduleTable.c
@@ -0,0 +1,224 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+
+#define PROCESS_COUNT 4
+#define time_calc(x, y) ((y.tv_sec - x.tv_sec) * 1000000) + (y.tv_usec - x.tv_usec)
+
+
+/* TODO
+add heap for priority
+compute priority
+*/
+
+int go=1;
+int turn=0;
+float v;
+float throughput;
+struct timeval start_time;
+int turns;
+int completed_jobs;
+
+struct process {
+ int virgin;
+ int (*proc)(int);
+ int turnaround[9];
+ struct timeval start_t;
+ int runs;
+ float save;
+ int turn;
+};
+
+struct process pt[PROCESS_COUNT]; /*process table*/
+
+void
+cpusched(signum)
+int signum;
+{
+ pt[turn].virgin=0;
+ pt[turn].save=v;
+ go=0;
+}
+
+int
+f0(x)
+int x;
+{
+ register int i=0;
+ register int t;
+ signal(SIGUSR1, cpusched);
+ if (!x) goto start;
+ v=0.0;
+
+start:
+ while (go && (v > -200.0)) {
+ printf("0");fflush(stdout);
+ t = (rand() % 1024);
+ v -= 2.0;
+ if ((v>0.0) || ((((int) v) % 2) == -1)) {
+ printf("f0, found odd or positive, v= %f\n", v);
+ exit(1);
+ }
+ usleep(t*100);
+ }
+ if (v <= -200.0) pt[0].virgin=1;
+ go=1;
+}
+
+int
+f1(x)
+int x;
+{
+ register int i=0;
+ register int t;
+ if (!x) goto start2;
+ v= -1.0;
+
+start2:
+ while (go && (v > -401.0)) {
+ printf("1");fflush(stdout);
+ t = (rand() % 2048);
+ v -= 2.0;
+ if ((v>0.0) || ((((int) v) % 2) != -1)) {
+ printf("f1, found even or positive\n");
+ exit(1);
+ }
+ usleep(t*100);
+ }
+ if (v <= -401.0) pt[1].virgin=1;
+ go=1;
+}
+
+int
+f2(x)
+int x;
+{
+ register int i=0;
+ register int t;
+ if (!x) goto start3;
+ v= 1.0;
+
+start3:
+ while (go) {
+ printf("2");fflush(stdout);
+ t = (rand() % 4096);
+ v += 2.0;
+ if ((v<0.0) || ((((int) v) % 2) != 1)) {
+ printf("f2, found even or negative\n");
+ exit(1);
+ }
+ usleep(t*100);
+ }
+ go=1;
+}
+
+int
+f3(x)
+int x;
+{
+ register int i=0;
+ register int t;
+ if (!x) goto start4;
+ v= 0.0;
+
+start4:
+ while (go) {
+ printf("3");fflush(stdout);
+ t = (rand() % 4096);
+ v += 2.0;
+ if ((v<0.0) || ((((int) v) % 2) == 1)) {
+ printf("f3, found odd or negative\n");
+ exit(1);
+ }
+ usleep(t*100);
+ }
+ go=1;
+}
+
+void turnaround_calc(p, n)
+struct process *p;
+int n;
+{
+ int i;
+ p->turnaround[8] = 0;
+ for (i = 0; i < n; i++) {
+ p->turnaround[8] += p->turnaround[i] / n;
+ }
+ return;
+}
+
+int main(argc, argv, envp)
+int argc;
+char **argv, **envp;
+{
+ int pid, i, last;
+ struct timeval end_t;
+ gettimeofday(&start_time, NULL);
+
+ for (i = 0; i < PROCESS_COUNT; i++) {
+ pt[i].virgin = 1;
+ }
+
+ pt[0].proc=f0;
+ pt[1].proc=f1;
+ pt[2].proc=f2;
+ pt[3].proc=f3;
+
+ signal(SIGUSR1, cpusched);
+ if (pid=fork()) {
+ while (1) {
+ go = 1;
+ sleep(5);
+ if (go)
+ kill(pid, SIGUSR1);
+ }
+ } else {
+ while (1) {
+ printf("turn= %d\n", ++turns);
+ v=pt[turn].save;
+ if (pt[turn].virgin)
+ gettimeofday(&pt[turn].start_t, NULL);
+
+ pt[turn].proc(pt[turn].virgin);
+
+ gettimeofday(&end_t, NULL);
+
+ if (pt[turn].virgin) {
+ pt[turn].turnaround[pt[turn].runs % 8] = time_calc(pt[turn].start_t, end_t);
+ turnaround_calc(&pt[turn], (pt[turn].runs < 8 ? pt[turn].runs + 1 : 8));
+ pt[turn].runs++;
+ completed_jobs++;
+ kill(getppid(), SIGUSR1);
+ } else if (pt[turn].runs == 0){
+ pt[turn].turnaround[8] = (time_calc(pt[turn].start_t, end_t)) / 2;
+ }
+
+ throughput = completed_jobs / (float)(end_t.tv_sec - start_time.tv_sec);
+ pt[turn].turn++;
+
+ if (turns == 1000) {
+ kill(getppid(), 9);
+ exit(1);
+ }
+
+ printf("\n");
+
+ for (i = 0; i < 4; i++){
+ printf("\t[%d]\tturnaround= %9d\truns= %3d\tturn= %d\n", i, pt[i].turnaround[8], pt[i].runs, pt[i].turn);
+ }
+
+ printf("\ntime= %5d\tthroughput= %9f\tcompleted_jobs= %d\n\n\n", end_t.tv_sec - start_time.tv_sec, throughput, completed_jobs);
+
+ last = turn;
+ turn = 0;
+ for (i = 1; i < PROCESS_COUNT; i++) {
+ turn = ((pt[turn].turnaround[8] < pt[i].turnaround[8]) && (turn != last)) ? turn : i;
+ }
+
+ }
+ }
+}
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));
+ }
+}
diff --git a/CS3871/timing/client.c b/CS3871/timing/client.c
new file mode 100644
index 0000000..9a83a5b
--- /dev/null
+++ b/CS3871/timing/client.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+
+#define BUFFER_SIZE 1024
+
+typedef struct number_val {
+ int val;
+ struct timeval tv;
+} num;
+
+int sock_init(argv)
+char **argv;
+{
+ struct sockaddr_in address, serv_addr;
+ int sock = 0, valread;
+ char buffer[1024] = {0};
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("Socket creation error\n");
+ return -1;
+ }
+
+ memset(&serv_addr, '0', sizeof(serv_addr));
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(atoi(argv[2]));
+
+ if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0) {
+ perror("Invalid address/Address not supported\n");
+ return -1;
+ }
+
+ if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+ perror("Connection Failed");
+ return -1;
+ }
+ return sock;
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ int sock = 0, valread, start_ptr = -1, end_ptr = 0, qset, i;
+ double avg = 0, cnt;
+ char buffer[1024] = {0};
+ num num_buffer[BUFFER_SIZE];
+ fd_set rs, ws, es;
+ struct timeval now, *ww, tmp;
+
+ sock = sock_init(argv);
+
+ ww = NULL;
+
+ printf("Connected, waiting for numbers...\n");
+ while (1) {
+ FD_ZERO(&rs); FD_ZERO(&ws); FD_ZERO(&es);
+ FD_SET(sock, &rs);
+
+ qset = select(sock + 1, &rs, (fd_set *) 0, (fd_set *) 0, ww);
+
+ gettimeofday(&now, NULL);
+ now.tv_sec = now.tv_sec - 60;
+
+ ww = &tmp;
+ tmp.tv_sec = 0;
+ tmp.tv_usec = 500000;
+
+ if (FD_ISSET(sock, &rs)) {
+ valread = read(sock, buffer, 1024);
+ for (i = 0; i < valread; i+=2) {
+ if (end_ptr == BUFFER_SIZE)
+ end_ptr = 0;
+ if (end_ptr != start_ptr) {
+ gettimeofday(&(num_buffer[end_ptr].tv), NULL);
+ num_buffer[end_ptr].val = atoi(buffer + i);
+ end_ptr++;
+ } else {
+ printf("dropping number...\n");
+ }
+ }
+ }
+
+ if (start_ptr == -1)
+ start_ptr = 0;
+
+ if (start_ptr < end_ptr) {
+ for (i = start_ptr; i < end_ptr; i++) {
+ if (num_buffer[i].tv.tv_sec <= now.tv_sec)
+ start_ptr = i + 1;
+ }
+ } else {
+ for (i = start_ptr; i < BUFFER_SIZE; i++) {
+ num_buffer[end_ptr].val = atoi(buffer);
+ end_ptr++;
+ num_buffer[end_ptr].val = atoi(buffer);
+ end_ptr++;
+ num_buffer[end_ptr].val = atoi(buffer);
+ end_ptr++;
+ if (num_buffer[i].tv.tv_sec <= now.tv_sec)
+ start_ptr = i + 1;
+ }
+
+ for (i = 0; i < end_ptr; i++) {
+ if (num_buffer[i].tv.tv_sec <= now.tv_sec)
+ start_ptr = i + 1;
+ }
+
+ start_ptr %= BUFFER_SIZE;
+ }
+
+ avg = 0;
+ cnt = start_ptr > end_ptr ? (BUFFER_SIZE - start_ptr + end_ptr) : (end_ptr - start_ptr);
+ cnt = cnt == 0 ? 10 : cnt;
+
+ if (start_ptr < end_ptr) {
+ for (i = start_ptr; i < end_ptr; i++)
+ avg += num_buffer[i].val / cnt;
+ } else {
+ for (i = start_ptr; i < BUFFER_SIZE; i++)
+ avg += num_buffer[i].val / cnt;
+ for (i = 0; i < end_ptr; i++)
+ avg += num_buffer[i].val /cnt;
+ }
+
+ printf("avg: %10.5f\n", avg);
+ }
+}