#include #include #include #include // 1 - best fit // 2 - worst fit // 3 - first fit enum Algorithm { BEST_FIT = 1, WORST_FIT = 2, FIRST_FIT = 3 }; enum Algorithm algorithm; int memSize; int totalAllocated = 0; int totalMemAllocated = 0; int totalFailed = 0; int totalTerminated = 0; int totalFreedMemory = 0; int *memory; void allocateByIndex(int index, int howMuchToAllocate, int processId) { for (int i = index; i < index + howMuchToAllocate; ++i) { memory[i] = processId; // Statistics totalMemAllocated++; } } bool doAllocate(int howMuchToAllocate, int processId) { int FirstFitIndex = -1; int WorstFitIndex = -1; int BestFitIndex = -1; int startIndex = -1; int size = 0; int smallestSoFar = memSize; int biggestSoFar = 0; for (int i = 0; i < memSize; ++i) { if (memory[i] == 0) { if (size == 0) { startIndex = i; } size++; } else { if (size >= howMuchToAllocate) { // On first fit, set the start index if (FirstFitIndex == -1) { FirstFitIndex = startIndex; } // If the size of the contiguous empty memory is bigger than the largest contiguous empty memory so far, set the index and update the size if (size > biggestSoFar) { WorstFitIndex = startIndex; biggestSoFar = size; } // If the size of the contiguous empty memory is smaller than the smallest contiguous empty memory so far, set the index and update the size if (size > 0 && smallestSoFar > size) { BestFitIndex = startIndex; smallestSoFar = size; } } size = 0; startIndex = -1; } } // Check if the last chunk is the first fit if (FirstFitIndex == -1 && size >= howMuchToAllocate) { FirstFitIndex = startIndex; } // Check if the last chunk is the smallest if (size > 0 && smallestSoFar >= size) { BestFitIndex = startIndex; } // Check if the last chunk is the biggest if (size >= biggestSoFar) { WorstFitIndex = startIndex; } // Since first fit is always set if there is space, we can error on that for any algorithm if (FirstFitIndex == -1 || howMuchToAllocate > memSize) { printf("Process %d failed to allocate %d memory\n", processId, howMuchToAllocate); // Statistics totalFailed++; // Early exit because there is no space, so don't touch memory return false; } switch (algorithm) { case BEST_FIT: { allocateByIndex(BestFitIndex, howMuchToAllocate, processId); break; } case WORST_FIT: { allocateByIndex(WorstFitIndex, howMuchToAllocate, processId); break; } case FIRST_FIT: { allocateByIndex(FirstFitIndex, howMuchToAllocate, processId); break; } default: { printf("There was an error, the algorithm is uninitialized"); exit(0); } } // Statistics totalAllocated++; return true; } bool doFree(int processId) { bool found = false; for (int i = 0; i < memSize; ++i) { if (memory[i] == processId) { memory[i] = 0; found = true; // Statistics totalFreedMemory++; } } if (found) { // Statistics totalTerminated++; } else { printf("Process %d failed to free memory\n", processId); // Statistics // Might not need to be counted as a failed request? totalFailed++; } return found; } int calcFinalMemory() { int total = 0; for (int i = 0; i < memSize; ++i) { if (memory[i] == 0) { total++; } } return total; } int getNumberOfChunks() { int total = 0; bool inChunk = false; for (int i = 0; i < memSize; ++i) { if (memory[i] == 0) { if (!inChunk) { inChunk = true; total++; } } else { inChunk = false; } } return total; } int getSmallest() { int smallestSize = memSize; int size = 0; for (int i = 0; i < memSize; ++i) { if (memory[i] == 0) { size++; } else if (smallestSize > size && size != 0) { smallestSize = size; size = 0; } } // Check if the last chunk is the smallest if (smallestSize >= memSize) { smallestSize = size; } return smallestSize; } int getBiggest() { int biggestSize = 0; int size = 0; for (int i = 0; i < memSize; ++i) { if (memory[i] == 0) { size++; } else if (size > biggestSize) { biggestSize = size; size = 0; } } // Check if the last chunk is the biggest if (biggestSize <= size) { biggestSize = size; } return biggestSize; } int main(int argc, char **argv) { for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "-b") == 0) { algorithm = BEST_FIT; } else if (strcmp(argv[i], "-w") == 0) { algorithm = WORST_FIT; } else if (strcmp(argv[i], "-s") == 0) { memSize = atoi(argv[i + 1]); } else if (strcmp(argv[i], "-f") == 0) { algorithm = FIRST_FIT; } } if (memSize >= 0) { // Use calloc to initialize memory to 0, which means empty in our case memory = calloc(memSize, sizeof(int)); } else { printf("The program requires size\n"); exit(0); } char operation; int id = 1337; int size; while (EOF != scanf("%c", &operation)) { switch (operation) { case 'N': scanf(" %d %d\n", &id, &size); doAllocate(size, id); break; case 'T': scanf(" %d\n", &id); doFree(id); break; case 'S': printf("Total Processes created %d, Total allocated memory %d, Total Processes\n" "terminated %d, Total freed memory %d, Final memory available %d, Final\n" "smallest and largest fragmented memory sizes %d and %d, total failed requests:%d, number of memory chunks: %d\n", totalAllocated, totalMemAllocated, totalTerminated, totalFreedMemory, calcFinalMemory(), getSmallest(), getBiggest(), totalFailed, getNumberOfChunks()); break; } } return 0; }