diff --git a/Utilities/sync.h b/Utilities/sync.h index 6e4d87ea38..df2481108e 100644 --- a/Utilities/sync.h +++ b/Utilities/sync.h @@ -99,13 +99,13 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t if (!timeout) { - rec.cv.wait(lock, [&] { return !rec.mask; }); + rec.cv.wait(lock, FN(!rec.mask)); } else if (futex_op == FUTEX_WAIT) { const auto nsec = std::chrono::nanoseconds(timeout->tv_nsec + timeout->tv_sec * 1000000000ull); - if (!rec.cv.wait_for(lock, nsec, [&] { return !rec.mask; })) + if (!rec.cv.wait_for(lock, nsec, FN(!rec.mask))) { res = -1; errno = ETIMEDOUT; diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 0dc71757c4..89ceef0e26 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -791,12 +791,7 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) } } - std::sort(m_flat_list.begin(), m_flat_list.end(), [&](const auto& a, const auto& b) - { - std::basic_string_view lhs = a.first; - std::basic_string_view rhs = b.first; - return lhs < rhs; - }); + std::sort(m_flat_list.begin(), m_flat_list.end(), FN(x.first < y.first)); struct work { diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 1faf39f648..cdc83ac82f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -1150,18 +1150,10 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr path, vm::ptr fd) } // Sort files, keeping . and .. - std::stable_sort(data.begin() + 2, data.end(), [](const fs::dir_entry& a, const fs::dir_entry& b) - { - return a.name < b.name; - }); + std::stable_sort(data.begin() + 2, data.end(), FN(x.name < y.name)); // Remove duplicates - const auto last = std::unique(data.begin(), data.end(), [](const fs::dir_entry& a, const fs::dir_entry& b) - { - return a.name == b.name; - }); - - data.erase(last, data.end()); + data.erase(std::unique(data.begin(), data.end(), FN(x.name == y.name)), data.end()); if (const u32 id = idm::make(processed_path, std::move(data))) { diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index c912b20595..4f83c623df 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -183,7 +183,7 @@ namespace rsx scale_y = scale.height; scale_z = scale.depth; image_type = type; - samples = msaa_samples; + samples = msaa_samples; } sampled_image_descriptor(image_resource_type external_handle, deferred_request_command reason, @@ -495,10 +495,7 @@ namespace rsx { // Sort with oldest data first // Ensures that new data tramples older data - std::sort(data.sections_to_flush.begin(), data.sections_to_flush.end(), [](const auto& a, const auto& b) - { - return (a->last_write_tag < b->last_write_tag); - }); + std::sort(data.sections_to_flush.begin(), data.sections_to_flush.end(), FN(x->last_write_tag < y->last_write_tag)); } rsx::simple_array sections_to_transfer; diff --git a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h index 8b5f7a8625..a951375813 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h @@ -265,10 +265,7 @@ namespace rsx sort_list.push_back({ local[index]->last_write_tag, 1, index }); } - std::sort(sort_list.begin(), sort_list.end(), [](const auto& a, const auto& b) - { - return (a.tag < b.tag); - }); + std::sort(sort_list.begin(), sort_list.end(), FN(x.tag < y.tag)); } auto add_rtt_resource = [&](auto& section, u16 slice) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index e8a2856a29..fa240b5fd3 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -269,10 +269,7 @@ namespace vk process_list_function(m_render_targets_storage, m_render_targets_memory_range); process_list_function(m_depth_stencil_storage, m_depth_stencil_memory_range); - std::sort(sorted_list.begin(), sorted_list.end(), [](const auto& a, const auto& b) - { - return a->last_rw_access_tag < b->last_rw_access_tag; - }); + std::sort(sorted_list.begin(), sorted_list.end(), FN(x->last_rw_access_tag < y->last_rw_access_tag)); // Remove upto target_memory bytes from VRAM u64 bytes_spilled = 0; diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 4e5570f243..4a351f9a5d 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -951,10 +951,7 @@ namespace vk // Sort upload heap entries based on size. if (host_coherent_types.size() > 1) { - std::sort(host_coherent_types.begin(), host_coherent_types.end(), [](const auto& a, const auto& b) - { - return a.size > b.size; - }); + std::sort(host_coherent_types.begin(), host_coherent_types.end(), FN(x.size > y.size)); } for (auto& type : host_coherent_types) diff --git a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp index f0b0896dea..b3455cd87d 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp @@ -135,10 +135,7 @@ namespace vk } ensure(free_memory_map.size() == num_types); - std::sort(free_memory_map.begin(), free_memory_map.end(), [](const auto& a, const auto& b) - { - return a.second > b.second; - }); + std::sort(free_memory_map.begin(), free_memory_map.end(), FN(x.second > y.second)); std::vector new_type_ids(num_types); std::vector new_type_sizes(num_types); diff --git a/rpcs3/Emu/cache_utils.cpp b/rpcs3/Emu/cache_utils.cpp index 25dc292a89..e352d48143 100644 --- a/rpcs3/Emu/cache_utils.cpp +++ b/rpcs3/Emu/cache_utils.cpp @@ -13,13 +13,13 @@ namespace rpcs3::cache std::string get_ppu_cache() { auto& _main = g_fxo->get(); - + if (!g_fxo->is_init() || _main.cache.empty()) { ppu_log.error("PPU Cache location not initialized."); return {}; } - + return _main.cache; } @@ -75,10 +75,7 @@ namespace rpcs3::cache cache_dir.close(); // sort oldest first - std::sort(file_list.begin(), file_list.end(), [](auto left, auto right) - { - return left.mtime < right.mtime; - }); + std::sort(file_list.begin(), file_list.end(), FN(x.mtime < y.mtime)); // keep removing until cache is empty or enough bytes have been cleared // cache is cleared down to 80% of limit to increase interval between clears diff --git a/rpcs3/util/atomic.cpp b/rpcs3/util/atomic.cpp index 778bf441b7..3278b33015 100644 --- a/rpcs3/util/atomic.cpp +++ b/rpcs3/util/atomic.cpp @@ -571,11 +571,8 @@ static u32 cond_alloc(uptr iptr, u128 mask, u32 tls_slot = -1) return pos / 7; }); - const u64 bits = s_cond_bits[level3].fetch_op([](u64& bits) - { - // Set lowest clear bit - bits |= bits + 1; - }); + // Set lowest clear bit + const u64 bits = s_cond_bits[level3].fetch_op(FN(x |= x + 1, void())); // Find lowest clear bit (before it was set in fetch_op) const u32 id = level3 * 64 + std::countr_one(bits); @@ -647,20 +644,9 @@ static void cond_free(u32 cond_id, u32 tls_slot = -1) // Release the semaphore tree in the reverse order s_cond_bits[cond_id / 64] &= ~(1ull << (cond_id % 64)); - s_cond_sem3[level2].atomic_op([&](u128& val) - { - val -= u128{1} << (level3 * 7); - }); - - s_cond_sem2[level1].atomic_op([&](u128& val) - { - val -= u128{1} << (level2 * 11); - }); - - s_cond_sem1.atomic_op([&](u128& val) - { - val -= u128{1} << (level1 * 14); - }); + s_cond_sem3[level2].atomic_op(FN(x -= u128{1} << (level3 * 7))); + s_cond_sem2[level1].atomic_op(FN(x -= u128{1} << (level2 * 11))); + s_cond_sem1.atomic_op(FN(x -= u128{1} << (level1 * 14))); } static cond_handle* cond_id_lock(u32 cond_id, u128 mask, uptr iptr = 0) diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index 1f3fbf5d0e..7ce7e36446 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -55,6 +55,48 @@ using namespace std::literals; #define AUDIT(...) (static_cast(0)) #endif +namespace utils +{ + template + struct fn_helper + { + F f; + + fn_helper(F&& f) + : f(std::forward(f)) + { + } + + template + auto operator()(Args&&... args) const + { + if constexpr (sizeof...(Args) == 0) + return f(0, 0, 0, 0); + else if constexpr (sizeof...(Args) == 1) + return f(std::forward(args)..., 0, 0, 0); + else if constexpr (sizeof...(Args) == 2) + return f(std::forward(args)..., 0, 0); + else if constexpr (sizeof...(Args) == 3) + return f(std::forward(args)..., 0); + else if constexpr (sizeof...(Args) == 4) + return f(std::forward(args)...); + else + static_assert(sizeof...(Args) <= 4); + } + }; + + template + fn_helper(F&& f) -> fn_helper; +} + +// Shorter lambda. +#define FN(...) \ + ::utils::fn_helper([&]( \ + [[maybe_unused]] auto&& x, \ + [[maybe_unused]] auto&& y, \ + [[maybe_unused]] auto&& z, \ + [[maybe_unused]] auto&& w){ return (__VA_ARGS__); }) + #if __cpp_lib_bit_cast < 201806L namespace std { @@ -885,6 +927,21 @@ constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(), fmt::raw_verify_error({line, col, file, func}, msg); } +template requires (std::is_invocable_v) +constexpr decltype(auto) ensure(T&& arg, F&& pred, const_str msg = const_str(), + u32 line = __builtin_LINE(), + u32 col = __builtin_COLUMN(), + const char* file = __builtin_FILE(), + const char* func = __builtin_FUNCTION()) noexcept +{ + if (std::forward(pred)(std::forward(arg))) [[likely]] + { + return std::forward(arg); + } + + fmt::raw_verify_error({line, col, file, func}, msg); +} + // narrow() function details template struct narrow_impl diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index 55677b59c6..ca06af72b0 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -198,9 +198,7 @@ namespace utils #endif }(); - ensure(r > 0 && r <= 0x10000); - - return r; + return ensure(r, FN(((x & (x - 1)) == 0 && x > 0 && x <= 0x10000))); } // Convert memory protection (internal) @@ -607,8 +605,7 @@ namespace utils if (const char c = fs::file("/proc/sys/vm/overcommit_memory").read(); c == '0' || c == '1') { // Simply use memfd for overcommit memory - m_file = ::memfd_create_("", 0); - ensure(m_file >= 0); + m_file = ensure(::memfd_create_("", 0), FN(x >= 0)); ensure(::ftruncate(m_file, m_size) >= 0); return; } @@ -634,8 +631,7 @@ namespace utils if ((vm_overcommit & 3) == 0) { #if defined(__FreeBSD__) - m_file = ::memfd_create_("", 0); - ensure(m_file >= 0); + m_file = ensure(::memfd_create_("", 0), FN(x >= 0)); #else const std::string name = "/rpcs3-mem2-" + std::to_string(reinterpret_cast(this)); @@ -827,7 +823,7 @@ namespace utils { // TODO: Implement it } - + if (MapViewOfFile3(m_handle, GetCurrentProcess(), target, 0, m_size, MEM_REPLACE_PLACEHOLDER, PAGE_EXECUTE_READWRITE, nullptr, 0)) { if (prot != protection::rw && prot != protection::wx)