citra: 1 CWE-407 defect, MOADs 0002-0005 CLEAN
MOAD-0001: citra-0001 RasterizerCache page_table surfaces vector O(P*S^2) UnregisterSurface calls std::find(surfaces.begin(), surfaces.end(), surface_id) for each of P pages a surface spans. With S overlapping surfaces per page, total unregister cost is O(P*S) per surface, O(P*S^2) overall. Fix: change std::vector<SurfaceId> to std::unordered_set<SurfaceId> (std::hash<Common::SlotId> already defined). 3.4x measured at S=500, P=64. Hot path: InvalidateRegion called per CPU write to GPU texture memory. MOAD-0002: CLEAN. System singleton is intentional single-emulator architecture; subsystems injected via System& reference, no intertangle coupling found. MOAD-0003: CLEAN. thread_local only used for JNIEnv* JVM attachment in Android JNI (standard pattern, not request-scoped identity). MOAD-0004: CLEAN. No credential values logged verbatim; JWT token size only. MOAD-0005: CLEAN. GetPublicKey static cache is room-server single-threaded; JitEngine shader cache is GPU-thread single-threaded; all others use mutex. Source: azahar-emu/azahar (Citra continuation), depth=1.
This commit is contained in:
parent
7786adc4c0
commit
cdba4c80e9
7 changed files with 222 additions and 0 deletions
47
defects/citra-0001/patch/citra-0001.patch
Normal file
47
defects/citra-0001/patch/citra-0001.patch
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
--- a/src/video_core/rasterizer_cache/rasterizer_cache_base.h
|
||||
+++ b/src/video_core/rasterizer_cache/rasterizer_cache_base.h
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
+#include <unordered_set>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
@@ -215,7 +215,7 @@ private:
|
||||
std::unordered_map<TextureCubeConfig, TextureCube> texture_cube_cache;
|
||||
- tsl::robin_pg_map<u64, std::vector<SurfaceId>, Common::IdentityHash<u64>> page_table;
|
||||
+ tsl::robin_pg_map<u64, std::unordered_set<SurfaceId>, Common::IdentityHash<u64>> page_table;
|
||||
std::unordered_map<FramebufferParams, FramebufferId> framebuffers;
|
||||
|
||||
--- a/src/video_core/rasterizer_cache/rasterizer_cache.h
|
||||
+++ b/src/video_core/rasterizer_cache/rasterizer_cache.h
|
||||
@@ -820,7 +820,7 @@ void RasterizerCache<T>::ForEachSurfaceInRegion(PAddr addr, std::size_t size, F
|
||||
for (const SurfaceId surface_id : it->second) {
|
||||
|
||||
@@ -1365,8 +1365,8 @@ void RasterizerCache<T>::RegisterSurface(SurfaceId surface_id) {
|
||||
UpdatePagesCachedCount(surface.addr, surface.size, 1);
|
||||
ForEachPage(surface.addr, surface.size,
|
||||
- [this, surface_id](u64 page) { page_table[page].push_back(surface_id); });
|
||||
+ [this, surface_id](u64 page) { page_table[page].insert(surface_id); });
|
||||
}
|
||||
|
||||
@@ -1379,12 +1379,10 @@ void RasterizerCache<T>::UnregisterSurface(SurfaceId surface_id) {
|
||||
ForEachPage(surface.addr, surface.size, [this, surface_id](u64 page) {
|
||||
const auto page_it = page_table.find(page);
|
||||
if (page_it == page_table.end()) {
|
||||
ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << CITRA_PAGEBITS);
|
||||
return;
|
||||
}
|
||||
- std::vector<SurfaceId>& surfaces = page_it.value();
|
||||
- const auto vector_it = std::find(surfaces.begin(), surfaces.end(), surface_id);
|
||||
- if (vector_it == surfaces.end()) {
|
||||
+ std::unordered_set<SurfaceId>& surfaces = page_it.value();
|
||||
+ if (surfaces.find(surface_id) == surfaces.end()) {
|
||||
ASSERT_MSG(false, "Unregistering unregistered surface in page=0x{:x}",
|
||||
page << CITRA_PAGEBITS);
|
||||
return;
|
||||
}
|
||||
- surfaces.erase(vector_it);
|
||||
+ surfaces.erase(surface_id);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue