Implement FN (lambda shortener)

Useful for some higher order functions.
Allows to make short lambdas even shorter.
This commit is contained in:
Nekotekina 2022-06-30 20:56:34 +03:00 committed by Ivan
parent 5c6f5a1610
commit 4b787b22c8
12 changed files with 80 additions and 72 deletions

View File

@ -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;

View File

@ -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<u32> lhs = a.first;
std::basic_string_view<u32> rhs = b.first;
return lhs < rhs;
});
std::sort(m_flat_list.begin(), m_flat_list.end(), FN(x.first < y.first));
struct work
{

View File

@ -1150,18 +1150,10 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> 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<lv2_fs_object, lv2_dir>(processed_path, std::move(data)))
{

View File

@ -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<section_storage_type*> sections_to_transfer;

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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<u32> new_type_ids(num_types);
std::vector<u64> new_type_sizes(num_types);

View File

@ -13,13 +13,13 @@ namespace rpcs3::cache
std::string get_ppu_cache()
{
auto& _main = g_fxo->get<ppu_module>();
if (!g_fxo->is_init<ppu_module>() || _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

View File

@ -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)

View File

@ -55,6 +55,48 @@ using namespace std::literals;
#define AUDIT(...) (static_cast<void>(0))
#endif
namespace utils
{
template <typename F>
struct fn_helper
{
F f;
fn_helper(F&& f)
: f(std::forward<F>(f))
{
}
template <typename... Args>
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>(args)..., 0, 0, 0);
else if constexpr (sizeof...(Args) == 2)
return f(std::forward<Args>(args)..., 0, 0);
else if constexpr (sizeof...(Args) == 3)
return f(std::forward<Args>(args)..., 0);
else if constexpr (sizeof...(Args) == 4)
return f(std::forward<Args>(args)...);
else
static_assert(sizeof...(Args) <= 4);
}
};
template <typename F>
fn_helper(F&& f) -> fn_helper<F>;
}
// 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 <typename T, typename F> requires (std::is_invocable_v<F, T&&>)
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<F>(pred)(std::forward<T>(arg))) [[likely]]
{
return std::forward<T>(arg);
}
fmt::raw_verify_error({line, col, file, func}, msg);
}
// narrow() function details
template <typename From, typename To = void, typename = void>
struct narrow_impl

View File

@ -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<char>(); 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<u64>(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)