summaryrefslogtreecommitdiff
path: root/src/storage/cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/storage/cache.cc')
-rw-r--r--src/storage/cache.cc94
1 files changed, 36 insertions, 58 deletions
diff --git a/src/storage/cache.cc b/src/storage/cache.cc
index f15c919..8acdf08 100644
--- a/src/storage/cache.cc
+++ b/src/storage/cache.cc
@@ -27,51 +27,20 @@ Cache::~Cache()
Response Cache::write_word(Accessor accessor, signed int data, int address)
{
- Response r = WAIT;
-
- /* Do this first--then process the first cycle immediately. */
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- this->data->at(index).at(offset) = data;
- this->meta[index].at(1) = 1;
- r = OK;
- }
- }
-
- return r;
+ return process(accessor, address, [&](int index, int offset) {
+ this->data->at(index).at(offset) = data;
+ this->meta[index].at(1) = 1;
+ });
}
Response Cache::write_line(
Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address)
{
- Response r = WAIT;
-
- /* Do this first--then process the first cycle immediately. */
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- this->data->at(index) = data_line;
- this->meta[index].at(1) = 1;
- r = OK;
- }
- }
-
- return r;
+ return process(accessor, address, [&](int index, int offset) {
+ (void)offset;
+ this->data->at(index) = data_line;
+ this->meta[index].at(1) = 1;
+ });
}
// TODO: tests for multi level cache
@@ -80,26 +49,38 @@ Response Cache::read_line(
int address,
std::array<signed int, LINE_SIZE> &data_line)
{
- Response r = WAIT;
- if (this->requester == IDLE)
- this->requester = accessor;
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- data_line = this->data->at(index);
- r = OK;
- }
+ return process(accessor, address, [&](int index, int offset) {
+ (void)offset;
+ data_line = this->data->at(index);
+ });
+}
+
+Response Cache::read_word(Accessor accessor, int address, signed int &data)
+{
+ return process(accessor, address, [&](int index, int offset) {
+ data = this->data->at(index).at(offset);
+ });
+}
+
+Response Cache::process(
+ Accessor accessor,
+ int address,
+ std::function<void(int index, int offset)> request_handler)
+{
+ Response r = this->is_access_cleared(accessor, address);
+ if (r == OK) {
+ int tag, index, offset;
+ get_bit_fields(address, &tag, &index, &offset);
+ request_handler(index, offset);
}
return r;
}
-Response Cache::read_word(Accessor accessor, int address, signed int &data)
+Response Cache::is_access_cleared(Accessor accessor, int address)
{
- Response r = WAIT;
+ Response r;
+ r = WAIT;
+ /* Do this first--then process the first cycle immediately. */
if (this->requester == IDLE)
this->requester = accessor;
if (this->requester == accessor) {
@@ -107,9 +88,6 @@ Response Cache::read_word(Accessor accessor, int address, signed int &data)
if (this->is_waiting)
r = BLOCKED;
else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- data = this->data->at(index).at(offset);
r = OK;
}
}