This repository has been archived by the owner on Feb 25, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlru_stack.cpp
199 lines (175 loc) · 4.2 KB
/
lru_stack.cpp
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <cstring>
#include <iostream>
#include "lru_stack.h"
using namespace std;
#define LRU_DEBUG 0
/* LRU stack default constructor
*
* Constructs a 1-way LRU stack
*/
LRU_stack::LRU_stack()
{
ways = 1;
// Create the single node
head = new llnode;
head->way_number = 0;
head->prev = NULL;
head->next = NULL;
tail = head;
}
/* LRU stack constructor
*
* Constructs an LRU stack that is as deep as the number of ways in the
* set. The LRU stack is a doubly-linked list.
*/
LRU_stack::LRU_stack(unsigned int assoc)
{
llnode * lead_p;
llnode * lag_p;
ways = assoc;
head = new llnode; // Create the head node
head->way_number = 0;
head->prev = NULL;
lead_p = head;
lag_p = head;
// Create as many nodes as there are ways
for(unsigned int i = 1; i < ways; ++i)
{
lead_p->next = new llnode;
lead_p = lead_p->next;
lead_p->prev = lag_p;
lead_p->way_number = i;
lag_p = lead_p;
}
// Terminate the linked list
lead_p->next = NULL;
tail = lead_p;
}
/* LRU stack destructor
*
* Iterates through the doubly-linked list and frees all memory
*/
LRU_stack::~LRU_stack()
{
llnode * node_p = head;
// Free all memory
for(unsigned int i = 0; i < ways; ++i)
{
head = head->next;
delete node_p;
node_p = head;
}
// Make sure the LRU stack is not used again
head = NULL;
tail = NULL;
ways = 0;
}
/* LRU stack update_stack_on_hit
*
* Performs a linear search for the newly referenced block (in terms of
* the way number). Since it was a hit, we simply need to update the
* stack.
*/
void LRU_stack::update_stack_on_hit(unsigned long long ref_way_num)
{
#if LRU_DEBUG
cout << "Updating stack on hit at " << ref_way_num << endl;
#endif
llnode * node_p = head;
if(ref_way_num >= ways)
{
#if LRU_DEBUG
cout << "ref_way_num >= ways" << endl;
#endif
return;
}
if(head->way_number == ref_way_num)
{
#if LRU_DEBUG
cout << "head->way_number == ref_way_num" << endl;
#endif
return;
}
while(node_p != tail)
{
node_p = node_p->next;
if(node_p->way_number == ref_way_num)
{
#if LRU_DEBUG
cout << "Found ref_way_num == " << ref_way_num << endl;
#endif
node_p->prev->next = node_p->next;
if(node_p == tail)
{
#if LRU_DEBUG
cout << "ref_way_num was at the tail" << endl;
#endif
tail = node_p->prev;
}
else
{
#if LRU_DEBUG
cout << "ref_way_num was NOT at the tail" << endl;
#endif
node_p->next->prev = node_p->prev;
}
node_p->next = head;
node_p->prev = NULL;
head->prev = node_p;
head = node_p;
#if LRU_DEBUG
cout << "Finished updating LRU stack. Exiting..." << endl;
#endif
return;
}
}
#if LRU_DEBUG
cout << "Impossible! ref_way_num not in LRU stack" << endl;
#endif
return;
}
/* LRU stack update_stack_on_miss
*
* Moves the least recently used node from the tail of the linked list
* to the head of the list. Since it was a miss, we need to both update
* the stack and return the way number of the least recently used block.
*/
unsigned long long LRU_stack::update_stack_on_miss()
{
llnode * node_p = tail;
#if LRU_DEBUG
cout << "Updating LRU stack on miss" << endl;
#endif
if(head == tail)
{
#if LRU_DEBUG
cout << "Inserting into way " << head->way_number << endl;
#endif
return head->way_number;
}
node_p->prev->next = NULL;
tail = node_p->prev;
head->prev = node_p;
node_p->next = head;
node_p->prev = NULL;
head = node_p;
#if LRU_DEBUG
cout << "Inserting into way " << head->way_number << endl;
#endif
return head->way_number;
}
/* LRU stack print_stack
*
* Iterates through the stack from the most recently used to the least
* recently used, and prints the way numbers
*/
void LRU_stack::print_stack()
{
llnode * node_p = head;
for(unsigned int i = 0; i < ways; ++i)
{
cout << node_p->way_number << endl;
node_p = node_p->next;
}
return;
}