Implement waitable atomics

Moved Atomic.h to util/atomic.hpp
List source files in CMakeLists.txt
This commit is contained in:
Nekotekina 2019-07-27 01:34:10 +03:00
parent ec2db8edbc
commit f63e89f9b4
25 changed files with 661 additions and 69 deletions

View File

@ -1,6 +1,6 @@
#pragma once
#include "Atomic.h"
#include "util/atomic.hpp"
#include <memory>
#include <cstddef>

View File

@ -1,7 +1,7 @@
#pragma once
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
#include "StrFmt.h"
#include <climits>

View File

@ -1,7 +1,7 @@
#pragma once
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
#include <string>
#include <memory>

View File

@ -22,7 +22,7 @@ Intersection (&) and symmetric difference (^) is also available.
*/
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
template <typename T>
class atomic_bs_t;

View File

@ -1,7 +1,7 @@
#pragma once
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
#include <shared_mutex>
#include "asm.h"

View File

@ -4,7 +4,7 @@
#include <deque>
#include <list>
#include "Atomic.h"
#include "util/atomic.hpp"
template <typename T, T Mod = T::__state_enum_max, typename Under = std::underlying_type_t<T>>
T operator ++(T& value, int)

View File

@ -1,7 +1,7 @@
#pragma once
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
//! Simple sizeless array base for concurrent access. Cannot shrink, only growths automatically.
//! There is no way to know the current size. The smaller index is, the faster it's accessed.

View File

@ -2,7 +2,7 @@
#include <mutex>
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
// Shared mutex with small size (u32).
class shared_mutex final

View File

@ -2,7 +2,7 @@
#include <mutex>
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
// Lightweight semaphore helper class
class semaphore_base

View File

@ -3,7 +3,7 @@
/* For internal use. Don't include. */
#include "types.h"
#include "Atomic.h"
#include "util/atomic.hpp"
#include "dynamic_library.h"
#ifdef _WIN32

View File

@ -3,7 +3,7 @@
#include "types.h"
#include "mutex.h"
#include "cond.h"
#include "Atomic.h"
#include "util/atomic.hpp"
#include "VirtualMemory.h"
#include <memory>

View File

@ -35,7 +35,22 @@ include(${CMAKE_SOURCE_DIR}/3rdparty/qt5.cmake)
add_subdirectory(Emu)
add_subdirectory(rpcs3qt)
file(GLOB RPCS3_SRC "*.cpp")
set(RPCS3_SRC
basic_keyboard_handler.cpp
basic_mouse_handler.cpp
ds3_pad_handler.cpp
ds4_pad_handler.cpp
evdev_joystick_handler.cpp
keyboard_pad_handler.cpp
main.cpp
mm_joystick_handler.cpp
pad_thread.cpp
rpcs3_app.cpp
rpcs3_version.cpp
stb_image.cpp
stdafx.cpp
xinput_pad_handler.cpp
)
if(WIN32)
add_executable(rpcs3 WIN32 ${RPCS3_SRC})

View File

