diff --git a/Assignment-2.pdf b/Assignment-2.pdf new file mode 100644 index 0000000..95d2081 Binary files /dev/null and b/Assignment-2.pdf differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b3c90f7 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +CC = gcc +OPTIONS = -Wall -Wextra -Werror + +all: generate_students kernel request_generator_admin request_generator_manager request_generator_member server + +clear: + rm disk generate_students kernel server request_generator_admin requests.txt log.txt requests + +generate_students: generate_students.c + $(CC) -Wall -g generate_students.c -o generate_students + +kernel: + $(CC) -Wall -g kernel.c -o kernel + +request_generator_admin: request_generator_admin.c + $(CC) -Wall -g request_generator_admin.c -o request_generator_admin + +request_generator_manager: request_generator_manager.c + $(CC) -Wall -g request_generator_manager.c -o request_generator_manager + +request_generator_member: request_generator_member.c + $(CC) -Wall -g request_generator_member.c -o request_generator_member + +server: server.c + $(CC) -Wall -g server.c -o server +# build: +# @$(CC) -Wall -g $(MODULE).c -o bin/$(MODULE) +# @./bin/$(MODULE) + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..8dc007f --- /dev/null +++ b/README.txt @@ -0,0 +1,7 @@ +OS PROJECT: Student Management Program + +Name: Roll No: +Cecily Ambooken IIB2022003 +Rakim Middya IIT2022255 +Rishab Bohra IIB2022004 +Veerathu Sindhu IIB2022006 \ No newline at end of file diff --git a/a b/a new file mode 100755 index 0000000..8be0970 Binary files /dev/null and b/a differ diff --git a/disk b/disk new file mode 100644 index 0000000..b0f4f3a Binary files /dev/null and b/disk differ diff --git a/generate_students b/generate_students new file mode 100755 index 0000000..d3aea61 Binary files /dev/null and b/generate_students differ diff --git a/generate_students.c b/generate_students.c new file mode 100644 index 0000000..5b5bdea --- /dev/null +++ b/generate_students.c @@ -0,0 +1,160 @@ +#ifndef GENERATE +#define GENERATE + +#include +#include +#include +#include +#include +#include +#include + +#include "student.h" + +// Function to load names from a file into an array + + +unsigned int randval() +{ + unsigned int randval; + FILE *f; + f = fopen("/dev/random", "r"); + fread(&randval, sizeof(randval), 1, f); + fclose(f); + return randval; +} + +void loadNamesFromFile(char* filename, char array[][MAX_STRING_LEN], int numNames) +{ + FILE *file = fopen(filename, "r"); + for (int i = 0; i < 20; i++) + { + char ch = fgetc(file); + int j = 0; + while (ch != EOF) + { + //printf("%c", ch); + if (ch == '\n') + { + array[i][j] = '\0'; + break; + } + array[i][j] = ch; + ch = fgetc(file); + j++; + } + // fgets(array[i], MAX_NAME_LEN, file); + } + for (int i = 0; i < numNames-1; i++) + { + array[i][strlen(array[i]) - 1] = '\0'; + } + fclose(file); +} + +char* generateFullName(char first_names[20][MAX_STRING_LEN], char last_names[20][MAX_STRING_LEN]) +{ + srand(time(NULL)); + int i = randval()%20; + int j = randval()%20; + char *name = malloc(sizeof(char)*105); + sprintf(name, "%s %s", first_names[i], last_names[j]); + //printf("%s", name); + return name; +} + +char* getRandomString(char names[][MAX_STRING_LEN], int range) +{ + srand(time(NULL)); + int num = randval() % range; + return names[num]; +} + +struct Student generateStudent(int id) +{ + struct Student student; + + char firstNames[20][MAX_STRING_LEN]; + char lastNames[20][MAX_STRING_LEN]; + char hostelNames[5][MAX_STRING_LEN]; + char courses[5][MAX_STRING_LEN]; + + loadNamesFromFile("names/firstname.txt", firstNames, 20); + loadNamesFromFile("names/lastname.txt", lastNames, 20); + loadNamesFromFile("names/hostelnames.txt", hostelNames, 5); + loadNamesFromFile("names/coursenames.txt", courses, 5); + + srand(time(NULL)); + student.id = id; + strcpy(student.name, generateFullName(firstNames, lastNames)); + strcpy(student.hostel, getRandomString(hostelNames, 5)); + strcpy(student.course, getRandomString(courses, 5)); + student.roomNumber = randval() % 400 + 101; + sprintf(student.dob, "%d/%d/%d", randval() % 28 + 1, randval() % 12 + 1, randval() % 16 + 1985); + student.yearOfStudy = randval() % 5 + 1; + + return student; +} + +void registration(struct Student student) +{ + FILE *file = fopen("disk", "a"); + if (file == NULL) + { + perror("Error opening database file"); + exit(0); + } + + fwrite(&student, 1, sizeof(struct Student), file); + fclose(file); +} + +double GetTime() +{ + struct timeval t; + int rc = gettimeofday(&t, NULL); + assert(rc == 0); + return (double) t.tv_sec + (double) t.tv_usec/1e6; +} + +void Spin(int howlong) +{ + double t = GetTime(); + while ((GetTime() - t) < (double) howlong); // do nothing in loop +} + + +void generate() +{ + FILE *file = fopen("disk", "a"); + if (file == NULL) + { + perror("Error opening database file"); + exit(0); + } + fseek(file, -sizeof(struct Student), SEEK_CUR); + struct Student temp; + fread(&temp, 1, sizeof(struct Student), file); + if (temp.id >= 100) + { + // printf("Registration complete for 100 students.\n"); + fclose(file); + return; + } + + for (int i = 0; i < 100; i++) + { + struct Student student = generateStudent(i+1); + //Spin(1); + registration(student); + } + + // printf("Registration complete for 100 students.\n"); + fclose(file); +} + +int main() +{ + generate(); +} +#endif \ No newline at end of file diff --git a/kerncall.c b/kerncall.c new file mode 100644 index 0000000..f52dda4 --- /dev/null +++ b/kerncall.c @@ -0,0 +1,91 @@ +#ifndef KERNCALL +#define KERNCALL + +#include +#include +#include + +#include "student.h" +#include "log.c" + +struct kerncall { + char ch; // 'u' = updateFile 's' = searchFile; + int id; // id to update/search + int newRoomNo; // room number to update +}; + + +void writeToPipe(int fd, char ch, int id, int newRoomNo) +{ + struct kerncall k = {0}; + k.ch = ch; + k.id = id; + k.newRoomNo = newRoomNo; + write(fd, &k, sizeof(k)); +} + +struct Student searchFile(int id, int flag) +{ + FILE* db = fopen("disk", "r"); + if (db == NULL) + { + perror("Error opening database file"); + exit(0); + } + struct Student temp; + while(fread(&temp, 1, sizeof(struct Student), db) && sizeof(temp) == sizeof(struct Student)) + { + if (temp.id == id) + { + if (flag == 0) + { + // printf("%d, %s, %s, %s, %d, %s, Year %d\n", temp.id, temp.name, + // temp.hostel, temp.course, temp.roomNumber, temp.dob, temp.yearOfStudy); + } + fclose(db); + return temp; + } + } + + // printf("NOT FOUND!!\n"); + fclose(db); + temp.id = -1; + return temp; +} + +// Update the file. +void updateFile(int id, int newRoomNumber) +{ + /* + * + * Implement the logic for updating here. + * First search file, but instead of returning a number, get the file pointer. + * Use fseek to reposition the file pointer. The number of bytes will be similar. + * And write the new struct there. + * + */ + FILE* db = fopen("disk", "r+"); + if (db == NULL) + { + perror("Error opening database file"); + exit(0); + } + + struct Student temp; + + while(fread(&temp, 1, sizeof(struct Student), db) && sizeof(temp) == sizeof(struct Student)) + { + if (temp.id == id) + { + temp.roomNumber = newRoomNumber; + fseek(db, -sizeof(struct Student), SEEK_CUR); + fwrite(&temp, 1, sizeof(struct Student), db); + fclose(db); + return; + } + } + + fclose(db); + return; +} +#endif \ No newline at end of file diff --git a/kernel b/kernel new file mode 100755 index 0000000..ea95287 Binary files /dev/null and b/kernel differ diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..52af853 --- /dev/null +++ b/kernel.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include + +#include "kerncall.c" +#include "student.h" +#include "operation.h" +#include "request.h" + +struct Student searchFile(int id, int flag); +void updateFile(int id, int newRoomNumber); + +int main() +{ + int pid = fork(); + if (pid < 0) + { + perror("Fork couldn't be created: "); + } + else if (pid == 0) + { + //char *argv[] = {"generate_students", "", "\0"}; + execl("./generate_students", "generate_students", NULL); + exit(0); + } + + pid_t wpid; + int status = 0; + + while ((wpid = wait(&status)) > 0); + + /* + For two way communication between request generator and kernel, there + needs to be two pipes: reqToKern[] and kernToReq[] + req to Kern will be for writing by kern and reading by req + kern to req will be for writing by req and reading by kern + */ + + int reqToKern[2]; + int kernToReq[2]; + + pipe(reqToKern); + pipe(kernToReq); + + char reqToKernStr[] = {reqToKern[0], reqToKern[1], '\0'}; + char kernToReqStr[] = {kernToReq[0], kernToReq[1], '\0'}; + + int pidAdmin = fork(); + if (pid < 0) + { + perror("Fork couldn't be created: "); + } + else if (pidAdmin == 0) + { + // printf("admin\n"); + execl("./request_generator_admin", "request_generator_admin", reqToKernStr, kernToReqStr, NULL); + } + + int pidManager = fork(); + if (pid < 0) + { + perror("Fork couldn't be created: "); + } + else if (pidManager == 0) + { + execl("./request_generator_manager", "request_generator_manager", reqToKernStr, kernToReqStr, NULL); + } + + int pidMember = fork(); + if (pid < 0) + { + perror("Fork couldn't be created: "); + } + else if (pidMember == 0) + { + execl("./request_generator_member", "request_generator_member", reqToKernStr, kernToReqStr, NULL); + } + + int flag = 0; + read(reqToKern[0], &flag, sizeof(flag)); + + /* + if the request generator has asked for a connection with server, then make a new pipe and + return the values else return 0 if pipes failed to get created. + */ + + int reqToServe[2]; + + if (flag == 1) + { + int pp = pipe(reqToServe); + if (pp == -1) + { + int temp = 0; // indicating that pipe couldn't be created + write(kernToReq[1], &temp, sizeof(temp)); + } + + else + { + write(kernToReq[1], &reqToServe[0], sizeof(reqToServe[0])); + write(kernToReq[1], &reqToServe[1], sizeof(reqToServe[1])); + int pid = fork(); + if (pid == 0) + { + execl("./server", "server", reqToKernStr, kernToReqStr, NULL); + } + } + } + // pid_t wpid; + // int status = 0; + + while ((wpid = wait(&status)) > 0); // wait for all the child programs to exit; + + // printf("Exiting Kernel!!\n"); +} \ No newline at end of file diff --git a/log.c b/log.c new file mode 100644 index 0000000..c5df074 --- /dev/null +++ b/log.c @@ -0,0 +1,23 @@ +#ifndef LOG +#define LOG +#include +#include + +void writeOne() +{ + FILE* log = fopen("log.txt", "a"); + //fprintf(log, "Accessed Linked List: 1 second\n"); + fprintf(log, "1\n"); + fclose(log); + // sleep(1); +} + +void writeTwo() +{ + FILE* log = fopen("log.txt", "a"); + //fprintf(log, "Accessed File: 2 seconds\n"); + fprintf(log, "2\n"); + fclose(log); + // sleep(2); +} +#endif diff --git a/main_memory.c b/main_memory.c new file mode 100644 index 0000000..540be9e --- /dev/null +++ b/main_memory.c @@ -0,0 +1,176 @@ +#ifndef MEMORY +#define MEMORY + +#include +#include +//#include "main.c" +#include "log.c" +#include "student.h" +#include "kerncall.c" + +typedef struct Node +{ + struct Student student; + struct Node* next; +}node; + +node* newNode(struct Student newStudent); +void addNode(node** head, struct Student std); +void removeHeadNode(node** head, int update); +void search(node** head, int id); +void update(node** head, int id, int hostelRoomNumber); +void printList(node* head); +void freeList(node** head); +void deleteNode(node** head, int id); + +// int main() +// { +// // node* head = malloc(sizeof(node)); +// // head->student = std; +// // head->next = NULL; +// node *head = NULL; +// for (int i = 1; i <= 5; i++) +// { +// struct Student std = generateStudent(i); +// addNode(&head, std); +// } +// deleteNode(&head, 3); +// printList(head); +// //search(head, 15); +// } + +void search(node** head, int id) +{ + writeOne(); + node* temp = *head; + int f = 0; + while (temp != NULL) + { + if (temp->student.id == id) + { + f = 1; + break; + } + temp = temp->next; + } + + if (f == 1) + { + // struct Student tempStd = temp->student; + // printf("%d, %s, %s, %s, %d, %s, Year %d\n", tempStd.id, tempStd.name, + // tempStd.hostel, tempStd.course, tempStd.roomNumber, tempStd.dob, tempStd.yearOfStudy); + } + else + { + writeTwo(); + struct Student tempStd = searchFile(id, 0); + addNode(head, tempStd); + } + return; +} + + +void addNode(node** head, struct Student std) +{ + node* newNode = malloc(sizeof(node)); + newNode->next = NULL; + newNode->student = std; + + if (*head == NULL) + { + *head = newNode; + return; + } + + node* temp = *head; + int count = 1; + while(temp->next != NULL) + { + count++; + temp = temp->next; + } + + //printf("Count: %d\n", count); + + if (count >= 5) + removeHeadNode(head, 1); + temp->next = newNode; +} + +void removeHeadNode(node** head, int update) +{ + struct Student std = (*head)->student; + *head = (*head)->next; + if (update == 1) + { + updateFile(std.id, std.roomNumber); + } +} + +void printList(node* head) +{ + while(head != NULL) + { + printf("%d ", head->student.id); + head = head->next; + } + printf("\n"); +} + + + +void update(node** head, int id, int hostelRoomNumber) +{ + node* temp = *head; + int f = 0; + writeOne(); + while (temp != NULL) + { + if (temp->student.id == id) + { + f = 1; + break; + } + temp = temp->next; + } + + if (f == 1) + { + temp->student.roomNumber = hostelRoomNumber; + } + else + { + writeTwo(); + struct Student tempStd = searchFile(id, 1); + tempStd.roomNumber = hostelRoomNumber; + addNode(head, tempStd); + } + return; +} + +void deleteNode(node** head, int id) +{ + node* prev = *head; + if (prev->student.id == id) + { + *head = (*head)->next; + free(prev); + } + else + { + node* temp = prev->next; + while (prev != NULL) + { + temp = prev->next; + if (temp != NULL) + { + if (temp->student.id == id) + { + prev->next = temp->next; + } + } + prev = prev->next; + } + } +} +#endif \ No newline at end of file diff --git a/names/coursenames.txt b/names/coursenames.txt new file mode 100644 index 0000000..0be34cd --- /dev/null +++ b/names/coursenames.txt @@ -0,0 +1,5 @@ +Btech +Mtech +PHD +MS +MBA \ No newline at end of file diff --git a/names/firstname.txt b/names/firstname.txt new file mode 100644 index 0000000..33282d4 --- /dev/null +++ b/names/firstname.txt @@ -0,0 +1,20 @@ +Olivia +Sindhu +Emma +Noah +Ava +Josh +Sophia +Jackson +Roshan +Rakim +Mia +Lucas +Harper +Rishab +Amelia +Elijah +Charlotte +James +Lily +Cecily \ No newline at end of file diff --git a/names/hostelnames.txt b/names/hostelnames.txt new file mode 100644 index 0000000..a2a6bc8 --- /dev/null +++ b/names/hostelnames.txt @@ -0,0 +1,5 @@ +Ruby Hostel +Sapphire Hostel +Emerald Hostel +Diamond Hostel +Topaz Hostel \ No newline at end of file diff --git a/names/input.txt b/names/input.txt new file mode 100644 index 0000000..808d522 --- /dev/null +++ b/names/input.txt @@ -0,0 +1,100 @@ +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 +1 9 +1 10 +1 11 +1 12 +1 13 +1 14 +1 15 +1 16 +1 17 +1 18 +1 19 +1 20 +1 21 +1 22 +1 23 +1 24 +1 25 +1 26 +1 27 +1 28 +1 29 +1 30 +1 31 +1 32 +1 33 +1 34 +1 35 +1 36 +1 37 +1 38 +1 39 +1 40 +1 41 +1 42 +1 43 +1 44 +1 45 +1 46 +1 47 +1 48 +1 49 +1 50 +1 51 +1 52 +1 53 +1 54 +1 55 +1 56 +1 57 +1 58 +1 59 +1 60 +1 61 +1 62 +1 63 +1 64 +1 65 +1 66 +1 67 +1 68 +1 69 +1 70 +1 71 +1 72 +1 73 +1 74 +1 75 +1 76 +1 77 +1 78 +1 79 +1 80 +1 81 +1 82 +1 83 +1 84 +1 85 +1 86 +1 87 +1 88 +1 89 +1 90 +1 91 +1 92 +1 93 +1 94 +1 95 +1 96 +1 97 +1 98 +1 99 +1 100 diff --git a/names/lastname.txt b/names/lastname.txt new file mode 100644 index 0000000..f39a654 --- /dev/null +++ b/names/lastname.txt @@ -0,0 +1,20 @@ +Smith +Johnson +Williams +Jones +Brown +Davis +Miller +Wilson +Moore +Taylor +Anderson +Thomas +Jackson +White +Harris +Martin +Thompson +Garcia +Martinez +Robinson \ No newline at end of file diff --git a/operation.h b/operation.h new file mode 100644 index 0000000..158cc0b --- /dev/null +++ b/operation.h @@ -0,0 +1,12 @@ +#ifndef OPERATION +#define OPERATION + +struct operation +{ + char status; // 'r' - ready 'u' - running 'b' - blocked + char role; // 'a' - admin 'm' - manager 'x' - members + int opID; + int stdID; + int roomNo; +}; +#endif diff --git a/output.txt b/output.txt new file mode 100644 index 0000000..1dd2ae9 --- /dev/null +++ b/output.txt @@ -0,0 +1,21 @@ +DEPORTES: Football Club +----------------------- +Scenario 1: + +Throughput: 1920.000000 +Mean Response Time: 0.000521 + +Scenario 2: + +Increased Memory by 20% +Throughput: 3963.870968 +Mean Response Time: 0.000252 + +Increased Memory by 50% +Throughput: 1187.246377 +Mean Response Time: 0.000842 + +Scenario 3: + +Original times: 151 158 155 +Updated times: 75 79 77 diff --git a/queue.c b/queue.c new file mode 100644 index 0000000..fca90e4 --- /dev/null +++ b/queue.c @@ -0,0 +1,155 @@ +#include +#include + +#include "operation.h" + +struct qnode { + struct operation key; + struct qnode* next; +}; + +struct Queue { + struct qnode *front, *rear; +}; + +struct qnode* newQnode(struct operation k) +{ + struct qnode* temp = (struct qnode*)malloc(sizeof(struct qnode)); + temp->key = k; + temp->next = NULL; + return temp; +} + +struct Queue* createqueue() +{ + struct Queue* q = (struct Queue*)malloc(sizeof(struct Queue)); + q->front = q->rear = NULL; + return q; +} + +void enqueue(struct Queue* q, struct operation k) +{ + struct qnode* temp = newQnode(k); + + if (q->rear == NULL) { + q->front = q->rear = temp; + } + + q->rear->next = temp; + q->rear = temp; +} + +struct operation dequeue(struct Queue* q) +{ + struct operation key = {0}; + // key.opID = '9'; + + if (q->front == NULL) + return key; + + struct qnode* temp = q->front; + key = temp->key; + + q->front = q->front->next; + + if (q->front == NULL) + q->rear = NULL; + + //free(temp); + return key; +} + +void enqueueAdmin(struct Queue* q, struct operation key) +{ + struct qnode* temp = newQnode(key); + + if (q->rear == NULL) { + q->front = q->rear = temp; + return; + } + + struct qnode* tempq = q->front->next; + + if (tempq == NULL) + { + q->front->next = temp; + return; + } + + temp->next = q->front->next; + q->front->next = temp; + return; +} + +void enqueueManager(struct Queue* q, struct operation key) +{ + struct qnode* temp = newQnode(key); + + if (q->rear == NULL) { + q->front = q->rear = temp; + return; + } + + struct qnode* tempq = q->front; + + int n = 1; + + while (tempq != NULL) + { + if (n == 3 && tempq->next != NULL) + { + temp->next = tempq->next; + tempq->next = temp; + return; + + } + else if (tempq->next == NULL) + { + tempq->next = temp; + return; + } + if (tempq->key.role != 'a') + { + n++; + } + tempq = tempq->next; + + } + return; +} + + +void enqueueMember(struct Queue* q, struct operation key) +{ + enqueue(q, key); +} + +// int main() +// { +// struct Queue* q = createqueue(); +// struct operation op = {0}; +// op.opID = '1'; +// enqueue(q, op); +// op.opID = '2'; +// enqueue(q, op); +// op.opID = '4'; +// enqueueAdmin(q, op); +// op.opID = '5'; +// enqueue(q, op); +// op.opID = '6'; +// enqueue(q, op); +// op.opID = '3'; +// enqueueManager(q, op); + + + +// int n = 10; +// while(n--) +// { +// if (q->front != NULL) +// printf("%d. Front: %c\n", 10-n,q->front->key.opID); +// dequeue(q); +// } +// return 0; +// } + diff --git a/randval.c b/randval.c new file mode 100644 index 0000000..65bfe58 --- /dev/null +++ b/randval.c @@ -0,0 +1,15 @@ +#include + +unsigned int randval() +{ + unsigned int randval; + FILE *f; + + f = fopen("/dev/random", "r"); + fread(&randval, sizeof(randval), 1, f); + fclose(f); + + return randval; + + return 0; +} diff --git a/reqfile_reader b/reqfile_reader new file mode 100755 index 0000000..e9860b2 Binary files /dev/null and b/reqfile_reader differ diff --git a/reqfile_reader.c b/reqfile_reader.c new file mode 100644 index 0000000..f2357e9 --- /dev/null +++ b/reqfile_reader.c @@ -0,0 +1,19 @@ +#include +#include + +#include "request.h" + + +int main() +{ + FILE* reqFiledb = fopen("requests", "r"); + struct request req; + while(fread(&req, 1, sizeof(struct request), reqFiledb) && sizeof(req) == sizeof(struct request)) + { + // printf("ID : %d\n", req.request_sequence_no); + // printf("submission_time : %d\n", req.submission_time); + // printf("completion_time : %d\n", req.completion_time); + // printf("waiting_time : %d\n", req.total_waiting_time); + } + fclose(reqFiledb); +} \ No newline at end of file diff --git a/request.h b/request.h new file mode 100644 index 0000000..f4cb99a --- /dev/null +++ b/request.h @@ -0,0 +1,7 @@ +struct request +{ + int request_sequence_no; + double submission_time; + double completion_time; + double total_waiting_time; +}; \ No newline at end of file diff --git a/request_generator_admin b/request_generator_admin new file mode 100755 index 0000000..c8ba132 Binary files /dev/null and b/request_generator_admin differ diff --git a/request_generator_admin.c b/request_generator_admin.c new file mode 100644 index 0000000..b74fd3f --- /dev/null +++ b/request_generator_admin.c @@ -0,0 +1,64 @@ +#include +#include +#include + +#include "operation.h" +#include "randval.c" + +int main(int argc, char* argv[]) +{ + int reqToKern[2]; //request to kern + reqToKern[0] = argv[1][0]; + reqToKern[1] = argv[1][1]; + + int kernToReq[2]; // kern to request + kernToReq[0] = argv[2][0]; + kernToReq[1] = argv[2][1]; + + // request to establish a connection with server + + int buffer = 1; + + write(reqToKern[1], &buffer, sizeof(buffer)); + + read(kernToReq[0], &buffer , sizeof(int)); + + int reqToServe[2]; + if (buffer != 0) + { + reqToServe[0] = buffer; + read(kernToReq[0], &reqToServe[1], sizeof(reqToServe[1])); + } + + // printf("Read: %d\n", reqToServe[0]); + // printf("Write: %d\n", reqToServe[1]); + + struct operation op; + for (int i = 0; i < 12; i++) + { + int waitTime = randval()%4+2; + sleep(waitTime); + + op.opID = 0; + op.stdID = 0; + op.roomNo = 0; + + op.role = 'a'; + op.opID = randval()%4; + + if (op.opID != 0) + { + op.stdID = randval()%100; + } + if (op.opID == 2) + { + op.roomNo = randval() % 400 + 101; + } + // printf("%d. reqgen: %c\n", i+1, op.role); + write(reqToKern[1], &op, sizeof(op)); + } + + op.opID = -1; + write(reqToKern[1], &op, sizeof(op)); + exit(0); +} \ No newline at end of file diff --git a/request_generator_manager b/request_generator_manager new file mode 100755 index 0000000..0bdbb32 Binary files /dev/null and b/request_generator_manager differ diff --git a/request_generator_manager.c b/request_generator_manager.c new file mode 100644 index 0000000..aedbecb --- /dev/null +++ b/request_generator_manager.c @@ -0,0 +1,63 @@ +#include +#include +#include + +#include "operation.h" +#include "randval.c" + +int main(int argc, char* argv[]) +{ + int reqToKern[2]; //request to kern + reqToKern[0] = argv[1][0]; + reqToKern[1] = argv[1][1]; + + // int kernToReq[2]; // kern to request + // kernToReq[0] = argv[2][0]; + // kernToReq[1] = argv[2][1]; + + // request to establish a connection with server + + // int buffer = 1; + + // write(reqToKern[1], &buffer, sizeof(buffer)); + // read(kernToReq[0], &buffer , sizeof(int)); + + // int reqToServe[2]; + // if (buffer != 0) + // { + // reqToServe[0] = buffer; + // read(kernToReq[0], &reqToServe[1], sizeof(reqToServe[1])); + // } + + // printf("Read: %d\n", reqToServe[0]); + // printf("Write: %d\n", reqToServe[1]); + + struct operation op; + for (int i = 0; i < 15; i++) + { + int waitTime = randval()%4+1; + sleep(waitTime); + + op.opID = 0; + op.stdID = 0; + op.roomNo = 0; + + op.role = 'm'; + op.opID = randval()%4; + + if (op.opID != 0) + { + op.stdID = randval()%100; + } + if (op.opID == 2) + { + op.roomNo = randval() % 400 + 101; + } + // printf("%d. reqgen: %c\n", i+1, op.role); + write(reqToKern[1], &op, sizeof(op)); + } + + op.opID = -1; + write(reqToKern[1], &op, sizeof(op)); + exit(0); +} \ No newline at end of file diff --git a/request_generator_member b/request_generator_member new file mode 100755 index 0000000..8526e60 Binary files /dev/null and b/request_generator_member differ diff --git a/request_generator_member.c b/request_generator_member.c new file mode 100644 index 0000000..4277938 --- /dev/null +++ b/request_generator_member.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "operation.h" +#include "randval.c" + +int main(int argc, char* argv[]) +{ + int reqToKern[2]; //request to kern + reqToKern[0] = argv[1][0]; + reqToKern[1] = argv[1][1]; + + // int kernToReq[2]; // kern to request + // kernToReq[0] = argv[2][0]; + // kernToReq[1] = argv[2][1]; + + // request to establish a connection with server + + // int buffer = 1; + + // write(reqToKern[1], &buffer, sizeof(buffer)); + // read(kernToReq[0], &buffer , sizeof(int)); + + // int reqToServe[2]; + // if (buffer != 0) + // { + // reqToServe[0] = buffer; + // read(kernToReq[0], &reqToServe[1], sizeof(reqToServe[1])); + // } + + // printf("Read: %d\n", reqToServe[0]); + // printf("Write: %d\n", reqToServe[1]); + + struct operation op; + for (int i = 0; i < 35; i++) + { + sleep(1); + + op.opID = 0; + op.stdID = 0; + op.roomNo = 0; + + op.role = 'x'; + op.opID = randval()%4; + + if (op.opID != 0) + { + op.stdID = randval()%100; + } + if (op.opID == 2) + { + op.roomNo = randval() % 400 + 101; + } + // printf("%d. reqgen: %c\n", i+1, op.role); + write(reqToKern[1], &op, sizeof(op)); + } + + op.opID = -1; + write(reqToKern[1], &op, sizeof(op)); + exit(0); +} \ No newline at end of file diff --git a/requests b/requests new file mode 100644 index 0000000..91ea982 Binary files /dev/null and b/requests differ diff --git a/requests.txt b/requests.txt new file mode 100644 index 0000000..9d1d360 --- /dev/null +++ b/requests.txt @@ -0,0 +1,310 @@ +ID : 1 +submission_time : 1692898982000.055420 +completion_time : 1692898982000.055664 +waiting_time : 0.000244 + +ID : 2 +submission_time : 1692898983000.055420 +completion_time : 1692898983000.055420 +waiting_time : 0.000000 + +ID : 3 +submission_time : 1692898984000.054932 +completion_time : 1692898984000.055176 +waiting_time : 0.000244 + +ID : 4 +submission_time : 1692898984000.055420 +completion_time : 1692898984000.056396 +waiting_time : 0.000977 + +ID : 5 +submission_time : 1692898984000.056396 +completion_time : 1692898984000.056641 +waiting_time : 0.000244 + +ID : 6 +submission_time : 1692898985000.056152 +completion_time : 1692898985000.056396 +waiting_time : 0.000244 + +ID : 7 +submission_time : 1692898986000.055176 +completion_time : 1692898986000.055420 +waiting_time : 0.000244 + +ID : 8 +submission_time : 1692898986000.055420 +completion_time : 1692898986000.055420 +waiting_time : 0.000000 + +ID : 9 +submission_time : 1692898986000.056152 +completion_time : 1692898986000.056396 +waiting_time : 0.000244 + +ID : 10 +submission_time : 1692898987000.056396 +completion_time : 1692898987000.056641 +waiting_time : 0.000244 + +ID : 11 +submission_time : 1692898988000.056641 +completion_time : 1692898988000.057617 +waiting_time : 0.000977 + +ID : 12 +submission_time : 1692898989000.055664 +completion_time : 1692898989000.055664 +waiting_time : 0.000000 + +ID : 13 +submission_time : 1692898989000.055664 +completion_time : 1692898989000.055664 +waiting_time : 0.000000 + +ID : 14 +submission_time : 1692898989000.056885 +completion_time : 1692898989000.056885 +waiting_time : 0.000000 + +ID : 15 +submission_time : 1692898990000.057129 +completion_time : 1692898990000.057373 +waiting_time : 0.000244 + +ID : 16 +submission_time : 1692898991000.057129 +completion_time : 1692898991000.057373 +waiting_time : 0.000244 + +ID : 17 +submission_time : 1692898992000.057373 +completion_time : 1692898992000.057861 +waiting_time : 0.000488 + +ID : 18 +submission_time : 1692898993000.055664 +completion_time : 1692898993000.055908 +waiting_time : 0.000244 + +ID : 19 +submission_time : 1692898993000.057373 +completion_time : 1692898993000.057617 +waiting_time : 0.000244 + +ID : 20 +submission_time : 1692898994000.056152 +completion_time : 1692898994000.056396 +waiting_time : 0.000244 + +ID : 21 +submission_time : 1692898994000.057861 +completion_time : 1692898994000.058105 +waiting_time : 0.000244 + +ID : 22 +submission_time : 1692898995000.058105 +completion_time : 1692898995000.058105 +waiting_time : 0.000000 + +ID : 23 +submission_time : 1692898996000.056396 +completion_time : 1692898996000.056396 +waiting_time : 0.000000 + +ID : 24 +submission_time : 1692898996000.058105 +completion_time : 1692898996000.058350 +waiting_time : 0.000244 + +ID : 25 +submission_time : 1692898997000.055908 +completion_time : 1692898997000.056152 +waiting_time : 0.000244 + +ID : 26 +submission_time : 1692898997000.058350 +completion_time : 1692898997000.058350 +waiting_time : 0.000000 + +ID : 27 +submission_time : 1692898998000.058350 +completion_time : 1692898998000.058350 +waiting_time : 0.000000 + +ID : 28 +submission_time : 1692898999000.056641 +completion_time : 1692898999000.057129 +waiting_time : 0.000488 + +ID : 29 +submission_time : 1692898999000.058594 +completion_time : 1692898999000.059814 +waiting_time : 0.001221 + +ID : 30 +submission_time : 1692899000000.058838 +completion_time : 1692899000000.059814 +waiting_time : 0.000977 + +ID : 31 +submission_time : 1692899001000.056152 +completion_time : 1692899001000.056396 +waiting_time : 0.000244 + +ID : 32 +submission_time : 1692899001000.059082 +completion_time : 1692899001000.059326 +waiting_time : 0.000244 + +ID : 33 +submission_time : 1692899002000.059326 +completion_time : 1692899002000.059570 +waiting_time : 0.000244 + +ID : 34 +submission_time : 1692899003000.056885 +completion_time : 1692899003000.058105 +waiting_time : 0.001221 + +ID : 35 +submission_time : 1692899003000.059570 +completion_time : 1692899003000.059814 +waiting_time : 0.000244 + +ID : 36 +submission_time : 1692899004000.059814 +completion_time : 1692899004000.060059 +waiting_time : 0.000244 + +ID : 37 +submission_time : 1692899005000.056396 +completion_time : 1692899005000.056396 +waiting_time : 0.000000 + +ID : 38 +submission_time : 1692899005000.059814 +completion_time : 1692899005000.059814 +waiting_time : 0.000000 + +ID : 39 +submission_time : 1692899006000.060059 +completion_time : 1692899006000.060303 +waiting_time : 0.000244 + +ID : 40 +submission_time : 1692899007000.056396 +completion_time : 1692899007000.087646 +waiting_time : 0.031250 + +ID : 41 +submission_time : 1692899007000.087891 +completion_time : 1692899007000.088623 +waiting_time : 0.000732 + +ID : 42 +submission_time : 1692899008000.056641 +completion_time : 1692899008000.056885 +waiting_time : 0.000244 + +ID : 43 +submission_time : 1692899008000.057129 +completion_time : 1692899008000.057373 +waiting_time : 0.000244 + +ID : 44 +submission_time : 1692899008000.060547 +completion_time : 1692899008000.060791 +waiting_time : 0.000244 + +ID : 45 +submission_time : 1692899009000.060547 +completion_time : 1692899009000.060791 +waiting_time : 0.000244 + +ID : 46 +submission_time : 1692899010000.057617 +completion_time : 1692899010000.057617 +waiting_time : 0.000000 + +ID : 47 +submission_time : 1692899010000.060791 +completion_time : 1692899010000.060791 +waiting_time : 0.000000 + +ID : 48 +submission_time : 1692899011000.057129 +completion_time : 1692899011000.057129 +waiting_time : 0.000000 + +ID : 49 +submission_time : 1692899011000.060791 +completion_time : 1692899011000.061035 +waiting_time : 0.000244 + +ID : 50 +submission_time : 1692899012000.061035 +completion_time : 1692899012000.061279 +waiting_time : 0.000244 + +ID : 51 +submission_time : 1692899013000.061523 +completion_time : 1692899013000.062744 +waiting_time : 0.001221 + +ID : 52 +submission_time : 1692899014000.057373 +completion_time : 1692899014000.058350 +waiting_time : 0.000977 + +ID : 53 +submission_time : 1692899014000.061768 +completion_time : 1692899014000.062012 +waiting_time : 0.000244 + +ID : 54 +submission_time : 1692899015000.057861 +completion_time : 1692899015000.058105 +waiting_time : 0.000244 + +ID : 55 +submission_time : 1692899015000.062012 +completion_time : 1692899015000.062256 +waiting_time : 0.000244 + +ID : 56 +submission_time : 1692899016000.057617 +completion_time : 1692899016000.057617 +waiting_time : 0.000000 + +ID : 57 +submission_time : 1692899016000.062012 +completion_time : 1692899016000.062256 +waiting_time : 0.000244 + +ID : 57 +submission_time : 1692899018000.058105 +completion_time : 1692899018000.058105 +waiting_time : 0.000000 + +ID : 58 +submission_time : 1692899020000.057861 +completion_time : 1692899020000.057861 +waiting_time : 0.000000 + +ID : 59 +submission_time : 1692899023000.058350 +completion_time : 1692899023000.058594 +waiting_time : 0.000244 + +ID : 59 +submission_time : 1692899024000.058105 +completion_time : 1692899024000.060059 +waiting_time : 0.001953 + +ID : 60 +submission_time : 1692899028000.058594 +completion_time : 1692899028000.058838 +waiting_time : 0.000244 + diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..2954a89 --- /dev/null +++ b/run.sh @@ -0,0 +1,42 @@ +make clear +make -B all + +rm output.txt + +echo "DEPORTES: Football Club" >> output.txt +echo "-----------------------" >> output.txt +echo "Scenario 1:" >> output.txt +echo "" >> output.txt +./kernel >> output.txt +echo "" >> output.txt +time1=$(awk '{ sum += $1 } END { print sum/1.0 }' log.txt); +rm log.txt + +echo "Scenario 2:" >> output.txt +echo "" >> output.txt +echo "Increased Memory by 20%" >> output.txt +sed -i -e 's/count >= 5/count >= 6/g' main_memory.c +make clear +make -B all +./kernel >> output.txt +time2=$(awk '{ sum += $1 } END { print sum }' log.txt); +rm log.txt + +echo "" >> output.txt +echo "Increased Memory by 50%" >> output.txt +sed -i -e 's/count >= 6/count >= 9/g' main_memory.c +make clear +make -B all +./kernel >> output.txt +time3=$(awk '{ sum += $1 } END { print sum}' log.txt); +rm log.txt + +sed -i -e 's/count >= 9/count >= 5/g' main_memory.c + +echo "" >> output.txt +echo "Scenario 3:" >> output.txt +echo "" >> output.txt +echo "Original times: $time1 $time2 $time3" >> output.txt +echo "Updated times: $((time1 / 2)) $((time2 / 2)) $((time3 / 2))" >> output.txt +echo "" +cat output.txt diff --git a/server b/server new file mode 100755 index 0000000..5bc5811 Binary files /dev/null and b/server differ diff --git a/server.c b/server.c new file mode 100644 index 0000000..7f3b7e8 --- /dev/null +++ b/server.c @@ -0,0 +1,429 @@ +#ifndef SERVER +#define SERVER + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.c" +#include "student.h" +#include "main_memory.c" +#include "operation.h" +#include "request.h" +#include "queue.c" +#include "kerncall.c" + +// Functional Prototypes +struct request server(int number, char op_id, int st_id, int newRoomNumber); +void registerStudent(); +void registration(struct Student student); +struct Student generateStudent(int id); +char* getRandomString(char names[][MAX_STRING_LEN], int range); +char* generateFullName(char first_names[20][MAX_STRING_LEN], char last_names[20][MAX_STRING_LEN]); +void loadNamesFromFile(char* filename, char array[][MAX_STRING_LEN], int numNames); +double timeInSeconds(void) ; +double GetTime(); +unsigned int randval(); + +void delete(int id, node* head); +void printFile(char* filename); + +int main(int argc, char* argv[]) +{ + int reqToKern[2]; + reqToKern[0] = argv[1][0]; + reqToKern[1] = argv[1][1]; + + /* + + int kernToReq[2]; + kernToReq[0] = argv[2][0]; + kernToReq[1] = argv[2][1]; + */ + // printf("serverRead: %d\n", reqToServe[0]); + // printf("Write: %d\n", reqToServe[1]); + + int sum = 0; + + struct operation op; + int count = 1; + + struct Queue* q = createqueue(); + double sumOfTurnaroundTime = 0; + + double totalTurnaroundAdmin = 0; + double totalTurnaroundManager = 0; + double totalTurnaroundMember = 0; + + FILE* reqFile = fopen("requests.txt", "w"); + FILE* reqFiledb = fopen("requests", "w"); + + while((read(reqToKern[0], &op, sizeof(op)))) + { + if (op.opID == -1) + { + count--; + sum += op.opID; + if (sum == -3) + { + break; + } + } + + else + { + struct request req; + req.request_sequence_no = count; + req.submission_time = timeInSeconds(); + + switch (op.role) + { + case 'x': + { + enqueueMember(q, op); + break; + } + + case 'm': + { + enqueueManager(q, op); + break; + } + + case 'a': + { + enqueueAdmin(q, op); + break; + } + default: + break; + } + + op = dequeue(q); + server(count, op.opID+'0', op.stdID, op.roomNo); + + req.completion_time = timeInSeconds(); + req.total_waiting_time = req.completion_time-req.submission_time; + sumOfTurnaroundTime += req.total_waiting_time; + if (op.role == 'x') + { + totalTurnaroundMember += req.total_waiting_time; + } + if (op.role == 'm') + { + totalTurnaroundManager += req.total_waiting_time; + } + if (op.role == 'a') + { + totalTurnaroundAdmin += req.total_waiting_time; + } + + fprintf(reqFile, "ID : %d\n", count); + fprintf(reqFile, "submission_time : %f\n", req.submission_time); + fprintf(reqFile, "completion_time : %f\n", req.completion_time); + fprintf(reqFile, "waiting_time : %f\n", req.total_waiting_time); + fprintf(reqFile, "\n"); + + fwrite(&req, 1, sizeof(req), reqFiledb); + fflush(reqFile); + fflush(reqFiledb); + count++; + } + } + + double meanTurnaroundTime = sumOfTurnaroundTime/count; + printf("Throughput: %f\n", count/(sumOfTurnaroundTime)); + printf("Mean Response Time: %f\n", meanTurnaroundTime); + /* + printf("ADMIN:\n"); + printf("Throughput: %f\n", 12/(totalTurnaroundAdmin)); + printf("Mean Response Time: %f\n\n", totalTurnaroundAdmin/12); + + printf("MANAGER:\n"); + printf("Throughput: %f\n", 15/(totalTurnaroundManager)); + printf("Mean Response Time: %f\n\n", totalTurnaroundManager/15); + + printf("MEMBER:\n"); + printf("Throughput: %f\n", 35/(totalTurnaroundMember)); + printf("Mean Response Time: %f\n\n", totalTurnaroundMember/35); + */ + fclose(reqFile); + fclose(reqFiledb); +} + +struct request server(int number, char op_id, int st_id, int newRoomNumber) +{ + node *head = NULL; + struct request req; + req.request_sequence_no = number; + req.submission_time = time(NULL); + switch(op_id) + { + case '0': + { + registerStudent(); + break; + } + + + case '1': + { + //scanf("%d", &st_id); + search(&head, st_id); + break; + } + + + case '2': + { + //scanf("%d", &st_id); + //scanf("%d\n", &newRoomNumber); + update(&head, st_id, newRoomNumber); + break; + } + + + case'3': + { + //scanf("%d", &st_id); + delete(st_id, head); + //printFile("disk.tmp"); + break; + } + + case '4': + { + printFile("disk"); + break; + } + + } + + while (head != NULL) + { + removeHeadNode(&head, 1); + } + + req.completion_time = time(NULL); + return req; +} + +double GetTime() +{ + struct timeval t; + int rc = gettimeofday(&t, NULL); + assert(rc == 0); + return (double) t.tv_sec + (double) t.tv_usec/1e6; +} + +double timeInSeconds(void) +{ + struct timeval tv; + + gettimeofday(&tv,NULL); + return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000.0)/1000.0; +} + + +// Register a user and update the file accordingly +// First get the last roll no. used and then use generate_student(id) to write it to the file. +// Use printFile to see if the file is updated. +void registerStudent() +{ + writeTwo(); + FILE* db = fopen("disk", "r+"); + if (db == NULL) + { + perror("Error opening database file"); + exit(0); + } + struct Student temp; + int id = 0; + + while(fread(&temp, 1, sizeof(struct Student), db) && sizeof(temp) == sizeof(struct Student)) + { + id = temp.id; + } + + struct Student s; + id++; + s = generateStudent(id); + fwrite(&s, 1, sizeof(struct Student), db); + fclose(db); +} + +// Delete a line from the file + +void delete(int id, node* head) +{ + /* + * + * Implement the logic for deleting here. + * + * First search file, but instead of returning a number, get the line number. + * Now make a new copy of the file and copy all the lines except that one. + * Delete the original file and rename the current file to disk. + * + * refer https://www.w3resource.com/c-programming-exercises/file-handling/c-file-handling-exercise-8.php + * + */ + FILE* db = fopen("disk", "r"); + FILE* dbTemp = fopen("disk.tmp", "w"); + writeTwo(); + + if (db == NULL) + { + perror("Error opening database file"); + exit(0); + } + if (dbTemp == NULL) + { + perror("Error opening database file"); + exit(0); + } + + struct Student temp; + while(fread(&temp, 1, sizeof(struct Student), db) && sizeof(temp) == sizeof(struct Student)) + { + if (temp.id != id) + { + fwrite(&temp, 1, sizeof(struct Student), dbTemp); + } + } + + fclose(db); + fclose(dbTemp); + remove("disk"); + rename("disk.tmp", "disk"); + + if (head != NULL) + { + if (head->student.id != id) + { + removeHeadNode(&head, 1); + } + else + { + removeHeadNode(&head, 0); + } + } + return; +} + +void printFile(char* filename) +{ + FILE* db = fopen(filename, "r"); + if (db == NULL) + { + perror("Error opening database file"); + exit(0); + } + struct Student temp; + while(fread(&temp, 1, sizeof(struct Student), db) && sizeof(temp) == sizeof(struct Student)) + { + printf("%d: %s\n", temp.id, temp.name); + } + fclose(db); +} + +unsigned int randval() +{ + unsigned int randval; + FILE *f; + f = fopen("/dev/random", "r"); + fread(&randval, sizeof(randval), 1, f); + fclose(f); + return randval; +} + +void loadNamesFromFile(char* filename, char array[][MAX_STRING_LEN], int numNames) +{ + FILE *file = fopen(filename, "r"); + for (int i = 0; i < 20; i++) + { + char ch = fgetc(file); + int j = 0; + while (ch != EOF) + { + //printf("%c", ch); + if (ch == '\n') + { + array[i][j] = '\0'; + break; + } + array[i][j] = ch; + ch = fgetc(file); + j++; + } + // fgets(array[i], MAX_NAME_LEN, file); + } + for (int i = 0; i < numNames-1; i++) + { + array[i][strlen(array[i]) - 1] = '\0'; + } + fclose(file); +} + +char* generateFullName(char first_names[20][MAX_STRING_LEN], char last_names[20][MAX_STRING_LEN]) +{ + srand(time(NULL)); + int i = randval()%20; + int j = randval()%20; + char *name = malloc(sizeof(char)*105); + sprintf(name, "%s %s", first_names[i], last_names[j]); + //printf("%s", name); + return name; +} + +char* getRandomString(char names[][MAX_STRING_LEN], int range) +{ + srand(time(NULL)); + int num = randval() % range; + return names[num]; +} + +struct Student generateStudent(int id) +{ + struct Student student; + + char firstNames[20][MAX_STRING_LEN]; + char lastNames[20][MAX_STRING_LEN]; + char hostelNames[5][MAX_STRING_LEN]; + char courses[5][MAX_STRING_LEN]; + + loadNamesFromFile("names/firstname.txt", firstNames, 20); + loadNamesFromFile("names/lastname.txt", lastNames, 20); + loadNamesFromFile("names/hostelnames.txt", hostelNames, 5); + loadNamesFromFile("names/coursenames.txt", courses, 5); + + srand(time(NULL)); + student.id = id; + strcpy(student.name, generateFullName(firstNames, lastNames)); + strcpy(student.hostel, getRandomString(hostelNames, 5)); + strcpy(student.course, getRandomString(courses, 5)); + student.roomNumber = randval() % 400 + 101; + sprintf(student.dob, "%d/%d/%d", randval() % 28 + 1, randval() % 12 + 1, randval() % 16 + 1985); + student.yearOfStudy = randval() % 5 + 1; + + return student; +} + +void registration(struct Student student) +{ + FILE *file = fopen("disk", "a"); + if (file == NULL) + { + perror("Error opening database file"); + exit(0); + } + + fwrite(&student, 1, sizeof(struct Student), file); + fclose(file); +} + +#endif diff --git a/student.h b/student.h new file mode 100644 index 0000000..400eda4 --- /dev/null +++ b/student.h @@ -0,0 +1,18 @@ +#ifndef STUDENT +#define STUDENT + +#define MAX_STRING_LEN 50 + +// Define a structure to hold student information +struct Student +{ + int id; + char name[MAX_STRING_LEN]; + char hostel[MAX_STRING_LEN]; + char course[MAX_STRING_LEN]; + int roomNumber; + char dob[13]; + int yearOfStudy; +}; + +#endif