mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-09 23:59:33 +01:00
Implement Exceptional Signal Handler + Fix Destruction Behavior
An exceptional signal handler allows us to convert an OS signal into a C++ exception, this allows us to alleviate a lot of crashes that would otherwise occur from signals being thrown during execution of games and be able to handle them gracefully.
This commit is contained in:
parent
3cde568c51
commit
668f623256
4
.idea/codeStyles/Project.xml
generated
4
.idea/codeStyles/Project.xml
generated
@ -82,8 +82,8 @@
|
|||||||
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="CLASS_MEMBER_FUNCTION,STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="1.8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
2
.idea/discord.xml
generated
2
.idea/discord.xml
generated
@ -2,6 +2,6 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DiscordIntegrationProjectSettings" description="Lightswitch is an experimental Nintendo Switch emulator for Android phones." />
|
<component name="DiscordIntegrationProjectSettings" description="Lightswitch is an experimental Nintendo Switch emulator for Android phones." />
|
||||||
<component name="DiscordProjectSettings">
|
<component name="DiscordProjectSettings">
|
||||||
<option name="show" value="true" />
|
<option name="show" value="PROJECT_FILES" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
51
.idea/inspectionProfiles/Project_Default.xml
generated
51
.idea/inspectionProfiles/Project_Default.xml
generated
@ -175,6 +175,7 @@
|
|||||||
<inspection_tool class="AndroidLintJobSchedulerService" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintJobSchedulerService" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintKeyboardInaccessibleWidget" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintKeyboardInaccessibleWidget" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintKotlinPropertyAccess" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="AndroidLintKotlinPropertyAccess" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="AndroidLintKtxExtensionAvailable" enabled="false" level="INFO" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintLabelFor" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintLabelFor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintLambdaLast" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="AndroidLintLambdaLast" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintLibraryCustomView" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintLibraryCustomView" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
@ -226,6 +227,7 @@
|
|||||||
<inspection_tool class="AndroidLintNewerVersionAvailable" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="AndroidLintNewerVersionAvailable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintNfcTechWhitespace" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintNfcTechWhitespace" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintNoHardKeywords" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="AndroidLintNoHardKeywords" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="AndroidLintNonConstantResourceId" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintNonResizeableActivity" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="AndroidLintNonResizeableActivity" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintNotInterpolated" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintNotInterpolated" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintNotSibling" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintNotSibling" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
@ -257,6 +259,8 @@
|
|||||||
<inspection_tool class="AndroidLintProtectedPermissions" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintProtectedPermissions" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintProxyPassword" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintProxyPassword" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintPxUsage" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintPxUsage" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="AndroidLintQueryAllPackagesPermission" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="AndroidLintQueryPermissionsNeeded" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintRange" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintRange" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintRecycle" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintRecycle" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintRecyclerView" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintRecyclerView" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -280,6 +284,7 @@
|
|||||||
<inspection_tool class="AndroidLintSQLiteString" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintSQLiteString" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintSSLCertificateSocketFactoryCreateSocket" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintSSLCertificateSocketFactoryCreateSocket" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintSSLCertificateSocketFactoryGetInsecure" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintSSLCertificateSocketFactoryGetInsecure" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="AndroidLintScopedStorage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AndroidLintScrollViewCount" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintScrollViewCount" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintScrollViewSize" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintScrollViewSize" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AndroidLintSdCardPath" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AndroidLintSdCardPath" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -407,11 +412,13 @@
|
|||||||
<option name="m_limit" value="1" />
|
<option name="m_limit" value="1" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="AnonymousClassVariableHidesContainingMethodVariable" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AnonymousClassVariableHidesContainingMethodVariable" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="AnonymousHasLambdaAlternative" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="AnonymousInnerClassMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="AnonymousInnerClassMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ApiName" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ApiName" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="ApiNamespace" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ApiNamespace" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="ApiParameter" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ApiParameter" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="ArgumentSelectionDefects" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="ArrayCanBeReplacedWithEnumValues" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="ArrayCanBeReplacedWithEnumValues" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
<inspection_tool class="ArrayCreationWithoutNewKeyword" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="ArrayCreationWithoutNewKeyword" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
<inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -561,6 +568,7 @@
|
|||||||
<inspection_tool class="CheckValidXmlInScriptTagBody" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="CheckValidXmlInScriptTagBody" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="CheckXmlFileWithXercesValidator" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="CheckXmlFileWithXercesValidator" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="ClangTidy" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="ClangTidyInspection" enabled="false" level="WARNING" enabled_by_default="false">
|
<inspection_tool class="ClangTidyInspection" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
<option name="useCustomListOfClangTidyChecks" value="false" />
|
<option name="useCustomListOfClangTidyChecks" value="false" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
@ -672,7 +680,7 @@
|
|||||||
<inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ConstantConditionIf" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="ConstantConditionIf" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ConstantConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ConstantConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ConstantConditions" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
|
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
|
||||||
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
|
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
@ -825,6 +833,7 @@
|
|||||||
<option name="ignoreThrowables" value="true" />
|
<option name="ignoreThrowables" value="true" />
|
||||||
<option name="commentsAreContent" value="true" />
|
<option name="commentsAreContent" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="EmptyDeclOrStmt" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="EmptyDirectory" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="EmptyDirectory" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="EmptyFinallyBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="EmptyFinallyBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="EmptyInitializer" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="EmptyInitializer" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -931,10 +940,12 @@
|
|||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="ForeachStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ForeachStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="FormatSpecifiers" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="FormatSpecifiers" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="ForwardCompatibility" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="FrequentlyUsedInheritorInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="FrequentlyUsedInheritorInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
<inspection_tool class="FromClosedRangeMigration" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="FromClosedRangeMigration" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="FullJavaName" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="FullJavaName" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="FullMethodName" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="FullMethodName" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="FunctionImplicitDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="FunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="FunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="FunctionParameterCountMismatch" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="FunctionParameterCountMismatch" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="FunctionWithLambdaExpressionBody" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="FunctionWithLambdaExpressionBody" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
@ -1283,7 +1294,9 @@
|
|||||||
<inspection_tool class="JUnitDatapoint" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JUnitDatapoint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JUnitRule" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JUnitRule" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JUnitTestNG" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JUnitTestNG" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="Java8ListSort" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="Java9CollectionFactory" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="Java9CollectionFactory" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="Java9ModuleExportsPackageToItself" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="Java9RedundantRequiresStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="Java9RedundantRequiresStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="Java9ReflectionClassVisibility" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="Java9ReflectionClassVisibility" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="Java9UndeclaredServiceUsage" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="Java9UndeclaredServiceUsage" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1324,6 +1337,7 @@
|
|||||||
<inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JavaLangInvokeHandleSignature" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaLangInvokeHandleSignature" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JavaMapForEach" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaMapForEach" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="JavaModuleNaming" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="JavaReflectionInvocation" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaReflectionInvocation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JavaReflectionMemberAccess" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaReflectionMemberAccess" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JavaRequiresAutoModule" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JavaRequiresAutoModule" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1360,9 +1374,11 @@
|
|||||||
<inspection_tool class="KotlinDeprecation" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinDeprecation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinDoubleNegation" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinDoubleNegation" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinEqualsBetweenInconvertibleTypes" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinEqualsBetweenInconvertibleTypes" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="KotlinInternalExternalFunction" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="KotlinInternalInJava" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="KotlinInternalInJava" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinInvalidBundleOrProperty" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="KotlinInvalidBundleOrProperty" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinJniMissingFunction" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="KotlinJniMissingFunction" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="KotlinLoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="KotlinRedundantOverride" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinRedundantOverride" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinThrowableNotThrown" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinThrowableNotThrown" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="KotlinUnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="KotlinUnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1639,6 +1655,7 @@
|
|||||||
<inspection_tool class="NotifyWithoutCorrespondingWait" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NotifyWithoutCorrespondingWait" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="NullArgumentToVariableArgMethod" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NullArgumentToVariableArgMethod" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="NullChecksToSafeCall" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="NullChecksToSafeCall" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="NullDereferences" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="NullThrown" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NullThrown" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="NullableBooleanElvis" enabled="true" level="INFO" enabled_by_default="true" />
|
<inspection_tool class="NullableBooleanElvis" enabled="true" level="INFO" enabled_by_default="true" />
|
||||||
<inspection_tool class="NullableProblems" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="NullableProblems" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
@ -1654,11 +1671,14 @@
|
|||||||
<inspection_tool class="NumberEquality" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NumberEquality" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="NumericOverflow" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NumericOverflow" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="NumericToString" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="NumericToString" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="OCDFA" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="OCGlobalUnused" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCGlobalUnused" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OCInconsistentNaming" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="OCInconsistentNaming" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="OCLegacyObjCLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCLegacyObjCLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="OCLoopDoesntUseConditionVariable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="OCNotLocalizedString" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCNotLocalizedString" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OCNotReleasedIvar" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCNotReleasedIvar" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="OCSimplify" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="OCUnusedClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCUnusedClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OCUnusedClassInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="OCUnusedClassInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OCUnusedConcept" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="OCUnusedConcept" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
@ -1694,6 +1714,7 @@
|
|||||||
<option name="ignoreRequiredObsoleteCollectionTypes" value="true" />
|
<option name="ignoreRequiredObsoleteCollectionTypes" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="ObsoleteExperimentalCoroutines" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ObsoleteExperimentalCoroutines" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="ObsoleteKotlinJsPackages" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="ObviousNullCheck" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ObviousNullCheck" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OctalAndDecimalIntegersMixed" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OctalAndDecimalIntegersMixed" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="OctalLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="OctalLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1782,6 +1803,7 @@
|
|||||||
<inspection_tool class="PatternValidation" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="PatternValidation" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="CHECK_NON_CONSTANT_VALUES" value="true" />
|
<option name="CHECK_NON_CONSTANT_VALUES" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PatternVariableCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PermissionUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="PermissionUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PlaceholderCountMatchesArgumentCount" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PlaceholderCountMatchesArgumentCount" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="PlatformExtensionReceiverOfInline" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PlatformExtensionReceiverOfInline" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1799,6 +1821,7 @@
|
|||||||
<inspection_tool class="PointlessNullCheck" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PointlessNullCheck" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="PreviewMultipleParameterProviders" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="PrimitiveArrayArgumentToVariableArgMethod" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PrimitiveArrayArgumentToVariableArgMethod" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1807,6 +1830,10 @@
|
|||||||
<inspection_tool class="PrivatePropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="PrivatePropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ProblematicVarargsMethodOverride" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ProblematicVarargsMethodOverride" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ProblematicWhitespace" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="ProblematicWhitespace" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="ProhibitJvmOverloadsOnConstructorsOfAnnotationClassesMigration" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="ProhibitRepeatedUseSiteTargetAnnotationsMigration" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="ProhibitTypeParametersForLocalVariablesMigration" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="ProhibitUseSiteTargetAnnotationsOnSuperTypesMigration" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="ProjectFingerprint" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="ProjectFingerprint" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PropertyAndIvarTypeMismatch" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PropertyAndIvarTypeMismatch" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="PropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="PropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
@ -1958,6 +1985,7 @@
|
|||||||
<inspection_tool class="RecursiveEqualsCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RecursiveEqualsCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RecursivePropertyAccessor" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RecursivePropertyAccessor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantArrayCreation" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantArrayCreation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="RedundantAsSequence" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantAsync" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantAsync" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantClassCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantClassCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1966,6 +1994,7 @@
|
|||||||
<inspection_tool class="RedundantComparatorComparing" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantComparatorComparing" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantCompareCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantCompareCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantElseInIf" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="RedundantElseInIf" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="RedundantElvisReturnNull" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantEmptyInitializerBlock" enabled="true" level="INFO" enabled_by_default="true" />
|
<inspection_tool class="RedundantEmptyInitializerBlock" enabled="true" level="INFO" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantEnumConstructorInvocation" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantEnumConstructorInvocation" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantExplicitClose" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantExplicitClose" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -1978,6 +2007,8 @@
|
|||||||
<option name="ignoreSerializable" value="false" />
|
<option name="ignoreSerializable" value="false" />
|
||||||
<option name="ignoreCloneable" value="false" />
|
<option name="ignoreCloneable" value="false" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="RedundantInnerClassModifier" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="RedundantLabelMigration" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantLabeledSwitchRuleCodeBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantLabeledSwitchRuleCodeBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantLambdaArrow" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantLambdaArrow" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantLambdaParameterType" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="RedundantLambdaParameterType" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
@ -1986,6 +2017,7 @@
|
|||||||
<inspection_tool class="RedundantNotNullExtensionReceiverOfInline" enabled="false" level="INFORMATION" enabled_by_default="false" />
|
<inspection_tool class="RedundantNotNullExtensionReceiverOfInline" enabled="false" level="INFORMATION" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantObjectTypeCheck" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="RedundantObjectTypeCheck" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantOperationOnEmptyContainer" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantOperationOnEmptyContainer" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="RedundantRecordConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantRequireNotNullCall" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantRequireNotNullCall" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantReturnLabel" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantReturnLabel" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="RedundantRunCatching" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="RedundantRunCatching" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
@ -2071,8 +2103,10 @@
|
|||||||
<inspection_tool class="RequiredAttributes" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="RequiredAttributes" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="myAdditionalRequiredHtmlAttributes" value="" />
|
<option name="myAdditionalRequiredHtmlAttributes" value="" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ResourceNotFound" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="ResourceParameter" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ResourceParameter" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="RestSignature" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="RestSignature" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="RestrictReturnStatementTargetMigration" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="ResultOfObjectAllocationIgnored" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ResultOfObjectAllocationIgnored" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ResultSetIndexZero" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ResultSetIndexZero" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ReturnFromFinallyBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ReturnFromFinallyBlock" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -2130,6 +2164,7 @@
|
|||||||
<inspection_tool class="ShellCheck" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="ShellCheck" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="ShiftOutOfRange" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="ShiftOutOfRange" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ShrinkerArrayType" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="ShrinkerArrayType" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="ShrinkerInnerClassSeparator" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="ShrinkerInvalidFlags" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="ShrinkerInvalidFlags" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="ShrinkerUnresolvedReference" enabled="false" level="ERROR" enabled_by_default="false" />
|
<inspection_tool class="ShrinkerUnresolvedReference" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="SignalWithoutCorrespondingAwait" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SignalWithoutCorrespondingAwait" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -2234,6 +2269,7 @@
|
|||||||
<inspection_tool class="SuspiciousArrayMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousArrayMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SuspiciousAsDynamic" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousAsDynamic" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SuspiciousCollectionReassignment" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousCollectionReassignment" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="SuspiciousDateFormat" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="SuspiciousEqualsCombination" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousEqualsCombination" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SuspiciousGetterSetter" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousGetterSetter" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SuspiciousIndentAfterControlStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuspiciousIndentAfterControlStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -2342,6 +2378,7 @@
|
|||||||
<option name="m_onlyLookAtBlocks" value="false" />
|
<option name="m_onlyLookAtBlocks" value="false" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="TooBroadThrows" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="TooBroadThrows" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="TrailingComma" enabled="false" level="INFO" enabled_by_default="false" />
|
||||||
<inspection_tool class="TrailingSpacesInProperty" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="TrailingSpacesInProperty" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="TransientFieldInNonSerializableClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="TransientFieldInNonSerializableClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -2449,6 +2486,7 @@
|
|||||||
<option name="m_ignoreStaticMethodCalls" value="false" />
|
<option name="m_ignoreStaticMethodCalls" value="false" />
|
||||||
<option name="m_ignoreStaticAccessFromStaticContext" value="false" />
|
<option name="m_ignoreStaticAccessFromStaticContext" value="false" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnreachableCode" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnresolvedCollectionMessage" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnresolvedCollectionMessage" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnresolvedMessage" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnresolvedMessage" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnresolvedPropertyKey" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="UnresolvedPropertyKey" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
@ -2462,23 +2500,31 @@
|
|||||||
<option name="REPORT_POSTFIX_EXPRESSIONS" value="true" />
|
<option name="REPORT_POSTFIX_EXPRESSIONS" value="true" />
|
||||||
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
|
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedClass" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="UnusedConcept" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedDefine" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="UnusedDefine" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedEquals" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedEquals" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedExpressionResult" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedExpressionResult" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedGlobalDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedImportStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedImportStatement" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedIncludeDirective" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedIncludeDirective" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedInstanceVariable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedLabel" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedLabel" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedLambdaExpressionBody" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedLambdaExpressionBody" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedLibrary" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedLibrary" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedLocalVariable" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedLocalVariable" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedLocalization" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedLocalization" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedMacro" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedMainParameter" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedMainParameter" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedMessageFormatParameter" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedMessageFormatParameter" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedMethod" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedParameter" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedParameter" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedProperty" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedProperty" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedReceiverParameter" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedReceiverParameter" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnusedReturnValue" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedReturnValue" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedStruct" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedSymbol" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnusedSymbol" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnusedTemplateParameter" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedUnaryOperator" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="UnusedUnaryOperator" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UnusedValue" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="UnusedValue" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="UpperCaseFieldNameNotConstant" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UpperCaseFieldNameNotConstant" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
@ -2527,6 +2573,7 @@
|
|||||||
<inspection_tool class="WaitOrAwaitWithoutTimeout" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="WaitOrAwaitWithoutTimeout" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="WaitWhileHoldingTwoLocks" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="WaitWhileHoldingTwoLocks" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="WarningOnMainUnusedParameterMigration" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
|
||||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
|
||||||
|
6
.idea/kotlinc.xml
generated
Normal file
6
.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Kotlin2JvmCompilerArguments">
|
||||||
|
<option name="jvmTarget" value="14" />
|
||||||
|
</component>
|
||||||
|
</project>
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -43,7 +43,7 @@
|
|||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Controller Configuration" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
<configuration default="false" name="Controller Configuration" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
||||||
<module name="app" />
|
<module name="Skyline.app" />
|
||||||
<option name="DEPLOY" value="true" />
|
<option name="DEPLOY" value="true" />
|
||||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
||||||
<option name="DEPLOY_AS_INSTANT" value="false" />
|
<option name="DEPLOY_AS_INSTANT" value="false" />
|
||||||
<option name="ARTIFACT_NAME" value="" />
|
<option name="ARTIFACT_NAME" value="" />
|
||||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||||
|
<option name="ALL_USERS" value="false" />
|
||||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
||||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||||
<option name="MODE" value="specific_activity" />
|
<option name="MODE" value="specific_activity" />
|
||||||
@ -41,11 +42,16 @@
|
|||||||
</Native>
|
</Native>
|
||||||
<Profilers>
|
<Profilers>
|
||||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||||
|
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
||||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
||||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
||||||
|
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
|
||||||
|
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
|
||||||
</Profilers>
|
</Profilers>
|
||||||
<option name="DEEP_LINK" value="" />
|
<option name="DEEP_LINK" value="" />
|
||||||
<option name="ACTIVITY_CLASS" value="emu.skyline.input.ControllerActivity" />
|
<option name="ACTIVITY_CLASS" value="emu.skyline.input.ControllerActivity" />
|
||||||
|
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
|
||||||
|
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
8
.idea/runConfigurations/Setting.xml
generated
8
.idea/runConfigurations/Setting.xml
generated
@ -1,11 +1,12 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Setting" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
<configuration default="false" name="Setting" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
||||||
<module name="app" />
|
<module name="Skyline.app" />
|
||||||
<option name="DEPLOY" value="true" />
|
<option name="DEPLOY" value="true" />
|
||||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
||||||
<option name="DEPLOY_AS_INSTANT" value="false" />
|
<option name="DEPLOY_AS_INSTANT" value="false" />
|
||||||
<option name="ARTIFACT_NAME" value="" />
|
<option name="ARTIFACT_NAME" value="" />
|
||||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||||
|
<option name="ALL_USERS" value="false" />
|
||||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
||||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||||
<option name="MODE" value="specific_activity" />
|
<option name="MODE" value="specific_activity" />
|
||||||
@ -41,11 +42,16 @@
|
|||||||
</Native>
|
</Native>
|
||||||
<Profilers>
|
<Profilers>
|
||||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||||
|
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
||||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
||||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
||||||
|
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
|
||||||
|
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
|
||||||
</Profilers>
|
</Profilers>
|
||||||
<option name="DEEP_LINK" value="" />
|
<option name="DEEP_LINK" value="" />
|
||||||
<option name="ACTIVITY_CLASS" value="emu.skyline.SettingsActivity" />
|
<option name="ACTIVITY_CLASS" value="emu.skyline.SettingsActivity" />
|
||||||
|
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
|
||||||
|
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
2
.idea/scopes/SkylineNative.xml
generated
2
.idea/scopes/SkylineNative.xml
generated
@ -1,3 +1,3 @@
|
|||||||
<component name="DependencyValidationManager">
|
<component name="DependencyValidationManager">
|
||||||
<scope name="SkylineNative" pattern="file[app]:src/main/cpp//*.cpp||file[app]:src/main/cpp//*.h||file[app]:src/main/cpp//*.S" />
|
<scope name="SkylineNative" pattern="file[Skyline.app]:src/main/cpp//*.cpp||file[Skyline.app]:src/main/cpp//*.h||file[Skyline.app]:src/main/cpp//*.S" />
|
||||||
</component>
|
</component>
|
@ -34,6 +34,8 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/emu_jni.cpp
|
${source_DIR}/emu_jni.cpp
|
||||||
${source_DIR}/loader_jni.cpp
|
${source_DIR}/loader_jni.cpp
|
||||||
${source_DIR}/skyline/common.cpp
|
${source_DIR}/skyline/common.cpp
|
||||||
|
${source_DIR}/skyline/common/settings.cpp
|
||||||
|
${source_DIR}/skyline/common/signal.cpp
|
||||||
${source_DIR}/skyline/nce/guest.S
|
${source_DIR}/skyline/nce/guest.S
|
||||||
${source_DIR}/skyline/nce.cpp
|
${source_DIR}/skyline/nce.cpp
|
||||||
${source_DIR}/skyline/jvm.cpp
|
${source_DIR}/skyline/jvm.cpp
|
||||||
|
@ -7,22 +7,25 @@
|
|||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include "skyline/loader/loader.h"
|
#include "skyline/loader/loader.h"
|
||||||
#include "skyline/common.h"
|
#include "skyline/common.h"
|
||||||
|
#include "skyline/common/settings.h"
|
||||||
#include "skyline/os.h"
|
#include "skyline/os.h"
|
||||||
#include "skyline/jvm.h"
|
#include "skyline/jvm.h"
|
||||||
#include "skyline/gpu.h"
|
#include "skyline/gpu.h"
|
||||||
#include "skyline/input.h"
|
#include "skyline/input.h"
|
||||||
|
#include "skyline/kernel/types/KProcess.h"
|
||||||
|
|
||||||
skyline::u16 fps;
|
skyline::u16 Fps;
|
||||||
skyline::u32 frametime;
|
skyline::u32 FrameTime;
|
||||||
std::weak_ptr<skyline::gpu::GPU> gpuWeak;
|
std::weak_ptr<skyline::kernel::OS> OsWeak;
|
||||||
std::weak_ptr<skyline::input::Input> inputWeak;
|
std::weak_ptr<skyline::gpu::GPU> GpuWeak;
|
||||||
|
std::weak_ptr<skyline::input::Input> InputWeak;
|
||||||
|
|
||||||
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(JNIEnv *env, jobject instance, jstring romUriJstring, jint romType, jint romFd, jint preferenceFd, jstring appFilesPathJstring) {
|
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(JNIEnv *env, jobject instance, jstring romUriJstring, jint romType, jint romFd, jint preferenceFd, jstring appFilesPathJstring) {
|
||||||
fps = 0;
|
Fps = 0;
|
||||||
frametime = 0;
|
FrameTime = 0;
|
||||||
|
|
||||||
pthread_setname_np(pthread_self(), "EmuMain");
|
pthread_setname_np(pthread_self(), "EmuMain");
|
||||||
setpriority(PRIO_PROCESS, static_cast<id_t>(gettid()), -8); // Set the priority of this process to the highest value
|
setpriority(PRIO_PGRP, static_cast<id_t>(gettid()), -8); // Set the priority of this process to the highest value
|
||||||
|
|
||||||
auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)};
|
auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)};
|
||||||
auto settings{std::make_shared<skyline::Settings>(preferenceFd)};
|
auto settings{std::make_shared<skyline::Settings>(preferenceFd)};
|
||||||
@ -35,9 +38,10 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
auto start{std::chrono::steady_clock::now()};
|
auto start{std::chrono::steady_clock::now()};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
skyline::kernel::OS os(jvmManager, logger, settings, std::string(appFilesPath));
|
auto os{std::make_shared<skyline::kernel::OS>(jvmManager, logger, settings, std::string(appFilesPath))};
|
||||||
gpuWeak = os.state.gpu;
|
OsWeak = os;
|
||||||
inputWeak = os.state.input;
|
GpuWeak = os->state.gpu;
|
||||||
|
InputWeak = os->state.input;
|
||||||
jvmManager->InitializeControllers();
|
jvmManager->InitializeControllers();
|
||||||
env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath);
|
env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath);
|
||||||
|
|
||||||
@ -45,14 +49,14 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
logger->Info("Launching ROM {}", romUri);
|
logger->Info("Launching ROM {}", romUri);
|
||||||
env->ReleaseStringUTFChars(romUriJstring, romUri);
|
env->ReleaseStringUTFChars(romUriJstring, romUri);
|
||||||
|
|
||||||
os.Execute(romFd, static_cast<skyline::loader::RomFormat>(romType));
|
os->Execute(romFd, static_cast<skyline::loader::RomFormat>(romType));
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
logger->Error(e.what());
|
logger->Error(e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
logger->Error("An unknown exception has occurred");
|
logger->Error("An unknown exception has occurred");
|
||||||
}
|
}
|
||||||
|
|
||||||
inputWeak.reset();
|
InputWeak.reset();
|
||||||
|
|
||||||
logger->Info("Emulation has ended");
|
logger->Info("Emulation has ended");
|
||||||
|
|
||||||
@ -62,38 +66,50 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
close(romFd);
|
close(romFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_exitGuest(JNIEnv *, jobject, jboolean halt) {
|
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_stopEmulation(JNIEnv *, jobject) {
|
||||||
// TODO
|
auto os{OsWeak.lock()};
|
||||||
exit(0);
|
while (!os)
|
||||||
|
os = OsWeak.lock();
|
||||||
|
auto process{os->state.process};
|
||||||
|
while (!process) {
|
||||||
|
process = os->state.process;
|
||||||
|
__sync_synchronize();
|
||||||
|
}
|
||||||
|
while (!process->mainThread)
|
||||||
|
__sync_synchronize();
|
||||||
|
auto thread{process->mainThread}; // We just need to kill the main thread, it'll kill the rest itself
|
||||||
|
while (!thread->running)
|
||||||
|
__sync_synchronize();
|
||||||
|
thread->Kill(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_setSurface(JNIEnv *, jobject, jobject surface) {
|
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_setSurface(JNIEnv *, jobject, jobject surface) {
|
||||||
auto gpu{gpuWeak.lock()};
|
auto gpu{GpuWeak.lock()};
|
||||||
while (!gpu)
|
while (!gpu)
|
||||||
gpu = gpuWeak.lock();
|
gpu = GpuWeak.lock();
|
||||||
gpu->presentation.UpdateSurface(surface);
|
gpu->presentation.UpdateSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint Java_emu_skyline_EmulationActivity_getFps(JNIEnv *, jobject) {
|
extern "C" JNIEXPORT jint Java_emu_skyline_EmulationActivity_getFps(JNIEnv *, jobject) {
|
||||||
return fps;
|
return Fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jfloat Java_emu_skyline_EmulationActivity_getFrametime(JNIEnv *, jobject) {
|
extern "C" JNIEXPORT jfloat Java_emu_skyline_EmulationActivity_getFrametime(JNIEnv *, jobject) {
|
||||||
return static_cast<float>(frametime) / 100;
|
return static_cast<float>(FrameTime) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setController(JNIEnv *, jobject, jint index, jint type, jint partnerIndex) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setController(JNIEnv *, jobject, jint index, jint type, jint partnerIndex) {
|
||||||
auto input{inputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
std::lock_guard guard(input->npad.mutex);
|
std::lock_guard guard(input->npad.mutex);
|
||||||
input->npad.controllers[index] = skyline::input::GuestController{static_cast<skyline::input::NpadControllerType>(type), static_cast<skyline::i8>(partnerIndex)};
|
input->npad.controllers[index] = skyline::input::GuestController{static_cast<skyline::input::NpadControllerType>(type), static_cast<skyline::i8>(partnerIndex)};
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_updateControllers(JNIEnv *, jobject) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_updateControllers(JNIEnv *, jobject) {
|
||||||
inputWeak.lock()->npad.Update();
|
InputWeak.lock()->npad.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonState(JNIEnv *, jobject, jint index, jlong mask, jboolean pressed) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonState(JNIEnv *, jobject, jint index, jlong mask, jboolean pressed) {
|
||||||
auto input{inputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
if (!input)
|
if (!input)
|
||||||
return; // We don't mind if we miss button updates while input hasn't been initialized
|
return; // We don't mind if we miss button updates while input hasn't been initialized
|
||||||
auto device{input->npad.controllers[index].device};
|
auto device{input->npad.controllers[index].device};
|
||||||
@ -102,7 +118,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValue(JNIEnv *, jobject, jint index, jint axis, jint value) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValue(JNIEnv *, jobject, jint index, jint axis, jint value) {
|
||||||
auto input{inputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
if (!input)
|
if (!input)
|
||||||
return; // We don't mind if we miss axis updates while input hasn't been initialized
|
return; // We don't mind if we miss axis updates while input hasn't been initialized
|
||||||
auto device{input->npad.controllers[index].device};
|
auto device{input->npad.controllers[index].device};
|
||||||
@ -113,7 +129,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValu
|
|||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setTouchState(JNIEnv *env, jobject, jintArray pointsJni) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setTouchState(JNIEnv *env, jobject, jintArray pointsJni) {
|
||||||
using Point = skyline::input::TouchScreenPoint;
|
using Point = skyline::input::TouchScreenPoint;
|
||||||
|
|
||||||
auto input{inputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
if (!input)
|
if (!input)
|
||||||
return; // We don't mind if we miss touch updates while input hasn't been initialized
|
return; // We don't mind if we miss touch updates while input hasn't been initialized
|
||||||
jboolean isCopy{false};
|
jboolean isCopy{false};
|
||||||
|
@ -16,6 +16,10 @@ namespace skyline::audio {
|
|||||||
outputStream->requestStart();
|
outputStream->requestStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Audio::~Audio() {
|
||||||
|
outputStream->requestStop();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<AudioTrack> Audio::OpenTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback) {
|
std::shared_ptr<AudioTrack> Audio::OpenTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback) {
|
||||||
std::lock_guard trackGuard(trackLock);
|
std::lock_guard trackGuard(trackLock);
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ namespace skyline::audio {
|
|||||||
public:
|
public:
|
||||||
Audio(const DeviceState &state);
|
Audio(const DeviceState &state);
|
||||||
|
|
||||||
|
~Audio();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Opens a new track that can be used to play sound
|
* @brief Opens a new track that can be used to play sound
|
||||||
* @param channelCount The amount channels that are present in the track
|
* @param channelCount The amount channels that are present in the track
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <oboe/Oboe.h>
|
#include <oboe/Oboe.h>
|
||||||
#include "circular_buffer.h"
|
#include <common.h>
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/types/KEvent.h>
|
#include <kernel/types/KEvent.h>
|
||||||
|
#include <common/circular_buffer.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace skyline::audio {
|
namespace skyline::audio {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <tinyxml2.h>
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "nce.h"
|
#include "nce.h"
|
||||||
@ -11,63 +10,6 @@
|
|||||||
#include "kernel/types/KThread.h"
|
#include "kernel/types/KThread.h"
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
Settings::Settings(int fd) {
|
|
||||||
tinyxml2::XMLDocument pref;
|
|
||||||
|
|
||||||
auto fileDeleter = [](FILE *file) { fclose(file); };
|
|
||||||
std::unique_ptr<FILE, decltype(fileDeleter)> file{fdopen(fd, "r"), fileDeleter};
|
|
||||||
if (pref.LoadFile(file.get()))
|
|
||||||
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
|
|
||||||
|
|
||||||
tinyxml2::XMLElement *elem{pref.LastChild()->FirstChild()->ToElement()};
|
|
||||||
while (elem) {
|
|
||||||
switch (elem->Value()[0]) {
|
|
||||||
case 's':
|
|
||||||
stringMap[elem->FindAttribute("name")->Value()] = elem->GetText();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
boolMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->BoolValue();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'i':
|
|
||||||
intMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->IntValue();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
__android_log_print(ANDROID_LOG_WARN, "emu-cpp", "Settings type is missing: %s for %s", elem->Value(), elem->FindAttribute("name")->Value());
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (elem->NextSibling())
|
|
||||||
elem = elem->NextSibling()->ToElement();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pref.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Settings::GetString(const std::string &key) {
|
|
||||||
return stringMap.at(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::GetBool(const std::string &key) {
|
|
||||||
return boolMap.at(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Settings::GetInt(const std::string &key) {
|
|
||||||
return intMap.at(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::List(const std::shared_ptr<Logger> &logger) {
|
|
||||||
for (auto &iter : stringMap)
|
|
||||||
logger->Info("Key: {}, Value: {}, Type: String", iter.first, GetString(iter.first));
|
|
||||||
|
|
||||||
for (auto &iter : boolMap)
|
|
||||||
logger->Info("Key: {}, Value: {}, Type: Bool", iter.first, GetBool(iter.first));
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::Logger(const std::string &path, LogLevel configLevel) : configLevel(configLevel) {
|
Logger::Logger(const std::string &path, LogLevel configLevel) : configLevel(configLevel) {
|
||||||
logFile.open(path, std::ios::trunc);
|
logFile.open(path, std::ios::trunc);
|
||||||
UpdateTag();
|
UpdateTag();
|
||||||
@ -95,6 +37,7 @@ namespace skyline {
|
|||||||
|
|
||||||
std::lock_guard guard(mtx);
|
std::lock_guard guard(mtx);
|
||||||
logFile << "0|" << str << "\n";
|
logFile << "0|" << str << "\n";
|
||||||
|
logFile.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Write(LogLevel level, std::string str) {
|
void Logger::Write(LogLevel level, std::string str) {
|
||||||
@ -112,10 +55,11 @@ namespace skyline {
|
|||||||
|
|
||||||
std::lock_guard guard(mtx);
|
std::lock_guard guard(mtx);
|
||||||
logFile << "1|" << levelCharacter[static_cast<u8>(level)] << '|' << threadName << '|' << str << '\n';
|
logFile << "1|" << levelCharacter[static_cast<u8>(level)] << '|' << threadName << '|' << str << '\n';
|
||||||
|
logFile.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceState::DeviceState(kernel::OS *os, std::shared_ptr<kernel::type::KProcess> &process, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger)
|
DeviceState::DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger)
|
||||||
: os(os), jvm(std::move(jvmManager)), settings(std::move(settings)), logger(std::move(logger)), process(process) {
|
: os(os), jvm(std::move(jvmManager)), settings(std::move(settings)), logger(std::move(logger)) {
|
||||||
// We assign these later as they use the state in their constructor and we don't want null pointers
|
// We assign these later as they use the state in their constructor and we don't want null pointers
|
||||||
nce = std::make_shared<nce::NCE>(*this);
|
nce = std::make_shared<nce::NCE>(*this);
|
||||||
gpu = std::make_shared<gpu::GPU>(*this);
|
gpu = std::make_shared<gpu::GPU>(*this);
|
||||||
|
@ -141,7 +141,7 @@ namespace skyline {
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
size_t PointerValue(T *item) {
|
size_t PointerValue(T *item) {
|
||||||
return reinterpret_cast<size_t>(item);
|
return reinterpret_cast<uintptr_t>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,48 +440,7 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
class Settings;
|
||||||
* @brief The Settings class is used to access the parameters set in the Java component of the application
|
|
||||||
*/
|
|
||||||
class Settings {
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, std::string> stringMap; //!< A mapping from all keys to their corresponding string value
|
|
||||||
std::unordered_map<std::string, bool> boolMap; //!< A mapping from all keys to their corresponding boolean value
|
|
||||||
std::unordered_map<std::string, int> intMap; //!< A mapping from all keys to their corresponding integer value
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @param fd An FD to the preference XML file
|
|
||||||
*/
|
|
||||||
Settings(int fd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves a particular setting as a string
|
|
||||||
* @param key The key of the setting
|
|
||||||
* @return The string value of the setting
|
|
||||||
*/
|
|
||||||
std::string GetString(const std::string &key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves a particular setting as a boolean
|
|
||||||
* @param key The key of the setting
|
|
||||||
* @return The boolean value of the setting
|
|
||||||
*/
|
|
||||||
bool GetBool(const std::string &key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves a particular setting as a integer
|
|
||||||
* @param key The key of the setting
|
|
||||||
* @return The integer value of the setting
|
|
||||||
*/
|
|
||||||
int GetInt(const std::string &key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Writes all settings keys and values to syslog, this function is for development purposes
|
|
||||||
*/
|
|
||||||
void List(const std::shared_ptr<Logger> &logger);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace nce {
|
namespace nce {
|
||||||
class NCE;
|
class NCE;
|
||||||
struct ThreadContext;
|
struct ThreadContext;
|
||||||
@ -511,19 +470,19 @@ namespace skyline {
|
|||||||
* @brief The state of the entire emulator is contained within this class, all objects related to emulation are tied into it
|
* @brief The state of the entire emulator is contained within this class, all objects related to emulation are tied into it
|
||||||
*/
|
*/
|
||||||
struct DeviceState {
|
struct DeviceState {
|
||||||
DeviceState(kernel::OS *os, std::shared_ptr<kernel::type::KProcess> &process, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger);
|
DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger);
|
||||||
|
|
||||||
kernel::OS *os;
|
kernel::OS *os;
|
||||||
std::shared_ptr<kernel::type::KProcess> &process;
|
|
||||||
thread_local static std::shared_ptr<kernel::type::KThread> thread; //!< The KThread of the thread which accesses this object
|
|
||||||
thread_local static nce::ThreadContext *ctx; //!< The context of the guest thread for the corresponding host thread
|
|
||||||
std::shared_ptr<nce::NCE> nce;
|
|
||||||
std::shared_ptr<gpu::GPU> gpu;
|
|
||||||
std::shared_ptr<audio::Audio> audio;
|
|
||||||
std::shared_ptr<input::Input> input;
|
|
||||||
std::shared_ptr<loader::Loader> loader;
|
|
||||||
std::shared_ptr<JvmManager> jvm;
|
std::shared_ptr<JvmManager> jvm;
|
||||||
std::shared_ptr<Settings> settings;
|
std::shared_ptr<Settings> settings;
|
||||||
std::shared_ptr<Logger> logger;
|
std::shared_ptr<Logger> logger;
|
||||||
|
std::shared_ptr<loader::Loader> loader;
|
||||||
|
std::shared_ptr<gpu::GPU> gpu;
|
||||||
|
std::shared_ptr<audio::Audio> audio;
|
||||||
|
std::shared_ptr<input::Input> input;
|
||||||
|
std::shared_ptr<nce::NCE> nce;
|
||||||
|
std::shared_ptr<kernel::type::KProcess> process;
|
||||||
|
thread_local static std::shared_ptr<kernel::type::KThread> thread; //!< The KThread of the thread which accesses this object
|
||||||
|
thread_local static nce::ThreadContext *ctx; //!< The context of the guest thread for the corresponding host thread
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
|
||||||
namespace skyline::audio {
|
namespace skyline {
|
||||||
/**
|
/**
|
||||||
* @brief An abstraction of an array into a circular buffer
|
* @brief An abstraction of an array into a circular buffer
|
||||||
* @tparam Type The type of elements stored in the buffer
|
* @tparam Type The type of elements stored in the buffer
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
|
||||||
namespace skyline::gpu {
|
namespace skyline {
|
||||||
/**
|
/**
|
||||||
* @brief An efficient consumer-producer structure with internal synchronization
|
* @brief An efficient consumer-producer oriented queue with internal synchronization
|
||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
class CircularQueue {
|
class CircularQueue {
|
65
app/src/main/cpp/skyline/common/settings.cpp
Normal file
65
app/src/main/cpp/skyline/common/settings.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
namespace skyline {
|
||||||
|
Settings::Settings(int fd) {
|
||||||
|
tinyxml2::XMLDocument pref;
|
||||||
|
|
||||||
|
auto fileDeleter = [](FILE *file) { fclose(file); };
|
||||||
|
std::unique_ptr<FILE, decltype(fileDeleter)> file{fdopen(fd, "r"), fileDeleter};
|
||||||
|
if (pref.LoadFile(file.get()))
|
||||||
|
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
|
||||||
|
|
||||||
|
tinyxml2::XMLElement *elem{pref.LastChild()->FirstChild()->ToElement()};
|
||||||
|
while (elem) {
|
||||||
|
switch (elem->Value()[0]) {
|
||||||
|
case 's':
|
||||||
|
stringMap[elem->FindAttribute("name")->Value()] = elem->GetText();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
boolMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->BoolValue();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
intMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->IntValue();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
__android_log_print(ANDROID_LOG_WARN, "emu-cpp", "Settings type is missing: %s for %s", elem->Value(), elem->FindAttribute("name")->Value());
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (elem->NextSibling())
|
||||||
|
elem = elem->NextSibling()->ToElement();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pref.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Settings::GetString(const std::string &key) {
|
||||||
|
return stringMap.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::GetBool(const std::string &key) {
|
||||||
|
return boolMap.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Settings::GetInt(const std::string &key) {
|
||||||
|
return intMap.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::List(const std::shared_ptr<Logger> &logger) {
|
||||||
|
for (auto &iter : stringMap)
|
||||||
|
logger->Info("{} = \"{}\"", iter.first, GetString(iter.first));
|
||||||
|
|
||||||
|
for (auto &iter : boolMap)
|
||||||
|
logger->Info("{} = {}", iter.first, GetBool(iter.first));
|
||||||
|
}
|
||||||
|
}
|
50
app/src/main/cpp/skyline/common/settings.h
Normal file
50
app/src/main/cpp/skyline/common/settings.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
|
namespace skyline {
|
||||||
|
/**
|
||||||
|
* @brief The Settings class is used to access preferences set in the Kotlin component of Skyline
|
||||||
|
*/
|
||||||
|
class Settings {
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::string> stringMap; //!< A mapping from all keys to their corresponding string value
|
||||||
|
std::unordered_map<std::string, bool> boolMap; //!< A mapping from all keys to their corresponding boolean value
|
||||||
|
std::unordered_map<std::string, int> intMap; //!< A mapping from all keys to their corresponding integer value
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @param fd An FD to the preference XML file
|
||||||
|
*/
|
||||||
|
Settings(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves a particular setting as a string
|
||||||
|
* @param key The key of the setting
|
||||||
|
* @return The string value of the setting
|
||||||
|
*/
|
||||||
|
std::string GetString(const std::string &key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves a particular setting as a boolean
|
||||||
|
* @param key The key of the setting
|
||||||
|
* @return The boolean value of the setting
|
||||||
|
*/
|
||||||
|
bool GetBool(const std::string &key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves a particular setting as a integer
|
||||||
|
* @param key The key of the setting
|
||||||
|
* @return The integer value of the setting
|
||||||
|
*/
|
||||||
|
int GetInt(const std::string &key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes all settings keys and values to syslog, this function is for development purposes
|
||||||
|
*/
|
||||||
|
void List(const std::shared_ptr<Logger> &logger);
|
||||||
|
};
|
||||||
|
}
|
136
app/src/main/cpp/skyline/common/signal.cpp
Normal file
136
app/src/main/cpp/skyline/common/signal.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <unwind.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "signal.h"
|
||||||
|
|
||||||
|
namespace skyline::signal {
|
||||||
|
thread_local SignalException signalException;
|
||||||
|
|
||||||
|
void ExceptionThrow() {
|
||||||
|
throw signalException;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExceptionalSignalHandler(int signal, siginfo *info, ucontext *context) {
|
||||||
|
signalException.signal = signal;
|
||||||
|
signalException.pc = context->uc_mcontext.pc;
|
||||||
|
if (signal == SIGSEGV)
|
||||||
|
signalException.faultAddress = info->si_addr;
|
||||||
|
context->uc_mcontext.pc = reinterpret_cast<u64>(&ExceptionThrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Signature>
|
||||||
|
Signature GetLibcFunction(const char *symbol) {
|
||||||
|
void *libc{dlopen("libc.so", RTLD_LOCAL | RTLD_LAZY)};
|
||||||
|
if (!libc)
|
||||||
|
throw exception("dlopen-ing libc has failed with: {}", dlerror());
|
||||||
|
auto function{reinterpret_cast<Signature>(dlsym(libc, symbol))};
|
||||||
|
if (!function)
|
||||||
|
throw exception("Cannot find '{}' in libc: {}", symbol, dlerror());
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sigaction(int signal, const struct sigaction *action, struct sigaction *oldAction) {
|
||||||
|
static decltype(&sigaction) real{};
|
||||||
|
if (!real)
|
||||||
|
real = GetLibcFunction<decltype(&sigaction)>("sigaction");
|
||||||
|
if (real(signal, action, oldAction) < 0)
|
||||||
|
throw exception("sigaction has failed with {}", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *(*TlsRestorer)(){};
|
||||||
|
|
||||||
|
void SetTlsRestorer(void *(*function)()) {
|
||||||
|
TlsRestorer = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<void (*)(int, struct siginfo *, void *), NSIG> DefaultSignalHandlers;
|
||||||
|
|
||||||
|
struct ThreadSignalHandler {
|
||||||
|
pthread_key_t key;
|
||||||
|
std::atomic<u32> count;
|
||||||
|
|
||||||
|
void Decrement();
|
||||||
|
|
||||||
|
static void DecrementStatic(ThreadSignalHandler *thiz) {
|
||||||
|
thiz->Decrement();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<ThreadSignalHandler, NSIG> ThreadSignalHandlers;
|
||||||
|
|
||||||
|
void ThreadSignalHandler::Decrement() {
|
||||||
|
u32 current;
|
||||||
|
while ((current = count.load()) && !count.compare_exchange_strong(current, --current));
|
||||||
|
if (current == 0) {
|
||||||
|
int signal{static_cast<int>(this - ThreadSignalHandlers.data())};
|
||||||
|
|
||||||
|
struct sigaction oldAction;
|
||||||
|
Sigaction(signal, nullptr, &oldAction);
|
||||||
|
|
||||||
|
struct sigaction action{
|
||||||
|
.sa_sigaction = DefaultSignalHandlers.at(signal),
|
||||||
|
.sa_flags = oldAction.sa_flags,
|
||||||
|
};
|
||||||
|
Sigaction(signal, &action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadSignalHandler(int signal, siginfo *info, ucontext *context) {
|
||||||
|
void *tls{}; // The TLS value prior to being restored if it is
|
||||||
|
if (TlsRestorer)
|
||||||
|
tls = TlsRestorer();
|
||||||
|
|
||||||
|
auto handler{reinterpret_cast<void (*)(int, struct siginfo *, ucontext *, void *)>(pthread_getspecific(ThreadSignalHandlers.at(signal).key))};
|
||||||
|
if (handler) {
|
||||||
|
handler(signal, info, context, tls);
|
||||||
|
} else {
|
||||||
|
auto defaultHandler{DefaultSignalHandlers.at(signal)};
|
||||||
|
if (defaultHandler)
|
||||||
|
defaultHandler(signal, info, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls)
|
||||||
|
asm volatile("MSR TPIDR_EL0, %x0"::"r"(tls));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSignalHandler(std::initializer_list<int> signals, void (*function)(int, struct siginfo *, ucontext *, void *)) {
|
||||||
|
static std::array<std::once_flag, NSIG> signalHandlerOnce{};
|
||||||
|
|
||||||
|
stack_t stack;
|
||||||
|
sigaltstack(nullptr, &stack);
|
||||||
|
struct sigaction action{
|
||||||
|
.sa_sigaction = reinterpret_cast<void (*)(int, siginfo *, void *)>(ThreadSignalHandler),
|
||||||
|
.sa_flags = SA_RESTART | SA_SIGINFO | (stack.ss_sp && stack.ss_size ? SA_ONSTACK : 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int signal : signals) {
|
||||||
|
auto &threadHandler{ThreadSignalHandlers.at(signal)};
|
||||||
|
std::call_once(signalHandlerOnce[signal], [signal, action, &threadHandler]() {
|
||||||
|
if (int result = pthread_key_create(&threadHandler.key, reinterpret_cast<void (*)(void *)>(&ThreadSignalHandler::DecrementStatic)))
|
||||||
|
throw exception("Failed to create per-thread signal handler pthread key: {}", strerror(result));
|
||||||
|
|
||||||
|
struct sigaction oldAction;
|
||||||
|
Sigaction(signal, &action, &oldAction);
|
||||||
|
if (oldAction.sa_flags && oldAction.sa_flags != action.sa_flags)
|
||||||
|
throw exception("Old sigaction flags aren't equivalent to the replaced signal: {:#b} | {:#b}", oldAction.sa_flags, action.sa_flags);
|
||||||
|
|
||||||
|
DefaultSignalHandlers.at(signal) = oldAction.sa_sigaction;
|
||||||
|
});
|
||||||
|
if (!pthread_getspecific(ThreadSignalHandlers.at(signal).key))
|
||||||
|
threadHandler.count++;
|
||||||
|
pthread_setspecific(ThreadSignalHandlers.at(signal).key, reinterpret_cast<void *>(function));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sigprocmask(int how, const sigset_t &set, sigset_t *oldSet) {
|
||||||
|
static decltype(&pthread_sigmask) real{};
|
||||||
|
if (!real)
|
||||||
|
real = GetLibcFunction<decltype(&sigprocmask)>("sigprocmask");
|
||||||
|
if (real(how, &set, oldSet) < 0)
|
||||||
|
throw exception("sigprocmask has failed with {}", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
66
app/src/main/cpp/skyline/common/signal.h
Normal file
66
app/src/main/cpp/skyline/common/signal.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
|
namespace skyline::signal {
|
||||||
|
/**
|
||||||
|
* @brief An exception object that is designed specifically to hold Linux signals
|
||||||
|
* @note This doesn't inherit std::exception as it shouldn't be caught as such
|
||||||
|
* @note Refer to the manpage siginfo(3) for information on members
|
||||||
|
*/
|
||||||
|
class SignalException {
|
||||||
|
public:
|
||||||
|
int signal{};
|
||||||
|
u64 pc{};
|
||||||
|
void *faultAddress{};
|
||||||
|
|
||||||
|
inline std::string what() const {
|
||||||
|
if (!faultAddress)
|
||||||
|
return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), pc);
|
||||||
|
else
|
||||||
|
return fmt::format("Signal: {} @ 0x{:X} (PC: 0x{:X})", strsignal(signal), reinterpret_cast<u64>(faultAddress), pc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A signal handler which automatically throws an exception with the corresponding signal metadata in a SignalException
|
||||||
|
*/
|
||||||
|
void ExceptionalSignalHandler(int signal, siginfo *, ucontext *context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Our delegator for sigaction, we need to do this due to sigchain hooking bionic's sigaction and it intercepting signals before they're passed onto userspace
|
||||||
|
* This not only leads to performance degradation but also requires host TLS to be in the TLS register which we cannot ensure for in-guest signals
|
||||||
|
*/
|
||||||
|
void Sigaction(int signal, const struct sigaction *action, struct sigaction *oldAction = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief If the TLS value of the code running prior to a signal has a custom TLS value, this should be used to restore it
|
||||||
|
* @param function A function which is inert if the TLS isn't required to be restored, it should return nullptr if TLS wasn't restored else the old TLS value
|
||||||
|
*/
|
||||||
|
void SetTlsRestorer(void *(*function)());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A wrapper around Sigaction to make it easy to set a sigaction signal handler for multiple signals and also allow for thread-local signal handlers
|
||||||
|
* @param function A sa_action callback with the old TLS (If present) as the 4th argument
|
||||||
|
*/
|
||||||
|
void SetSignalHandler(std::initializer_list<int> signals, void (*function)(int, struct siginfo *, ucontext *, void *));
|
||||||
|
|
||||||
|
inline void SetSignalHandler(std::initializer_list<int> signals, void (*function)(int, struct siginfo *, ucontext *)) {
|
||||||
|
SetSignalHandler(signals, reinterpret_cast<void (*)(int, struct siginfo *, ucontext *, void *)>(function));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Our delegator for sigprocmask, required due to libsigchain hooking this
|
||||||
|
*/
|
||||||
|
void Sigprocmask(int how, const sigset_t &set, sigset_t *oldSet = nullptr);
|
||||||
|
|
||||||
|
inline void BlockSignal(std::initializer_list<int> signals) {
|
||||||
|
sigset_t set{};
|
||||||
|
for (int signal : signals)
|
||||||
|
sigaddset(&set, signal);
|
||||||
|
Sigprocmask(SIG_BLOCK, set, nullptr);
|
||||||
|
}
|
||||||
|
}
|
@ -24,8 +24,8 @@ namespace skyline::gpu {
|
|||||||
std::shared_ptr<engine::Engine> maxwellCompute;
|
std::shared_ptr<engine::Engine> maxwellCompute;
|
||||||
std::shared_ptr<engine::Engine> maxwellDma;
|
std::shared_ptr<engine::Engine> maxwellDma;
|
||||||
std::shared_ptr<engine::Engine> keplerMemory;
|
std::shared_ptr<engine::Engine> keplerMemory;
|
||||||
gpfifo::GPFIFO gpfifo;
|
|
||||||
std::array<Syncpoint, constant::MaxHwSyncpointCount> syncpoints{};
|
std::array<Syncpoint, constant::MaxHwSyncpointCount> syncpoints{};
|
||||||
|
gpfifo::GPFIFO gpfifo;
|
||||||
|
|
||||||
inline GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
inline GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <common/signal.h>
|
||||||
|
#include <kernel/types/KProcess.h>
|
||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include <gpu/engines/maxwell_3d.h>
|
#include <gpu/engines/maxwell_3d.h>
|
||||||
#include "gpfifo.h"
|
#include "gpfifo.h"
|
||||||
@ -86,19 +88,38 @@ namespace skyline::gpu::gpfifo {
|
|||||||
|
|
||||||
void GPFIFO::Run() {
|
void GPFIFO::Run() {
|
||||||
pthread_setname_np(pthread_self(), "GPFIFO");
|
pthread_setname_np(pthread_self(), "GPFIFO");
|
||||||
pushBuffers->Process([this](PushBuffer& pushBuffer){
|
try {
|
||||||
if (pushBuffer.segment.empty())
|
signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}, signal::ExceptionalSignalHandler);
|
||||||
pushBuffer.Fetch(state.gpu->memoryManager);
|
pushBuffers->Process([this](PushBuffer &pushBuffer) {
|
||||||
Process(pushBuffer.segment);
|
if (pushBuffer.segment.empty())
|
||||||
});
|
pushBuffer.Fetch(state.gpu->memoryManager);
|
||||||
|
Process(pushBuffer.segment);
|
||||||
|
});
|
||||||
|
} catch (const signal::SignalException &e) {
|
||||||
|
if (e.signal != SIGINT) {
|
||||||
|
state.logger->Write(Logger::LogLevel::Error, e.what());
|
||||||
|
signal::BlockSignal({SIGINT});
|
||||||
|
state.process->mainThread->Kill(false);
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
state.logger->Write(Logger::LogLevel::Error, e.what());
|
||||||
|
state.process->mainThread->Kill(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPFIFO::Push(span<GpEntry> entries) {
|
void GPFIFO::Push(span<GpEntry> entries) {
|
||||||
bool beforeBarrier{true};
|
bool beforeBarrier{true};
|
||||||
pushBuffers->AppendTranform(entries, [&beforeBarrier, this](const GpEntry& entry){
|
pushBuffers->AppendTranform(entries, [&beforeBarrier, this](const GpEntry &entry) {
|
||||||
if (entry.sync == GpEntry::Sync::Wait)
|
if (entry.sync == GpEntry::Sync::Wait)
|
||||||
beforeBarrier = false;
|
beforeBarrier = false;
|
||||||
return PushBuffer(entry, state.gpu->memoryManager, beforeBarrier);
|
return PushBuffer(entry, state.gpu->memoryManager, beforeBarrier);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPFIFO::~GPFIFO() {
|
||||||
|
if (thread.joinable()) {
|
||||||
|
pthread_kill(thread.native_handle(), SIGINT);
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "circular_queue.h"
|
#include <common/circular_queue.h>
|
||||||
#include "engines/gpfifo.h"
|
#include "engines/gpfifo.h"
|
||||||
#include "memory_manager.h"
|
#include "memory_manager.h"
|
||||||
|
|
||||||
@ -163,6 +163,8 @@ namespace skyline::gpu {
|
|||||||
public:
|
public:
|
||||||
GPFIFO(const DeviceState &state) : state(state), gpfifoEngine(state) {}
|
GPFIFO(const DeviceState &state) : state(state), gpfifoEngine(state) {}
|
||||||
|
|
||||||
|
~GPFIFO();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param numBuffers The amount of push-buffers to allocate in the circular buffer
|
* @param numBuffers The amount of push-buffers to allocate in the circular buffer
|
||||||
*/
|
*/
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include "jvm.h"
|
#include "jvm.h"
|
||||||
#include "presentation_engine.h"
|
#include "presentation_engine.h"
|
||||||
|
|
||||||
extern skyline::u16 fps;
|
extern skyline::u16 Fps;
|
||||||
extern skyline::u32 frametime;
|
extern skyline::u32 FrameTime;
|
||||||
|
|
||||||
namespace skyline::gpu {
|
namespace skyline::gpu {
|
||||||
PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared<kernel::type::KEvent>(state)), bufferEvent(std::make_shared<kernel::type::KEvent>(state)) {}
|
PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared<kernel::type::KEvent>(state)), bufferEvent(std::make_shared<kernel::type::KEvent>(state)) {}
|
||||||
@ -29,7 +29,7 @@ namespace skyline::gpu {
|
|||||||
if (!env->IsSameObject(newSurface, nullptr))
|
if (!env->IsSameObject(newSurface, nullptr))
|
||||||
surface = env->NewGlobalRef(newSurface);
|
surface = env->NewGlobalRef(newSurface);
|
||||||
if (surface) {
|
if (surface) {
|
||||||
window = ANativeWindow_fromSurface(state.jvm->GetEnv(), surface);
|
window = ANativeWindow_fromSurface(env, surface);
|
||||||
ANativeWindow_acquire(window);
|
ANativeWindow_acquire(window);
|
||||||
resolution.width = static_cast<u32>(ANativeWindow_getWidth(window));
|
resolution.width = static_cast<u32>(ANativeWindow_getWidth(window));
|
||||||
resolution.height = static_cast<u32>(ANativeWindow_getHeight(window));
|
resolution.height = static_cast<u32>(ANativeWindow_getHeight(window));
|
||||||
@ -73,8 +73,8 @@ namespace skyline::gpu {
|
|||||||
if (frameTimestamp) {
|
if (frameTimestamp) {
|
||||||
auto now{util::GetTimeNs()};
|
auto now{util::GetTimeNs()};
|
||||||
|
|
||||||
frametime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
FrameTime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
||||||
fps = static_cast<u16>(constant::NsInSecond / (now - frameTimestamp));
|
Fps = static_cast<u16>(constant::NsInSecond / (now - frameTimestamp));
|
||||||
|
|
||||||
frameTimestamp = now;
|
frameTimestamp = now;
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,7 +14,7 @@ namespace skyline::gpu {
|
|||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
std::mutex windowMutex;
|
std::mutex windowMutex;
|
||||||
std::condition_variable windowConditional;
|
std::condition_variable windowConditional;
|
||||||
jobject surface; //!< The Surface object backing the ANativeWindow
|
jobject surface{}; //!< The Surface object backing the ANativeWindow
|
||||||
u64 frameTimestamp{}; //!< The timestamp of the last frame being shown
|
u64 frameTimestamp{}; //!< The timestamp of the last frame being shown
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -8,18 +8,19 @@ namespace skyline {
|
|||||||
* @brief A thread-local wrapper over JNIEnv and JavaVM which automatically handles attaching and detaching threads
|
* @brief A thread-local wrapper over JNIEnv and JavaVM which automatically handles attaching and detaching threads
|
||||||
*/
|
*/
|
||||||
struct JniEnvironment {
|
struct JniEnvironment {
|
||||||
static inline JNIEnv *env{};
|
JNIEnv *env{};
|
||||||
static inline JavaVM *vm{};
|
static inline JavaVM *vm{};
|
||||||
bool attached{};
|
bool attached{};
|
||||||
|
|
||||||
JniEnvironment(JNIEnv *environment) {
|
void Initialize(JNIEnv *environment) {
|
||||||
env = environment;
|
env = environment;
|
||||||
if (env->GetJavaVM(&vm) < 0)
|
if (env->GetJavaVM(&vm) < 0)
|
||||||
throw exception("Cannot get JavaVM from environment");
|
throw exception("Cannot get JavaVM from environment");
|
||||||
|
attached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JniEnvironment() {
|
JniEnvironment() {
|
||||||
if (vm) {
|
if (vm && !attached) {
|
||||||
vm->AttachCurrentThread(&env, nullptr);
|
vm->AttachCurrentThread(&env, nullptr);
|
||||||
attached = true;
|
attached = true;
|
||||||
}
|
}
|
||||||
@ -31,10 +32,14 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator JNIEnv *() {
|
operator JNIEnv *() {
|
||||||
|
if (!attached)
|
||||||
|
throw exception("Not attached");
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* operator->() {
|
JNIEnv *operator->() {
|
||||||
|
if (!attached)
|
||||||
|
throw exception("Not attached");
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -42,7 +47,7 @@ namespace skyline {
|
|||||||
thread_local inline JniEnvironment env;
|
thread_local inline JniEnvironment env;
|
||||||
|
|
||||||
JvmManager::JvmManager(JNIEnv *environ, jobject instance) : instance(environ->NewGlobalRef(instance)), instanceClass(reinterpret_cast<jclass>(environ->NewGlobalRef(environ->GetObjectClass(instance)))), initializeControllersId(environ->GetMethodID(instanceClass, "initializeControllers", "()V")), vibrateDeviceId(environ->GetMethodID(instanceClass, "vibrateDevice", "(I[J[I)V")), clearVibrationDeviceId(environ->GetMethodID(instanceClass, "clearVibrationDevice", "(I)V")) {
|
JvmManager::JvmManager(JNIEnv *environ, jobject instance) : instance(environ->NewGlobalRef(instance)), instanceClass(reinterpret_cast<jclass>(environ->NewGlobalRef(environ->GetObjectClass(instance)))), initializeControllersId(environ->GetMethodID(instanceClass, "initializeControllers", "()V")), vibrateDeviceId(environ->GetMethodID(instanceClass, "vibrateDevice", "(I[J[I)V")), clearVibrationDeviceId(environ->GetMethodID(instanceClass, "clearVibrationDevice", "(I)V")) {
|
||||||
env = JniEnvironment(environ);
|
env.Initialize(environ);
|
||||||
}
|
}
|
||||||
|
|
||||||
JvmManager::~JvmManager() {
|
JvmManager::~JvmManager() {
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
namespace skyline::kernel {
|
namespace skyline::kernel {
|
||||||
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {}
|
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
|
MemoryManager::~MemoryManager() {
|
||||||
|
if (base.address && base.size)
|
||||||
|
munmap(reinterpret_cast<void *>(base.address), base.size);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr size_t RegionAlignment{1ULL << 21}; //!< The minimum alignment of a HOS memory region
|
constexpr size_t RegionAlignment{1ULL << 21}; //!< The minimum alignment of a HOS memory region
|
||||||
|
|
||||||
void MemoryManager::InitializeVmm(memory::AddressSpaceType type) {
|
void MemoryManager::InitializeVmm(memory::AddressSpaceType type) {
|
||||||
|
@ -226,6 +226,8 @@ namespace skyline {
|
|||||||
|
|
||||||
MemoryManager(const DeviceState &state);
|
MemoryManager(const DeviceState &state);
|
||||||
|
|
||||||
|
~MemoryManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note This should be called before any mappings in the VMM or calls to InitalizeRegions are done
|
* @note This should be called before any mappings in the VMM or calls to InitalizeRegions are done
|
||||||
*/
|
*/
|
||||||
|
@ -169,7 +169,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
std::memcpy(source, destination, size);
|
std::memcpy(source, destination, size);
|
||||||
|
|
||||||
auto sourceObject{state.process->GetMemoryObject(destination)};
|
auto sourceObject{state.process->GetMemoryObject(source)};
|
||||||
if (!sourceObject)
|
if (!sourceObject)
|
||||||
throw exception("svcUnmapMemory: Cannot find source memory object in handle table for address 0x{:X}", source);
|
throw exception("svcUnmapMemory: Cannot find source memory object in handle table for address 0x{:X}", source);
|
||||||
|
|
||||||
@ -216,7 +216,9 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
void ExitProcess(const DeviceState &state) {
|
void ExitProcess(const DeviceState &state) {
|
||||||
state.logger->Debug("svcExitProcess: Exiting process");
|
state.logger->Debug("svcExitProcess: Exiting process");
|
||||||
exit(0);
|
if (state.thread->id)
|
||||||
|
state.process->mainThread->Kill(false);
|
||||||
|
std::longjmp(state.thread->originalCtx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr i32 IdealCoreDontCare{-1};
|
constexpr i32 IdealCoreDontCare{-1};
|
||||||
@ -269,8 +271,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
void ExitThread(const DeviceState &state) {
|
void ExitThread(const DeviceState &state) {
|
||||||
state.logger->Debug("svcExitThread: Exiting current thread: {}", state.thread->id);
|
state.logger->Debug("svcExitThread: Exiting current thread: {}", state.thread->id);
|
||||||
state.thread->Kill();
|
std::longjmp(state.thread->originalCtx, true);
|
||||||
pthread_exit(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SleepThread(const DeviceState &state) {
|
void SleepThread(const DeviceState &state) {
|
||||||
@ -708,34 +709,34 @@ namespace skyline::kernel::svc {
|
|||||||
void GetInfo(const DeviceState &state) {
|
void GetInfo(const DeviceState &state) {
|
||||||
enum class InfoState : u32 {
|
enum class InfoState : u32 {
|
||||||
// 1.0.0+
|
// 1.0.0+
|
||||||
AllowedCpuIdBitmask = 0,
|
AllowedCpuIdBitmask = 0,
|
||||||
AllowedThreadPriorityMask = 1,
|
AllowedThreadPriorityMask = 1,
|
||||||
AliasRegionBaseAddr = 2,
|
AliasRegionBaseAddr = 2,
|
||||||
AliasRegionSize = 3,
|
AliasRegionSize = 3,
|
||||||
HeapRegionBaseAddr = 4,
|
HeapRegionBaseAddr = 4,
|
||||||
HeapRegionSize = 5,
|
HeapRegionSize = 5,
|
||||||
TotalMemoryAvailable = 6,
|
TotalMemoryAvailable = 6,
|
||||||
TotalMemoryUsage = 7,
|
TotalMemoryUsage = 7,
|
||||||
IsCurrentProcessBeingDebugged = 8,
|
IsCurrentProcessBeingDebugged = 8,
|
||||||
ResourceLimit = 9,
|
ResourceLimit = 9,
|
||||||
IdleTickCount = 10,
|
IdleTickCount = 10,
|
||||||
RandomEntropy = 11,
|
RandomEntropy = 11,
|
||||||
// 2.0.0+
|
// 2.0.0+
|
||||||
AddressSpaceBaseAddr = 12,
|
AddressSpaceBaseAddr = 12,
|
||||||
AddressSpaceSize = 13,
|
AddressSpaceSize = 13,
|
||||||
StackRegionBaseAddr = 14,
|
StackRegionBaseAddr = 14,
|
||||||
StackRegionSize = 15,
|
StackRegionSize = 15,
|
||||||
// 3.0.0+
|
// 3.0.0+
|
||||||
TotalSystemResourceAvailable = 16,
|
TotalSystemResourceAvailable = 16,
|
||||||
TotalSystemResourceUsage = 17,
|
TotalSystemResourceUsage = 17,
|
||||||
TitleId = 18,
|
TitleId = 18,
|
||||||
// 4.0.0+
|
// 4.0.0+
|
||||||
PrivilegedProcessId = 19,
|
PrivilegedProcessId = 19,
|
||||||
// 5.0.0+
|
// 5.0.0+
|
||||||
UserExceptionContextAddr = 20,
|
UserExceptionContextAddr = 20,
|
||||||
// 6.0.0+
|
// 6.0.0+
|
||||||
TotalMemoryAvailableWithoutSystemResource = 21,
|
TotalMemoryAvailableWithoutSystemResource = 21,
|
||||||
TotalMemoryUsageWithoutSystemResource = 22,
|
TotalMemoryUsageWithoutSystemResource = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
InfoState info{static_cast<u32>(state.ctx->gpr.w1)};
|
InfoState info{static_cast<u32>(state.ctx->gpr.w1)};
|
||||||
|
@ -50,14 +50,15 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<KThread> KProcess::CreateThread(void *entry, u64 argument, void *stackTop, i8 priority, i8 idealCore) {
|
std::shared_ptr<KThread> KProcess::CreateThread(void *entry, u64 argument, void *stackTop, i8 priority, i8 idealCore) {
|
||||||
if (!stackTop && threads.empty()) { //!< Main thread stack is created by the kernel and owned by the process
|
if (!stackTop && !mainThread) { //!< Main thread stack is created by the kernel and owned by the process
|
||||||
mainThreadStack = mainThreadStack.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), state.process->npdm.meta.mainThreadStackSize, memory::Permission{true, true, false}, memory::states::Stack);
|
mainThreadStack = mainThreadStack.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), state.process->npdm.meta.mainThreadStackSize, memory::Permission{true, true, false}, memory::states::Stack);
|
||||||
if (mprotect(mainThreadStack->ptr, PAGE_SIZE, PROT_NONE))
|
if (mprotect(mainThreadStack->ptr, PAGE_SIZE, PROT_NONE))
|
||||||
throw exception("Failed to create guard page for thread stack at 0x{:X}", mainThreadStack->ptr);
|
throw exception("Failed to create guard page for thread stack at 0x{:X}", mainThreadStack->ptr);
|
||||||
stackTop = mainThreadStack->ptr + mainThreadStack->size;
|
stackTop = mainThreadStack->ptr + mainThreadStack->size;
|
||||||
}
|
}
|
||||||
auto thread{NewHandle<KThread>(this, threads.size(), entry, argument, stackTop, (priority == -1) ? state.process->npdm.meta.mainThreadPriority : priority, (idealCore == -1) ? state.process->npdm.meta.idealCore : idealCore).item};
|
auto thread{NewHandle<KThread>(this, threadIndex++, entry, argument, stackTop, (priority == -1) ? state.process->npdm.meta.mainThreadPriority : priority, (idealCore == -1) ? state.process->npdm.meta.idealCore : idealCore).item};
|
||||||
threads.push_back(thread);
|
if (!mainThread)
|
||||||
|
mainThread = thread;
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,13 +24,10 @@ namespace skyline {
|
|||||||
* @brief KProcess manages process-global state such as memory, kernel handles allocated to the process and synchronization primitives
|
* @brief KProcess manages process-global state such as memory, kernel handles allocated to the process and synchronization primitives
|
||||||
*/
|
*/
|
||||||
class KProcess : public KSyncObject {
|
class KProcess : public KSyncObject {
|
||||||
public:
|
public: // We have intermittent public/private members to ensure proper construction/destruction order
|
||||||
MemoryManager memory; // This is here to ensure it is present during the destruction of dependent objects
|
MemoryManager memory;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<KObject>> handles;
|
|
||||||
std::shared_mutex handleMutex;
|
|
||||||
|
|
||||||
struct WaitStatus {
|
struct WaitStatus {
|
||||||
std::atomic_bool flag{false};
|
std::atomic_bool flag{false};
|
||||||
i8 priority;
|
i8 priority;
|
||||||
@ -47,6 +44,8 @@ namespace skyline {
|
|||||||
std::mutex mutexLock;
|
std::mutex mutexLock;
|
||||||
std::mutex conditionalLock;
|
std::mutex conditionalLock;
|
||||||
|
|
||||||
|
size_t threadIndex{}; //!< The ID assigned to the next created thread
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The status of a single TLS page (A page is 4096 bytes on ARMv8)
|
* @brief The status of a single TLS page (A page is 4096 bytes on ARMv8)
|
||||||
* Each TLS page has 8 slots, each 0x200 (512) bytes in size
|
* Each TLS page has 8 slots, each 0x200 (512) bytes in size
|
||||||
@ -69,10 +68,15 @@ namespace skyline {
|
|||||||
public:
|
public:
|
||||||
std::shared_ptr<KPrivateMemory> mainThreadStack;
|
std::shared_ptr<KPrivateMemory> mainThreadStack;
|
||||||
std::shared_ptr<KPrivateMemory> heap;
|
std::shared_ptr<KPrivateMemory> heap;
|
||||||
std::vector<std::shared_ptr<KThread>> threads;
|
|
||||||
std::vector<std::shared_ptr<TlsPage>> tlsPages;
|
std::vector<std::shared_ptr<TlsPage>> tlsPages;
|
||||||
|
std::shared_ptr<KThread> mainThread;
|
||||||
vfs::NPDM npdm;
|
vfs::NPDM npdm;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_mutex handleMutex;
|
||||||
|
std::vector<std::shared_ptr<KObject>> handles;
|
||||||
|
|
||||||
|
public:
|
||||||
KProcess(const DeviceState &state);
|
KProcess(const DeviceState &state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,7 @@ namespace skyline::kernel::type {
|
|||||||
if (kernel.Valid())
|
if (kernel.Valid())
|
||||||
munmap(kernel.ptr, kernel.size);
|
munmap(kernel.ptr, kernel.size);
|
||||||
|
|
||||||
if (guest.Valid()) {
|
if (state.process && guest.Valid()) {
|
||||||
mmap(guest.ptr, guest.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
mmap(guest.ptr, guest.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
state.process->memory.InsertChunk(ChunkDescriptor{
|
state.process->memory.InsertChunk(ChunkDescriptor{
|
||||||
.ptr = guest.ptr,
|
.ptr = guest.ptr,
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
#include <common/signal.h>
|
||||||
#include <nce.h>
|
#include <nce.h>
|
||||||
#include <os.h>
|
#include <os.h>
|
||||||
#include "KProcess.h"
|
#include "KProcess.h"
|
||||||
@ -15,29 +15,19 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KThread::~KThread() {
|
KThread::~KThread() {
|
||||||
Kill();
|
if (running && pthread != pthread_self()) {
|
||||||
}
|
pthread_kill(pthread, SIGINT);
|
||||||
|
if (thread)
|
||||||
/**
|
thread->join();
|
||||||
* @brief Our delegator for sigaction, we need to do this due to sigchain hooking bionic's sigaction and it intercepting signals before they're passed onto userspace
|
else
|
||||||
* This not only leads to performance degradation but also requires host TLS to be in the TLS register which we cannot ensure for in-guest signals
|
pthread_join(pthread, nullptr);
|
||||||
*/
|
|
||||||
inline void Sigaction(int signal, const struct sigaction &action, struct sigaction *oldAction = nullptr) {
|
|
||||||
static decltype(&sigaction) realSigaction{};
|
|
||||||
if (!realSigaction) {
|
|
||||||
void *libc{dlopen("libc.so", RTLD_LOCAL | RTLD_LAZY)};
|
|
||||||
if (!libc)
|
|
||||||
throw exception("dlopen-ing libc has failed with: {}", dlerror());
|
|
||||||
realSigaction = reinterpret_cast<decltype(&sigaction)>(dlsym(libc, "sigaction"));
|
|
||||||
if (!realSigaction)
|
|
||||||
throw exception("Cannot find 'sigaction' in libc: {}", dlerror());
|
|
||||||
}
|
}
|
||||||
if (realSigaction(signal, &action, oldAction) < 0)
|
|
||||||
throw exception("sigaction has failed with {}", strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::StartThread() {
|
void KThread::StartThread() {
|
||||||
pthread_setname_np(pthread_self(), fmt::format("HOS-{}", id).c_str());
|
std::array<char, 16> threadName;
|
||||||
|
pthread_getname_np(pthread, threadName.data(), threadName.size());
|
||||||
|
pthread_setname_np(pthread, fmt::format("HOS-{}", id).c_str());
|
||||||
state.logger->UpdateTag();
|
state.logger->UpdateTag();
|
||||||
|
|
||||||
if (!ctx.tpidrroEl0)
|
if (!ctx.tpidrroEl0)
|
||||||
@ -47,12 +37,17 @@ namespace skyline::kernel::type {
|
|||||||
state.ctx = &ctx;
|
state.ctx = &ctx;
|
||||||
state.thread = shared_from_this();
|
state.thread = shared_from_this();
|
||||||
|
|
||||||
struct sigaction sigact{
|
if (setjmp(originalCtx)) { // Returns 1 if it's returning from guest, 0 otherwise
|
||||||
.sa_sigaction = &nce::NCE::SignalHandler,
|
running = false;
|
||||||
.sa_flags = SA_SIGINFO,
|
Signal();
|
||||||
};
|
|
||||||
for (int signal : {SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV})
|
pthread_setname_np(pthread, threadName.data());
|
||||||
Sigaction(signal, sigact);
|
state.logger->UpdateTag();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}, nce::NCE::SignalHandler);
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"MRS X0, TPIDR_EL0\n\t"
|
"MRS X0, TPIDR_EL0\n\t"
|
||||||
@ -136,28 +131,32 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Start(bool self) {
|
void KThread::Start(bool self) {
|
||||||
|
std::unique_lock lock(mutex);
|
||||||
if (!running) {
|
if (!running) {
|
||||||
running = true;
|
running = true;
|
||||||
state.logger->Debug("Starting thread #{}", id);
|
state.logger->Debug("Starting thread #{}", id);
|
||||||
if (self)
|
if (self) {
|
||||||
|
pthread = pthread_self();
|
||||||
|
lock.unlock();
|
||||||
StartThread();
|
StartThread();
|
||||||
else
|
} else {
|
||||||
thread.emplace(&KThread::StartThread, this);
|
thread.emplace(&KThread::StartThread, this);
|
||||||
|
pthread = thread->native_handle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Kill() {
|
void KThread::Kill(bool join) {
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
if (running) {
|
if (running) {
|
||||||
|
pthread_kill(pthread, SIGINT);
|
||||||
|
if (join)
|
||||||
|
pthread_join(pthread, nullptr);
|
||||||
running = false;
|
running = false;
|
||||||
Signal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::UpdatePriority(i8 priority) {
|
void KThread::UpdatePriority(i8 priority) {
|
||||||
this->priority = priority;
|
this->priority = priority;
|
||||||
auto priorityValue{constant::AndroidPriority.Rescale(constant::HosPriority, priority)};
|
|
||||||
|
|
||||||
if (setpriority(PRIO_PROCESS, getpid(), priorityValue) == -1)
|
|
||||||
throw exception("Couldn't set thread priority to {} for #{}", priorityValue, id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <csetjmp>
|
||||||
#include <nce/guest.h>
|
#include <nce/guest.h>
|
||||||
#include "KSyncObject.h"
|
#include "KSyncObject.h"
|
||||||
#include "KPrivateMemory.h"
|
#include "KPrivateMemory.h"
|
||||||
@ -35,7 +36,6 @@ namespace skyline {
|
|||||||
|
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u8 CoreCount{4}; // The amount of cores an HOS process can be scheduled onto (User applications can only be on the first 3 cores, the last one is reserved for the system)
|
constexpr u8 CoreCount{4}; // The amount of cores an HOS process can be scheduled onto (User applications can only be on the first 3 cores, the last one is reserved for the system)
|
||||||
constexpr kernel::type::Priority AndroidPriority{19, -8}; //!< The range of priorities for Android
|
|
||||||
constexpr kernel::type::Priority HosPriority{0, 63}; //!< The range of priorities for Horizon OS
|
constexpr kernel::type::Priority HosPriority{0, 63}; //!< The range of priorities for Horizon OS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,25 +43,28 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @brief KThread manages a single thread of execution which is responsible for running guest code and kernel code which is invoked by the guest
|
* @brief KThread manages a single thread of execution which is responsible for running guest code and kernel code which is invoked by the guest
|
||||||
*/
|
*/
|
||||||
class KThread : public KSyncObject, public std::enable_shared_from_this<KThread> {
|
class KThread : public KSyncObject, public std::enable_shared_from_this<KThread> {
|
||||||
private:
|
private:
|
||||||
KProcess *parent;
|
KProcess *parent;
|
||||||
std::optional<std::thread> thread; //!< If this KThread is backed by a host thread then this'll hold it
|
std::optional<std::thread> thread; //!< If this KThread is backed by a host thread then this'll hold it
|
||||||
|
pthread_t pthread{}; //!< The pthread_t for the host thread running this guest thread
|
||||||
|
|
||||||
void StartThread();
|
void StartThread();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::mutex mutex; //!< Synchronizes all thread state changes
|
||||||
bool running{false};
|
bool running{false};
|
||||||
std::atomic<bool> cancelSync{false}; //!< This is to flag to a thread to cancel a synchronization call it currently is in
|
std::atomic<bool> cancelSync{false}; //!< This is to flag to a thread to cancel a synchronization call it currently is in
|
||||||
|
|
||||||
KHandle handle;
|
KHandle handle;
|
||||||
size_t id; //!< Index of thread in parent process's KThread vector
|
size_t id; //!< Index of thread in parent process's KThread vector
|
||||||
|
|
||||||
nce::ThreadContext ctx{};
|
nce::ThreadContext ctx{}; //!< The context of the guest thread during the last SVC
|
||||||
|
jmp_buf originalCtx; //!< The context of the host thread prior to jumping into guest code
|
||||||
|
|
||||||
void* entry;
|
void *entry;
|
||||||
u64 entryArgument;
|
u64 entryArgument;
|
||||||
void* stackTop;
|
void *stackTop;
|
||||||
|
|
||||||
i8 priority;
|
i8 priority;
|
||||||
i8 idealCore;
|
i8 idealCore;
|
||||||
@ -80,15 +83,10 @@ namespace skyline {
|
|||||||
void Start(bool self = false);
|
void Start(bool self = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the internal state of the thread to signal it being dead
|
* @param join Returns after the guest thread has joined rather than instantly
|
||||||
* @note This should only be called by the host thread running this guest thread
|
|
||||||
*/
|
*/
|
||||||
void Kill();
|
void Kill(bool join);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the host priority using setpriority with a rescaled the priority from HOS to Android
|
|
||||||
* @note It also affects guest scheduler behavior, this isn't purely for host
|
|
||||||
*/
|
|
||||||
void UpdatePriority(i8 priority);
|
void UpdatePriority(i8 priority);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <sched.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "common/signal.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "gpu.h"
|
#include "gpu.h"
|
||||||
#include "jvm.h"
|
#include "jvm.h"
|
||||||
@ -23,57 +23,84 @@ namespace skyline::nce {
|
|||||||
} else {
|
} else {
|
||||||
throw exception("Unimplemented SVC 0x{:X}", svc);
|
throw exception("Unimplemented SVC 0x{:X}", svc);
|
||||||
}
|
}
|
||||||
|
} catch (const signal::SignalException &e) {
|
||||||
|
if (e.signal != SIGINT) {
|
||||||
|
state.logger->Error("{} (SVC: 0x{:X})", e.what(), svc);
|
||||||
|
if (state.thread->id) {
|
||||||
|
signal::BlockSignal({SIGINT});
|
||||||
|
state.process->mainThread->Kill(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::longjmp(state.thread->originalCtx, true);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
state.logger->Error("{} (SVC: 0x{:X})", e.what(), svc);
|
state.logger->Error("{} (SVC: 0x{:X})", e.what(), svc);
|
||||||
exit(0);
|
if (state.thread->id) {
|
||||||
|
signal::BlockSignal({SIGINT});
|
||||||
|
state.process->mainThread->Kill(false);
|
||||||
|
}
|
||||||
|
std::longjmp(state.thread->originalCtx, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCE::SignalHandler(int signal, siginfo *, void *context) {
|
void NCE::SignalHandler(int signal, siginfo *info, ucontext *context, void *oldTls) {
|
||||||
|
if (oldTls) {
|
||||||
|
const auto &state{*reinterpret_cast<ThreadContext *>(oldTls)->state};
|
||||||
|
|
||||||
|
state.logger->Warn("Thread #{} has crashed due to signal: {}", state.thread->id, strsignal(signal));
|
||||||
|
|
||||||
|
std::string raw;
|
||||||
|
std::string trace;
|
||||||
|
std::string cpuContext;
|
||||||
|
|
||||||
|
const auto &ctx{reinterpret_cast<ucontext *>(context)->uc_mcontext};
|
||||||
|
constexpr u16 instructionCount{20}; // The amount of previous instructions to print
|
||||||
|
auto offset{ctx.pc - (instructionCount * sizeof(u32)) + (2 * sizeof(u32))};
|
||||||
|
span instructions(reinterpret_cast<u32 *>(offset), instructionCount);
|
||||||
|
for (auto &instruction : instructions) {
|
||||||
|
instruction = __builtin_bswap32(instruction);
|
||||||
|
|
||||||
|
if (offset == ctx.pc)
|
||||||
|
trace += fmt::format("\n-> 0x{:X} : 0x{:08X}", offset, instruction);
|
||||||
|
else
|
||||||
|
trace += fmt::format("\n 0x{:X} : 0x{:08X}", offset, instruction);
|
||||||
|
|
||||||
|
raw += fmt::format("{:08X}", instruction);
|
||||||
|
offset += sizeof(u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.fault_address)
|
||||||
|
cpuContext += fmt::format("\nFault Address: 0x{:X}", ctx.fault_address);
|
||||||
|
|
||||||
|
if (ctx.sp)
|
||||||
|
cpuContext += fmt::format("\nStack Pointer: 0x{:X}", ctx.sp);
|
||||||
|
|
||||||
|
for (u8 index{}; index < ((sizeof(mcontext_t::regs) / sizeof(u64)) - 2); index += 2)
|
||||||
|
cpuContext += fmt::format("\n{}X{}: 0x{:<16X} {}{}: 0x{:X}", index < 10 ? ' ' : '\0', index, ctx.regs[index], index < 10 ? ' ' : '\0', index + 1, ctx.regs[index]);
|
||||||
|
|
||||||
|
state.logger->Debug("Process Trace:{}", trace);
|
||||||
|
state.logger->Debug("Raw Instructions: 0x{}", raw);
|
||||||
|
state.logger->Debug("CPU Context:{}", cpuContext);
|
||||||
|
|
||||||
|
context->uc_mcontext.pc = reinterpret_cast<skyline::u64>(&std::longjmp);
|
||||||
|
context->uc_mcontext.regs[0] = reinterpret_cast<u64>(state.thread->originalCtx);
|
||||||
|
context->uc_mcontext.regs[1] = true;
|
||||||
|
} else {
|
||||||
|
signal::ExceptionalSignalHandler(signal, info, context); //!< Delegate throwing a host exception to the exceptional signal handler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *NceTlsRestorer() {
|
||||||
ThreadContext *threadCtx;
|
ThreadContext *threadCtx;
|
||||||
asm volatile("MRS %x0, TPIDR_EL0":"=r"(threadCtx));
|
asm volatile("MRS %x0, TPIDR_EL0":"=r"(threadCtx));
|
||||||
|
if (threadCtx->magic != constant::SkyTlsMagic)
|
||||||
|
return nullptr;
|
||||||
asm volatile("MSR TPIDR_EL0, %x0"::"r"(threadCtx->hostTpidrEl0));
|
asm volatile("MSR TPIDR_EL0, %x0"::"r"(threadCtx->hostTpidrEl0));
|
||||||
|
return threadCtx;
|
||||||
const auto &state{*threadCtx->state};
|
|
||||||
state.logger->Warn("Thread #{} has crashed due to signal: {}", state.thread->id, strsignal(signal));
|
|
||||||
|
|
||||||
std::string raw;
|
|
||||||
std::string trace;
|
|
||||||
std::string cpuContext;
|
|
||||||
|
|
||||||
const auto &ctx{reinterpret_cast<ucontext *>(context)->uc_mcontext};
|
|
||||||
constexpr u16 instructionCount{20}; // The amount of previous instructions to print
|
|
||||||
auto offset{ctx.pc - (instructionCount * sizeof(u32)) + (2 * sizeof(u32))};
|
|
||||||
span instructions(reinterpret_cast<u32 *>(offset), instructionCount);
|
|
||||||
for (auto &instruction : instructions) {
|
|
||||||
instruction = __builtin_bswap32(instruction);
|
|
||||||
|
|
||||||
if (offset == ctx.pc)
|
|
||||||
trace += fmt::format("\n-> 0x{:X} : 0x{:08X}", offset, instruction);
|
|
||||||
else
|
|
||||||
trace += fmt::format("\n 0x{:X} : 0x{:08X}", offset, instruction);
|
|
||||||
|
|
||||||
raw += fmt::format("{:08X}", instruction);
|
|
||||||
offset += sizeof(u32);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.fault_address)
|
|
||||||
cpuContext += fmt::format("\nFault Address: 0x{:X}", ctx.fault_address);
|
|
||||||
|
|
||||||
if (ctx.sp)
|
|
||||||
cpuContext += fmt::format("\nStack Pointer: 0x{:X}", ctx.sp);
|
|
||||||
|
|
||||||
for (u8 index{}; index < ((sizeof(mcontext_t::regs) / sizeof(u64)) - 2); index += 2)
|
|
||||||
cpuContext += fmt::format("\n{}X{}: 0x{:<16X} {}{}: 0x{:X}", index < 10 ? ' ' : '\0', index, ctx.regs[index], index < 10 ? ' ' : '\0', index + 1, ctx.regs[index]);
|
|
||||||
|
|
||||||
state.logger->Warn("Process Trace:{}", trace);
|
|
||||||
state.logger->Warn("Raw Instructions: 0x{}", raw);
|
|
||||||
state.logger->Warn("CPU Context:{}", cpuContext);
|
|
||||||
|
|
||||||
asm volatile("MSR TPIDR_EL0, %x0"::"r"(threadCtx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NCE::NCE(DeviceState &state) : state(state) {}
|
NCE::NCE(const DeviceState &state) : state(state) {
|
||||||
|
signal::SetTlsRestorer(&NceTlsRestorer);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr u8 MainSvcTrampolineSize{17}; // Size of the main SVC trampoline function in u32 units
|
constexpr u8 MainSvcTrampolineSize{17}; // Size of the main SVC trampoline function in u32 units
|
||||||
constexpr u32 TpidrEl0{0x5E82}; // ID of TPIDR_EL0 in MRS
|
constexpr u32 TpidrEl0{0x5E82}; // ID of TPIDR_EL0 in MRS
|
||||||
|
@ -8,18 +8,18 @@
|
|||||||
|
|
||||||
namespace skyline::nce {
|
namespace skyline::nce {
|
||||||
/**
|
/**
|
||||||
* @brief The NCE (Native Code Execution) class is responsible for managing the state of catching instructions and directly controlling processes/threads
|
* @brief The NCE (Native Code Execution) class is responsible for managing state relevant to the layer between the host and guest
|
||||||
*/
|
*/
|
||||||
class NCE {
|
class NCE {
|
||||||
private:
|
private:
|
||||||
DeviceState &state;
|
const DeviceState &state;
|
||||||
|
|
||||||
static void SvcHandler(u16 svc, ThreadContext* ctx);
|
static void SvcHandler(u16 svc, ThreadContext* ctx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void SignalHandler(int signal, siginfo *info, void *context);
|
static void SignalHandler(int signal, siginfo *info, ucontext *context, void *oldTls);
|
||||||
|
|
||||||
NCE(DeviceState &state);
|
NCE(const DeviceState &state);
|
||||||
|
|
||||||
struct PatchData {
|
struct PatchData {
|
||||||
size_t size; //!< Size of the .patch section
|
size_t size; //!< Size of the .patch section
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
struct DeviceState;
|
struct DeviceState;
|
||||||
|
namespace constant {
|
||||||
|
constexpr u64 SkyTlsMagic{util::MakeMagic<u64>("SKYTLS")};
|
||||||
|
}
|
||||||
namespace nce {
|
namespace nce {
|
||||||
struct WRegister {
|
struct WRegister {
|
||||||
u32 lower;
|
u32 lower;
|
||||||
@ -96,6 +99,7 @@ namespace skyline {
|
|||||||
u8 *tpidrroEl0; //!< Emulated HOS TPIDRRO_EL0
|
u8 *tpidrroEl0; //!< Emulated HOS TPIDRRO_EL0
|
||||||
u8 *tpidrEl0; //!< Emulated HOS TPIDR_EL0
|
u8 *tpidrEl0; //!< Emulated HOS TPIDR_EL0
|
||||||
const DeviceState *state;
|
const DeviceState *state;
|
||||||
|
u64 magic{constant::SkyTlsMagic};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace guest {
|
namespace guest {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
namespace skyline::kernel {
|
namespace skyline::kernel {
|
||||||
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath) : state(this, process, jvmManager, settings, logger), serviceManager(state), appFilesPath(appFilesPath) {}
|
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath) : state(this, jvmManager, settings, logger), serviceManager(state), appFilesPath(appFilesPath) {}
|
||||||
|
|
||||||
void OS::Execute(int romFd, loader::RomFormat romType) {
|
void OS::Execute(int romFd, loader::RomFormat romType) {
|
||||||
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
||||||
@ -29,6 +29,7 @@ namespace skyline::kernel {
|
|||||||
else
|
else
|
||||||
throw exception("Unsupported ROM extension.");
|
throw exception("Unsupported ROM extension.");
|
||||||
|
|
||||||
|
auto& process{state.process};
|
||||||
process = std::make_shared<kernel::type::KProcess>(state);
|
process = std::make_shared<kernel::type::KProcess>(state);
|
||||||
auto entry{state.loader->LoadProcessData(process, state)};
|
auto entry{state.loader->LoadProcessData(process, state)};
|
||||||
process->InitializeHeap();
|
process->InitializeHeap();
|
||||||
|
@ -13,7 +13,6 @@ namespace skyline::kernel {
|
|||||||
class OS {
|
class OS {
|
||||||
public:
|
public:
|
||||||
DeviceState state;
|
DeviceState state;
|
||||||
std::shared_ptr<type::KProcess> process;
|
|
||||||
service::ServiceManager serviceManager;
|
service::ServiceManager serviceManager;
|
||||||
std::string appFilesPath; //!< The full path to the app's files directory
|
std::string appFilesPath; //!< The full path to the app's files directory
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <common/settings.h>
|
||||||
#include "IProfile.h"
|
#include "IProfile.h"
|
||||||
|
|
||||||
namespace skyline::service::account {
|
namespace skyline::service::account {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <common/settings.h>
|
||||||
#include <kernel/types/KProcess.h>
|
#include <kernel/types/KProcess.h>
|
||||||
#include "ICommonStateGetter.h"
|
#include "ICommonStateGetter.h"
|
||||||
|
|
||||||
|
@ -68,11 +68,9 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
private external fun executeApplication(romUri : String, romType : Int, romFd : Int, preferenceFd : Int, appFilesPath : String)
|
private external fun executeApplication(romUri : String, romType : Int, romFd : Int, preferenceFd : Int, appFilesPath : String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This sets the halt flag in libskyline to the provided value, if set to true it causes libskyline to halt emulation
|
* Terminate of all emulator threads and cause [emulationThread] to return
|
||||||
*
|
|
||||||
* @param halt The value to set halt to
|
|
||||||
*/
|
*/
|
||||||
private external fun exitGuest(halt : Boolean)
|
private external fun stopEmulation()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This sets the surface object in libskyline to the provided value, emulation is halted if set to null
|
* This sets the surface object in libskyline to the provided value, emulation is halted if set to null
|
||||||
@ -233,31 +231,26 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
* This is used to stop the currently executing ROM and replace it with the one specified in the new intent
|
* This is used to stop the currently executing ROM and replace it with the one specified in the new intent
|
||||||
*/
|
*/
|
||||||
override fun onNewIntent(intent : Intent?) {
|
override fun onNewIntent(intent : Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
shouldFinish = false
|
shouldFinish = false
|
||||||
|
|
||||||
exitGuest(true)
|
stopEmulation()
|
||||||
emulationThread.join()
|
emulationThread.join()
|
||||||
|
|
||||||
shouldFinish = true
|
shouldFinish = true
|
||||||
|
|
||||||
executeApplication(intent?.data!!)
|
executeApplication(intent?.data!!)
|
||||||
|
|
||||||
super.onNewIntent(intent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This is used to halt emulation entirely
|
|
||||||
*/
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
shouldFinish = false
|
shouldFinish = false
|
||||||
|
|
||||||
exitGuest(true)
|
stopEmulation()
|
||||||
emulationThread.join(1000)
|
emulationThread.join()
|
||||||
|
|
||||||
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
|
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
|
||||||
vibrators.clear()
|
vibrators.clear()
|
||||||
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user