CS3413/Assignment8/code/main.c

174 lines
4.7 KiB
C
Raw Normal View History

2023-11-28 13:19:22 -04:00
#include <stdio.h>
#include <stdlib.h>
// Data structures and helper functions
typedef struct DiskRequest {
int position;
int time;
} DiskRequest;
typedef struct DiskQueue {
DiskRequest *requests;
int index;
int size;
} DiskQueue;
DiskQueue *createDiskQueue() {
DiskQueue *queue = malloc(sizeof(DiskQueue));
if (queue == NULL) {
printf("Error allocating memory for queue\n");
exit(EXIT_FAILURE);
}
queue->requests = malloc(sizeof(DiskRequest));
if (queue->requests == NULL) {
printf("Error allocating memory for queue requests\n");
exit(EXIT_FAILURE);
}
queue->index = 0;
queue->size = 0;
return queue;
}
DiskRequest diskRequest(int position, int time) {
DiskRequest request;
request.position = position;
request.time = time;
return request;
}
void enqueue(DiskQueue *queue, DiskRequest request) {
queue->requests = realloc(queue->requests, sizeof(DiskRequest) * (queue->size + 1));
queue->requests[queue->size] = request;
queue->size++;
}
DiskRequest dequeue(DiskQueue *queue) {
DiskRequest request = queue->requests[queue->index];
queue->index++;
return request;
}
// Allocates a new queue with the requests that have the same time
2023-11-28 17:21:49 -04:00
DiskQueue *queueOfSameTime(DiskQueue *queue, int time) {
2023-11-28 13:19:22 -04:00
DiskQueue *sameTimeQueue = createDiskQueue();
for (int i = queue->index; i < queue->size - queue->index; i++) {
if (queue->requests[i].time == time) {
enqueue(sameTimeQueue, queue->requests[i]);
}
}
return sameTimeQueue;
}
// Compare function for disk requests by position
int compareDiskRequestsByPosition(const void *a, const void *b) {
DiskRequest *requestA = (DiskRequest *) a;
DiskRequest *requestB = (DiskRequest *) b;
return requestA->position - requestB->position;
}
// Sorts the queue by position, in place
2023-11-28 17:21:49 -04:00
DiskQueue *sortQueueByPosition(DiskQueue *queue) {
2023-11-28 13:19:22 -04:00
qsort(queue->requests, queue->size, sizeof(DiskRequest), compareDiskRequestsByPosition);
return queue;
}
void destroyDiskQueue(DiskQueue *queue) {
free(queue->requests);
free(queue);
}
typedef enum DiskDirection {
UP, DOWN
} DiskDirection;
// Global tracking variables
DiskDirection currentDirection = UP;
int movement = 0;
double seekTime = 0;
// Array for storing the requests
DiskQueue *queue;
double timeToProcessRequest(int position, int destination) {
2023-11-28 17:21:49 -04:00
//The time (a floating point number) required to process a request is computed by distance the head travels divided by 5
//Plus additional 15 milliseconds penalty if the direction has to change (for FCFS)
2023-11-28 13:19:22 -04:00
double time = 0;
2023-11-28 17:21:49 -04:00
// Calculated this way so that positive means up and negative means down
int distance = destination - position;
DiskDirection direction = (distance > 0) ? UP : DOWN;
time += abs(distance) / 5.0;
if (direction != currentDirection) {
2023-11-28 13:19:22 -04:00
time += 15;
currentDirection = direction;
}
return time;
}
// Your simulated disk is of size 10000, numbered from 0 to 9999.
// In first come first the time the request comes in is irrelevant
void fcfs(int start) {
int position = start;
for (int i = 0; i < queue->size; i++) {
DiskRequest request = dequeue(queue);
2023-11-28 19:44:53 -04:00
while (seekTime < request.time) { seekTime++; }
2023-11-28 13:19:22 -04:00
seekTime += timeToProcessRequest(position, request.position);
movement += abs(position - request.position);
position = request.position;
}
}
void cscan(int start) {
int currentTime = 0;
int position = start;
for (int i = 0; i < queue->size; i++) {
DiskRequest request = dequeue(queue);
while (currentTime < request.time) { currentTime++; }
DiskQueue *sameTimeQueue = sortQueueByPosition(queueOfSameTime(queue, request.time));
2023-11-28 17:21:49 -04:00
for (; i < sameTimeQueue->size; i++) {
2023-11-28 13:19:22 -04:00
DiskRequest request = dequeue(sameTimeQueue);
// Need to return to 0 because we have reached the end of the disk on the current pass
if (request.position < position) {
seekTime += timeToProcessRequest(position, 9999);
movement += abs(position - 9999);
position = 9999;
seekTime += timeToProcessRequest(position, 0);
movement += abs(position - 0);
position = 0;
}
seekTime += timeToProcessRequest(position, request.position);
movement += abs(position - request.position);
position = request.position;
}
//destroyDiskQueue(sameTimeQueue);
}
}
int main(int argc, char **argv) {
int position, time;
char algorithm = argv[1][0];
int start = 0;
queue = createDiskQueue();
while (EOF != (scanf("%i %i\n", &position, &time))) {
enqueue(queue, diskRequest(position, time));
// printf("Delete me: position %i, Delete me: time %i\n", position, time);
}
if (algorithm == 'F') {
fcfs(start);
2023-11-28 17:21:49 -04:00
printf("Movement:%i Time:%.1lf\n", movement, seekTime);
2023-11-28 13:19:22 -04:00
} else if (algorithm == 'C') {
cscan(start);
2023-11-28 17:21:49 -04:00
// Stupid printf difference to pass tests, could call once after if statement
printf("Movement: %i Time:%.1lf\n", movement, seekTime);
2023-11-28 13:19:22 -04:00
}
destroyDiskQueue(queue);
return 0;
}