@ -1,6 +1,8 @@
file(GLOB SRC_FILES "*.cpp")
add_library(rpcs3_emu ${SRC_FILES})
add_library(rpcs3_emu
IdManager.cpp
System.cpp
VFS.cpp
)
target_link_libraries(rpcs3_emu
PRIVATE
@ -15,8 +17,26 @@ target_include_directories(rpcs3_emu
# Utilities
file(GLOB UTILITIES_SRC_FILES "../../Utilities/*.cpp")
target_sources(rpcs3_emu PRIVATE ${UTILITIES_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
../util/atomic.cpp
../../Utilities/bin_patch.cpp
../../Utilities/cond.cpp
../../Utilities/Config.cpp
../../Utilities/dynamic_library.cpp
../../Utilities/File.cpp
../../Utilities/GDBDebugServer.cpp
../../Utilities/JIT.cpp
../../Utilities/Log.cpp
../../Utilities/LUrlParser.cpp
../../Utilities/mutex.cpp
../../Utilities/rXml.cpp
../../Utilities/sema.cpp
../../Utilities/StrFmt.cpp
../../Utilities/sysinfo.cpp
../../Utilities/Thread.cpp
../../Utilities/version.cpp
../../Utilities/VirtualMemory.cpp
)
target_include_directories(rpcs3_emu PUBLIC "${CMAKE_SOURCE_DIR}")
@ -33,17 +53,39 @@ endif()
# Crypto
file(GLOB CRYPTO_SRC_FILES "../Crypto/*.cpp")
target_sources(rpcs3_emu PRIVATE ${CRYPTO_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
../Crypto/aes.cpp
../Crypto/ec.cpp
../Crypto/key_vault.cpp
../Crypto/lz.cpp
../Crypto/sha1.cpp
../Crypto/unedat.cpp
../Crypto/unpkg.cpp
../Crypto/unself.cpp
../Crypto/utils.cpp
)
# Loader
file(GLOB LOADER_SRC_FILES "../Loader/*.cpp")
target_sources(rpcs3_emu PRIVATE ${LOADER_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
../Loader/ELF.cpp
../Loader/PSF.cpp
../Loader/PUP.cpp
../Loader/TAR.cpp
../Loader/TROPUSR.cpp
../Loader/TRP.cpp
)
# Audio
file(GLOB_RECURSE AUDIO_SRC_FILES "Audio/*.cpp")
target_sources(rpcs3_emu PRIVATE ${AUDIO_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
Audio/AudioDumper.cpp
Audio/AL/OpenALBackend.cpp
Audio/ALSA/ALSABackend.cpp
Audio/Pulse/PulseBackend.cpp
Audio/XAudio2/XAudio27Backend.cpp
Audio/XAudio2/XAudio28Backend.cpp
Audio/XAudio2/XAudio2Backend.cpp
)
if(WIN32)
# Slimmed down version of minidx9 for XAudio2_7 only
@ -56,8 +98,180 @@ target_link_libraries(rpcs3_emu
# Cell
file(GLOB_RECURSE CELL_SRC_FILES "Cell/*.cpp")
target_sources(rpcs3_emu PRIVATE ${CELL_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
Cell/MFC.cpp
Cell/PPUAnalyser.cpp
Cell/PPUDisAsm.cpp
Cell/PPUFunction.cpp
Cell/PPUInterpreter.cpp
Cell/PPUModule.cpp
Cell/PPUThread.cpp
Cell/PPUTranslator.cpp
Cell/RawSPUThread.cpp
Cell/SPUAnalyser.cpp
Cell/SPUASMJITRecompiler.cpp
Cell/SPUDisAsm.cpp
Cell/SPUInterpreter.cpp
Cell/SPURecompiler.cpp
Cell/SPUThread.cpp
Cell/lv2/lv2.cpp
Cell/lv2/sys_cond.cpp
Cell/lv2/sys_config.cpp
Cell/lv2/sys_dbg.cpp
Cell/lv2/sys_event.cpp
Cell/lv2/sys_event_flag.cpp
Cell/lv2/sys_fs.cpp
Cell/lv2/sys_gamepad.cpp
Cell/lv2/sys_gpio.cpp
Cell/lv2/sys_interrupt.cpp
Cell/lv2/sys_lwcond.cpp
Cell/lv2/sys_lwmutex.cpp
Cell/lv2/sys_memory.cpp
Cell/lv2/sys_mmapper.cpp
Cell/lv2/sys_mutex.cpp
Cell/lv2/sys_net.cpp
Cell/lv2/sys_overlay.cpp
Cell/lv2/sys_ppu_thread.cpp
Cell/lv2/sys_process.cpp
Cell/lv2/sys_prx.cpp
Cell/lv2/sys_rsx.cpp
Cell/lv2/sys_rwlock.cpp
Cell/lv2/sys_semaphore.cpp
Cell/lv2/sys_spu.cpp
Cell/lv2/sys_ss.cpp
Cell/lv2/sys_time.cpp
Cell/lv2/sys_timer.cpp
Cell/lv2/sys_trace.cpp
Cell/lv2/sys_tty.cpp
Cell/lv2/sys_usbd.cpp
Cell/lv2/sys_vm.cpp
Cell/Modules/cellAdec.cpp
Cell/Modules/cellAtrac.cpp
Cell/Modules/cellAtracMulti.cpp
Cell/Modules/cellAudio.cpp
Cell/Modules/cellAudioOut.cpp
Cell/Modules/cellAvconfExt.cpp
Cell/Modules/cellBgdl.cpp
Cell/Modules/cellCamera.cpp
Cell/Modules/cellCelp8Enc.cpp
Cell/Modules/cellCelpEnc.cpp
Cell/Modules/cellCrossController.cpp
Cell/Modules/cellDaisy.cpp
Cell/Modules/cellDmux.cpp
Cell/Modules/cellDtcpIpUtility.cpp
Cell/Modules/cellFiber.cpp
Cell/Modules/cellFont.cpp
Cell/Modules/cellFontFT.cpp
Cell/Modules/cell_FreeType2.cpp
Cell/Modules/cellFs.cpp
Cell/Modules/cellGame.cpp
Cell/Modules/cellGameExec.cpp
Cell/Modules/cellGcmSys.cpp
Cell/Modules/cellGem.cpp
Cell/Modules/cellGifDec.cpp
Cell/Modules/cellHttp.cpp
Cell/Modules/cellHttpUtil.cpp
Cell/Modules/cellImeJp.cpp
Cell/Modules/cellJpgDec.cpp
Cell/Modules/cellJpgEnc.cpp
Cell/Modules/cellKb.cpp
Cell/Modules/cellKey2char.cpp
Cell/Modules/cellL10n.cpp
Cell/Modules/cellLibprof.cpp
Cell/Modules/cellMic.cpp
Cell/Modules/cellMouse.cpp
Cell/Modules/cellMsgDialog.cpp
Cell/Modules/cellMusic.cpp
Cell/Modules/cellMusicDecode.cpp
Cell/Modules/cellMusicExport.cpp
Cell/Modules/cellNetAoi.cpp
Cell/Modules/cellNetCtl.cpp
Cell/Modules/cellOskDialog.cpp
Cell/Modules/cellOvis.cpp
Cell/Modules/cellPad.cpp
Cell/Modules/cellPamf.cpp
Cell/Modules/cellPesmUtility.cpp
Cell/Modules/cellPhotoDecode.cpp
Cell/Modules/cellPhotoExport.cpp
Cell/Modules/cellPhotoImport.cpp
Cell/Modules/cellPngDec.cpp
Cell/Modules/cellPngEnc.cpp
Cell/Modules/cellPrint.cpp
Cell/Modules/cellRec.cpp
Cell/Modules/cellRemotePlay.cpp
Cell/Modules/cellResc.cpp
Cell/Modules/cellRtcAlarm.cpp
Cell/Modules/cellRtc.cpp
Cell/Modules/cellRudp.cpp
Cell/Modules/cellSail.cpp
Cell/Modules/cellSailRec.cpp
Cell/Modules/cellSaveData.cpp
Cell/Modules/cellScreenshot.cpp
Cell/Modules/cellSearch.cpp
Cell/Modules/cellSheap.cpp
Cell/Modules/cellSpudll.cpp
Cell/Modules/cellSpurs.cpp
Cell/Modules/cellSpursJq.cpp
Cell/Modules/cellSpursSpu.cpp
Cell/Modules/cellSsl.cpp
Cell/Modules/cellStorage.cpp
Cell/Modules/cellSubDisplay.cpp
Cell/Modules/cellSync2.cpp
Cell/Modules/cellSync.cpp
Cell/Modules/cellSysconf.cpp
Cell/Modules/cellSysmodule.cpp
Cell/Modules/cellSysutilAp.cpp
Cell/Modules/cellSysutilAvc2.cpp
Cell/Modules/cellSysutilAvc.cpp
Cell/Modules/cellSysutilAvcExt.cpp
Cell/Modules/cellSysutil.cpp
Cell/Modules/cellSysutilMisc.cpp
Cell/Modules/cellSysutilNpEula.cpp
Cell/Modules/cellUsbd.cpp
Cell/Modules/cellUsbpspcm.cpp
Cell/Modules/cellUserInfo.cpp
Cell/Modules/cellVdec.cpp
Cell/Modules/cellVideoExport.cpp
Cell/Modules/cellVideoOut.cpp
Cell/Modules/cellVideoPlayerUtility.cpp
Cell/Modules/cellVideoUpload.cpp
Cell/Modules/cellVoice.cpp
Cell/Modules/cellVpost.cpp
Cell/Modules/cellWebBrowser.cpp
Cell/Modules/libad_async.cpp
Cell/Modules/libad_core.cpp
Cell/Modules/libmedi.cpp
Cell/Modules/libmixer.cpp
Cell/Modules/libsnd3.cpp
Cell/Modules/libsynth2.cpp
Cell/Modules/sceNp2.cpp
Cell/Modules/sceNpClans.cpp
Cell/Modules/sceNpCommerce2.cpp
Cell/Modules/sceNp.cpp
Cell/Modules/sceNpMatchingInt.cpp
Cell/Modules/sceNpSns.cpp
Cell/Modules/sceNpTrophy.cpp
Cell/Modules/sceNpTus.cpp
Cell/Modules/sceNpUtil.cpp
Cell/Modules/StaticHLE.cpp
Cell/Modules/sys_game.cpp
Cell/Modules/sys_heap.cpp
Cell/Modules/sys_io.cpp
Cell/Modules/sys_libc_.cpp
Cell/Modules/sys_libc.cpp
Cell/Modules/sys_lv2dbg.cpp
Cell/Modules/sys_lwcond_.cpp
Cell/Modules/sys_lwmutex_.cpp
Cell/Modules/sys_mempool.cpp
Cell/Modules/sys_mmapper_.cpp
Cell/Modules/sys_net_.cpp
Cell/Modules/sys_ppu_thread_.cpp
Cell/Modules/sys_prx_.cpp
Cell/Modules/sysPrxForUser.cpp
Cell/Modules/sys_rsxaudio_.cpp
Cell/Modules/sys_spinlock.cpp
Cell/Modules/sys_spu_.cpp
)
if(NOT MSVC)
set_source_files_properties(Cell/PPUTranslator.cpp PROPERTIES COMPILE_FLAGS -fno-rtti)
@ -73,44 +287,109 @@ endif()
# CPU
file(GLOB_RECURSE CPU_SRC_FILES "CPU/*.cpp")
target_sources(rpcs3_emu PRIVATE ${CPU_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
CPU/CPUThread.cpp
CPU/CPUTranslator.cpp
)
target_link_libraries(rpcs3_emu
PUBLIC 3rdparty::llvm 3rdparty::asmjit)
# Io
file(GLOB_RECURSE IO_SRC_FILES "Io/*.cpp")
target_sources(rpcs3_emu PRIVATE ${IO_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
Io/PadHandler.cpp
)
# Memory
file(GLOB_RECURSE MEMORY_SRC_FILES "Memory/*.cpp")
target_sources(rpcs3_emu PRIVATE ${MEMORY_SRC_FILES})
target_sources(rpcs3_emu PRIVATE
Memory/vm.cpp
)
# RSX
file(GLOB RSX_SRC_FILES
"RSX/*.cpp"
"RSX/Common/*.cpp"
"RSX/Null/*.cpp"
"RSX/Overlays/*.cpp"
"RSX/Capture/*.cpp"
"RSX/GL/*.cpp")
target_sources(rpcs3_emu PRIVATE
RSX/CgBinaryFragmentProgram.cpp
RSX/CgBinaryVertexProgram.cpp
RSX/gcm_enums.cpp
RSX/gcm_printing.cpp
RSX/GSRender.cpp
RSX/RSXFIFO.cpp
RSX/rsx_methods.cpp
RSX/RSXOffload.cpp
RSX/RSXTexture.cpp
RSX/RSXThread.cpp
RSX/rsx_utils.cpp
RSX/Common/BufferUtils.cpp
RSX/Common/FragmentProgramDecompiler.cpp
RSX/Common/ProgramStateCache.cpp
RSX/Common/ShaderParam.cpp
RSX/Common/surface_store.cpp
RSX/Common/TextureUtils.cpp
RSX/Common/VertexProgramDecompiler.cpp
RSX/Null/NullGSRender.cpp
RSX/Overlays/overlay_edit_text.cpp
RSX/Overlays/overlay_font.cpp
RSX/Overlays/overlay_list_view.cpp
RSX/Overlays/overlay_message_dialog.cpp
RSX/Overlays/overlay_osk.cpp
RSX/Overlays/overlay_perf_metrics.cpp
RSX/Overlays/overlay_progress_bar.cpp
RSX/Overlays/overlay_save_dialog.cpp
RSX/Overlays/overlays.cpp
RSX/Overlays/overlay_shader_compile_notification.cpp
RSX/Overlays/overlay_trophy_notification.cpp
RSX/Capture/rsx_capture.cpp
RSX/Capture/rsx_replay.cpp
RSX/GL/GLCommonDecompiler.cpp
RSX/GL/GLFragmentProgram.cpp
RSX/GL/GLGSRender.cpp
RSX/GL/GLHelpers.cpp
RSX/GL/GLRenderTargets.cpp
RSX/GL/GLTexture.cpp
RSX/GL/GLVertexBuffers.cpp
RSX/GL/GLVertexProgram.cpp
RSX/GL/OpenGL.cpp
)
if(TARGET 3rdparty_vulkan)
file(GLOB VULKAN_SRCS "RSX/VK/*.cpp")
list(APPEND RSX_SRC_FILES ${VULKAN_SRCS})
target_sources(rpcs3_emu PRIVATE
RSX/VK/VKCommonDecompiler.cpp
RSX/VK/VKFormats.cpp
RSX/VK/VKFragmentProgram.cpp
RSX/VK/VKFramebuffer.cpp
RSX/VK/VKGSRender.cpp
RSX/VK/VKHelpers.cpp
RSX/VK/VKMemAlloc.cpp
RSX/VK/VKProgramPipeline.cpp
RSX/VK/VKRenderPass.cpp
RSX/VK/VKResolveHelper.cpp
RSX/VK/VKResourceManager.cpp
RSX/VK/VKTexture.cpp
RSX/VK/VKVertexBuffers.cpp
RSX/VK/VKVertexProgram.cpp
RSX/VK/VulkanAPI.cpp
)
endif()
if (WIN32)
file(GLOB DX12_SRCS "RSX/D3D12/*.cpp")
list(APPEND RSX_SRC_FILES ${DX12_SRCS})
target_sources(rpcs3_emu PRIVATE
RSX/D3D12/D3D12Buffer.cpp
RSX/D3D12/D3D12CommonDecompiler.cpp
RSX/D3D12/D3D12Formats.cpp
RSX/D3D12/D3D12FragmentProgramDecompiler.cpp
RSX/D3D12/D3D12GSRender.cpp
RSX/D3D12/D3D12MemoryHelpers.cpp
RSX/D3D12/D3D12Overlay.cpp
RSX/D3D12/D3D12PipelineState.cpp
RSX/D3D12/D3D12RenderTargetSets.cpp
RSX/D3D12/D3D12Texture.cpp
RSX/D3D12/D3D12Utils.cpp
RSX/D3D12/D3D12VertexProgramDecompiler.cpp
)
endif()
target_sources(rpcs3_emu PRIVATE ${RSX_SRC_FILES})
target_link_libraries(rpcs3_emu
PUBLIC
3rdparty::ffmpeg 3rdparty::cereal

View File

@ -2,8 +2,7 @@
#include "vm.h"
#include "Utilities/cond.h"
#include "Utilities/Atomic.h"
#include "util/atomic.hpp"
class notifier;

View File

@ -1,6 +0,0 @@
file(GLOB SRC_FILES "*.cpp")
add_library(rpcs3_rsx_dx12 ${SRC_FILES})
target_link_libraries(rpcs3_rsx_dx12
PRIVATE
rpcs3_stdafx 3rdparty::gsl 3rdparty::optional)

View File

@ -3,7 +3,7 @@
#include "Emu/Memory/vm_ptr.h"
#include "gcm_enums.h"
#include "gcm_printing.h"
#include "Utilities/Atomic.h"
#include "util/atomic.hpp"
struct CellGcmControl

View File

@ -1,6 +0,0 @@
file(GLOB SRC_FILES "*.cpp")
add_library(rpcs3_rsx_gl ${SRC_FILES})
target_link_libraries(rpcs3_rsx_gl
PRIVATE
rpcs3_stdafx 3rdparty::opengl 3rdparty::gsl 3rdparty::optional 3rdparty::cereal)

View File

@ -1,7 +1,7 @@
#pragma once
#include <Utilities/types.h>
#include <Utilities/Atomic.h>
#include "Utilities/types.h"
#include "util/atomic.hpp"
#include "rsx_utils.h"
#include "Emu/Cell/lv2/sys_rsx.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include "VFS.h"
#include "Utilities/Atomic.h"
#include "util/atomic.hpp"
#include "Utilities/Config.h"
#include <functional>
#include <memory>

View File

@ -69,6 +69,9 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="util\atomic.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\Utilities\bin_patch.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@ -368,7 +371,7 @@
<ItemGroup>
<ClInclude Include="..\3rdparty\stblib\stb_image.h" />
<ClInclude Include="..\Utilities\address_range.h" />
<ClInclude Include="..\Utilities\Atomic.h" />
<ClInclude Include="util\atomic.hpp" />
<ClInclude Include="..\Utilities\AtomicPtr.h" />
<ClInclude Include="..\Utilities\BEType.h" />
<ClInclude Include="..\Utilities\bin_patch.h" />

View File

@ -1012,7 +1012,10 @@
<ClInclude Include="Emu\Cell\SPUAnalyser.h">
<Filter>Emu\Cell</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\Atomic.h">
<ClInclude Include="util\atomic.hpp">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="util\atomic.cpp">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\Common\TextureUtils.h">

View File

@ -1,5 +1,59 @@
file(GLOB SRC_FILES "*.cpp")
file(GLOB UI_FILES "*.ui")
set(SRC_FILES
about_dialog.cpp
auto_pause_settings_dialog.cpp
breakpoint_handler.cpp
breakpoint_list.cpp
cg_disasm_window.cpp
custom_dialog.cpp
debugger_frame.cpp
debugger_list.cpp
_discord_utils.cpp
emu_settings.cpp
find_dialog.cpp
game_compatibility.cpp
game_list_frame.cpp
game_list_grid.cpp
game_list_grid_delegate.cpp
gl_gs_frame.cpp
gs_frame.cpp
gui_settings.cpp
input_dialog.cpp
instruction_editor_dialog.cpp
kernel_explorer.cpp
log_frame.cpp
main_window.cpp
memory_string_searcher.cpp
memory_viewer_panel.cpp
msg_dialog_frame.cpp
osk_dialog_frame.cpp
pad_settings_dialog.cpp
progress_dialog.cpp
qt_utils.cpp
register_editor_dialog.cpp
rsx_debugger.cpp
save_data_dialog.cpp
save_data_info_dialog.cpp
save_data_list_dialog.cpp
save_manager_dialog.cpp
settings_dialog.cpp
syntax_highlighter.cpp
trophy_manager_dialog.cpp
trophy_notification_frame.cpp
trophy_notification_helper.cpp
user_account.cpp
user_manager_dialog.cpp
vfs_dialog.cpp
vfs_dialog_tab.cpp
welcome_dialog.cpp
)
set(UI_FILES
about_dialog.ui
main_window.ui
pad_settings_dialog.ui
settings_dialog.ui
welcome_dialog.ui
)
set(RES_FILES "../resources.qrc")
@ -25,4 +79,3 @@ target_link_libraries(rpcs3_ui
3rdparty::discord-rpc
3rdparty::hidapi
3rdparty::libusb)

View File

@ -26,7 +26,7 @@ namespace std { inline namespace literals { inline namespace chrono_literals {}}
#include "Utilities/types.h"
#include "Utilities/BEType.h"
#include "Utilities/Atomic.h"
#include "util/atomic.hpp"
#include "Utilities/StrFmt.h"
#include "Utilities/File.h"
#include "Utilities/Log.h"

225
rpcs3/util/atomic.cpp Normal file
View File

@ -0,0 +1,225 @@
#include "atomic.hpp"
#include "Utilities/sync.h"
// Should be at least 65536, currently 1048576.
static constexpr std::uintptr_t s_hashtable_size = 1u << 20;
// ^2 means adjacent addresses within the same aligned u32 word will always collide.
static constexpr uint s_ignored_lsbits = 2;
// TODO: it's probably better to implement more effective futex emulation for OSX/BSD here.
static atomic_t<s64> s_hashtable[s_hashtable_size];
static inline bool ptr_cmp(const void* data, std::size_t size, u64 old_value)
{
switch (size)
{
case 1: return reinterpret_cast<const atomic_t<u8>*>(data)->load() == old_value;
case 2: return reinterpret_cast<const atomic_t<u16>*>(data)->load() == old_value;
case 4: return reinterpret_cast<const atomic_t<u32>*>(data)->load() == old_value;
case 8: return reinterpret_cast<const atomic_t<u64>*>(data)->load() == old_value;
}
return false;
}
void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value)
{
#ifdef _WIN32
if (OptWaitOnAddress)
{
OptWaitOnAddress(const_cast<volatile void*>(data), &old_value, size, INFINITE);
return;
}
#endif
const std::intptr_t iptr = reinterpret_cast<std::intptr_t>(data);
atomic_t<s64>& entry = s_hashtable[(iptr >> s_ignored_lsbits) % s_hashtable_size];
u32 new_value = 0;
const auto [_, ok] = entry.fetch_op([&](s64& value)
{
if ((value & 0xffff) == 0xffff || (value & 0xffff0000) == s64{0xffff0000})
{
// Return immediately on waiter overflow or signal overflow
return false;
}
if (!value || (value >> 32) == (iptr >> 16))
{
// Store 32 highest bits of signed 48-bit pointer
value |= (iptr >> 16) * 0x1'0000'0000;
}
else
{
// Zero highest bits (collision)
value &= 0xffffffff;
}
new_value = static_cast<u32>(++value);
return true;
});
if (!ok)
{
return;
}
if (ptr_cmp(data, size, old_value))
{
#ifdef _WIN32
NtWaitForKeyedEvent(nullptr, &entry, false, nullptr);
return;
#else
futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAIT_PRIVATE, new_value, nullptr);
#endif
}
while (true)
{
// Try to decrement
const auto [prev, ok] = entry.fetch_op([&](s64& value)
{
if (value & 0xffff)
{
value--;
if ((value & 0xffff) == 0)
{
// Reset on last waiter
value = 0;
}
return true;
}
return false;
});
if (ok)
{
break;
}
#ifdef _WIN32
static LARGE_INTEGER instant{};
if (!NtWaitForKeyedEvent(nullptr, &entry, false, &instant))
{
break;
}
#else
// Unreachable
std::terminate();
#endif
}
}
void atomic_storage_futex::notify_one(const void* data)
{
#ifdef _WIN32
if (OptWaitOnAddress)
{
OptWakeByAddressSingle(const_cast<void*>(data));
return;
}
#endif
const std::intptr_t iptr = reinterpret_cast<std::intptr_t>(data);
atomic_t<s64>& entry = s_hashtable[(iptr >> s_ignored_lsbits) % s_hashtable_size];
const auto [prev, ok] = entry.fetch_op([&](s64& value)
{
if (value & 0xffff && (value >> 32) == (iptr >> 16))
{
#ifdef _WIN32
// Try to decrement if no collision
value--;
if ((value & 0xffff) == 0)
{
// Reset on last waiter
value = 0;
}
#else
if ((value & 0xffff0000) == s64{0xffff0000})
{
// Signal overflow, do nothing
return false;
}
value += 0x10000;
#endif
return true;
}
return false;
});
if (ok)
{
#ifdef _WIN32
NtReleaseKeyedEvent(nullptr, &entry, false, nullptr);
return;
#else
futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 1);
return;
#endif
}
if (prev)
{
// Collision, notify everything
notify_all(data);
}
}
void atomic_storage_futex::notify_all(const void* data)
{
#ifdef _WIN32
if (OptWaitOnAddress)
{
OptWakeByAddressAll(const_cast<void*>(data));
return;
}
#endif
const std::intptr_t iptr = reinterpret_cast<std::intptr_t>(data);
atomic_t<s64>& entry = s_hashtable[(iptr >> s_ignored_lsbits) % s_hashtable_size];
// Consume everything
#ifdef _WIN32
for (uint count = static_cast<u16>(entry.exchange(0)); count; count--)
{
NtReleaseKeyedEvent(nullptr, &entry, false, nullptr);
}
#else
const auto [_, ok] = entry.fetch_op([&](s64& value)
{
if (value & 0xffff)
{
if ((value & 0xffff0000) == s64{0xffff0000})
{
// Signal overflow, do nothing
return false;
}
value += 0x10000;
return true;
}
return false;
});
if (ok)
{
futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 0x7fffffff);
}
#endif
}

View File

@ -1,12 +1,24 @@
#pragma once
#include "types.h"
#include "Utilities/types.h"
#include <functional>
#ifdef _MSC_VER
#include <atomic>
#endif
// Helper for waitable atomics (as in C++20 std::atomic)
struct atomic_storage_futex
{
private:
template <typename T>
friend class atomic_t;
static void wait(const void* data, std::size_t size, u64 old_value);
static void notify_one(const void* data);
static void notify_all(const void* data);
};
// Helper class, provides access to compiler-specific atomic intrinsics
template <typename T, std::size_t Size = sizeof(T)>
struct atomic_storage
@ -1173,4 +1185,19 @@ public:
{
return atomic_storage<type>::btr(m_data, bit);
}
void wait(type old_value) const noexcept
{
atomic_storage_futex::wait(&m_data, sizeof(T), std::bit_cast<get_uint_t<sizeof(T)>>(old_value));
}
void notify_one() noexcept
{
atomic_storage_futex::notify_one(&m_data);
}
void notify_all() noexcept
{
atomic_storage_futex::notify_all(&m_data);
}
};