Compare commits

..

120 Commits

Author SHA1 Message Date
ameerj 0cf78a34ba core: Reorder perf_stats destruction order on Shutdown
Avoids the gpu_core using perf_stats after it's been freed.
2021-11-04 20:19:58 -04:00
bunnei f178a8ef0c Merge pull request #7282 from ameerj/core-includes
core: Reduce unused header includes
2021-11-04 13:56:10 -07:00
bunnei b92c4abc96 Merge pull request #7285 from german77/acc
service/acc: Rename Unknown160 to InitializeApplicationInfoV2
2021-11-04 10:45:53 -07:00
german77 bee6b71553 service/acc: Rename Unknown160 to InitializeApplicationInfoV2 2021-11-04 10:10:58 -06:00
Fernando S 35aa153d6c Merge pull request #7283 from Morph1984/stub-160
service: acc: Stub acc:u0 '160'
2021-11-04 16:25:32 +01:00
Morph f2988ecabc service: acc: Stub acc:u0 '160'
- Used by Animal Crossing: New Horizons v2.0.0

Since the name is currently unknown, '160' is used as a placeholder.
2021-11-04 02:57:13 -04:00
ameerj b275f2e475 core: Fix transitive include build errors 2021-11-03 21:42:58 -04:00
ameerj 7c4b6aab2e core: Remove unused includes 2021-11-03 21:42:57 -04:00
Mai M 863e2e2b4f Merge pull request #7278 from Morph1984/svc-num-handles
svc: Correct WaitSynchronization num_handles param type
2021-11-03 06:59:07 -04:00
Morph b871388a31 svc: Correct WaitSynchronization num_handles param type
num_handles is a s32
2021-11-02 22:31:04 -04:00
bunnei 7ce29ea74e Merge pull request #7262 from FernandoS27/Buffalo-buffalo-Buffalo-buffalo-buffalo
ShaderCache: Order Phi Arguments from farthest away to nearest.
2021-11-02 16:34:03 -07:00
Mai M 43ba9db890 Merge pull request #7265 from Morph1984/gl-rasterizer-unused-include
gl_rasterizer: Remove unused includes
2021-11-02 18:43:31 -04:00
Mai M 3d1f2bb3aa Merge pull request #7268 from Morph1984/expected-resultval
common, result: Implement a subset of std::expected and use it in ResultVal
2021-11-02 18:41:57 -04:00
Morph cb09ea0f01 general: Remove MakeResult helpers
This is made obsolete by the presence of implicit constructors.
2021-11-02 17:23:19 -04:00
Morph 98b351758c hle/result: Amend ResultVal documentation
This amends the documentation slightly to reflect the updated interface.
2021-11-02 15:20:36 -04:00
Morph 52e52924bb hle/result: Reimplement ResultVal using Common::Expected
Common::Expected effectively provides the same functions as ResultVal, so we can implement it with this.
This can be replaced with std::expected with minimal effort should it be standardized in the C++ Standard Template Library.
2021-11-02 15:20:35 -04:00
Morph a41e9e93dd common: Implement a subset of P0323 (std::expected)
This implementation is based on and is a subset of the proposed implementation of std::expected
https://github.com/TartanLlama/expected/blob/master/include/tl/expected.hpp
2021-11-02 15:20:35 -04:00
bunnei b118fa8698 Merge pull request #7227 from vonchenplus/fix_memory_leak_v2
Fix memory leak v2
2021-11-01 20:11:30 -07:00
Fernando Sahmkow 2d4bbd83e6 Shader Cahe: Fix Phi Nodes on GLASM. 2021-11-02 00:59:25 +01:00
Fernando Sahmkow 194579bc4f ShaderCache: Fix Phi Nodes Type on OGL. 2021-11-01 22:26:17 +01:00
Morph d607ceacf4 gl_rasterizer: Remove unused includes
This removes unused includes, especially the core includes which were causing this file to be recompiled every time files included by those headers are modified.
2021-10-31 23:57:51 -04:00
Mai M f808a30f94 Merge pull request #7264 from zhaobot/tx-update-20211101021628
Update translations (2021-11-01)
2021-10-31 23:57:26 -04:00
The yuzu Community 02178137c9 Update translations (2021-11-01) 2021-11-01 02:16:50 +00:00
Fernando Sahmkow c50ad56bf5 ShaderCache: Order Phi Arguments from farthest away to nearest. 2021-10-31 19:34:15 +01:00
bunnei 99ba26460d Merge pull request #7246 from german77/userimage
profile_manager: Resize any image bigger than 256p
2021-10-31 04:07:34 -07:00
Fernando S 7aa0d97eed Merge pull request #7201 from ameerj/spirv-depth-sampling
emit_spirv_image: Fix depth image implicit lod sample in non-fragment stages
2021-10-30 16:45:58 +02:00
bunnei a3a353edf2 Merge pull request #6702 from lat9nq/disable-screensaver
yuzu_cmd, yuzu qt: Use SDL to disable the screen saver
2021-10-30 00:29:05 -07:00
bunnei 7c2c72a6d6 Merge pull request #7244 from Morph1984/application-lang-pt-br
file_sys/ns: Add Brazilian Portuguese to the list of ApplicationLanguage
2021-10-29 22:32:38 -07:00
lat9nq 604b6d1210 yuzu qt: Disable the screensaver with SDL2
Disables the screen saver when a game boots using SDL2 so that it works
on any supported platform.
2021-10-30 01:23:52 -04:00
bunnei 92159b210e Merge pull request #7240 from Morph1984/resultval-remove-cv
hle/result: Remove cv-qualifiers from Arg in MakeResult
2021-10-29 21:35:32 -07:00
german77 f503dbf071 profile_manager: Resize any image bigger than 256p 2021-10-29 17:56:51 -05:00
bunnei c1b199bd21 Merge pull request #7241 from Morph1984/resultval-move-assignment
hle/result: Add move assignment operator in ResultVal
2021-10-29 09:14:32 -07:00
bunnei 60e79d50f8 Merge pull request #7243 from lat9nq/nvdrv-warn
gl_device: Force GLASM on NVIDIA drivers 495-496
2021-10-28 17:57:53 -07:00
Mai M 06d097a18e Merge pull request #7245 from Morph1984/compile-opt-desc
CMakeLists: Document the /GT compile option
2021-10-28 20:45:50 -04:00
Morph 3f8d74dec1 CMakeLists: Document the /GT compile option 2021-10-28 20:43:46 -04:00
Morph cd49907248 Merge pull request #7007 from FernandoS27/intel-options
Build System: Build with JCC Erratum Mitigation
2021-10-28 20:40:13 -04:00
Morph baf599c1d3 file_sys: control_metadata: Add BrazilianPortuguese 2021-10-28 20:05:26 -04:00
Morph e4052a1dab ns: language: Add BrazilianPortuguese to ApplicationLanguage
It seems that Nintendo finally filled that last empty spot in ApplicationLanguage for a total of 16 supported languages.
2021-10-28 20:05:05 -04:00
Ameer J fac2e073a1 Merge pull request #7223 from Moonlacer/geometry_property_removal
per_game_ui: Geometry Property Removal and Minor Rewording to the Per Game UI
2021-10-28 19:39:00 -04:00
lat9nq 61121d1b22 gl_device: Force GLASM on NVIDIA drivers 495-496
GLSL shaders currently do not render correctly on the recent NVIDIA
drivers. This adds a check that forces assembly shaders for these
drivers since they seem unaffected and adds a warning informing of the
decision.

