Skip to content

Commit 2b19597

Browse files
committed
big picture mode: Create tiles multithreaded
1 parent f39c4c3 commit 2b19597

6 files changed

Lines changed: 101 additions & 70 deletions

File tree

Utilities/Thread.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4033,3 +4033,81 @@ bool thread_ctrl::is_main()
40334033
{
40344034
return get_tid() == utils::main_tid;
40354035
}
4036+
4037+
usz map_workload(std::string_view thread_name, usz thread_count, usz count, std::function<void(usz)>&& func)
4038+
{
4039+
ensure(!!func);
4040+
4041+
if (thread_count <= 1)
4042+
{
4043+
for (usz i = 0; i < count; i++)
4044+
{
4045+
func(i);
4046+
}
4047+
return 1;
4048+
}
4049+
4050+
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
4051+
4052+
atomic_t<usz> indexer = 0;
4053+
const auto iterate = [count, &func, &indexer]()
4054+
{
4055+
while (thread_ctrl::state() != thread_state::aborting)
4056+
{
4057+
// Make sure indexer does not exceed count
4058+
const usz index = indexer.fetch_op([count](usz& v)
4059+
{
4060+
if (v < count)
4061+
{
4062+
v++;
4063+
return true;
4064+
}
4065+
4066+
return false;
4067+
}).first;
4068+
4069+
if (index >= count)
4070+
{
4071+
break;
4072+
}
4073+
4074+
func(index);
4075+
}
4076+
};
4077+
named_thread_group workers(thread_name, ::narrow<u32>(thread_count) - 1, [&iterate, &num_threads_succeeded]()
4078+
{
4079+
iterate();
4080+
num_threads_succeeded++;
4081+
});
4082+
4083+
iterate();
4084+
4085+
workers.join();
4086+
4087+
return num_threads_succeeded + 1;
4088+
}
4089+
4090+
usz map_workload(std::string_view thread_name, usz thread_count, std::function<void()>&& func)
4091+
{
4092+
ensure(!!func);
4093+
4094+
if (thread_count <= 1)
4095+
{
4096+
func();
4097+
return 1;
4098+
}
4099+
4100+
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
4101+
4102+
named_thread_group workers(thread_name, ::narrow<u32>(thread_count) - 1, [&func, &num_threads_succeeded]()
4103+
{
4104+
func();
4105+
num_threads_succeeded++;
4106+
});
4107+
4108+
func();
4109+
4110+
workers.join();
4111+
4112+
return num_threads_succeeded + 1;
4113+
}

Utilities/Thread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,6 @@ class named_thread_group final
905905
::operator delete(static_cast<void*>(m_threads), std::align_val_t{alignof(Thread)});
906906
}
907907
};
908+
909+
usz map_workload(std::string_view thread_name, usz thread_count, usz count, std::function<void(usz)>&& func);
910+
usz map_workload(std::string_view thread_name, usz thread_count, std::function<void()>&& func);

rpcs3/Crypto/unpkg.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,26 +1363,10 @@ package_install_result package_reader::extract_data(std::deque<package_reader>&
13631363
if (reader.m_num_failures == 0)
13641364
{
13651365
const usz thread_count = std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size());
1366-
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
1367-
1368-
if (thread_count > 1)
1369-
{
1370-
named_thread_group workers("PKG Installer "sv, ::narrow<u32>(thread_count) - 1, [&]()
1371-
{
1372-
reader.extract_worker();
1373-
num_threads_succeeded++;
1374-
});
1375-
1376-
reader.extract_worker();
1377-
num_threads_succeeded++;
1378-
1379-
workers.join();
1380-
}
1381-
else
1366+
const u32 num_threads_succeeded = map_workload("PKG Installer "sv, thread_count, [&reader]()
13821367
{
13831368
reader.extract_worker();
1384-
num_threads_succeeded++;
1385-
}
1369+
});
13861370

