Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
4.1 kB
9
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>

#define PAGE_SIZE 256
#define PAGE_TABLE_SIZE 32768
#define TLB_SIZE 16
#define PHYSICAL_MEM_SIZE (1 << 15)

typedef struct {
    uint16_t page_number;
    uint16_t frame_number;
} TLBEntry;

int main(int argc, char *argv[]) {
    // Check command-line arguments
    if (argc != 1) {
        printf("Usage: %s\n", argv[0]);
        return 1;
    }

    // Open input file
    FILE *infile = fopen("addresses.txt", "r");
    if (infile == NULL) {
        printf("Error: could not open file addresses.txt\n");
        return 1;
    }

    // Open output file
    FILE *outfile = fopen("output.txt", "w");
    if (outfile == NULL) {
        printf("Error: could not open file output.txt\n");
        return 1;
    }

    // Open backing store file
    int backing_store_fd = open("BACKING_STORE.bin", O_RDONLY);
    if (backing_store_fd == -1) {
        printf("Error: could not open backing store file\n");
        return 1;
    }

    // Map backing store file to memory
    uint8_t *backing_store = mmap(NULL, 1 << 16, PROT_READ, MAP_PRIVATE, backing_store_fd, 0);
    if (backing_store == MAP_FAILED) {
        printf("Error: could not map backing store file to memory\n");
        return 1;
    }

    // Initialize page table and TLB
    uint16_t *page_table = calloc(PAGE_TABLE_SIZE, sizeof(uint16_t));
    TLBEntry *tlb = calloc(TLB_SIZE, sizeof(TLBEntry));
    int tlb_index = 0;

    // Initialize physical memory
    uint8_t *physical_mem = calloc(PHYSICAL_MEM_SIZE, sizeof(uint8_t));
    int oldest_frame_index = 0;

    // Read logical addresses from input file
    char buffer[10];
    uint16_t logical_address;
    uint16_t page_number;
    uint16_t offset;
    uint16_t frame_number;
    int page_faults = 0;
    int tlb_hits = 0;
    int tlb_misses = 0;
    int total_addresses = 0;
    while (fgets(buffer, 10, infile) != NULL) {
        total_addresses++;
        logical_address = atoi(buffer);
        page_number = (logical_address >> 8) & 0xff;
        offset = logical_address & 0xff;

        // Search TLB for page number
        int i;
        for (i = 0; i < TLB_SIZE; i++) {
            if (tlb[i].page_number == page_number) {
                frame_number = tlb[i].frame_number;
                tlb_hits++;
                break;
            }
        }

        // If not found in TLB, search page table
        if (i == TLB_SIZE) {
            frame_number = page_table[page_number];
            if (frame_number == 0) {
                // Page fault: read page from backing store
                page_faults++;
                frame_number = oldest_frame_index;
                oldest_frame_index = (oldest_frame_index + 1) % (PHYSICAL_MEM_SIZE / PAGE_SIZE);
                memcpy(physical_mem + frame_number * PAGE_SIZE, backing_store + page_number * PAGE_SIZE, PAGE_SIZE);
                page_table[page_number] = frame_number;
            }
            // Update TLB with new entry
            tlb[tlb_index].page_number = page_number;
            tlb[tlb_index].frame_number = frame_number;
            tlb_index = (tlb_index + 1) % TLB_SIZE;
            tlb_misses++;
        }

        // Calculate physical address and value at that address
        uint16_t physical_address = (frame_number << 8) | offset;
        int value = physical_mem[frame_number * PAGE_SIZE + offset];

        // Write output to file
        fprintf(outfile, "Virtual address: %d Physical address: %d Value: %d\n", logical_address, physical_address, value);
    }

    // Write statistics to file
    fprintf(outfile, "Page faults: %d TLB hits: %d TLB misses: %d Total addresses: %d\n", page_faults, tlb_hits, tlb_misses, total_addresses);

    // Clean up
    fclose(infile);
    fclose(outfile);
    munmap(backing_store, 1 << 16);
    free(page_table);
    free(tlb);
    free(physical_mem);

    return 0;
}