Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.

Commit

Permalink
Revert "Artic Base: Fix out of bounds cache reads (#127)"
Browse files Browse the repository at this point in the history
This reverts commit 05cccb5.
  • Loading branch information
PabloMK7 authored May 15, 2024
1 parent 05cccb5 commit b612c0c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 56 deletions.
8 changes: 0 additions & 8 deletions src/common/static_lru_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,8 @@ class StaticLRUCache {
}
}

void invalidate(const key_type& key) {
auto i = find(key);
if (i != m_list.cend()) {
m_list.erase(i);
}
}

void clear() {
m_list.clear();
m_array.fill(value_type{});
}

private:
Expand Down
59 changes: 11 additions & 48 deletions src/core/file_sys/artic_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,13 @@ ResultVal<std::size_t> ArticCache::Read(s32 file_handle, std::size_t offset, std
auto res =
ReadFromArtic(file_handle, reinterpret_cast<u8*>(big_cache_entry.second.data()),
length, offset);
if (res.Failed()) {
big_cache.invalidate(std::make_pair(offset, length));
if (res.Failed())
return res;
}
read_progress = res.Unwrap();
length = res.Unwrap();
} else {
LOG_TRACE(Service_FS, "ArticCache BHIT: offset={}, length={}", offset,
read_progress);
}
memcpy(buffer, big_cache_entry.second.data(), read_progress);
if (read_progress < length) {
// Invalidate the entry as it is not fully read
big_cache.invalidate(std::make_pair(offset, length));
LOG_TRACE(Service_FS, "ArticCache BHIT: offset={}, length={}", offset, length);
}
memcpy(buffer, big_cache_entry.second.data(), length);
} else {
if (segments[0].second < very_big_cache_skip) {
std::unique_lock very_big_read_guard(very_big_cache_mutex);
Expand All @@ -51,68 +44,38 @@ ResultVal<std::size_t> ArticCache::Read(s32 file_handle, std::size_t offset, std
auto res = ReadFromArtic(
file_handle, reinterpret_cast<u8*>(very_big_cache_entry.second.data()),
length, offset);
if (res.Failed()) {
very_big_cache.invalidate(std::make_pair(offset, length));
if (res.Failed())
return res;
}
read_progress = res.Unwrap();
length = res.Unwrap();
} else {
LOG_TRACE(Service_FS, "ArticCache VBHIT: offset={}, length={}", offset,
read_progress);
}
memcpy(buffer, very_big_cache_entry.second.data(), read_progress);
if (read_progress < length) {
// Invalidate the entry as it is not fully read
very_big_cache.invalidate(std::make_pair(offset, length));
LOG_TRACE(Service_FS, "ArticCache VBHIT: offset={}, length={}", offset, length);
}
memcpy(buffer, very_big_cache_entry.second.data(), length);
} else {
LOG_TRACE(Service_FS, "ArticCache SKIP: offset={}, length={}", offset, length);

auto res = ReadFromArtic(file_handle, buffer, length, offset);
if (res.Failed())
return res;
read_progress = res.Unwrap();
length = res.Unwrap();
}
}
return read_progress;
return length;
}

// TODO(PabloMK7): Make cache thread safe, read the comment in CacheReady function.
std::unique_lock read_guard(cache_mutex);
bool read_past_end = false;
for (const auto& seg : segments) {
if (read_past_end) {
break;
}
std::size_t read_size = cache_line_size;
std::size_t page = OffsetToPage(seg.first);
// Check if segment is in cache
auto cache_entry = cache.request(page);
if (!cache_entry.first) {
// If not found, read from artic and cache the data
auto res = ReadFromArtic(file_handle, cache_entry.second.data(), read_size, page);
if (res.Failed()) {
// Invalidate the requested entry as it is not populated
cache.invalidate(page);

// In the very unlikely case the file size is a multiple of the cache size,
// and the game request more data than the file size, this will save us from
// returning an incorrect out of bounds error caused by reading at just the very end
// of the file.
constexpr u32 out_of_bounds_read = 714;
if (res.Code().description == out_of_bounds_read) {
return read_progress;
}
if (res.Failed())
return res;
}
size_t expected_read_size = read_size;
read_size = res.Unwrap();
//
if (read_size < expected_read_size) {
// Invalidate the requested entry as it is not fully read
cache.invalidate(page);
read_past_end = true;
}
LOG_TRACE(Service_FS, "ArticCache MISS: page={}, length={}, into={}", page, seg.second,
(seg.first - page));
} else {
Expand Down

0 comments on commit b612c0c

Please sign in to comment.