13871371
if (thread_count != num_threads_succeeded)
13881372
{

rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -120,50 +120,11 @@ namespace rsx
120120

121121
// Parse entries (multithreaded)
122122
const std::vector<game_enumeration<big_picture_game_entry>::path_entry>& entries = m_game_enumeration.path_entries();
123-
const usz thread_count = std::min<usz>(utils::get_thread_count(), entries.size());
124-
if (thread_count > 1)
123+
usz thread_count = std::min<usz>(utils::get_thread_count(), entries.size());
124+
map_workload("BPM Parser "sv, thread_count, entries.size(), [this, &entries](usz index)
125125
{
126-
atomic_t<usz> entry_indexer = 0;
127-
const auto parse_entries = [this, &entry_indexer, &entries]()
128-
{
129-
while (thread_ctrl::state() != thread_state::aborting)
130-
{
131-
// Make sure entry_indexer does not exceed m_install_entries
132-
const usz index = entry_indexer.fetch_op([&entries](usz& v)
133-
{
134-
if (v < entries.size())
135-
{
136-
v++;
137-
return true;
138-
}
139-
140-
return false;
141-
}).first;
142-
143-
if (index >= entries.size())
144-
{
145-
break;
146-
}
147-
148-
m_game_enumeration.parse_entry(entries[index]);
149-
}
150-
};
151-
named_thread_group workers("BPM Parser "sv, ::narrow<u32>(thread_count) - 1, [&parse_entries]()
152-
{
153-
parse_entries();
154-
});
155-
156-
parse_entries();
157-
158-
workers.join();
159-
}
160-
else
161-
{
162-
for (const game_enumeration<big_picture_game_entry>::path_entry& entry : entries)
163-
{
164-
m_game_enumeration.parse_entry(entry);
165-
}
166-
}
126+
m_game_enumeration.parse_entry(entries[index]);
127+
});
167128

168129
// Try to update the app version for disc games if there is a patch
169130
// Also try to find updated game icons and movies
@@ -186,11 +147,19 @@ namespace rsx
186147
return a.name < b.name;
187148
});
188149

189-
finish_reload();
150+
// Create tiles (multithreaded)
151+
std::vector<std::unique_ptr<big_picture_game_tile>> tiles(m_games.size());
152+
thread_count = std::min<usz>(utils::get_thread_count(), tiles.size());
153+
map_workload("BPM Tiles "sv, thread_count, tiles.size(), [this, &tiles](usz index)
154+
{
155+
tiles[index] = std::make_unique<big_picture_game_tile>(m_games[index], m_tile_size);
156+
});
157+
158+
finish_reload(std::move(tiles));
190159
});
191160
}
192161

193-
void big_picture_game_grid::finish_reload()
162+
void big_picture_game_grid::finish_reload(std::vector<std::unique_ptr<big_picture_game_tile>>&& tiles)
194163
{
195164
std::lock_guard lock(m_reload_mutex);
196165

@@ -206,7 +175,7 @@ namespace rsx
206175

207176
std::unique_ptr<horizontal_layout> row;
208177

209-
for (usz i = 0; i < m_games.size(); i++)
178+
for (usz i = 0; i < tiles.size(); i++)
210179
{
211180
if (i % m_columns == 0)
212181
{
@@ -219,8 +188,7 @@ namespace rsx
219188
row->pack_padding = 20;
220189
}
221190

222-
auto tile = std::make_unique<big_picture_game_tile>(m_games[i], m_tile_size);
223-
m_tiles.push_back(row->add_element(tile));
191+
m_tiles.push_back(row->add_element(tiles[i]));
224192
}
225193

226194
if (row)

rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace rsx
4747

4848
private:
4949
void start_reload();
50-
void finish_reload();
50+
void finish_reload(std::vector<std::unique_ptr<big_picture_game_tile>>&& tiles);
5151
void select_tile(s32 index);
5252

5353
static constexpr u16 m_columns = 5;

rpcs3/rpcs3qt/memory_string_searcher.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ u64 memory_viewer_panel::OnSearch(std::string wstr, u32 mode)
185185

186186
vm::writer_lock rlock;
187187

188-
const named_thread_group workers("Memory Searcher "sv, max_threads, [&]()
188+
map_workload("Memory Searcher "sv, max_threads, [&]()
189189
{
190190
if (mode == as_inst || mode == as_fake_spu_inst || mode == as_regex_inst || mode == as_regex_fake_spu_inst)
191191
{
@@ -448,7 +448,5 @@ u64 memory_viewer_panel::OnSearch(std::string wstr, u32 mode)
448448
found += local_found;
449449
});
450450

451-
workers.join();
452-
453451
return found;
454452
}

0 commit comments

Comments
 (0)