Date: Thu, 26 Sep 2019 00:29:25 +0000 (UTC) From: Jan Beich <jbeich@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r512864 - in head/emulators/rpcs3: . files Message-ID: <201909260029.x8Q0TPrK015459@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jbeich Date: Thu Sep 26 00:29:25 2019 New Revision: 512864 URL: https://svnweb.freebsd.org/changeset/ports/512864 Log: emulators/rpcs3: update to 0.0.6.8777 Changes: https://github.com/RPCS3/rpcs3/compare/5ec35c7da...5ac631e03 Added: head/emulators/rpcs3/files/extra-patch-revert-9710473a2e3e (contents, props changed) Deleted: head/emulators/rpcs3/files/patch-llvm_cmake_modules_HandleLLVMOptions.cmake Modified: head/emulators/rpcs3/Makefile (contents, props changed) head/emulators/rpcs3/distinfo (contents, props changed) head/emulators/rpcs3/files/extra-patch-revert-4504ac2d1248 (contents, props changed) Modified: head/emulators/rpcs3/Makefile ============================================================================== --- head/emulators/rpcs3/Makefile Thu Sep 26 00:29:09 2019 (r512863) +++ head/emulators/rpcs3/Makefile Thu Sep 26 00:29:25 2019 (r512864) @@ -2,13 +2,10 @@ PORTNAME= rpcs3 DISTVERSIONPREFIX= v -DISTVERSION= 0.0.7-8760 # git rev-list --count HEAD -DISTVERSIONSUFFIX= -g5ec35c7da +DISTVERSION= 0.0.7-8777 # git rev-list --count HEAD +DISTVERSIONSUFFIX= -g5ac631e03 CATEGORIES= emulators -PATCH_SITES= https://github.com/${GH_ACCOUNT}/${GH_PROJECT}/commit/ -PATCHFILES+= 0d9c9c4358e9.patch:-p1 - MAINTAINER= jbeich@FreeBSD.org COMMENT= PS3 emulator/debugger @@ -51,7 +48,9 @@ LLD_UNSAFE= yes # XXX ports/219089 .endif # XXX Remove after FreeBSD 11.2/12.0 reach EOL i.e., around 2020-02-01 +# XXX Switch to bundled libc++ to avoid error-prone reverts .if !exists(/usr/include/c++/v1/charconv) && exists(/usr/lib/libc++.so) +EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-revert-9710473a2e3e EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-revert-f9ad6358563b EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-revert-4504ac2d1248 EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-revert-5bd17a44c972 Modified: head/emulators/rpcs3/distinfo ============================================================================== --- head/emulators/rpcs3/distinfo Thu Sep 26 00:29:09 2019 (r512863) +++ head/emulators/rpcs3/distinfo Thu Sep 26 00:29:25 2019 (r512864) @@ -1,6 +1,6 @@ -TIMESTAMP = 1569197741 -SHA256 (RPCS3-rpcs3-v0.0.7-8760-g5ec35c7da_GH0.tar.gz) = 8be1b5ee89331f539e575d375fb094b3e1f8c11800afbd2f0e338a7f94f7d5b5 -SIZE (RPCS3-rpcs3-v0.0.7-8760-g5ec35c7da_GH0.tar.gz) = 5601486 +TIMESTAMP = 1569442852 +SHA256 (RPCS3-rpcs3-v0.0.7-8777-g5ac631e03_GH0.tar.gz) = 991dce4b8471b0252b12d8fd206dc94d1fdefa014d06ab773b01cc85a7a239ba +SIZE (RPCS3-rpcs3-v0.0.7-8777-g5ac631e03_GH0.tar.gz) = 5599517 SHA256 (RPCS3-hidapi-hidapi-0.8.0-rc1-27-g9220f5e_GH0.tar.gz) = 3120e0b701943f452760e45f9fc1ac50bab356ad4c807b4cac4598041c5ca1a5 SIZE (RPCS3-hidapi-hidapi-0.8.0-rc1-27-g9220f5e_GH0.tar.gz) = 105400 SHA256 (RPCS3-llvm-b860b5e8f4ee_GH0.tar.gz) = c151972a0c8ceac568c24b61e63d2ecbdac0f125185e23fc2238e0a14048256e @@ -19,5 +19,3 @@ SHA256 (USCiLab-cereal-v1.2.0_GH0.tar.gz) = 1ccf3ed205 SIZE (USCiLab-cereal-v1.2.0_GH0.tar.gz) = 299883 SHA256 (zeux-pugixml-v1.9-51-g8bf806c_GH0.tar.gz) = 37bed90f3dadb642acca41508391d1409a75af05f34f13da56c866d5c3c4b00d SIZE (zeux-pugixml-v1.9-51-g8bf806c_GH0.tar.gz) = 560956 -SHA256 (0d9c9c4358e9.patch) = 10fbe5b4a92917ecceb0870c8c30a28fa518432ce2facee621cc8816e7e1c8b8 -SIZE (0d9c9c4358e9.patch) = 920 Modified: head/emulators/rpcs3/files/extra-patch-revert-4504ac2d1248 ============================================================================== --- head/emulators/rpcs3/files/extra-patch-revert-4504ac2d1248 Thu Sep 26 00:29:09 2019 (r512863) +++ head/emulators/rpcs3/files/extra-patch-revert-4504ac2d1248 Thu Sep 26 00:29:25 2019 (r512864) @@ -71,20 +71,25 @@ rpcs3/util/atomic.cpp:307:5: error: use of undeclared #ifdef _WIN32 LARGE_INTEGER qw; qw.QuadPart = -static_cast<s64>(timeout / 100); -@@ -260,13 +245,6 @@ void atomic_storage_futex::wait(const void* data, std: +@@ -259,18 +244,6 @@ void atomic_storage_futex::wait(const void* data, std: + { + if (value & s_waiter_mask) { - value -= s_waiter_mask & -s_waiter_mask; - -#ifdef _WIN32 - if (!fallback) - { +- if ((value & s_signal_mask) == 0) +- { +- return false; +- } +- - value -= s_signal_mask & -s_signal_mask; - } -#endif - + value -= s_waiter_mask & -s_waiter_mask; + if ((value & s_waiter_mask) == 0) - { - // Reset on last waiter @@ -279,7 +257,7 @@ void atomic_storage_futex::wait(const void* data, std: return false; }); Added: head/emulators/rpcs3/files/extra-patch-revert-9710473a2e3e ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/emulators/rpcs3/files/extra-patch-revert-9710473a2e3e Thu Sep 26 00:29:25 2019 (r512864) @@ -0,0 +1,783 @@ +--- Utilities/sync.h.orig 2019-09-25 20:20:52 UTC ++++ Utilities/sync.h +@@ -15,6 +15,7 @@ + #include <linux/futex.h> + #include <sys/time.h> + #include <unistd.h> ++#else + #endif + #include <algorithm> + #include <ctime> +@@ -24,8 +25,12 @@ + #include <unordered_map> + + #ifdef _WIN32 +-DYNAMIC_IMPORT("ntdll.dll", NtWaitForSingleObject, NTSTATUS(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout)); ++DYNAMIC_IMPORT("ntdll.dll", NtWaitForKeyedEvent, NTSTATUS(HANDLE Handle, PVOID Key, BOOLEAN Alertable, PLARGE_INTEGER Timeout)); ++DYNAMIC_IMPORT("ntdll.dll", NtReleaseKeyedEvent, NTSTATUS(HANDLE Handle, PVOID Key, BOOLEAN Alertable, PLARGE_INTEGER Timeout)); + DYNAMIC_IMPORT("ntdll.dll", NtDelayExecution, NTSTATUS(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval)); ++inline utils::dynamic_import<BOOL(volatile VOID* Address, PVOID CompareAddress, SIZE_T AddressSize, DWORD dwMilliseconds)> OptWaitOnAddress("kernel32.dll", "WaitOnAddress"); ++inline utils::dynamic_import<VOID(PVOID Address)> OptWakeByAddressSingle("kernel32.dll", "WakeByAddressSingle"); ++inline utils::dynamic_import<VOID(PVOID Address)> OptWakeByAddressAll("kernel32.dll", "WakeByAddressAll"); + #endif + + #ifndef __linux__ +--- rpcs3/util/atomic.cpp.orig 2019-09-25 20:20:52 UTC ++++ rpcs3/util/atomic.cpp +@@ -1,24 +1,11 @@ + #include "atomic.hpp" + +-// USE_FUTEX takes precedence over USE_POSIX +- +-#ifdef __linux__ +-#define USE_FUTEX +-#define USE_POSIX +-#endif +- + #include "Utilities/sync.h" + #include "Utilities/asm.h" + +-#ifdef USE_POSIX +-#include <semaphore.h> +-#endif +- + #include <map> + #include <mutex> + #include <condition_variable> +-#include <iterator> +-#include <memory> + + // Total number of entries, should be a power of 2. + static constexpr std::uintptr_t s_hashtable_size = 1u << 22; +@@ -35,18 +22,8 @@ static constexpr u64 s_waiter_mask = 0x7fff'0000'0000' + // + static constexpr u64 s_collision_bit = 0x8000'0000'0000'0000; + +-#ifdef USE_FUTEX +-static constexpr u64 s_sema_mask = 0; +-#else +-// Number of search groups (defines max semaphore count as gcount * 64) +-static constexpr u32 s_sema_gcount = 64; +- +-// Bits encoding allocated semaphore index (zero = not allocated yet) +-static constexpr u64 s_sema_mask = (64 * s_sema_gcount - 1) << 2; +-#endif +- + // Implementation detail (remaining bits out of 32 available for futex) +-static constexpr u64 s_signal_mask = 0xffffffff & ~(s_waiter_mask | s_pointer_mask | s_collision_bit | s_sema_mask); ++static constexpr u64 s_signal_mask = 0xffffffff & ~(s_waiter_mask | s_pointer_mask | s_collision_bit); + + // Callback for wait() function, returns false if wait should return + static thread_local bool(*s_tls_wait_cb)(const void* data) = [](const void*) +@@ -54,140 +31,6 @@ static thread_local bool(*s_tls_wait_cb)(const void* d + return true; + }; + +-#ifndef USE_FUTEX +- +-#ifdef USE_POSIX +-using sema_handle = sem_t; +-#elif defined(_WIN32) +-using sema_handle = HANDLE; +-#else +-namespace +-{ +- struct dumb_sema +- { +- u64 count = 0; +- std::mutex mutex; +- std::condition_variable cond; +- }; +-} +- +-using sema_handle = std::unique_ptr<dumb_sema>; +-#endif +- +-// Array of native semaphores +-static sema_handle s_sema_list[64 * s_sema_gcount]{}; +- +-// Array of associated reference counters +-static atomic_t<u64> s_sema_refs[64 * s_sema_gcount]{}; +- +-// Allocation bits (reserve first bit) +-static atomic_t<u64> s_sema_bits[s_sema_gcount]{1}; +- +-static u32 sema_alloc() +-{ +- // Diversify search start points to reduce contention and increase immediate success chance +-#ifdef _WIN32 +- const u32 start = GetCurrentProcessorNumber(); +-#elif __linux__ +- const u32 start = sched_getcpu(); +-#else +- const u32 start = __rdtsc(); +-#endif +- +- for (u32 i = 0; i < s_sema_gcount * 3; i++) +- { +- const u32 group = (i + start) % s_sema_gcount; +- +- const auto [bits, ok] = s_sema_bits[group].fetch_op([](u64& bits) +- { +- if (~bits) +- { +- // Set lowest clear bit +- bits |= bits + 1; +- return true; +- } +- +- return false; +- }); +- +- if (ok) +- { +- // Find lowest clear bit +- const u32 id = group * 64 + utils::cnttz64(~bits, false); +- +-#ifdef USE_POSIX +- // Initialize semaphore (should be very fast) +- sem_init(&s_sema_list[id], 0, 0); +-#elif defined(_WIN32) +- if (!s_sema_list[id]) +- { +- s_sema_list[id] = CreateSemaphoreW(nullptr, 0, 0x7fff'ffff, nullptr); +- } +-#else +- if (!s_sema_list[id]) +- { +- s_sema_list[id] = std::make_unique<dumb_sema>(); +- } +-#endif +- +- // Initialize ref counter +- if (s_sema_refs[id]++) +- { +- std::abort(); +- } +- +- return id; +- } +- } +- +- return 0; +-} +- +-static void sema_free(u32 id) +-{ +- if (id && id < 64 * s_sema_gcount) +- { +- // Dereference first +- if (--s_sema_refs[id]) +- { +- return; +- } +- +-#ifdef USE_POSIX +- // Destroy semaphore (should be very fast) +- sem_destroy(&s_sema_list[id]); +-#else +- // No action required +-#endif +- +- // Reset allocation bit +- s_sema_bits[id / 64] &= ~(1ull << (id % 64)); +- } +-} +- +-static bool sema_get(u32 id) +-{ +- if (id && id < 64 * s_sema_gcount) +- { +- // Increment only if the semaphore is allocated +- if (s_sema_refs[id].fetch_op([](u64& refs) +- { +- if (refs) +- { +- // Increase reference from non-zero value +- refs++; +- } +- })) +- { +- return true; +- } +- } +- +- return false; +-} +- +-#endif +- + static inline bool ptr_cmp(const void* data, std::size_t size, u64 old_value, u64 mask) + { + switch (size) +@@ -308,8 +151,27 @@ namespace + } + } + ++#if !defined(_WIN32) && !defined(__linux__) ++ + void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask) + { ++ fallback_wait(data, size, old_value, timeout, mask); ++} ++ ++void atomic_storage_futex::notify_one(const void* data) ++{ ++ fallback_notify_one(data); ++} ++ ++void atomic_storage_futex::notify_all(const void* data) ++{ ++ fallback_notify_all(data); ++} ++ ++#else ++ ++void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask) ++{ + if (!timeout) + { + return; +@@ -323,8 +185,6 @@ void atomic_storage_futex::wait(const void* data, std: + + bool fallback = false; + +- u32 sema_id = -1; +- + const auto [_, ok] = entry.fetch_op([&](u64& value) + { + if ((value & s_waiter_mask) == s_waiter_mask || (value & s_signal_mask) == s_signal_mask) +@@ -333,15 +193,15 @@ void atomic_storage_futex::wait(const void* data, std: + return false; + } + +-#ifndef USE_FUTEX +- sema_id = (value & s_sema_mask) >> 2; +-#endif +- + if (!value || (value & s_pointer_mask) == (iptr & s_pointer_mask)) + { + // Store pointer bits + value |= (iptr & s_pointer_mask); + fallback = false; ++ ++#ifdef _WIN32 ++ value += s_signal_mask & -s_signal_mask; ++#endif + } + else + { +@@ -361,93 +221,13 @@ void atomic_storage_futex::wait(const void* data, std: + return; + } + +-#ifndef USE_FUTEX +- for (u32 loop_count = 0; !fallback && loop_count < 7; loop_count++) +- { +- // Try to allocate a semaphore +- if (!sema_id) +- { +- const u32 sema = sema_alloc(); +- +- if (!sema) +- { +- break; +- } +- +- sema_id = entry.atomic_op([&](u64& value) -> u32 +- { +- if (value & s_sema_mask) +- { +- return (value & s_sema_mask) >> 2; +- } +- +- // Insert allocated semaphore +- value += s_signal_mask & -s_signal_mask; +- value |= (u64{sema} << 2); +- return 0; +- }); +- +- if (sema_id) +- { +- // Drop unnecessary allocation +- sema_free(sema); +- } +- else +- { +- sema_id = sema; +- break; +- } +- } +- +- if (!sema_get(sema_id)) +- { +- sema_id = 0; +- continue; +- } +- +- // Try to increment sig (check semaphore validity) +- const auto [_old, ok] = entry.fetch_op([&](u64& value) +- { +- if ((value & s_signal_mask) == s_signal_mask) +- { +- return false; +- } +- +- if ((value & s_sema_mask) >> 2 != sema_id) +- { +- return false; +- } +- +- value += s_signal_mask & -s_signal_mask; +- return true; +- }); +- +- if (!ok) +- { +- sema_free(sema_id); +- sema_id = 0; +- +- if ((_old & s_signal_mask) == s_signal_mask) +- { +- // Break on signal overflow +- break; +- } +- +- continue; +- } +- +- break; +- } +-#endif +- + if (fallback) + { + fallback_wait(data, size, old_value, timeout, mask); + } +- else if (sema_id && ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data)) ++ else if (ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data)) + { +-#ifndef USE_FUTEX +-#if defined(_WIN32) && !defined(USE_POSIX) ++#ifdef _WIN32 + LARGE_INTEGER qw; + qw.QuadPart = -static_cast<s64>(timeout / 100); + +@@ -457,60 +237,13 @@ void atomic_storage_futex::wait(const void* data, std: + qw.QuadPart -= 1; + } + +- if (!NtWaitForSingleObject(s_sema_list[sema_id], false, timeout + 1 ? &qw : nullptr)) ++ if (!NtWaitForKeyedEvent(nullptr, &entry, false, timeout + 1 ? &qw : nullptr)) + { +- fallback = true; ++ // Return if no errors, continue if timed out ++ s_tls_wait_cb(nullptr); ++ return; + } +-#elif defined(USE_POSIX) +- struct timespec ts; +- clock_gettime(CLOCK_REALTIME, &ts); +- ts.tv_sec += timeout / 1'000'000'000; +- ts.tv_nsec += timeout % 1'000'000'000; +- ts.tv_sec += ts.tv_nsec / 1'000'000'000; +- ts.tv_nsec %= 1'000'000'000; +- +- // It's pretty unreliable because it uses absolute time, which may jump backwards. Sigh. +- if (timeout + 1) +- { +- if (sem_timedwait(&s_sema_list[sema_id], &ts) == 0) +- { +- fallback = true; +- } +- } +- else +- { +- if (sem_wait(&s_sema_list[sema_id]) == 0) +- { +- fallback = true; +- } +- } + #else +- dumb_sema& sema = *s_sema_list[sema_id]; +- +- std::unique_lock lock(sema.mutex); +- +- if (timeout + 1) +- { +- sema.cond.wait_for(lock, std::chrono::nanoseconds(timeout), [&] +- { +- return sema.count > 0; +- }); +- } +- else +- { +- sema.cond.wait(lock, [&] +- { +- return sema.count > 0; +- }); +- } +- +- if (sema.count > 0) +- { +- sema.count--; +- fallback = true; +- } +-#endif +-#else + struct timespec ts; + ts.tv_sec = timeout / 1'000'000'000; + ts.tv_nsec = timeout % 1'000'000'000; +@@ -519,11 +252,6 @@ void atomic_storage_futex::wait(const void* data, std: + #endif + } + +- if (!sema_id) +- { +- fallback = true; +- } +- + while (true) + { + // Try to decrement +@@ -531,21 +259,15 @@ void atomic_storage_futex::wait(const void* data, std: + { + if (value & s_waiter_mask) + { +-#ifndef USE_FUTEX +- // If timeout ++#ifdef _WIN32 + if (!fallback) + { +- if ((value & s_signal_mask) == 0 || (value & s_sema_mask) >> 2 != sema_id) ++ if ((value & s_signal_mask) == 0) + { + return false; + } + + value -= s_signal_mask & -s_signal_mask; +- +- if ((value & s_signal_mask) == 0) +- { +- value &= ~s_sema_mask; +- } + } + #endif + +@@ -568,45 +290,22 @@ void atomic_storage_futex::wait(const void* data, std: + break; + } + +-#ifndef USE_FUTEX +-#if defined(_WIN32) && !defined(USE_POSIX) ++#ifdef _WIN32 + static LARGE_INTEGER instant{}; + +- if (!NtWaitForSingleObject(s_sema_list[sema_id], false, &instant)) ++ if (!NtWaitForKeyedEvent(nullptr, &entry, false, &instant)) + { +- fallback = true; ++ break; + } +-#elif defined(USE_POSIX) +- if (sem_trywait(&s_sema_list[sema_id]) == 0) +- { +- fallback = true; +- } + #else +- dumb_sema& sema = *s_sema_list[sema_id]; +- +- std::unique_lock lock(sema.mutex); +- +- if (sema.count > 0) +- { +- sema.count--; +- fallback = true; +- } ++ // Unreachable ++ std::terminate(); + #endif +-#endif + } + +-#ifndef USE_FUTEX +- if (sema_id) +- { +- sema_free(sema_id); +- } +-#endif +- + s_tls_wait_cb(nullptr); + } + +-#ifdef USE_FUTEX +- + void atomic_storage_futex::notify_one(const void* data) + { + const std::uintptr_t iptr = reinterpret_cast<std::uintptr_t>(data); +@@ -617,6 +316,23 @@ void atomic_storage_futex::notify_one(const void* data + { + if (value & s_waiter_mask && (value & s_pointer_mask) == (iptr & s_pointer_mask)) + { ++#ifdef _WIN32 ++ if ((value & s_signal_mask) == 0) ++ { ++ // No relevant waiters, do nothing ++ return false; ++ } ++ ++ // Try to decrement if possible ++ value -= s_waiter_mask & -s_waiter_mask; ++ value -= s_signal_mask & -s_signal_mask; ++ ++ if ((value & s_waiter_mask) == 0) ++ { ++ // Reset on last waiter ++ value = 0; ++ } ++#else + if ((value & s_signal_mask) == s_signal_mask) + { + // Signal overflow, do nothing +@@ -631,7 +347,7 @@ void atomic_storage_futex::notify_one(const void* data + notify_all(data); + return false; + } +- ++#endif + return true; + } + else if (value & s_waiter_mask && value & s_collision_bit) +@@ -645,7 +361,11 @@ void atomic_storage_futex::notify_one(const void* data + + if (ok) + { ++#ifdef _WIN32 ++ NtReleaseKeyedEvent(nullptr, &entry, false, nullptr); ++#else + futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 1); ++#endif + } + } + +@@ -655,6 +375,53 @@ void atomic_storage_futex::notify_all(const void* data + + atomic_t<u64>& entry = s_hashtable[(iptr >> 2) % s_hashtable_size]; + ++ // Try to consume everything ++#ifdef _WIN32 ++ const auto [old, ok] = entry.fetch_op([&](u64& value) ++ { ++ if (value & s_waiter_mask) ++ { ++ if ((value & s_pointer_mask) == (iptr & s_pointer_mask)) ++ { ++ if ((value & s_signal_mask) == 0) ++ { ++ // No relevant waiters, do nothing ++ return false; ++ } ++ ++ const u64 count = (value & s_signal_mask) / (s_signal_mask & -s_signal_mask); ++ value -= (s_waiter_mask & -s_waiter_mask) * count; ++ value -= (s_signal_mask & -s_signal_mask) * count; ++ ++ if ((value & s_waiter_mask) == 0) ++ { ++ // Reset on last waiter ++ value = 0; ++ } ++ ++ return true; ++ } ++ ++ if (value & s_collision_bit) ++ { ++ fallback_notify_all(data); ++ return false; ++ } ++ } ++ ++ return false; ++ }); ++ ++ if (!ok) ++ { ++ return; ++ } ++ ++ for (u64 count = old & s_signal_mask; count; count -= s_signal_mask & -s_signal_mask) ++ { ++ NtReleaseKeyedEvent(nullptr, &entry, false, nullptr); ++ } ++#else + const auto [_, ok] = entry.fetch_op([&](u64& value) + { + if (value & s_waiter_mask) +@@ -685,6 +452,7 @@ void atomic_storage_futex::notify_all(const void* data + { + futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 0x7fffffff); + } ++#endif + } + + #endif +@@ -704,158 +472,3 @@ void atomic_storage_futex::raw_notify(const void* data + notify_all(data); + } + } +- +-#ifndef USE_FUTEX +- +-void atomic_storage_futex::notify_one(const void* data) +-{ +- const std::uintptr_t iptr = reinterpret_cast<std::uintptr_t>(data); +- +- atomic_t<u64>& entry = s_hashtable[(iptr >> 2) % s_hashtable_size]; +- +- const u64 value = entry; +- +- if (value & s_waiter_mask && (value & s_pointer_mask) == (iptr & s_pointer_mask)) +- { +- if ((value & s_signal_mask) == 0 || (value & s_sema_mask) == 0) +- { +- // No relevant waiters, do nothing +- return; +- } +- } +- else if (value & s_waiter_mask && value & s_collision_bit) +- { +- fallback_notify_one(data); +- return; +- } +- else +- { +- return; +- } +- +- const u32 sema_id = (value & s_sema_mask) >> 2; +- +- if (!sema_get(sema_id)) +- { +- return; +- } +- +- const auto [_, ok] = entry.fetch_op([&](u64& value) +- { +- if ((value & s_waiter_mask) == 0 || (value & s_pointer_mask) != (iptr & s_pointer_mask)) +- { +- return false; +- } +- +- if ((value & s_signal_mask) == 0 || (value & s_sema_mask) >> 2 != sema_id) +- { +- return false; +- } +- +- value -= s_signal_mask & -s_signal_mask; +- +- // Reset allocated semaphore on last waiter +- if ((value & s_signal_mask) == 0) +- { +- value &= ~s_sema_mask; +- } +- +- return true; +- }); +- +- if (ok) +- { +-#ifdef USE_POSIX +- sem_post(&s_sema_list[sema_id]); +-#elif defined(_WIN32) +- ReleaseSemaphore(s_sema_list[sema_id], 1, nullptr); +-#else +- dumb_sema& sema = *s_sema_list[sema_id]; +- +- sema.mutex.lock(); +- sema.count += 1; +- sema.mutex.unlock(); +- sema.cond.notify_one(); +-#endif +- } +- +- sema_free(sema_id); +-} +- +-void atomic_storage_futex::notify_all(const void* data) +-{ +- const std::uintptr_t iptr = reinterpret_cast<std::uintptr_t>(data); +- +- atomic_t<u64>& entry = s_hashtable[(iptr >> 2) % s_hashtable_size]; +- +- const u64 value = entry; +- +- if (value & s_waiter_mask && (value & s_pointer_mask) == (iptr & s_pointer_mask)) +- { +- if ((value & s_signal_mask) == 0 || (value & s_sema_mask) == 0) +- { +- // No relevant waiters, do nothing +- return; +- } +- } +- else if (value & s_waiter_mask && value & s_collision_bit) +- { +- fallback_notify_all(data); +- return; +- } +- else +- { +- return; +- } +- +- const u32 sema_id = (value & s_sema_mask) >> 2; +- +- if (!sema_get(sema_id)) +- { +- return; +- } +- +- const auto [_, count] = entry.fetch_op([&](u64& value) -> u32 +- { +- if ((value & s_waiter_mask) == 0 || (value & s_pointer_mask) != (iptr & s_pointer_mask)) +- { +- return 0; +- } +- +- if ((value & s_signal_mask) == 0 || (value & s_sema_mask) >> 2 != sema_id) +- { +- return 0; +- } +- +- const u32 r = (value & s_signal_mask) / (s_signal_mask & -s_signal_mask); +- value &= ~s_sema_mask; +- value &= ~s_signal_mask; +- return r; +- }); +- +-#ifdef USE_POSIX +- for (u32 i = 0; i < count; i++) +- { +- sem_post(&s_sema_list[sema_id]); +- } +-#elif defined(_WIN32) +- if (count) +- { +- ReleaseSemaphore(s_sema_list[sema_id], count, nullptr); +- } +-#else +- if (count) +- { +- dumb_sema& sema = *s_sema_list[sema_id]; +- +- sema.mutex.lock(); +- sema.count += count; +- sema.mutex.unlock(); +- sema.cond.notify_all(); +- } +-#endif +- +- sema_free(sema_id); +-} +- +-#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909260029.x8Q0TPrK015459>