-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.c
More file actions
133 lines (115 loc) · 3.38 KB
/
cache.c
File metadata and controls
133 lines (115 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "cache.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "bits.h"
#include "cpu.h"
#include "lru.h"
char *make_block(int block_size) {
// TODO:
// Make and initialize a block's accessed bits given the block_size.
//
// HINT: if it wasn't clear already, this gets put in the "accessed" field
char* block = (char*) malloc(sizeof(char)*(block_size));
for(int i = 0; i< (block_size); i++){
block[i] = '0';
}
return block;
}
Line *make_lines(int line_count, int block_size) {
// TODO:
// Make and initialize the lines given the line count. Then
// make and initialize the blocks.
//
// HINT: this will be placed in the "accessed" field of a Line
Line *lines = (Line*) malloc(sizeof(Line)*line_count);
int i;
for(i = 0; i< line_count; i++){
Line line;
line.valid = '0';
line.tag = 0;
line.accessed = make_block(block_size);
line.block_size = block_size;
lines[i] = line;
}
return lines;
}
Set *make_sets(int set_count, int line_count, int block_size) {
// TODO:
// Make and initialize the sets given the set count. Then
// make and initialize the line and blocks.
//
Set *sets = (Set*) malloc(sizeof(Set)*set_count);
int i;
for(i = 0; i< set_count; i++){
Set set;
set.lines = make_lines(line_count, block_size);
set.line_count = line_count;
set.lru_queue = NULL;
sets[i] = set;
}
return sets;
}
Cache *make_cache(int set_bits, int line_count, int block_bits) {
Cache *cache = (Cache*) malloc(sizeof(Cache));
// TODO:
// Make and initialize the cache, sets, lines, and blocks.
// You should use the `exp2` function to determine the
// set_count and block_count from the set_bits and block_bits
// respectively (use `man exp2` from the command line).
//
// ADD YOUR CODE HERE:
int set_count = (int)(exp2(set_bits));
int block_count = (int)(exp2(block_bits));
cache -> set_count = set_count;
cache -> sets = make_sets(set_count, line_count, block_count);
cache -> line_count = line_count;
cache -> block_size = block_count;
cache -> set_bits = set_bits;
cache -> block_bits = block_bits;
// END TODO
// Create LRU queues for sets:
if (cache != NULL) {
lru_init(cache);
}
return cache;
}
void delete_block(char *accessed) { free(accessed); }
void delete_lines(Line *lines, int line_count) {
for (int i = 0; i < line_count; i++) {
delete_block(lines[i].accessed);
}
free(lines);
}
void delete_sets(Set *sets, int set_count) {
for (int i = 0; i < set_count; i++) {
delete_lines(sets[i].lines, sets[i].line_count);
}
free(sets);
}
void delete_cache(Cache *cache) {
lru_destroy(cache);
delete_sets(cache->sets, cache->set_count);
free(cache);
}
AccessResult cache_access(Cache *cache, TraceLine *trace_line) {
unsigned int s = get_set(cache, trace_line->address);
unsigned int t = get_line(cache, trace_line->address);
unsigned int b = get_byte(cache, trace_line->address);
// Get the set:
Set *set = &cache->sets[s];
// Get the line:
LRUResult result;
lru_fetch(set, t, &result);
Line *line = result.line;
// printf("the line contents : %s\n", line -> accessed);
// If it was a miss we will clear the accessed bits:
if (result.access != HIT) {
for (int i = 0; i < cache->block_size; i++) {
line->accessed[i] = 0;
}
}
// Then set the accessed byte to 1:
line->accessed[b] = 1;
return result.access;
}