Developers can disable the check by enabling graphics debugging.
2021-10-28 19:38:49 -04:00
Morph 1b5c37fa29 hle/result: Declare copy/move constructor/assignment as noexcept
While we're at it, we can also declare these copy/move constructor/assignment as noexcept.
2021-10-28 04:00:21 -04:00
Morph 189927c237 hle/result: Add move assignment operator in ResultVal
ResultVal was missing a move assignment operator, add it.
2021-10-28 03:52:21 -04:00
Morph 1ff9ad4e7c hle/result: Remove cv-qualifiers from Arg in MakeResult
This removes the const qualification for types when MakeResult(arg) is used in a const member function, allowing for automatic deduction and removing the need to manually specify the non-const type as the template argument.
2021-10-28 03:07:18 -04:00
Ameer J 40c8a8c627 Merge pull request #7186 from MightyCreak/fix-crash-configure-window
ui: fix crash when closing configure window
2021-10-26 22:15:45 -04:00
Feng Chen dd29285e35 Fix dangling kernel objects when exiting 2021-10-27 09:06:30 +08:00
Feng Chen 052017e189 Revert PR7009 2021-10-27 09:06:30 +08:00
Feng Chen a8b0104923 Fix memory leak 2021-10-27 09:06:22 +08:00
Moonlacer 1665e2d2a6 Geometry property removal and rewording 2021-10-25 17:39:36 -05:00
Morph 63ed7d9af7 Merge pull request #7193 from FernandoS27/idle
SVC: Implement svcInfo:IdleTickCount
2021-10-25 09:17:49 -04:00
Ameer J 3c8c17be4d Merge pull request #7218 from bylaws/aswdqdsam
Fixup channel submit IOCTL syncpoint parameters
2021-10-24 19:35:00 -04:00
Ameer J aed5878dd3 Merge pull request #7222 from FernandoS27/fix-indixed-textures-again
TexturePass: Fix clamping  of images as this allowed negative indices.
2021-10-24 15:16:31 -04:00
Fernando Sahmkow e5291e2031 TexturePass: Fix clamping of images as this allowed negative indices. 2021-10-24 20:46:36 +02:00
Mai M 3be87bed8d Merge pull request #7221 from astrelsky/stepfix
Fixed ARM_Dynamic_64 Step
2021-10-24 14:43:40 -04:00
Andrew Strelsky 31b9797296 Fixed ARM_Dynamic_64 Step 2021-10-24 11:16:32 -04:00
Fernando S 5299554bb0 Merge pull request #7206 from vonchenplus/fix_vulkan_viewport_issue
Vulkan Rasterizer: Fix viewport issue
2021-10-24 01:53:04 +02:00
Billy Laws 2dbef58eeb Fixup channel submit IOCTL syncpoint parameters
The current arguments worked by happenstance as games only ever submit
one syncpoint and request one fence back, if a game were to do something
other than this then the arguments would've been parsed entirely wrong.
2021-10-24 00:01:35 +01:00
Ameer J 494e34af6a Merge pull request #7070 from FernandoS27/want-you-bad
Vulkan Rasterizer: Correct DepthBias/PolygonOffset on Vulkan.
2021-10-23 18:02:23 -04:00
Fernando Sahmkow ad8afaf1ef Vulran Rasterizer: address feedback. 2021-10-23 23:46:29 +02:00
Narr the Reg 2686bf6734 Merge pull request #7217 from yuzu-emu/revert-6515-gc_thread_safe
Revert "input_common: Fix data race on GC implementation"
2021-10-23 16:41:09 -05:00
Fernando S 33e92c15eb Revert "input_common: Fix data race on GC implementation" 2021-10-23 23:32:16 +02:00
Fernando S 7461196839 Merge pull request #6515 from german77/gc_thread_safe
input_common: Fix data race on GC implementation
2021-10-23 23:28:22 +02:00
Feng Chen b769bea61b Fix vulkan viewport issue 2021-10-22 22:56:31 +08:00
bunnei b65314dc21 Merge pull request #7207 from ameerj/vs-2022
cmake: Update conan to support Visual Studio 2022
2021-10-20 15:17:50 -07:00
ameerj 1841f63a40 common/alignment: Fix VS2022 compilation
VS2022 seems to introduce an optimization when moving vectors to check for equality of the element values. AlignmentAllocator needed to overload the equality operator to fix compilation of its usage in vector moving.
2021-10-20 01:22:00 -04:00
ameerj b01aa721ff input_common: Fix VS2022 compilation errors 2021-10-20 01:21:59 -04:00
ameerj f190547bbb cmake: Update conan for VS2022 support 2021-10-19 20:30:27 -04:00
bunnei c82318c9cb Merge pull request #7197 from Moonlacer/tas_help_link
tas_ui: Add a Help Link to the TAS Page on the yuzu Website, Along with Minor Grammar Changes
2021-10-19 15:49:30 -07:00
bunnei c871320760 Merge pull request #7198 from ameerj/settings-chrono
settings: Remove std::chrono usage
2021-10-19 09:55:50 -07:00
ameerj 06894b0711 emit_spirv_image: Fix depth image implicit lod sample in compute
Ensures all drivers behave the same way in this case.
2021-10-17 17:09:11 -04:00
bunnei 4e81b799f1 Merge pull request #7173 from Morph1984/invalidate-unmap
KPageTable: Perform ranged invalidation when unmapping code memory
2021-10-17 03:25:26 -07:00
ameerj ef811c6425 settings: Remove std::chrono usage
Alleviates the dependency on chrono for all files that include settings.h
2021-10-17 00:37:49 -04:00
Moonlacer abe6d39b1a add_link
remove_accident

