|
|
|
@ -14,6 +14,10 @@
@@ -14,6 +14,10 @@
|
|
|
|
|
0 - success |
|
|
|
|
1 - usage error |
|
|
|
|
-1 - file error |
|
|
|
|
|
|
|
|
|
@TODO Rename block_bits to block_offset_bits. |
|
|
|
|
@TODO Fix format |
|
|
|
|
@TODO Fix casts of parse_int_arg in main to int rather than uint8_t. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/**** Headers ****/ |
|
|
|
@ -196,10 +200,11 @@ void bad_usage_error(void)
@@ -196,10 +200,11 @@ void bad_usage_error(void)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Parses a string into a size_t. |
|
|
|
|
Parses a string into a an positive integer; error if not possible. |
|
|
|
|
@param arg The string to parse. |
|
|
|
|
@param opt The option being parsed. If 'E', the output can not be 0. |
|
|
|
|
@return The parsed long integer if the argument was an integer. |
|
|
|
|
Otherwise, used only for helpful error messages. |
|
|
|
|
@return The parsed long integer if the argument was valid . |
|
|
|
|
@note Exits if argument is invalid. |
|
|
|
|
*/ |
|
|
|
|
long parse_int_arg(char* arg, char opt) |
|
|
|
@ -221,21 +226,29 @@ long parse_int_arg(char* arg, char opt)
@@ -221,21 +226,29 @@ long parse_int_arg(char* arg, char opt)
|
|
|
|
|
/**
|
|
|
|
|
Calculates a size using a given number of bits. |
|
|
|
|
@param bits The power of 2 to use. |
|
|
|
|
@note Exits if number of bits is larger than a size_t. |
|
|
|
|
@return 2^bits if it does not overflow. |
|
|
|
|
@note Exits if number of bits is larger than a signed int. |
|
|
|
|
@TODO Fix format string to ints. |
|
|
|
|
*/ |
|
|
|
|
long bits_to_size(int bits) |
|
|
|
|
{ |
|
|
|
|
int max_shift = 8*sizeof(int); |
|
|
|
|
int max_shift = 8*sizeof(int)-1; |
|
|
|
|
if (bits > max_shift-1) { |
|
|
|
|
printf("Argument %hhd too large (-s and -b must be less than %hhd)", bits, max_shift); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
return (size_t)1 << bits; |
|
|
|
|
return (long)1 << bits; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************** SUB-MAIN FUNCTIONS *****************************/ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Increments the cgiven ache operation counters based on the given result code. |
|
|
|
|
@param result The cache operation result code to parse (H, M, or E). |
|
|
|
|
@param score The score struct to increment. |
|
|
|
|
@TODO Fix this into a total of 3 conditionals. |
|
|
|
|
*/ |
|
|
|
|
void increment_result_counters(char result, results* score) |
|
|
|
|
{ |
|
|
|
|
score->hits += (result == 'H'); |
|
|
|
@ -250,6 +263,12 @@ void increment_result_counters(char result, results* score)
@@ -250,6 +263,12 @@ void increment_result_counters(char result, results* score)
|
|
|
|
|
|
|
|
|
|
/********************* CACHE CREATION/DELETION FUNCTIONS *********************/ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@param num_sets The number of sets in the cache. |
|
|
|
|
@param num_lines The number of lines in each set. |
|
|
|
|
@return A pointer to the allocated cache's set list. |
|
|
|
|
@TODO Handle cases where not enough space can be allocated. |
|
|
|
|
*/ |
|
|
|
|
linked_line** make_cache(long num_sets, long num_lines) |
|
|
|
|
{ |
|
|
|
|
linked_line** cache = (linked_line**)calloc(num_sets, sizeof(linked_line*)); |
|
|
|
@ -279,6 +298,10 @@ linked_line* make_set(linked_line* newer, long num_lines) {
@@ -279,6 +298,10 @@ linked_line* make_set(linked_line* newer, long num_lines) {
|
|
|
|
|
return current; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@param cache A pointer to the cache to free. |
|
|
|
|
@param num_sets The number of sets in the cache. |
|
|
|
|
*/ |
|
|
|
|
void free_cache(linked_line** cache, long num_sets) |
|
|
|
|
{ |
|
|
|
|
int ii; |
|
|
|
@ -302,6 +325,10 @@ void free_set(linked_line* line) {
@@ -302,6 +325,10 @@ void free_set(linked_line* line) {
|
|
|
|
|
|
|
|
|
|
/************************** CACHE VIEWING FUNCTIONS **************************/ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@cache The cache to print. |
|
|
|
|
@cache num_sets The number of sets in the cache. |
|
|
|
|
*/ |
|
|
|
|
void print_cache(linked_line** cache, long num_sets) |
|
|
|
|
{ |
|
|
|
|
int ii; |
|
|
|
@ -310,6 +337,12 @@ void print_cache(linked_line** cache, long num_sets)
@@ -310,6 +337,12 @@ void print_cache(linked_line** cache, long num_sets)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Prints a cache line and all lines modified less recently than it in its set.<br /> |
|
|
|
|
The format is: <br /> |
|
|
|
|
address validity.tag address of newer:address of older |
|
|
|
|
@param line The set/line to print, or NULL. If null, does nothing. |
|
|
|
|
*/ |
|
|
|
|
void print_set(linked_line* line) |
|
|
|
|
{ |
|
|
|
|
if (line != NULL) { |
|
|
|
@ -323,6 +356,19 @@ void print_set(linked_line* line)
@@ -323,6 +356,19 @@ void print_set(linked_line* line)
|
|
|
|
|
|
|
|
|
|
/*************************** CACHE ACCESS FUNCTIONS ***************************/ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Simulates a cache access operation. |
|
|
|
|
@param cache The cache to access. |
|
|
|
|
@param address The address to access in the cache. |
|
|
|
|
@param set_bits The number of set bits in the address. |
|
|
|
|
@param block_bits The number of block offset bits in the address. |
|
|
|
|
@param num_lines The number of lines per set. |
|
|
|
|
@return 'H' if a hit, 'M' if a miss, 'E' if a miss and eviction |
|
|
|
|
|
|
|
|
|
@TODO Pass set and tag into cache_access instead of an address and sizes. |
|
|
|
|
@TODO Make the tag and set retrieval a function? |
|
|
|
|
@TODO Make the re-linking of the set into its own function. |
|
|
|
|
*/ |
|
|
|
|
char cache_access(linked_line** cache, long address, |
|
|
|
|
int set_bits, int block_bits, long num_lines) |
|
|
|
|
{ |
|
|
|
@ -353,8 +399,13 @@ char cache_access(linked_line** cache, long address,
@@ -353,8 +399,13 @@ char cache_access(linked_line** cache, long address,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@returns the first line with a matching tag, the first invalid line, |
|
|
|
|
or the first line without an older (i.e. the end of the set |
|
|
|
|
Finds a line in the given set that holds the given tag, or the least-recently |
|
|
|
|
used line if the tag is not in the set, or the next invalid line if not all |
|
|
|
|
of the lines have been used. |
|
|
|
|
@param line Initially, the most-recently-used line in the set. In the |
|
|
|
|
recursion, iterates through the lines in the set. |
|
|
|
|
@returns The first line with a matching tag, the first invalid line, |
|
|
|
|
or the first line without an older (i.e. the end of the set). |
|
|
|
|
*/ |
|
|
|
|
linked_line* find_line(linked_line* line, long tag) |
|
|
|
|
{ |
|
|
|
|