#include #include #include #include #include #include #include #include "util.h" /* Measure the time it takes to access a block with virtual address addr. */ CYCLES measure_one_block_access_time(ADDR_PTR addr) { CYCLES cycles; asm volatile("mov %1, %%r8\n\t" "lfence\n\t" "rdtsc\n\t" "mov %%eax, %%edi\n\t" "mov (%%r8), %%r8\n\t" "lfence\n\t" "rdtsc\n\t" "sub %%edi, %%eax\n\t" : "=a"(cycles) /*output*/ : "r"(addr) : "r8", "edi"); return cycles; } /* * CLFlushes the given address. * * Note: clflush is provided to help you debug and should not be used in your * final submission */ void clflush(ADDR_PTR addr) { asm volatile ("clflush (%0)"::"r"(addr)); } int fd; size_t file_size; char *allocate_shared_buffer() { const char *filepath = "shared_file"; int fd = open(filepath, O_RDONLY, (mode_t)0600); if (fd == -1) { perror("Error opening file for writing, please run `python3 gen_file.py` to get the file for shared buf"); exit(EXIT_FAILURE); } struct stat fileInfo = {0}; if (fstat(fd, &fileInfo) == -1) { perror("Error getting the file size"); exit(EXIT_FAILURE); } if (fileInfo.st_size == 0) { fprintf(stderr, "Error: File is empty, nothing to do\n"); exit(EXIT_FAILURE); } if (fileInfo.st_size < SEC_RANGE * ALIGN) { close(fd); perror("File is too small\n"); exit(EXIT_FAILURE); } char *buf = mmap(0, fileInfo.st_size, PROT_READ, MAP_SHARED, fd, 0); if (buf == MAP_FAILED) { close(fd); perror("Error mmapping the file"); exit(EXIT_FAILURE); } file_size = fileInfo.st_size; return buf; } void deallocate_shared_buffer(char *buf) { // Don't forget to free the mmapped memory if (munmap(buf, file_size) == -1) { close(fd); perror("Error un-mmapping the file"); exit(EXIT_FAILURE); } // Un-mmaping doesn't close the file, so we still need to do that. close(fd); }