fix_whoopsie
2021-10-16 21:48:49 -05:00
Ameer J 3791c7ca82 Merge pull request #7077 from FernandoS27/face-down
A series of fixes to queries and indexed samplers.
2021-10-16 21:41:54 -04:00
Fernando Sahmkow 3f4444b552 Shader Compiler: avoid overflowed indices on indixed samplers. 2021-10-17 03:38:09 +02:00
Ameer J 5b735a4c9d Merge pull request #7127 from FernandoS27/i-saw-a-wabbit
A few fixes on Vulkan and Rasterizer Caching
2021-10-16 21:37:43 -04:00
Mai M 28d343d288 Merge pull request #7195 from MightyCreak/fix-warning-typo
main: fix typo in warning message
2021-10-16 19:50:41 -04:00
Fernando Sahmkow da6673e79a SVC: Implement svcInfo:IdleTickCount
Used by the Witcher 3
2021-10-16 20:33:44 +02:00
Romain Failliot 992f325662 main: fix typo in warning message 2021-10-16 12:53:06 -04:00
Mai M 622bc478e6 Merge pull request #7192 from zhaobot/tx-update-20211016064801
Update translations (2021-10-16)
2021-10-16 09:22:40 -04:00
The yuzu Community 67189d747c Update translations (2021-10-16) 2021-10-16 06:48:21 +00:00
Fernando S 8b996015a8 Merge pull request #7190 from Morph1984/missing-ui-main
main: Add missing make_unique for ui
2021-10-16 01:48:10 +02:00
Morph d4c79a0404 main: Add missing make_unique for ui 2021-10-15 19:36:52 -04:00
bunnei aef3ae1cb9 Merge pull request #7187 from FernandoS27/boy-i-say-boy
NVHost_Ctrl: Force wait if the gpu falls behind too long.
2021-10-15 16:14:32 -07:00
Morph f40b425cd7 Merge pull request #7189 from FearlessTobi/translation-ci
.ci/transifex: Mark docker.sh as executable
2021-10-15 19:07:06 -04:00
FearlessTobi 20b20a1086 .ci/transifex: Mark docker.sh as executable 2021-10-16 00:59:18 +02:00
Morph 41b4047536 Merge pull request #7188 from Morph1984/web-applet-include
qt_web_browser: Add missing QApplication include
2021-10-15 18:52:22 -04:00
Feng Chen de81571289 service/vi: Stub IHOSBinderDriver::TransactParcel GetBufferHistory (#7184) 2021-10-15 18:50:45 -04:00
Morph 2b622411fd qt_web_browser: Add missing QApplication include 2021-10-15 18:48:50 -04:00
Fernando Sahmkow 53cf91d151 NvHost/Core: Address Feedback. 2021-10-16 00:23:27 +02:00
FernandoS27 198c6ad0d7 Suspend temporally 2021-10-16 00:23:23 +02:00
FernandoS27 7dca0bc11d NVHost_Ctrl: Force wait if the gpu falls behind too long. 2021-10-16 00:22:01 +02:00
Mai M dc385b7392 Merge pull request #7182 from Morph1984/system
yuzu: Remove all remaining global system instances
2021-10-15 17:57:58 -04:00
Romain Failliot 427ce8dcef ui: fix crash when closing configure window
This crash happens 100% of the time (on Linux at least), you just need
to open the configure window and click OK.

It seems to happen when the tabs are destroyed and once all the tabs are
destroyed, a final signal is sent with `index == -1`. So `debug_tab_tab`
doesn't exist anymore when this happens, so the crash.
2021-10-15 17:43:30 -04:00
Morph 5c6ca597c5 bootmanager: Forward declare System and SystemResultStatus 2021-10-15 17:35:34 -04:00
Morph f0dc07dbac yuzu: Construct system in GMainWindow 2021-10-15 17:35:33 -04:00
Morph 17763a44d5 core: Move ResultStatus outside of System
Allows it to be a forward declaration in other header files.
2021-10-15 17:34:49 -04:00
Morph 218ebc1fe8 yuzu_cmd: Remove remaining static system instances 2021-10-15 17:34:48 -04:00
Morph b6719094e6 core: Remove static system instance 2021-10-15 17:34:48 -04:00
Mai M 2a5014b193 Merge pull request #7183 from FearlessTobi/translation-ci
.ci: Use Github Actions to update translation source files
2021-10-15 17:06:01 -04:00
Mai M 764369f4c7 Merge pull request #7172 from Morph1984/out-of-bounds
string_util: Prevent out of bounds access in u16string_view buffer
2021-10-15 17:04:44 -04:00
Mai M d5c4af2d5b Merge pull request #7174 from MightyCreak/hide-cursor-by-default
Check "Hide mouse on inactivity" by default
2021-10-15 17:03:10 -04:00
Mai M 5b7b7276d5 Merge pull request #7185 from Morph1984/make_unique_ui
yuzu: Use make_unique instead of operator new for constructing ui
2021-10-15 16:58:45 -04:00
Romain Failliot ecef109162 Hide mouse cursor by default 2021-10-15 16:01:20 -04:00
Creak bad122b195 main: Slightly refactor NCA entry installation in InstallNCA (#7181)
* main: Slightly refactor NCA entry installation in InstallNCA

Co-authored-by: Ameer J <52414509+ameerj@users.noreply.github.com>
2021-10-15 15:57:25 -04:00
Morph 86908d569e main: Use std::unique_ptr for ui 2021-10-15 15:35:59 -04:00
Morph ab441fb009 configuration: Use std::make_unique instead of operator new for ui 2021-10-15 15:26:32 -04:00
lat9nq 851fe91b69 config: Read network_interface
Let's yuzu_cmd use a network interface. Also adds it to the default ini.
2021-10-15 12:14:09 -04:00
FearlessTobi 07b82427ab .ci: Use Github Actions to update translation source files 2021-10-15 15:12:14 +02:00
Moonlacer c68ce25a14 settings_ui: Better NVDEC Description For Each Video Rendering Option (#7165)
* better_description

* Revert "better_description"

This reverts commit 3a152a6ba6.

* better_nvdec_wording

* best_performance

* update_word_stuff

* another_update
2021-10-14 18:01:12 -07:00
Morph 0d6057b2fa string_util: Make use of std::string_view and add bounds checking
Makes use of std::string_view in StringFromFixedZeroTerminatedBuffer and add bounds checking
2021-10-14 14:09:34 -04:00
Morph 3ffff78a27 string_util: Prevent out of bounds access in u16string_view buffer 2021-10-14 14:09:34 -04:00
Morph 50384e2619 KPageTable: Perform ranged invalidation when unmapping code memory
Co-Authored-By: Fernando S. <1731197+FernandoS27@users.noreply.github.com>
2021-10-13 14:27:11 -04:00
Fernando Sahmkow 0498669b4b Vulkan: Fix failing barrier on refresh. 2021-10-04 20:56:15 +02:00
FernandoS27 bb8bf740e9 RasterizerInterface: Correct size of CPU addresses to cache. 2021-10-04 20:47:31 +02:00
FernandoS27 7f4de3466a Vulkan: Fix the master Semaphore 2021-10-04 20:46:58 +02:00
Fernando Sahmkow d702b393a4 Vulkan Query Cache: make sure to wait for the query result. 2021-09-24 01:14:17 +02:00
Fernando Sahmkow 8fdb51ab46 QueryCache: Flush queries in order of running. 2021-09-24 01:13:42 +02:00
Fernando Sahmkow 60a3980561 Vulkan Rasterizer: Correct DepthBias/PolygonOffset on Vulkan. 2021-09-23 03:49:10 +02:00
Fernando Sahmkow 13471ddf86 Build System: Build with JCC Erratum Mitigation 2021-09-15 21:32:44 +02:00
Rodrigo Locatti d4cab35533 input_common: Fix data race on GC implementation 2021-08-07 16:46:26 -05:00
236 changed files with 77516 additions and 17653 deletions
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash -e
# Setup RC file for tx
cat << EOF > ~/.transifexrc
[https://www.transifex.com]
hostname = https://www.transifex.com
username = api
password = $TRANSIFEX_API_TOKEN
EOF
set -x
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
cmake --version
gcc -v
tx --version
mkdir build && cd build
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF
make translation
cd ..
cd dist/languages
tx push -s
+23
View File
@@ -0,0 +1,23 @@
name: yuzu-ci
on:
push:
branches: [ master ]
tags: [ "*" ]
pull_request:
branches: [ master ]
jobs:
transifex:
runs-on: ubuntu-latest
container: yuzuemu/build-environments:linux-transifex
if: ${{ github.repository == 'yuzu-emu/yuzu' && !github.head_ref }}
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
fetch-depth: 0
- name: Update Translation
run: ./.ci/scripts/transifex/docker.sh
env:
TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
+3 -2
View File
@@ -411,12 +411,13 @@ if (CONAN_REQUIRED_LIBS)
# Download conan.cmake automatically, you can also just copy the conan.cmake file
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.15/conan.cmake"
# TODO: Use a tagged release. The latest tagged release does not support VS2022 as of this writing.
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/43e385830ee35377dbd2dcbe8d5a9e750301ea00/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake")
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_check(VERSION 1.24.0 REQUIRED)
conan_check(VERSION 1.41.0 REQUIRED)
# Manually add iconv to fix a dep conflict between qt and sdl2
# We don't need to add it through find_package or anything since the other two can find it just fine
+5826
View File
File diff suppressed because it is too large Load Diff
+5840
View File
File diff suppressed because it is too large Load Diff
+5821
View File
File diff suppressed because it is too large Load Diff
+2392 -1306
View File
File diff suppressed because it is too large Load Diff
+2456 -1355
View File
File diff suppressed because it is too large Load Diff
+2836 -1719
View File
File diff suppressed because it is too large Load Diff
+2668 -1553
View File
File diff suppressed because it is too large Load Diff
+2578 -1499
View File
File diff suppressed because it is too large Load Diff
+5848
View File
File diff suppressed because it is too large Load Diff
+5795
View File
File diff suppressed because it is too large Load Diff
+2711 -1616
View File
File diff suppressed because it is too large Load Diff
+2621 -1496
View File
File diff suppressed because it is too large Load Diff
+2443 -1347
View File
File diff suppressed because it is too large Load Diff
+2817 -1724
View File
File diff suppressed because it is too large Load Diff
+2914 -1769
View File
File diff suppressed because it is too large Load Diff
+5822
View File
File diff suppressed because it is too large Load Diff
+5852
View File
File diff suppressed because it is too large Load Diff
+2453 -1353
View File
File diff suppressed because it is too large Load Diff
+5839
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -32,6 +32,7 @@ if (MSVC)
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
# /Zc:inline - Let codegen omit inline functions in object files
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
# /GT - Supports fiber safety for data allocated using static thread-local storage
add_compile_options(
/MP
/Zi
@@ -44,6 +45,7 @@ if (MSVC)
/Zc:externConstexpr
/Zc:inline
/Zc:throwingNew
/GT
# External headers diagnostics
/experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
@@ -69,6 +71,10 @@ if (MSVC)
/we5038 # data member 'member1' will be initialized after data member 'member2'
)
if (ARCHITECTURE_x86_64)
add_compile_options(/QIntel-jcc-erratum)
endif()
# /GS- - No stack buffer overflow checks
add_compile_options("$<$<CONFIG:Release>:/GS->")
+1
View File
@@ -55,6 +55,7 @@ add_library(common STATIC
dynamic_library.h
error.cpp
error.h
expected.h
fiber.cpp
fiber.h
fs/file.cpp
+6 -1
View File
@@ -64,7 +64,7 @@ public:
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
using is_always_equal = std::true_type;
using is_always_equal = std::false_type;
constexpr AlignmentAllocator() noexcept = default;
@@ -83,6 +83,11 @@ public:
struct rebind {
using other = AlignmentAllocator<T2, Align>;
};
template <typename T2, size_t Align2>
constexpr bool operator==(const AlignmentAllocator<T2, Align2>&) const noexcept {
return std::is_same_v<T, T2> && Align == Align2;
}
};
} // namespace Common
+987
View File
@@ -0,0 +1,987 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This is based on the proposed implementation of std::expected (P0323)
// https://github.com/TartanLlama/expected/blob/master/include/tl/expected.hpp
#pragma once
#include <type_traits>
#include <utility>
namespace Common {
template <typename T, typename E>
class Expected;
template <typename E>
class Unexpected {
public:
Unexpected() = delete;
constexpr explicit Unexpected(const E& e) : m_val{e} {}
constexpr explicit Unexpected(E&& e) : m_val{std::move(e)} {}
constexpr E& value() & {
return m_val;
}
constexpr const E& value() const& {
return m_val;
}
constexpr E&& value() && {
return std::move(m_val);
}
constexpr const E&& value() const&& {
return std::move(m_val);
}
private:
E m_val;
};
template <typename E>
constexpr auto operator<=>(const Unexpected<E>& lhs, const Unexpected<E>& rhs) {
return lhs.value() <=> rhs.value();
}
struct unexpect_t {
constexpr explicit unexpect_t() = default;
};
namespace detail {
struct no_init_t {
constexpr explicit no_init_t() = default;
};
/**
* This specialization is for when T is not trivially destructible,
* so the destructor must be called on destruction of `expected'
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
constexpr expected_storage_base(no_init_t) : m_has_val{false} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr expected_storage_base(std::in_place_t, Args&&... args)
: m_val{std::forward<Args>(args)...}, m_has_val{true} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr expected_storage_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: m_val{il, std::forward<Args>(args)...}, m_has_val{true} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit expected_storage_base(unexpect_t, Args&&... args)
: m_unexpect{std::forward<Args>(args)...}, m_has_val{false} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit expected_storage_base(unexpect_t, std::initializer_list<U> il,
Args&&... args)
: m_unexpect{il, std::forward<Args>(args)...}, m_has_val{false} {}
~expected_storage_base() {
if (m_has_val) {
m_val.~T();
}
}
union {
T m_val;
Unexpected<E> m_unexpect;
};
bool m_has_val;
};
/**
* This specialization is for when T is trivially destructible,
* so the destructor of `expected` can be trivial
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base<T, E, true> {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
constexpr expected_storage_base(no_init_t) : m_has_val{false} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr expected_storage_base(std::in_place_t, Args&&... args)
: m_val{std::forward<Args>(args)...}, m_has_val{true} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr expected_storage_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: m_val{il, std::forward<Args>(args)...}, m_has_val{true} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit expected_storage_base(unexpect_t, Args&&... args)
: m_unexpect{std::forward<Args>(args)...}, m_has_val{false} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit expected_storage_base(unexpect_t, std::initializer_list<U> il,
Args&&... args)
: m_unexpect{il, std::forward<Args>(args)...}, m_has_val{false} {}
~expected_storage_base() = default;
union {
T m_val;
Unexpected<E> m_unexpect;
};
bool m_has_val;
};
template <typename T, typename E>
struct expected_operations_base : expected_storage_base<T, E> {
using expected_storage_base<T, E>::expected_storage_base;
template <typename... Args>
void construct(Args&&... args) noexcept {
new (std::addressof(this->m_val)) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
template <typename Rhs>
void construct_with(Rhs&& rhs) noexcept {
new (std::addressof(this->m_val)) T{std::forward<Rhs>(rhs).get()};
this->m_has_val = true;
}
template <typename... Args>
void construct_error(Args&&... args) noexcept {
new (std::addressof(this->m_unexpect)) Unexpected<E>{std::forward<Args>(args)...};
this->m_has_val = false;
}
void assign(const expected_operations_base& rhs) noexcept {
if (!this->m_has_val && rhs.m_has_val) {
geterr().~Unexpected<E>();
construct(rhs.get());
} else {
assign_common(rhs);
}
}
void assign(expected_operations_base&& rhs) noexcept {
if (!this->m_has_val && rhs.m_has_val) {
geterr().~Unexpected<E>();
construct(std::move(rhs).get());
} else {
assign_common(rhs);
}
}
template <typename Rhs>
void assign_common(Rhs&& rhs) {
if (this->m_has_val) {
if (rhs.m_has_val) {
get() = std::forward<Rhs>(rhs).get();
} else {
destroy_val();
construct_error(std::forward<Rhs>(rhs).geterr());
}
} else {
if (!rhs.m_has_val) {
geterr() = std::forward<Rhs>(rhs).geterr();
}
}
}
bool has_value() const {
return this->m_has_val;
}
constexpr T& get() & {
return this->m_val;
}
constexpr const T& get() const& {
return this->m_val;
}
constexpr T&& get() && {
return std::move(this->m_val);
}
constexpr const T&& get() const&& {
return std::move(this->m_val);
}
constexpr Unexpected<E>& geterr() & {
return this->m_unexpect;
}
constexpr const Unexpected<E>& geterr() const& {
return this->m_unexpect;
}
constexpr Unexpected<E>&& geterr() && {
return std::move(this->m_unexpect);
}
constexpr const Unexpected<E>&& geterr() const&& {
return std::move(this->m_unexpect);
}
constexpr void destroy_val() {
get().~T();
}
};
/**
* This manages conditionally having a trivial copy constructor
* This specialization is for when T is trivially copy constructible
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
/**
* This specialization is for when T is not trivially copy constructible
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
expected_copy_base() = default;
expected_copy_base(const expected_copy_base& rhs)
: expected_operations_base<T, E>{no_init_t{}} {
if (rhs.has_value()) {
this->construct_with(rhs);
} else {
this->construct_error(rhs.geterr());
}
}
expected_copy_base(expected_copy_base&&) = default;
expected_copy_base& operator=(const expected_copy_base&) = default;
expected_copy_base& operator=(expected_copy_base&&) = default;
};
/**
* This manages conditionally having a trivial move constructor
* This specialization is for when T is trivially move constructible
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
};
/**
* This specialization is for when T is not trivially move constructible
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
expected_move_base() = default;
expected_move_base(const expected_move_base&) = default;
expected_move_base(expected_move_base&& rhs) noexcept(std::is_nothrow_move_constructible_v<T>)
: expected_copy_base<T, E>{no_init_t{}} {
if (rhs.has_value()) {
this->construct_with(std::move(rhs));
} else {
this->construct_error(std::move(rhs.geterr()));
}
}
expected_move_base& operator=(const expected_move_base&) = default;
expected_move_base& operator=(expected_move_base&&) = default;
};
/**
* This manages conditionally having a trivial copy assignment operator
* This specialization is for when T is trivially copy assignable
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
std::is_trivially_copy_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
};
/**
* This specialization is for when T is not trivially copy assignable
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
expected_copy_assign_base() = default;
expected_copy_assign_base(const expected_copy_assign_base&) = default;
expected_copy_assign_base(expected_copy_assign_base&&) = default;
expected_copy_assign_base& operator=(const expected_copy_assign_base& rhs) {
this->assign(rhs);
return *this;
}
expected_copy_assign_base& operator=(expected_copy_assign_base&&) = default;
};
/**
* This manages conditionally having a trivial move assignment operator
* This specialization is for when T is trivially move assignable
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
std::is_trivially_move_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
};
/**
* This specialization is for when T is not trivially move assignable
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
expected_move_assign_base() = default;
expected_move_assign_base(const expected_move_assign_base&) = default;
expected_move_assign_base(expected_move_assign_base&&) = default;
expected_move_assign_base& operator=(const expected_move_assign_base&) = default;
expected_move_assign_base& operator=(expected_move_assign_base&& rhs) noexcept(
std::conjunction_v<std::is_nothrow_move_constructible<T>,
std::is_nothrow_move_assignable<T>>) {
this->assign(std::move(rhs));
return *this;
}
};
/**
* expected_delete_ctor_base will conditionally delete copy and move constructors
* depending on whether T is copy/move constructible
* Additionally, this requires E to be copy/move constructible
*/
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
bool EnableMove = std::is_move_constructible_v<T>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = default;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, true, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = delete;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, true> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = default;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
expected_delete_ctor_base(expected_delete_ctor_base&&) noexcept = delete;
expected_delete_ctor_base& operator=(const expected_delete_ctor_base&) = default;
expected_delete_ctor_base& operator=(expected_delete_ctor_base&&) noexcept = default;
};
/**
* expected_delete_assign_base will conditionally delete copy and move assignment operators
* depending on whether T is copy/move constructible + assignable
* Additionally, this requires E to be copy/move constructible + assignable
*/
template <
typename T, typename E,
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = default;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, true, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = default;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = delete;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, true> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = delete;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = default;
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
expected_delete_assign_base(expected_delete_assign_base&&) noexcept = default;
expected_delete_assign_base& operator=(const expected_delete_assign_base&) = delete;
expected_delete_assign_base& operator=(expected_delete_assign_base&&) noexcept = delete;
};
/**
* This is needed to be able to construct the expected_default_ctor_base which follows,
* while still conditionally deleting the default constructor.
*/
struct default_constructor_tag {
constexpr explicit default_constructor_tag() = default;
};
/**
* expected_default_ctor_base will ensure that expected
* has a deleted default constructor if T is not default constructible
* This specialization is for when T is default constructible
*/
template <typename T, typename E, bool Enable = std::is_default_constructible_v<T>>
struct expected_default_ctor_base {
constexpr expected_default_ctor_base() noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base const&) noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base&&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base const&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base&&) noexcept = default;
constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
};
template <typename T, typename E>
struct expected_default_ctor_base<T, E, false> {
constexpr expected_default_ctor_base() noexcept = delete;
constexpr expected_default_ctor_base(expected_default_ctor_base const&) noexcept = default;
constexpr expected_default_ctor_base(expected_default_ctor_base&&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base const&) noexcept = default;
expected_default_ctor_base& operator=(expected_default_ctor_base&&) noexcept = default;
constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
};
template <typename T, typename E, typename U>
using expected_enable_forward_value =
std::enable_if_t<std::is_constructible_v<T, U&&> &&
!std::is_same_v<std::remove_cvref_t<U>, std::in_place_t> &&
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::is_same_v<Unexpected<E>, std::remove_cvref_t<U>>>;
template <typename T, typename E, typename U, typename G, typename UR, typename GR>
using expected_enable_from_other = std::enable_if_t<
std::is_constructible_v<T, UR> && std::is_constructible_v<E, GR> &&
!std::is_constructible_v<T, Expected<U, G>&> && !std::is_constructible_v<T, Expected<U, G>&&> &&
!std::is_constructible_v<T, const Expected<U, G>&> &&
!std::is_constructible_v<T, const Expected<U, G>&&> &&
!std::is_convertible_v<Expected<U, G>&, T> && !std::is_convertible_v<Expected<U, G>&&, T> &&
!std::is_convertible_v<const Expected<U, G>&, T> &&
!std::is_convertible_v<const Expected<U, G>&&, T>>;
} // namespace detail
template <typename T, typename E>
class Expected : private detail::expected_move_assign_base<T, E>,
private detail::expected_delete_ctor_base<T, E>,
private detail::expected_delete_assign_base<T, E>,
private detail::expected_default_ctor_base<T, E> {
public:
using value_type = T;
using error_type = E;
using unexpected_type = Unexpected<E>;
constexpr Expected() = default;
constexpr Expected(const Expected&) = default;
constexpr Expected(Expected&&) = default;
Expected& operator=(const Expected&) = default;
Expected& operator=(Expected&&) = default;
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args&&...>>* = nullptr>
constexpr Expected(std::in_place_t, Args&&... args)
: impl_base{std::in_place, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<T, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr Expected(std::in_place_t, std::initializer_list<U> il, Args&&... args)
: impl_base{std::in_place, il, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, const G&>>* = nullptr,
std::enable_if_t<!std::is_convertible_v<const G&, E>>* = nullptr>
constexpr explicit Expected(const Unexpected<G>& e)
: impl_base{unexpect_t{}, e.value()}, ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, const G&>>* = nullptr,
std::enable_if_t<std::is_convertible_v<const G&, E>>* = nullptr>
constexpr Expected(Unexpected<G> const& e)
: impl_base{unexpect_t{}, e.value()}, ctor_base{detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, G&&>>* = nullptr,
std::enable_if_t<!std::is_convertible_v<G&&, E>>* = nullptr>
constexpr explicit Expected(Unexpected<G>&& e) noexcept(std::is_nothrow_constructible_v<E, G&&>)
: impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{
detail::default_constructor_tag{}} {}
template <typename G = E, std::enable_if_t<std::is_constructible_v<E, G&&>>* = nullptr,
std::enable_if_t<std::is_convertible_v<G&&, E>>* = nullptr>
constexpr Expected(Unexpected<G>&& e) noexcept(std::is_nothrow_constructible_v<E, G&&>)
: impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{
detail::default_constructor_tag{}} {}
template <typename... Args, std::enable_if_t<std::is_constructible_v<E, Args&&...>>* = nullptr>
constexpr explicit Expected(unexpect_t, Args&&... args)
: impl_base{unexpect_t{}, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename... Args,
std::enable_if_t<std::is_constructible_v<E, std::initializer_list<U>&, Args&&...>>* =
nullptr>
constexpr explicit Expected(unexpect_t, std::initializer_list<U> il, Args&&... args)
: impl_base{unexpect_t{}, il, std::forward<Args>(args)...},
ctor_base{detail::default_constructor_tag{}} {}
template <typename U, typename G,
std::enable_if_t<!(std::is_convertible_v<U const&, T> &&
std::is_convertible_v<G const&, E>)>* = nullptr,
detail::expected_enable_from_other<T, E, U, G, const U&, const G&>* = nullptr>
constexpr explicit Expected(const Expected<U, G>& rhs)
: ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(*rhs);
} else {
this->construct_error(rhs.error());
}
}
template <typename U, typename G,
std::enable_if_t<(std::is_convertible_v<U const&, T> &&
std::is_convertible_v<G const&, E>)>* = nullptr,
detail::expected_enable_from_other<T, E, U, G, const U&, const G&>* = nullptr>
constexpr Expected(const Expected<U, G>& rhs) : ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(*rhs);
} else {
this->construct_error(rhs.error());
}
}
template <typename U, typename G,
std::enable_if_t<!(std::is_convertible_v<U&&, T> && std::is_convertible_v<G&&, E>)>* =
nullptr,
detail::expected_enable_from_other<T, E, U, G, U&&, G&&>* = nullptr>
constexpr explicit Expected(Expected<U, G>&& rhs)
: ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
this->construct_error(std::move(rhs.error()));
}
}
template <typename U, typename G,
std::enable_if_t<(std::is_convertible_v<U&&, T> && std::is_convertible_v<G&&, E>)>* =
nullptr,
detail::expected_enable_from_other<T, E, U, G, U&&, G&&>* = nullptr>
constexpr Expected(Expected<U, G>&& rhs) : ctor_base{detail::default_constructor_tag{}} {
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
this->construct_error(std::move(rhs.error()));
}
}
template <typename U = T, std::enable_if_t<!std::is_convertible_v<U&&, T>>* = nullptr,
detail::expected_enable_forward_value<T, E, U>* = nullptr>
constexpr explicit Expected(U&& v) : Expected{std::in_place, std::forward<U>(v)} {}
template <typename U = T, std::enable_if_t<std::is_convertible_v<U&&, T>>* = nullptr,
detail::expected_enable_forward_value<T, E, U>* = nullptr>
constexpr Expected(U&& v) : Expected{std::in_place, std::forward<U>(v)} {}
template <typename U = T, typename G = T,
std::enable_if_t<std::is_nothrow_constructible_v<T, U&&>>* = nullptr,
std::enable_if_t<(
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::remove_cvref_t<U>>> &&
std::is_constructible_v<T, U> && std::is_assignable_v<G&, U> &&
std::is_nothrow_move_constructible_v<E>)>* = nullptr>
Expected& operator=(U&& v) {
if (has_value()) {
val() = std::forward<U>(v);
} else {
err().~Unexpected<E>();
new (valptr()) T{std::forward<U>(v)};
this->m_has_val = true;
}
return *this;
}
template <typename U = T, typename G = T,
std::enable_if_t<!std::is_nothrow_constructible_v<T, U&&>>* = nullptr,
std::enable_if_t<(
!std::is_same_v<Expected<T, E>, std::remove_cvref_t<U>> &&
!std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::remove_cvref_t<U>>> &&
std::is_constructible_v<T, U> && std::is_assignable_v<G&, U> &&
std::is_nothrow_move_constructible_v<E>)>* = nullptr>
Expected& operator=(U&& v) {
if (has_value()) {
val() = std::forward<U>(v);
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{std::forward<U>(v)};
this->m_has_val = true;
}
return *this;
}
template <typename G = E, std::enable_if_t<std::is_nothrow_copy_constructible_v<G> &&
std::is_assignable_v<G&, G>>* = nullptr>
Expected& operator=(const Unexpected<G>& rhs) {
if (!has_value()) {
err() = rhs;
} else {
this->destroy_val();
new (errptr()) Unexpected<E>{rhs};
this->m_has_val = false;
}
return *this;
}
template <typename G = E, std::enable_if_t<std::is_nothrow_move_constructible_v<G> &&
std::is_move_assignable_v<G>>* = nullptr>
Expected& operator=(Unexpected<G>&& rhs) noexcept {
if (!has_value()) {
err() = std::move(rhs);
} else {
this->destroy_val();
new (errptr()) Unexpected<E>{std::move(rhs)};
this->m_has_val = false;
}
return *this;
}
template <typename... Args,
std::enable_if_t<std::is_nothrow_constructible_v<T, Args&&...>>* = nullptr>
void emplace(Args&&... args) {
if (has_value()) {
val() = T{std::forward<Args>(args)...};
} else {
err().~Unexpected<E>();
new (valptr()) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename... Args,
std::enable_if_t<!std::is_nothrow_constructible_v<T, Args&&...>>* = nullptr>
void emplace(Args&&... args) {
if (has_value()) {
val() = T{std::forward<Args>(args)...};
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename U, typename... Args,
std::enable_if_t<std::is_nothrow_constructible_v<T, std::initializer_list<U>&,
Args&&...>>* = nullptr>
void emplace(std::initializer_list<U> il, Args&&... args) {
if (has_value()) {
T t{il, std::forward<Args>(args)...};
val() = std::move(t);
} else {
err().~Unexpected<E>();
new (valptr()) T{il, std::forward<Args>(args)...};
this->m_has_val = true;
}
}
template <typename U, typename... Args,
std::enable_if_t<!std::is_nothrow_constructible_v<T, std::initializer_list<U>&,
Args&&...>>* = nullptr>
void emplace(std::initializer_list<U> il, Args&&... args) {
if (has_value()) {
T t{il, std::forward<Args>(args)...};
val() = std::move(t);
} else {
auto tmp = std::move(err());
err().~Unexpected<E>();
new (valptr()) T{il, std::forward<Args>(args)...};
this->m_has_val = true;
}
}
constexpr T* operator->() {
return valptr();
}
constexpr const T* operator->() const {
return valptr();
}
template <typename U = T>
constexpr U& operator*() & {
return val();
}
template <typename U = T>
constexpr const U& operator*() const& {
return val();
}
template <typename U = T>
constexpr U&& operator*() && {
return std::move(val());
}
template <typename U = T>
constexpr const U&& operator*() const&& {
return std::move(val());
}
constexpr bool has_value() const noexcept {
return this->m_has_val;
}
constexpr explicit operator bool() const noexcept {
return this->m_has_val;
}
template <typename U = T>
constexpr U& value() & {
return val();
}
template <typename U = T>
constexpr const U& value() const& {
return val();
}
template <typename U = T>
constexpr U&& value() && {
return std::move(val());
}
template <typename U = T>
constexpr const U&& value() const&& {
return std::move(val());
}
constexpr E& error() & {
return err().value();
}
constexpr const E& error() const& {
return err().value();
}
constexpr E&& error() && {
return std::move(err().value());
}
constexpr const E&& error() const&& {
return std::move(err().value());
}
template <typename U>
constexpr T value_or(U&& v) const& {
static_assert(std::is_copy_constructible_v<T> && std::is_convertible_v<U&&, T>,
"T must be copy-constructible and convertible from U&&");
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
}
template <typename U>
constexpr T value_or(U&& v) && {
static_assert(std::is_move_constructible_v<T> && std::is_convertible_v<U&&, T>,
"T must be move-constructible and convertible from U&&");
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
}
private:
static_assert(!std::is_reference_v<T>, "T must not be a reference");
static_assert(!std::is_same_v<T, std::remove_cv_t<std::in_place_t>>,
"T must not be std::in_place_t");
static_assert(!std::is_same_v<T, std::remove_cv_t<unexpect_t>>, "T must not be unexpect_t");
static_assert(!std::is_same_v<T, std::remove_cv_t<Unexpected<E>>>,
"T must not be Unexpected<E>");
static_assert(!std::is_reference_v<E>, "E must not be a reference");
T* valptr() {
return std::addressof(this->m_val);
}
const T* valptr() const {
return std::addressof(this->m_val);
}
Unexpected<E>* errptr() {
return std::addressof(this->m_unexpect);
}
const Unexpected<E>* errptr() const {
return std::addressof(this->m_unexpect);
}
template <typename U = T>
constexpr U& val() {
return this->m_val;
}
template <typename U = T>
constexpr const U& val() const {
return this->m_val;
}
constexpr Unexpected<E>& err() {
return this->m_unexpect;
}
constexpr const Unexpected<E>& err() const {
return this->m_unexpect;
}
using impl_base = detail::expected_move_assign_base<T, E>;
using ctor_base = detail::expected_default_ctor_base<T, E>;
};
template <typename T, typename E, typename U, typename F>
constexpr bool operator==(const Expected<T, E>& lhs, const Expected<U, F>& rhs) {
return (lhs.has_value() != rhs.has_value())
? false
: (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
}
template <typename T, typename E, typename U, typename F>
constexpr bool operator!=(const Expected<T, E>& lhs, const Expected<U, F>& rhs) {
return !operator==(lhs, rhs);
}
template <typename T, typename E, typename U>
constexpr bool operator==(const Expected<T, E>& x, const U& v) {
return x.has_value() ? *x == v : false;
}
template <typename T, typename E, typename U>
constexpr bool operator==(const U& v, const Expected<T, E>& x) {
return x.has_value() ? *x == v : false;
}
template <typename T, typename E, typename U>
constexpr bool operator!=(const Expected<T, E>& x, const U& v) {
return !operator==(x, v);
}
template <typename T, typename E, typename U>
constexpr bool operator!=(const U& v, const Expected<T, E>& x) {
return !operator==(v, x);
}
template <typename T, typename E>
constexpr bool operator==(const Expected<T, E>& x, const Unexpected<E>& e) {
return x.has_value() ? false : x.error() == e.value();
}
template <typename T, typename E>
constexpr bool operator==(const Unexpected<E>& e, const Expected<T, E>& x) {
return x.has_value() ? false : x.error() == e.value();
}
template <typename T, typename E>
constexpr bool operator!=(const Expected<T, E>& x, const Unexpected<E>& e) {
return !operator==(x, e);
}
template <typename T, typename E>
constexpr bool operator!=(const Unexpected<E>& e, const Expected<T, E>& x) {
return !operator==(e, x);
}
} // namespace Common
+2 -3
View File
@@ -7,7 +7,6 @@
#include <algorithm>
#include <array>
#include <atomic>
#include <chrono>
#include <map>
#include <optional>
#include <string>
@@ -487,9 +486,9 @@ struct Values {
// System
Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
// Measured in seconds since epoch
std::optional<std::chrono::seconds> custom_rtc;
std::optional<s64> custom_rtc;
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
std::chrono::seconds custom_rtc_differential;
s64 custom_rtc_differential;
BasicSetting<s32> current_user{0, "current_user"};
RangedSetting<s32> language_index{1, 0, 17, "language_index"};
+6 -6
View File
@@ -180,20 +180,20 @@ std::wstring UTF8ToUTF16W(const std::string& input) {
#endif
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len) {
std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer, std::size_t max_len) {
std::size_t len = 0;
while (len < max_len && buffer[len] != '\0')
while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
++len;
return std::string(buffer, len);
}
return std::string(buffer.begin(), buffer.begin() + len);
}
std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
std::size_t max_len) {
std::size_t len = 0;
while (len < max_len && buffer[len] != '\0')
while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
++len;
}
return std::u16string(buffer.begin(), buffer.begin() + len);
}
+1 -1
View File
@@ -63,7 +63,7 @@ template <typename InIt>
* Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
* NUL-terminated then the string ends at max_len characters.
*/
[[nodiscard]] std::string StringFromFixedZeroTerminatedBuffer(const char* buffer,
[[nodiscard]] std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer,
std::size_t max_len);
/**
-1
View File
@@ -9,7 +9,6 @@
#include <dynarmic/interface/A32/a32.h>
#include <dynarmic/interface/A64/a64.h>
#include <dynarmic/interface/exclusive_monitor.h>
#include "common/common_types.h"
#include "common/hash.h"
#include "core/arm/arm_interface.h"
+1 -2
View File
@@ -18,7 +18,6 @@
#include "core/core_timing.h"
#include "core/hardware_properties.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
@@ -263,7 +262,7 @@ void ARM_Dynarmic_64::Run() {
}
void ARM_Dynarmic_64::Step() {
cb->InterpreterFallback(jit->GetPC(), 1);
jit->Step();
}
ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_,
@@ -8,7 +8,6 @@
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
using Callback = Dynarmic::A32::Coprocessor::Callback;
using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord;
@@ -4,7 +4,6 @@
#pragma once
#include <memory>
#include <optional>
#include <dynarmic/interface/A32/coprocessor.h>
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include <memory>
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
#include "core/memory.h"
@@ -4,7 +4,6 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <dynarmic/interface/exclusive_monitor.h>
+64 -58
View File
@@ -19,20 +19,16 @@
#include "core/cpu_manager.h"
#include "core/device_memory.h"
#include "core/file_sys/bis_factory.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/mode.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs_factory.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/sdmc_factory.h"
#include "core/file_sys/vfs_concat.h"
#include "core/file_sys/vfs_real.h"
#include "core/hardware_interrupt_manager.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h"
#include "core/hle/service/am/applets/applets.h"
@@ -83,12 +79,6 @@ FileSys::StorageId GetStorageIdForFrontendSlot(
}
}
void KProcessDeleter(Kernel::KProcess* process) {
process->Destroy();
}
using KProcessPtr = std::unique_ptr<Kernel::KProcess, decltype(&KProcessDeleter)>;
} // Anonymous namespace
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
@@ -139,27 +129,47 @@ struct System::Impl {
: kernel{system}, fs_controller{system}, memory{system},
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
ResultStatus Run() {
status = ResultStatus::Success;
SystemResultStatus Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
kernel.Suspend(false);
core_timing.SyncPause(false);
cpu_manager.Pause(false);
is_paused = false;
return status;
}
ResultStatus Pause() {
status = ResultStatus::Success;
SystemResultStatus Pause() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
core_timing.SyncPause(true);
kernel.Suspend(true);
cpu_manager.Pause(true);
is_paused = true;
return status;
}
ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
std::unique_lock<std::mutex> StallCPU() {
std::unique_lock<std::mutex> lk(suspend_guard);
kernel.Suspend(true);
core_timing.SyncPause(true);
cpu_manager.Pause(true);
return lk;
}
void UnstallCPU() {
if (!is_paused) {
core_timing.SyncPause(false);
kernel.Suspend(false);
cpu_manager.Pause(false);
}
}
SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
device_memory = std::make_unique<Core::DeviceMemory>();
@@ -176,8 +186,9 @@ struct System::Impl {
cpu_manager.Initialize();
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch());
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
const auto current_time =
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
Settings::values.custom_rtc_differential =
Settings::values.custom_rtc.value_or(current_time) - current_time;
@@ -197,7 +208,7 @@ struct System::Impl {
gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
return ResultStatus::ErrorVideoCore;
return SystemResultStatus::ErrorVideoCore;
}
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
@@ -217,21 +228,22 @@ struct System::Impl {
LOG_DEBUG(Core, "Initialized OK");
return ResultStatus::Success;
return SystemResultStatus::Success;
}
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath,
u64 program_id, std::size_t program_index) {
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
const std::string& filepath, u64 program_id,
std::size_t program_index) {
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
program_id, program_index);
if (!app_loader) {
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
return ResultStatus::ErrorGetLoader;
return SystemResultStatus::ErrorGetLoader;
}
ResultStatus init_result{Init(system, emu_window)};
if (init_result != ResultStatus::Success) {
SystemResultStatus init_result{Init(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
Shutdown();
@@ -239,21 +251,20 @@ struct System::Impl {
}
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
main_process = KProcessPtr{Kernel::KProcess::Create(system.Kernel()), KProcessDeleter};
ASSERT(Kernel::KProcess::Initialize(main_process.get(), system, "main",
auto main_process = Kernel::KProcess::Create(system.Kernel());
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
Kernel::KProcess::ProcessType::Userland)
.IsSuccess());
main_process->Open();
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
Shutdown();
return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) +
static_cast<u32>(load_result));
return static_cast<SystemResultStatus>(
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeCurrentProcess(main_process.get());
kernel.MakeCurrentProcess(main_process);
kernel.InitializeCores();
// Initialize cheat engine
@@ -282,7 +293,7 @@ struct System::Impl {
GetAndResetPerfStats();
perf_stats->BeginSystemFrame();
status = ResultStatus::Success;
status = SystemResultStatus::Success;
return status;
}
@@ -313,13 +324,11 @@ struct System::Impl {
time_manager.Shutdown();
core_timing.Shutdown();
app_loader.reset();
perf_stats.reset();
gpu_core.reset();
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
applet_manager.ClearAll();
// TODO: The main process should be freed based on KAutoObject ref counting.
main_process.reset();
LOG_DEBUG(Core, "Shutdown OK");
}
@@ -355,7 +364,7 @@ struct System::Impl {
arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
}
void SetStatus(ResultStatus new_status, const char* details = nullptr) {
void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
status = new_status;
if (details) {
status_details = details;
@@ -366,6 +375,9 @@ struct System::Impl {
return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
}
std::mutex suspend_guard;
bool is_paused{};
Timing::CoreTiming core_timing;
Kernel::KernelCore kernel;
/// RealVfsFilesystem instance
@@ -378,7 +390,6 @@ struct System::Impl {
std::unique_ptr<Tegra::GPU> gpu_core;
std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
std::unique_ptr<Core::DeviceMemory> device_memory;
KProcessPtr main_process{nullptr, KProcessDeleter};
Core::Memory::Memory memory;
CpuManager cpu_manager;
std::atomic_bool is_powered_on{};
@@ -411,7 +422,7 @@ struct System::Impl {
/// Network instance
Network::NetworkInstance network_instance;
ResultStatus status = ResultStatus::Success;
SystemResultStatus status = SystemResultStatus::Success;
std::string status_details = "";
std::unique_ptr<Core::PerfStats> perf_stats;
@@ -428,22 +439,9 @@ struct System::Impl {
};
System::System() : impl{std::make_unique<Impl>(*this)} {}
System::~System() = default;
System& System::GetInstance() {
if (!s_instance) {
throw std::runtime_error("Using System instance before its initialization");
}
return *s_instance;
}
void System::InitializeGlobalInstance() {
if (s_instance) {
throw std::runtime_error("Reinitializing Global System instance.");
}
s_instance = std::unique_ptr<System>(new System);
}
CpuManager& System::GetCpuManager() {
return impl->cpu_manager;
}
@@ -452,16 +450,16 @@ const CpuManager& System::GetCpuManager() const {
return impl->cpu_manager;
}
System::ResultStatus System::Run() {
SystemResultStatus System::Run() {
return impl->Run();
}
System::ResultStatus System::Pause() {
SystemResultStatus System::Pause() {
return impl->Pause();
}
System::ResultStatus System::SingleStep() {
return ResultStatus::Success;
SystemResultStatus System::SingleStep() {
return SystemResultStatus::Success;
}
void System::InvalidateCpuInstructionCaches() {
@@ -476,8 +474,16 @@ void System::Shutdown() {
impl->Shutdown();
}
System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
u64 program_id, std::size_t program_index) {
std::unique_lock<std::mutex> System::StallCPU() {
return impl->StallCPU();
}
void System::UnstallCPU() {
impl->UnstallCPU();
}
SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
u64 program_id, std::size_t program_index) {
return impl->Load(*this, emu_window, filepath, program_id, program_index);
}
@@ -637,7 +643,7 @@ Loader::ResultStatus System::GetGameName(std::string& out) const {
return impl->GetGameName(out);
}
void System::SetStatus(ResultStatus new_status, const char* details) {
void System::SetStatus(SystemResultStatus new_status, const char* details) {
impl->SetStatus(new_status, details);
}
+28 -33
View File
@@ -7,6 +7,7 @@
#include <cstddef>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
@@ -104,55 +105,49 @@ struct PerfStatsResults;
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
const std::string& path);
/// Enumeration representing the return values of the System Initialize and Load process.
enum class SystemResultStatus : u32 {
Success, ///< Succeeded
ErrorNotInitialized, ///< Error trying to use core prior to initialization
ErrorGetLoader, ///< Error finding the correct application loader
ErrorSystemFiles, ///< Error in finding system files
ErrorSharedFont, ///< Error in finding shared font
ErrorVideoCore, ///< Error in the video core
ErrorUnknown, ///< Any other error
ErrorLoader, ///< The base for loader errors (too many to repeat)
};
class System {
public:
using CurrentBuildProcessID = std::array<u8, 0x20>;
explicit System();
~System();
System(const System&) = delete;
System& operator=(const System&) = delete;
System(System&&) = delete;
System& operator=(System&&) = delete;
~System();
/**
* Gets the instance of the System singleton class.
* @returns Reference to the instance of the System singleton class.
*/
[[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance();
static void InitializeGlobalInstance();
/// Enumeration representing the return values of the System Initialize and Load process.
enum class ResultStatus : u32 {
Success, ///< Succeeded
ErrorNotInitialized, ///< Error trying to use core prior to initialization
ErrorGetLoader, ///< Error finding the correct application loader
ErrorSystemFiles, ///< Error in finding system files
ErrorSharedFont, ///< Error in finding shared font
ErrorVideoCore, ///< Error in the video core
ErrorUnknown, ///< Any other error
ErrorLoader, ///< The base for loader errors (too many to repeat)
};
/**
* Run the OS and Application
* This function will start emulation and run the relevant devices
*/
[[nodiscard]] ResultStatus Run();
[[nodiscard]] SystemResultStatus Run();
/**
* Pause the OS and Application
* This function will pause emulation and stop the relevant devices
*/
[[nodiscard]] ResultStatus Pause();
[[nodiscard]] SystemResultStatus Pause();
/**
* Step the CPU one instruction
* @return Result status, indicating whether or not the operation succeeded.
*/
[[nodiscard]] ResultStatus SingleStep();
[[nodiscard]] SystemResultStatus SingleStep();
/**
* Invalidate the CPU instruction caches
@@ -166,16 +161,20 @@ public:
/// Shutdown the emulated system.
void Shutdown();
std::unique_lock<std::mutex> StallCPU();
void UnstallCPU();
/**
* Load an executable application.
* @param emu_window Reference to the host-system window used for video output and keyboard
* input.
* @param filepath String path to the executable application to load on the host file system.
* @param program_index Specifies the index within the container of the program to launch.
* @returns ResultStatus code, indicating if the operation succeeded.
* @returns SystemResultStatus code, indicating if the operation succeeded.
*/
[[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
u64 program_id = 0, std::size_t program_index = 0);
[[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
const std::string& filepath, u64 program_id = 0,
std::size_t program_index = 0);
/**
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -301,7 +300,7 @@ public:
/// Gets the name of the current game
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
void SetStatus(ResultStatus new_status, const char* details);
void SetStatus(SystemResultStatus new_status, const char* details);
[[nodiscard]] const std::string& GetStatusDetails() const;
@@ -403,12 +402,8 @@ public:
void ApplySettings();
private:
System();
struct Impl;
std::unique_ptr<Impl> impl;
inline static std::unique_ptr<System> s_instance{};
};
} // namespace Core
-1
View File
@@ -8,7 +8,6 @@
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <thread>
-1
View File
@@ -6,7 +6,6 @@
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "common/thread.h"
#include "core/arm/exclusive_monitor.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/cpu_manager.h"
-1
View File
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cstring>
#include "common/assert.h"
#include "core/crypto/ctr_encryption_layer.h"
namespace Core::Crypto {
-3
View File
@@ -10,14 +10,12 @@
#include <locale>
#include <map>
#include <sstream>
#include <string_view>
#include <tuple>
#include <vector>
#include <mbedtls/bignum.h>
#include <mbedtls/cipher.h>
#include <mbedtls/cmac.h>
#include <mbedtls/sha256.h>
#include "common/common_funcs.h"
#include "common/fs/file.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
@@ -30,7 +28,6 @@
#include "core/crypto/partition_data_manager.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/partition_filesystem.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h"
-1
View File
@@ -15,7 +15,6 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/crypto/partition_data_manager.h"
#include "core/file_sys/vfs_types.h"
namespace Common::FS {
class IOFile;
@@ -12,7 +12,6 @@
#include <cctype>
#include <cstring>
#include <mbedtls/sha256.h>
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/hex_util.h"
-1
View File
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cstring>
#include "common/assert.h"
#include "core/crypto/xts_encryption_layer.h"
namespace Core::Crypto {
-1
View File
@@ -14,7 +14,6 @@
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/partition_filesystem.h"
#include "core/file_sys/submission_package.h"
#include "core/file_sys/vfs_concat.h"
#include "core/file_sys/vfs_offset.h"
#include "core/file_sys/vfs_vector.h"
#include "core/loader/loader.h"
+2 -1
View File
@@ -9,7 +9,7 @@
namespace FileSys {
const std::array<const char*, 15> LANGUAGE_NAMES{{
const std::array<const char*, 16> LANGUAGE_NAMES{{
"AmericanEnglish",
"BritishEnglish",
"Japanese",
@@ -25,6 +25,7 @@ const std::array<const char*, 15> LANGUAGE_NAMES{{
"Korean",
"Taiwanese",
"Chinese",
"BrazilianPortuguese",
}};
std::string LanguageEntry::GetApplicationName() const {
+2 -2
View File
@@ -5,7 +5,6 @@
#pragma once
#include <array>
#include <memory>
#include <string>
#include "common/common_funcs.h"
#include "common/common_types.h"
@@ -88,11 +87,12 @@ enum class Language : u8 {
Korean = 12,
Taiwanese = 13,
Chinese = 14,
BrazilianPortuguese = 15,
Default = 255,
};
extern const std::array<const char*, 15> LANGUAGE_NAMES;
extern const std::array<const char*, 16> LANGUAGE_NAMES;
// A class representing the format used by NX metadata files, typically named Control.nacp.
// These store application name, dev name, title id, and other miscellaneous data.
-1
View File
@@ -6,7 +6,6 @@
#include <cstddef>
#include <iterator>
#include <string_view>
#include "common/common_funcs.h"
#include "common/common_types.h"
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <array>
#include <memory>
#include <vector>
#include "common/common_funcs.h"
#include "common/common_types.h"
+4 -7
View File
@@ -6,7 +6,6 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/nca_metadata.h"
@@ -39,13 +38,12 @@ void RomFSFactory::SetPackedUpdate(VirtualFile update_raw_file) {
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const {
if (!updatable) {
return MakeResult<VirtualFile>(file);
return file;
}
const PatchManager patch_manager{current_process_title_id, filesystem_controller,
content_provider};
return MakeResult<VirtualFile>(
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
return patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw);
}
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFS(u64 title_id, ContentRecordType type) const {
@@ -58,8 +56,7 @@ ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFS(u64 title_id, ContentRecor
const PatchManager patch_manager{title_id, filesystem_controller, content_provider};
return MakeResult<VirtualFile>(
patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), type));
return patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), type);
}
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFSWithProgramIndex(
@@ -83,7 +80,7 @@ ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage,
return ResultUnknown;
}
return MakeResult<VirtualFile>(romfs);
return romfs;
}
std::shared_ptr<NCA> RomFSFactory::GetEntry(u64 title_id, StorageId storage,
+2 -1
View File
@@ -5,8 +5,9 @@
#pragma once
#include <memory>
#include "common/common_types.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_types.h"
#include "core/hle/result.h"
namespace Loader {
+2 -2
View File
@@ -94,7 +94,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
return ResultUnknown;
}
return MakeResult<VirtualDir>(std::move(out));
return out;
}
ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
@@ -115,7 +115,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
return ResultUnknown;
}
return MakeResult<VirtualDir>(std::move(out));
return out;
}
VirtualDir SaveDataFactory::GetSaveDataSpaceDirectory(SaveDataSpaceId space) const {
-1
View File
@@ -8,7 +8,6 @@
#include <string>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/file_sys/vfs.h"
#include "core/hle/result.h"
+1 -1
View File
@@ -25,7 +25,7 @@ SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_)
SDMCFactory::~SDMCFactory() = default;
ResultVal<VirtualDir> SDMCFactory::Open() const {
return MakeResult<VirtualDir>(sd_dir);
return sd_dir;
}
VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const {
-1
View File
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cstring>
#include <string_view>
#include <fmt/ostream.h>
@@ -4,7 +4,6 @@
#pragma once
#include <string>
#include "core/file_sys/vfs_types.h"
namespace FileSys::SystemArchive {
-1
View File
@@ -9,7 +9,6 @@
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
-1
View File
@@ -6,7 +6,6 @@
#include <map>
#include <memory>
#include <string_view>
#include "core/file_sys/vfs.h"
namespace FileSys {
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <memory>
#include <string_view>
#include "core/file_sys/vfs.h"
@@ -5,7 +5,6 @@
#pragma once
#include <functional>
#include <optional>
#include "common/common_types.h"
namespace Core::Frontend {
@@ -5,7 +5,6 @@
#pragma once
#include <functional>
#include <thread>
#include "common/common_types.h"
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <functional>
#include <string_view>
#include "core/hle/service/am/applets/applet_web_browser_types.h"
-1
View File
@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cmath>
#include <mutex>
#include "common/settings.h"
#include "core/frontend/emu_window.h"
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <memory>
#include <tuple>
#include <utility>
#include "common/common_types.h"
#include "core/frontend/framebuffer_layout.h"
@@ -4,8 +4,6 @@
#pragma once
#include "common/common_types.h"
namespace Kernel::Board::Nintendo::Nx::Smc {
enum MemorySize {
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <cstddef>
#include <vector>
#include "common/common_types.h"
#include "core/hle/kernel/physical_memory.h"
-6
View File
@@ -5,7 +5,6 @@
#include <algorithm>
#include <array>
#include <sstream>
#include <utility>
#include <boost/range/algorithm_ext/erase.hpp>
@@ -19,14 +18,9 @@
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h"
#include "core/memory.h"
namespace Kernel {
@@ -20,8 +20,6 @@
#include "core/hle/kernel/k_system_control.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/memory_types.h"
#include "core/memory.h"
namespace Kernel::Init {
@@ -4,14 +4,9 @@
#pragma once
#include <atomic>
#include <boost/intrusive/rbtree.hpp>
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/intrusive_red_black_tree.h"
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_light_lock.h"
-1
View File
@@ -6,7 +6,6 @@
#include <atomic>
#include "common/assert.h"
#include "common/bit_util.h"
#include "common/common_types.h"
-1
View File
@@ -7,7 +7,6 @@
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/result.h"
namespace Kernel {
-2
View File
@@ -4,11 +4,9 @@
#pragma once
#include <memory>
#include <string>
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/result.h"
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <vector>
#include "core/arm/exclusive_monitor.h"
#include "core/core.h"
#include "core/hle/kernel/k_condition_variable.h"
+1
View File
@@ -56,6 +56,7 @@ bool KHandleTable::Remove(Handle handle) {
}
// Close the object.
kernel.UnregisterInUseObject(obj);
obj->Close();
return true;
}
-1
View File
@@ -8,7 +8,6 @@
#include "common/assert.h"
#include "common/bit_field.h"
#include "common/bit_util.h"
#include "common/common_types.h"
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_spin_lock.h"
@@ -10,7 +10,6 @@
#include "common/common_types.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel {
-1
View File
@@ -6,7 +6,6 @@
#include <atomic>
#include "common/common_types.h"
#include "core/hle/kernel/k_scoped_lock.h"
namespace Kernel {
-1
View File
@@ -8,7 +8,6 @@
#include <mutex>
#include <tuple>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/kernel/k_page_heap.h"
#include "core/hle/result.h"
-1
View File
@@ -4,7 +4,6 @@
#include "core/core.h"
#include "core/hle/kernel/k_page_heap.h"
#include "core/memory.h"
namespace Kernel {
-3
View File
@@ -5,12 +5,9 @@
#pragma once
#include <array>
#include <bit>
#include <vector>
#include "common/alignment.h"
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/kernel/k_page_bitmap.h"
#include "core/hle/kernel/memory_types.h"
+4 -2
View File
@@ -363,6 +363,8 @@ ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, st
block_manager->Update(src_addr, num_pages, KMemoryState::Normal,
KMemoryPermission::ReadAndWrite);
system.InvalidateCpuInstructionCacheRange(dst_addr, size);
return ResultSuccess;
}
@@ -857,7 +859,7 @@ ResultVal<VAddr> KPageTable::SetHeapSize(std::size_t size) {
current_heap_addr = heap_region_start + size;
}
return MakeResult<VAddr>(heap_region_start);
return heap_region_start;
}
ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
@@ -891,7 +893,7 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages,
block_manager->Update(addr, needed_num_pages, state, perm);
return MakeResult<VAddr>(addr);
return addr;
}
ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
-1
View File
@@ -4,7 +4,6 @@
#pragma once
#include <memory>
#include <string>
#include "common/common_types.h"
+6 -5
View File
@@ -434,11 +434,6 @@ void KProcess::PrepareForTermination() {
}
void KProcess::Finalize() {
// Release memory to the resource limit.
if (resource_limit != nullptr) {
resource_limit->Close();
}
// Finalize the handle table and close any open handles.
handle_table.Finalize();
@@ -460,6 +455,12 @@ void KProcess::Finalize() {
}
}
// Release memory to the resource limit.
if (resource_limit != nullptr) {
resource_limit->Close();
resource_limit = nullptr;
}
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
}
-1
View File
@@ -8,7 +8,6 @@
#include <cstddef>
#include <list>
#include <string>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "core/hle/kernel/k_address_arbiter.h"
+5
View File
@@ -49,6 +49,11 @@ public:
/// Gets the current running thread
[[nodiscard]] KThread* GetCurrentThread() const;
/// Gets the idle thread
[[nodiscard]] KThread* GetIdleThread() const {
return idle_thread;
}
/// Returns true if the scheduler is idle
[[nodiscard]] bool IsIdle() const {
return GetCurrentThread() == idle_thread;
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include "common/assert.h"
#include "core/hardware_properties.h"
#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
+2 -1
View File
@@ -7,7 +7,8 @@
#pragma once
#include "common/common_types.h"
#include <concepts>
#include <type_traits>
namespace Kernel {
@@ -8,7 +8,6 @@
#pragma once
#include "common/common_types.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h"
-1
View File
@@ -10,7 +10,6 @@
#include "core/hle/kernel/k_server_port.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
-3
View File
@@ -7,14 +7,11 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <boost/intrusive/list.hpp>
#include "common/common_types.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/result.h"
namespace Kernel {
+1 -1
View File
@@ -14,7 +14,6 @@
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_server_port.h"
@@ -22,6 +21,7 @@
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/service_thread.h"
#include "core/memory.h"
namespace Kernel {
-3
View File
@@ -7,14 +7,11 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <boost/intrusive/list.hpp>
#include "common/threadsafe_queue.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/service_thread.h"
#include "core/hle/result.h"
namespace Core::Memory {
-1
View File
@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_client_session.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
-1
View File
@@ -4,7 +4,6 @@
#pragma once
#include <memory>
#include <string>
#include "common/common_types.h"
@@ -4,12 +4,8 @@
#pragma once
#include <memory>
#include <string>
#include <boost/intrusive/list.hpp>
#include "common/assert.h"
#include "core/hle/kernel/slab_helpers.h"
namespace Kernel {
-4
View File
@@ -13,8 +13,6 @@
#include "common/common_types.h"
#include "common/fiber.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/thread_queue_list.h"
#include "core/core.h"
#include "core/cpu_manager.h"
#include "core/hardware_properties.h"
@@ -31,11 +29,9 @@
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h"
#include "core/hle/result.h"
#include "core/memory.h"
#ifdef ARCHITECTURE_x86_64
#include "core/arm/dynarmic/arm_dynarmic_32.h"
#include "core/arm/dynarmic/arm_dynarmic_64.h"
#endif
namespace {
-2
View File
@@ -4,8 +4,6 @@
#pragma once
#include "common/common_funcs.h"
namespace Kernel {
using namespace Common::Literals;
-2
View File
@@ -4,8 +4,6 @@
#pragma once
#include <memory>
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"
+30 -8
View File
@@ -39,9 +39,7 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/service_thread.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h"
#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/hle/service/sm/sm.h"
#include "core/memory.h"
@@ -91,12 +89,6 @@ struct KernelCore::Impl {
}
void Shutdown() {
// Shutdown all processes.
if (current_process) {
current_process->Finalize();
current_process->Close();
current_process = nullptr;
}
process_list.clear();
// Close all open server ports.
@@ -170,6 +162,24 @@ struct KernelCore::Impl {
// Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
// Close kernel objects that were not freed on shutdown
{
std::lock_guard lk(registered_in_use_objects_lock);
if (registered_in_use_objects.size()) {
for (auto& object : registered_in_use_objects) {
object->Close();
}
registered_in_use_objects.clear();
}
}
// Shutdown all processes.
if (current_process) {
current_process->Finalize();
current_process->Close();
current_process = nullptr;
}
// Track kernel objects that were not freed on shutdown
{
std::lock_guard lk(registered_objects_lock);
@@ -714,9 +724,11 @@ struct KernelCore::Impl {
std::unordered_set<KServerPort*> server_ports;
std::unordered_set<KServerSession*> server_sessions;
std::unordered_set<KAutoObject*> registered_objects;
std::unordered_set<KAutoObject*> registered_in_use_objects;
std::mutex server_ports_lock;
std::mutex server_sessions_lock;
std::mutex registered_objects_lock;
std::mutex registered_in_use_objects_lock;
std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
std::vector<Kernel::PhysicalCore> cores;
@@ -928,6 +940,16 @@ void KernelCore::UnregisterKernelObject(KAutoObject* object) {
impl->registered_objects.erase(object);
}
void KernelCore::RegisterInUseObject(KAutoObject* object) {
std::lock_guard lk(impl->registered_in_use_objects_lock);
impl->registered_in_use_objects.insert(object);
}
void KernelCore::UnregisterInUseObject(KAutoObject* object) {
std::lock_guard lk(impl->registered_in_use_objects_lock);
impl->registered_in_use_objects.erase(object);
}
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
return port != impl->named_ports.cend();
}
+8
View File
@@ -204,6 +204,14 @@ public:
/// destroyed during the current emulation session.
void UnregisterKernelObject(KAutoObject* object);
/// Registers kernel objects with guest in use state, this is purely for close
/// after emulation has been shutdown.
void RegisterInUseObject(KAutoObject* object);
/// Unregisters a kernel object previously registered with RegisterInUseObject when it was
/// destroyed during the current emulation session.
void UnregisterInUseObject(KAutoObject* object);
/// Determines whether or not the given port is a valid named port.
bool IsValidNamedPort(NamedPortTable::const_iterator port) const;

Some files were not shown because too many files have changed in this diff Show More