Compare commits

...

64 Commits

Author SHA1 Message Date
Lioncash
d66ab2b8aa filesys/romfs: Remove unused includes
These inclusions aren't used at all within the public interface, so they
can be removed.
2019-11-27 05:29:52 -05:00
Lioncash
ba3c55ab7b filesys/romfs: Make ProcessFile and ProcessDirectory internally linked
These functions aren't used outside of this file, so we can place them
within an anonymous namespace.
2019-11-27 05:26:35 -05:00
bunnei
31daaa7911 Merge pull request #3164 from ReinUsesLisp/half-cast-float
gl_shader_decompiler: Fix casts from fp32 to fp16
2019-11-26 09:11:23 -05:00
Fernando Sahmkow
59484442a0 Merge pull request #3162 from bunnei/fix-shared-ptr-crash
kernel: Fix reference management for client/server session.
2019-11-26 07:13:04 -04:00
ReinUsesLisp
ef4446cb11 gl_shader_decompiler: Fix casts from fp32 to f16
Casts from f32 to f16 zeroes the higher half of the target register.
2019-11-25 22:22:33 -03:00
bunnei
f6b9b7910e kernel: Fix reference management for client/server session.
- Fixes shutdown crash and crash in Pokemon SwSh.
2019-11-25 18:17:49 -05:00
bunnei
6d23b045a0 Merge pull request #3160 from DarkLordZach/opt-ea-clang-fmt
ci: Continue pipeline on clang format failure
2019-11-24 23:03:51 -05:00
Zach Hilman
8652313af2 ci: Continue pipeline on clang format failure 2019-11-24 21:31:37 -05:00
bunnei
2899c93818 Merge pull request #3158 from ReinUsesLisp/srgb-blit
gl_texture_cache: Apply sRGB on blits
2019-11-24 20:47:13 -05:00
bunnei
50c7539108 Merge pull request #3094 from lioncash/tables
service: Update function tables
2019-11-24 20:30:58 -05:00
bunnei
33a6b45a6c Merge pull request #3155 from bunnei/fix-asynch-gpu-wait
gpu_thread: Don't spin wait if there are no GPU commands.
2019-11-24 20:19:25 -05:00
bunnei
9046d4a548 kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects. (#3154)
* kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects.

- See https://github.com/citra-emu/citra/pull/4710 for details.
2019-11-24 20:15:51 -05:00
bunnei
b03242067d Merge pull request #3098 from ReinUsesLisp/shader-invalidations
gl_shader_cache: Miscellaneous changes to shaders
2019-11-24 19:36:30 -05:00
ReinUsesLisp
74fff717aa gl_texture_cache: Apply sRGB on blits
glBlitFramebuffer keeps in mind GL_FRAMEBUFFER_SRGB's state. Enable this
depending on the target surface pixel format.
2019-11-24 18:13:33 -03:00
bunnei
b7031b2b9d Merge pull request #3105 from ReinUsesLisp/fix-stencil-reg
maxwell_3d: Fix stencil_back_func_mask offset
2019-11-24 13:53:23 -05:00
bunnei
7298dcc016 Merge pull request #3156 from bunnei/sys-ticks
svc: GetSystemTick should return cntpct_el0, not core ticks.
2019-11-24 13:52:28 -05:00
bunnei
ec8bfe94a7 Merge pull request #3153 from FearlessTobi/port-4964
Port citra-emu/citra#4964: "Unfold UNREACHABLE implementation for dumb compilers"
2019-11-24 02:56:12 -05:00
bunnei
e81e0036b4 Merge pull request #3145 from ReinUsesLisp/buffer-cache-init
buffer_cache: Remove brace initialized for objects with default constructor
2019-11-24 02:55:02 -05:00
bunnei
63248f4edd Update svc.cpp 2019-11-23 16:01:06 -05:00
bunnei
6eaf7ab55f svc: GetSystemTick should return cntpct_el0, not core ticks. 2019-11-23 15:29:15 -05:00
bunnei
9ec84fc592 gpu_thread: Don't spin wait if there are no GPU commands. 2019-11-23 15:17:28 -05:00
bunnei
6a3fc5d2ff Merge pull request #3114 from FernandoS27/cond-var
Kernel: Correct behavior of Condition Variables to be more similar to real hardware.
2019-11-23 13:24:39 -05:00
bunnei
4ed183ee42 Merge pull request #3141 from ReinUsesLisp/gl-position
gl_shader_gen: Apply default value to gl_Position
2019-11-23 13:23:46 -05:00
bunnei
6e4d46908a Merge pull request #3130 from FernandoS27/cancel-sync
Kernel: Correct Cancel Synchronization.
2019-11-23 13:23:23 -05:00
Weiyi Wang
49e0a30dbd fix clang-format and lambda capture 2019-11-23 01:30:06 +01:00
Weiyi Wang
9a60d8a430 unfold UNREACHABLE implementation for dumb compilers
We relies on UNREACHABLE's noreturn attribute to eliminate parent's "no return value" warning. However, this was wrapped in a `if(!false)` block, which compilers may not unfold to recognize the noreturn nature.
2019-11-23 01:30:06 +01:00
ReinUsesLisp
dc2e83fa31 gl_device: Reserve base bindings on limited devices
SSBOs and other resources are limited per pipeline on Intel and AMD.
Heuristically reserve resources per stage having in mind the reported
OpenGL limits.
2019-11-22 21:28:50 -03:00
ReinUsesLisp
e3d7334be9 gl_state: Skip null texture binds
glBindTextureUnit doesn't support null textures. Skip binding these.
2019-11-22 21:28:50 -03:00
ReinUsesLisp
919ac2c4d3 gl_rasterizer: Disable compute shaders on Intel
Intel's proprietary driver enters in a corrupt state when compute
shaders are executed. For now, disable these.
2019-11-22 21:28:50 -03:00
ReinUsesLisp
894ad74b87 gl_shader_cache: Hack shared memory size
The current shared memory size seems to be smaller than what the game
actually uses. This makes Nvidia's driver consistently blow up; in the
case of FE3H it made it explode on Qt's SwapBuffers while SDL2 worked
just fine. For now keep this hack since it's still progress over the
previous hardcoded shared memory size.
2019-11-22 21:28:49 -03:00
ReinUsesLisp
e35b9597ef gl_shader_decompiler: Normalize image bindings 2019-11-22 21:28:49 -03:00
ReinUsesLisp
36d9b409fc gl_shader_decompiler: Normalize cbuf bindings
Stage and compute shaders were using a different binding counter.
Normalize these.
2019-11-22 21:28:49 -03:00
ReinUsesLisp
f936b86c7c gl_rasterizer: Add missing cbuf counter reset on compute 2019-11-22 21:28:49 -03:00
ReinUsesLisp
180417c514 gl_shader_cache: Remove dynamic BaseBinding specialization 2019-11-22 21:28:49 -03:00
ReinUsesLisp
c8a48aacc0 video_core: Unify ProgramType and ShaderStage into ShaderType 2019-11-22 21:28:48 -03:00
ReinUsesLisp
0f23359a44 gl_rasterizer: Bind graphics images to draw commands
Images were not being bound to draw invocations because these would
require a cache invalidation.
2019-11-22 21:28:48 -03:00
ReinUsesLisp
287ae2b9e8 gl_shader_cache: Specialize local memory size for compute shaders
Local memory size in compute shaders was stubbed with an arbitary size.
This commit specializes local memory size from guest GPU parameters.
2019-11-22 21:28:48 -03:00
ReinUsesLisp
dbeb523879 gl_shader_cache: Specialize shared memory size
Shared memory was being declared with an undefined size. Specialize from
guest GPU parameters the compute shader's shared memory size.
2019-11-22 21:28:47 -03:00
ReinUsesLisp
4f5d8e4342 gl_shader_cache: Specialize shader workgroup
Drop the usage of ARB_compute_variable_group_size and specialize compute
shaders instead. This permits compute to run on AMD and Intel
proprietary drivers.
2019-11-22 21:28:47 -03:00
ReinUsesLisp
dc9961f341 shader/texture: Handle TLDS texture type mismatches
Some games like "Fire Emblem: Three Houses" bind 2D textures to offsets
used by instructions of 1D textures. To handle the discrepancy this
commit uses the the texture type from the binding and modifies the
emitted code IR to build a valid backend expression.

E.g.: Bound texture is 2D and instruction is 1D, the emitted IR samples
a 2D texture in the coordinate ivec2(X, 0).
2019-11-22 21:28:47 -03:00
ReinUsesLisp
32c1bc6a67 shader/texture: Deduce texture buffers from locker
Instead of specializing shaders to separate texture buffers from 1D
textures, use the locker to deduce them while they are being decoded.
2019-11-22 21:28:47 -03:00
bunnei
bedc903c65 Merge pull request #3140 from FearlessTobi/port-4953
Port citra-emu/citra#4953: "citra_qt/main.ui: remove unused actions "Load Symbol Map..." and "Select Game Directory...""
2019-11-21 15:32:24 -05:00
bunnei
eedb048585 Merge pull request #3112 from lioncash/skip
service/am: Remove unnecessary Skip calls
2019-11-21 15:30:01 -05:00
bunnei
d7953b8ee5 Merge pull request #3111 from lioncash/query
am: Stub QueryApplicationPlayStatistics
2019-11-21 15:29:34 -05:00
Fernando Sahmkow
46bb609981 Kernel: Optimize condition variable threads management. 2019-11-21 11:13:29 -04:00
Fernando Sahmkow
2ab41ceff4 Kernel: Correct SignalProcessWideKey
When the target is 0, all threads must be processed.
2019-11-21 10:46:55 -04:00
Fernando Sahmkow
2d16507f9f Kernel: Correct behavior of Condition Variables to be more similar to real hardware.
This commit ensures cond var threads act exactly as they do in the real
console. The original implementation uses an RBTree and the behavior of
cond var threads is that at the same priority level they act like a
FIFO.
2019-11-21 10:46:55 -04:00
ReinUsesLisp
73aaf365e7 buffer_cache: Remove brace initialized for objects with default constructor 2019-11-20 16:00:40 -03:00
Mat M
c52f37f259 Merge pull request #3142 from ReinUsesLisp/depbar-log
shader/other: Reduce DEPBAR log severity
2019-11-19 19:52:41 -05:00
ReinUsesLisp
24f4198cee shader/other: Reduce DEPBAR log severity
While DEPBAR is stubbed it doesn't change anything from our end. Shading
languages handle what this instruction does implicitly. We are not
getting anything out fo this log except noise.
2019-11-19 21:26:40 -03:00
ReinUsesLisp
bc10714dcf gl_shader_gen: Apply default value to gl_Position
Nvidia has sane default output values for varyings, but the other
vendors don't apply these. To properly emulate this we would have to
analyze the shader header. For the time being, apply the same default
Nvidia applies so we get the same behaviour on non-Nvidia drivers.
2019-11-19 20:32:01 -03:00
bunnei
b0819e2ffb Merge pull request #3086 from ReinUsesLisp/format-lookups
texture_cache: Use a flat table instead of switch for texture format lookups
2019-11-19 18:29:17 -05:00
Tobias
f9d7a6bec6 citra_qt/main.ui: remove unused actions "Load Symbol Map..." and...
..."Select Game Directory..."

Co-authored-by: vvanelslande <vvanelslandedev@gmail.com>
2019-11-19 16:39:58 +01:00
bunnei
60993513af Merge pull request #3123 from ReinUsesLisp/logging-return
common/logging: Silence no return value warnings
2019-11-17 20:29:51 -05:00
Fernando Sahmkow
67a8bd1e70 Merge pull request #3126 from yuzu-emu/revert-3106-bitfield
Revert "common/bit_field: Silence sign-conversion warnings"
2019-11-16 14:23:15 -04:00
Fernando Sahmkow
7d16b2d2dd Kernel: Correct Cancel Synchronization.
This commit corrects the behavior of cancel synchronization when the
thread is running/ready and ensures the next wait is cancelled as it's
suppose to.
2019-11-16 12:41:51 -04:00
ReinUsesLisp
2ac834c722 common/logging: Silence no return value warnings 2019-11-15 18:43:35 -03:00
ReinUsesLisp
4681381a34 format_lookup_table: Address feedback
format_lookup_table: Drop bitfields

format_lookup_table: Use std::array for definition table

format_lookup_table: Include <limits> instead of <numeric>
2019-11-14 20:57:30 -03:00
ReinUsesLisp
80eacdf89b texture_cache: Use a table instead of switch for texture formats
Use a large flat array to look up texture formats. This allows us to
properly implement formats with different component types. It should
also be faster.
2019-11-14 20:57:10 -03:00
Lioncash
2c4c2b5eee service/am: Remove unnecessary Skip calls
We can simplify these by wrapping the necessary members in structs and
then simply reading out the whole struct.
2019-11-14 16:31:52 -05:00
ReinUsesLisp
48a1687f51 texture_cache: Drop abstracted ComponentType
Abstracted ComponentType was not being used in a meaningful way.
This commit drops its usage.

There is one place where it was being used to test compatibility between
two cached surfaces, but this one is implied in the pixel format.
Removing the component type test doesn't change the behaviour.
2019-11-14 18:21:42 -03:00
Lioncash
1cd8637bf0 am: Stub QueryApplicationPlayStatistics
Maintains implementation parity between QueryApplicationPlayStatistics
and QueryApplicationPlayStatisticsByUid.

These function the same behaviorally underneath the hood, with the only
difference being that one allows specifying a UID.
2019-11-14 16:02:39 -05:00
ReinUsesLisp
7990220df7 maxwell_3d: Fix stencil_back_func_mask offset
stencil_back_func_mask and stencil_back_mask were misplaced. This commit
addresses that issue.
2019-11-13 16:35:17 -03:00
Lioncash
e21b6ff79d service: Update function tables
Keeps the function tables up to date.

Updated based off information from Switchbrew.
2019-11-12 10:32:56 -05:00
150 changed files with 1922 additions and 1773 deletions

View File

@@ -10,6 +10,7 @@ stages:
jobs:
- job: format
displayName: 'clang'
continueOnError: true
pool:
vmImage: ubuntu-latest
steps:

View File

@@ -73,7 +73,7 @@ private:
EffectInStatus info{};
};
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event,
std::shared_ptr<Kernel::WritableEvent> buffer_event,
std::size_t instance_number)
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
effects(params.effect_count) {

View File

@@ -218,8 +218,7 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
class AudioRenderer {
public:
AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event,
std::size_t instance_number);
std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
~AudioRenderer();
std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
@@ -235,7 +234,7 @@ private:
class VoiceState;
AudioRendererParameter worker_params;
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event;
std::shared_ptr<Kernel::WritableEvent> buffer_event;
std::vector<VoiceState> voices;
std::vector<EffectState> effects;
std::unique_ptr<AudioOut> audio_out;

View File

@@ -41,8 +41,9 @@ __declspec(noinline, noreturn)
} \
while (0)
#define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!")
#define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
#define UNREACHABLE() assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); })
#define UNREACHABLE_MSG(...) \
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); })
#ifdef _DEBUG
#define DEBUG_ASSERT(_a_) ASSERT(_a_)

View File

@@ -272,8 +272,10 @@ const char* GetLogClassName(Class log_class) {
#undef CLS
#undef SUB
case Class::Count:
UNREACHABLE();
break;
}
UNREACHABLE();
return "Invalid";
}
const char* GetLevelName(Level log_level) {
@@ -288,9 +290,11 @@ const char* GetLevelName(Level log_level) {
LVL(Error);
LVL(Critical);
case Level::Count:
UNREACHABLE();
break;
}
#undef LVL
UNREACHABLE();
return "Invalid";
}
void SetGlobalFilter(const Filter& filter) {

View File

@@ -7,6 +7,7 @@
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "core/file_sys/vfs_types.h"

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "common/common_types.h"
#include "common/swap.h"
#include "core/file_sys/fsmitm_romfsbuild.h"
@@ -12,7 +14,7 @@
#include "core/file_sys/vfs_vector.h"
namespace FileSys {
namespace {
constexpr u32 ROMFS_ENTRY_EMPTY = 0xFFFFFFFF;
struct TableLocation {
@@ -51,7 +53,7 @@ struct FileEntry {
static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size.");
template <typename Entry>
static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offset) {
std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offset) {
Entry entry{};
if (file->ReadObject(&entry, offset) != sizeof(Entry))
return {};
@@ -99,6 +101,7 @@ void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file
this_dir_offset = entry.first.sibling;
}
}
} // Anonymous namespace
VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
RomFSHeader header{};

View File

@@ -5,10 +5,6 @@
#pragma once
#include <array>
#include <map>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/file_sys/vfs.h"
namespace FileSys {

View File

@@ -203,10 +203,10 @@ public:
void PushRaw(const T& value);
template <typename... O>
void PushMoveObjects(Kernel::SharedPtr<O>... pointers);
void PushMoveObjects(std::shared_ptr<O>... pointers);
template <typename... O>
void PushCopyObjects(Kernel::SharedPtr<O>... pointers);
void PushCopyObjects(std::shared_ptr<O>... pointers);
private:
u32 normal_params_size{};
@@ -298,7 +298,7 @@ void ResponseBuilder::Push(const First& first_value, const Other&... other_value
}
template <typename... O>
inline void ResponseBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {
inline void ResponseBuilder::PushCopyObjects(std::shared_ptr<O>... pointers) {
auto objects = {pointers...};
for (auto& object : objects) {
context->AddCopyObject(std::move(object));
@@ -306,7 +306,7 @@ inline void ResponseBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {
}
template <typename... O>
inline void ResponseBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) {
inline void ResponseBuilder::PushMoveObjects(std::shared_ptr<O>... pointers) {
auto objects = {pointers...};
for (auto& object : objects) {
context->AddMoveObject(std::move(object));
@@ -357,10 +357,10 @@ public:
T PopRaw();
template <typename T>
Kernel::SharedPtr<T> GetMoveObject(std::size_t index);
std::shared_ptr<T> GetMoveObject(std::size_t index);
template <typename T>
Kernel::SharedPtr<T> GetCopyObject(std::size_t index);
std::shared_ptr<T> GetCopyObject(std::size_t index);
template <class T>
std::shared_ptr<T> PopIpcInterface() {
@@ -465,12 +465,12 @@ void RequestParser::Pop(First& first_value, Other&... other_values) {
}
template <typename T>
Kernel::SharedPtr<T> RequestParser::GetMoveObject(std::size_t index) {
std::shared_ptr<T> RequestParser::GetMoveObject(std::size_t index) {
return context->GetMoveObject<T>(index);
}
template <typename T>
Kernel::SharedPtr<T> RequestParser::GetCopyObject(std::size_t index) {
std::shared_ptr<T> RequestParser::GetCopyObject(std::size_t index) {
return context->GetCopyObject<T>(index);
}

View File

@@ -21,7 +21,7 @@
namespace Kernel {
namespace {
// Wake up num_to_wake (or all) threads in a vector.
void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) {
void WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads, s32 num_to_wake) {
auto& system = Core::System::GetInstance();
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process
// them all.
@@ -59,7 +59,8 @@ ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 v
}
ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
const std::vector<std::shared_ptr<Thread>> waiting_threads =
GetThreadsWaitingOnAddress(address);
WakeThreads(waiting_threads, num_to_wake);
return RESULT_SUCCESS;
}
@@ -87,7 +88,8 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
}
// Get threads waiting on the address.
const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
const std::vector<std::shared_ptr<Thread>> waiting_threads =
GetThreadsWaitingOnAddress(address);
// Determine the modified value depending on the waiting count.
s32 updated_value;
@@ -172,21 +174,21 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
}
ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
Thread* current_thread = system.CurrentScheduler().GetCurrentThread();
current_thread->SetArbiterWaitAddress(address);
current_thread->SetStatus(ThreadStatus::WaitArb);
current_thread->InvalidateWakeupCallback();
current_thread->WakeAfterDelay(timeout);
system.PrepareReschedule(current_thread->GetProcessorID());
return RESULT_TIMEOUT;
}
std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const {
std::vector<std::shared_ptr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(
VAddr address) const {
// Retrieve all threads that are waiting for this address.
std::vector<SharedPtr<Thread>> threads;
std::vector<std::shared_ptr<Thread>> threads;
const auto& scheduler = system.GlobalScheduler();
const auto& thread_list = scheduler.GetThreadList();
@@ -198,7 +200,7 @@ std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr
// Sort them by priority, such that the highest priority ones come first.
std::sort(threads.begin(), threads.end(),
[](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
[](const std::shared_ptr<Thread>& lhs, const std::shared_ptr<Thread>& rhs) {
return lhs->GetPriority() < rhs->GetPriority();
});

View File

@@ -72,7 +72,7 @@ private:
ResultCode WaitForAddressImpl(VAddr address, s64 timeout);
// Gets the threads waiting on an address.
std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
std::vector<std::shared_ptr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
Core::System& system;
};

View File

@@ -15,11 +15,11 @@ namespace Kernel {
ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {}
ClientPort::~ClientPort() = default;
SharedPtr<ServerPort> ClientPort::GetServerPort() const {
std::shared_ptr<ServerPort> ClientPort::GetServerPort() const {
return server_port;
}
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
// Note: Threads do not wait for the server endpoint to call
// AcceptSession before returning from this call.
@@ -29,7 +29,8 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
active_sessions++;
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
auto [server, client] = ServerSession::CreateSessionPair(kernel, server_port->GetName(), this);
auto [server, client] =
ServerSession::CreateSessionPair(kernel, server_port->GetName(), SharedFrom(this));
if (server_port->HasHLEHandler()) {
server_port->GetHLEHandler()->ClientConnected(server);

View File

@@ -17,6 +17,9 @@ class ServerPort;
class ClientPort final : public Object {
public:
explicit ClientPort(KernelCore& kernel);
~ClientPort() override;
friend class ServerPort;
std::string GetTypeName() const override {
return "ClientPort";
@@ -30,7 +33,7 @@ public:
return HANDLE_TYPE;
}
SharedPtr<ServerPort> GetServerPort() const;
std::shared_ptr<ServerPort> GetServerPort() const;
/**
* Creates a new Session pair, adds the created ServerSession to the associated ServerPort's
@@ -38,7 +41,7 @@ public:
* waiting on it to awake.
* @returns ClientSession The client endpoint of the created Session pair, or error code.
*/
ResultVal<SharedPtr<ClientSession>> Connect();
ResultVal<std::shared_ptr<ClientSession>> Connect();
/**
* Signifies that a previously active connection has been closed,
@@ -47,10 +50,7 @@ public:
void ConnectionClosed();
private:
explicit ClientPort(KernelCore& kernel);
~ClientPort() override;
SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
std::shared_ptr<ServerPort> server_port; ///< ServerPort associated with this client port.
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
u32 active_sessions = 0; ///< Number of currently open sessions to this port
std::string name; ///< Name of client port (optional)

View File

@@ -16,25 +16,18 @@ ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {}
ClientSession::~ClientSession() {
// This destructor will be called automatically when the last ClientSession handle is closed by
// the emulated application.
// A local reference to the ServerSession is necessary to guarantee it
// will be kept alive until after ClientDisconnected() returns.
SharedPtr<ServerSession> server = parent->server;
if (server) {
if (auto server = parent->server.lock()) {
server->ClientDisconnected();
}
parent->client = nullptr;
}
ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) {
// Keep ServerSession alive until we're done working with it.
SharedPtr<ServerSession> server = parent->server;
if (server == nullptr)
return ERR_SESSION_CLOSED_BY_REMOTE;
ResultCode ClientSession::SendSyncRequest(Thread* thread) {
// Signal the server session that new data is available
return server->HandleSyncRequest(std::move(thread));
if (auto server = parent->server.lock()) {
return server->HandleSyncRequest(SharedFrom(thread));
}
return ERR_SESSION_CLOSED_BY_REMOTE;
}
} // namespace Kernel

View File

@@ -19,6 +19,9 @@ class Thread;
class ClientSession final : public Object {
public:
explicit ClientSession(KernelCore& kernel);
~ClientSession() override;
friend class ServerSession;
std::string GetTypeName() const override {
@@ -34,12 +37,9 @@ public:
return HANDLE_TYPE;
}
ResultCode SendSyncRequest(SharedPtr<Thread> thread);
ResultCode SendSyncRequest(Thread* thread);
private:
explicit ClientSession(KernelCore& kernel);
~ClientSession() override;
/// The parent session, which links to the server endpoint.
std::shared_ptr<Session> parent;

View File

@@ -44,7 +44,7 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) {
return RESULT_SUCCESS;
}
ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) {
DEBUG_ASSERT(obj != nullptr);
const u16 slot = next_free_slot;
@@ -70,7 +70,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
}
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
SharedPtr<Object> object = GetGeneric(handle);
std::shared_ptr<Object> object = GetGeneric(handle);
if (object == nullptr) {
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -99,11 +99,11 @@ bool HandleTable::IsValid(Handle handle) const {
return slot < table_size && objects[slot] != nullptr && generations[slot] == generation;
}
SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
if (handle == CurrentThread) {
return GetCurrentThread();
return SharedFrom(GetCurrentThread());
} else if (handle == CurrentProcess) {
return Core::System::GetInstance().CurrentProcess();
return SharedFrom(Core::System::GetInstance().CurrentProcess());
}
if (!IsValid(handle)) {

View File

@@ -68,7 +68,7 @@ public:
* @return The created Handle or one of the following errors:
* - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded.
*/
ResultVal<Handle> Create(SharedPtr<Object> obj);
ResultVal<Handle> Create(std::shared_ptr<Object> obj);
/**
* Returns a new handle that points to the same object as the passed in handle.
@@ -92,7 +92,7 @@ public:
* Looks up a handle.
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
*/
SharedPtr<Object> GetGeneric(Handle handle) const;
std::shared_ptr<Object> GetGeneric(Handle handle) const;
/**
* Looks up a handle while verifying its type.
@@ -100,7 +100,7 @@ public:
* type differs from the requested one.
*/
template <class T>
SharedPtr<T> Get(Handle handle) const {
std::shared_ptr<T> Get(Handle handle) const {
return DynamicObjectCast<T>(GetGeneric(handle));
}
@@ -109,7 +109,7 @@ public:
private:
/// Stores the Object referenced by the handle or null if the slot is empty.
std::array<SharedPtr<Object>, MAX_COUNT> objects;
std::array<std::shared_ptr<Object>, MAX_COUNT> objects;
/**
* The value of `next_generation` when the handle was created, used to check for validity. For

View File

@@ -32,23 +32,25 @@ SessionRequestHandler::SessionRequestHandler() = default;
SessionRequestHandler::~SessionRequestHandler() = default;
void SessionRequestHandler::ClientConnected(SharedPtr<ServerSession> server_session) {
void SessionRequestHandler::ClientConnected(std::shared_ptr<ServerSession> server_session) {
server_session->SetHleHandler(shared_from_this());
connected_sessions.push_back(std::move(server_session));
}
void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& server_session) {
void SessionRequestHandler::ClientDisconnected(
const std::shared_ptr<ServerSession>& server_session) {
server_session->SetHleHandler(nullptr);
boost::range::remove_erase(connected_sessions, server_session);
}
SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
const std::string& reason, u64 timeout, WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event) {
std::shared_ptr<WritableEvent> writable_event) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
thread->SetWakeupCallback([context = *this, callback](
ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, std::size_t index) mutable -> bool {
thread->SetWakeupCallback([context = *this, callback](ThreadWakeupReason reason,
std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object,
std::size_t index) mutable -> bool {
ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent);
callback(thread, context, reason);
context.WriteToOutgoingCommandBuffer(*thread);
@@ -75,8 +77,8 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
return writable_event;
}
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session,
SharedPtr<Thread> thread)
HLERequestContext::HLERequestContext(std::shared_ptr<Kernel::ServerSession> server_session,
std::shared_ptr<Thread> thread)
: server_session(std::move(server_session)), thread(std::move(thread)) {
cmd_buf[0] = 0;
}

View File

@@ -5,6 +5,7 @@
#pragma once
#include <array>
#include <functional>
#include <memory>
#include <optional>
#include <string>
@@ -60,20 +61,20 @@ public:
* associated ServerSession alive for the duration of the connection.
* @param server_session Owning pointer to the ServerSession associated with the connection.
*/
void ClientConnected(SharedPtr<ServerSession> server_session);
void ClientConnected(std::shared_ptr<ServerSession> server_session);
/**
* Signals that a client has just disconnected from this HLE handler and releases the
* associated ServerSession.
* @param server_session ServerSession associated with the connection.
*/
void ClientDisconnected(const SharedPtr<ServerSession>& server_session);
void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session);
protected:
/// List of sessions that are connected to this handler.
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
/// for the duration of the connection.
std::vector<SharedPtr<ServerSession>> connected_sessions;
std::vector<std::shared_ptr<ServerSession>> connected_sessions;
};
/**
@@ -97,7 +98,8 @@ protected:
*/
class HLERequestContext {
public:
explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<Thread> thread);
explicit HLERequestContext(std::shared_ptr<ServerSession> session,
std::shared_ptr<Thread> thread);
~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request.
@@ -109,12 +111,12 @@ public:
* Returns the session through which this request was made. This can be used as a map key to
* access per-client data on services.
*/
const SharedPtr<Kernel::ServerSession>& Session() const {
const std::shared_ptr<Kernel::ServerSession>& Session() const {
return server_session;
}
using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context,
ThreadWakeupReason reason)>;
using WakeupCallback = std::function<void(
std::shared_ptr<Thread> thread, HLERequestContext& context, ThreadWakeupReason reason)>;
/**
* Puts the specified guest thread to sleep until the returned event is signaled or until the
@@ -129,9 +131,9 @@ public:
* created.
* @returns Event that when signaled will resume the thread and call the callback function.
*/
SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout,
WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event = nullptr);
std::shared_ptr<WritableEvent> SleepClientThread(
const std::string& reason, u64 timeout, WakeupCallback&& callback,
std::shared_ptr<WritableEvent> writable_event = nullptr);
/// Populates this context with data from the requesting process/thread.
ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
@@ -209,20 +211,20 @@ public:
std::size_t GetWriteBufferSize(int buffer_index = 0) const;
template <typename T>
SharedPtr<T> GetCopyObject(std::size_t index) {
std::shared_ptr<T> GetCopyObject(std::size_t index) {
return DynamicObjectCast<T>(copy_objects.at(index));
}
template <typename T>
SharedPtr<T> GetMoveObject(std::size_t index) {
std::shared_ptr<T> GetMoveObject(std::size_t index) {
return DynamicObjectCast<T>(move_objects.at(index));
}
void AddMoveObject(SharedPtr<Object> object) {
void AddMoveObject(std::shared_ptr<Object> object) {
move_objects.emplace_back(std::move(object));
}
void AddCopyObject(SharedPtr<Object> object) {
void AddCopyObject(std::shared_ptr<Object> object) {
copy_objects.emplace_back(std::move(object));
}
@@ -266,11 +268,11 @@ private:
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<Kernel::ServerSession> server_session;
SharedPtr<Thread> thread;
std::shared_ptr<Kernel::ServerSession> server_session;
std::shared_ptr<Thread> thread;
// TODO(yuriks): Check common usage of this and optimize size accordingly
boost::container::small_vector<SharedPtr<Object>, 8> move_objects;
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
std::optional<IPC::CommandHeader> command_header;

View File

@@ -40,7 +40,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
// Lock the global kernel mutex when we enter the kernel HLE.
std::lock_guard lock{HLE::g_hle_lock};
SharedPtr<Thread> thread =
std::shared_ptr<Thread> thread =
system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle);
if (thread == nullptr) {
LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
@@ -53,7 +53,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
// Remove the thread from each of its waiting objects' waitlists
for (const auto& object : thread->GetWaitObjects()) {
object->RemoveWaitingThread(thread.get());
object->RemoveWaitingThread(thread);
}
thread->ClearWaitObjects();
@@ -64,8 +64,11 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
} else if (thread->GetStatus() == ThreadStatus::WaitMutex ||
thread->GetStatus() == ThreadStatus::WaitCondVar) {
thread->SetMutexWaitAddress(0);
thread->SetCondVarWaitAddress(0);
thread->SetWaitHandle(0);
if (thread->GetStatus() == ThreadStatus::WaitCondVar) {
thread->GetOwnerProcess()->RemoveConditionVariableThread(thread);
thread->SetCondVarWaitAddress(0);
}
auto* const lock_owner = thread->GetLockOwner();
// Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance
@@ -157,11 +160,11 @@ struct KernelCore::Impl {
std::atomic<u64> next_thread_id{1};
// Lists all processes that exist in the current session.
std::vector<SharedPtr<Process>> process_list;
std::vector<std::shared_ptr<Process>> process_list;
Process* current_process = nullptr;
Kernel::GlobalScheduler global_scheduler;
SharedPtr<ResourceLimit> system_resource_limit;
std::shared_ptr<ResourceLimit> system_resource_limit;
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
Core::Timing::EventType* preemption_event = nullptr;
@@ -190,15 +193,16 @@ void KernelCore::Shutdown() {
impl->Shutdown();
}
SharedPtr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
return impl->system_resource_limit;
}
SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const {
std::shared_ptr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(
Handle handle) const {
return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
}
void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) {
impl->process_list.push_back(std::move(process));
}
@@ -220,7 +224,7 @@ const Process* KernelCore::CurrentProcess() const {
return impl->current_process;
}
const std::vector<SharedPtr<Process>>& KernelCore::GetProcessList() const {
const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const {
return impl->process_list;
}
@@ -232,7 +236,7 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
return impl->global_scheduler;
}
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
impl->named_ports.emplace(std::move(name), std::move(port));
}

View File

@@ -6,6 +6,7 @@
#include <string>
#include <unordered_map>
#include <vector>
#include "core/hle/kernel/object.h"
namespace Core {
@@ -30,7 +31,7 @@ class Thread;
/// Represents a single instance of the kernel.
class KernelCore {
private:
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
using NamedPortTable = std::unordered_map<std::string, std::shared_ptr<ClientPort>>;
public:
/// Constructs an instance of the kernel using the given System
@@ -56,13 +57,13 @@ public:
void Shutdown();
/// Retrieves a shared pointer to the system resource limit instance.
SharedPtr<ResourceLimit> GetSystemResourceLimit() const;
std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const;
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
std::shared_ptr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(SharedPtr<Process> process);
void AppendNewProcess(std::shared_ptr<Process> process);
/// Makes the given process the new current process.
void MakeCurrentProcess(Process* process);
@@ -74,7 +75,7 @@ public:
const Process* CurrentProcess() const;
/// Retrieves the list of processes.
const std::vector<SharedPtr<Process>>& GetProcessList() const;
const std::vector<std::shared_ptr<Process>>& GetProcessList() const;
/// Gets the sole instance of the global scheduler
Kernel::GlobalScheduler& GlobalScheduler();
@@ -83,7 +84,7 @@ public:
const Kernel::GlobalScheduler& GlobalScheduler() const;
/// Adds a port to the named port table
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
/// Finds a port within the named port table with the given name.
NamedPortTable::iterator FindNamedPort(const std::string& name);

View File

@@ -22,10 +22,10 @@ namespace Kernel {
/// Returns the number of threads that are waiting for a mutex, and the highest priority one among
/// those.
static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
const SharedPtr<Thread>& current_thread, VAddr mutex_addr) {
static std::pair<std::shared_ptr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
const std::shared_ptr<Thread>& current_thread, VAddr mutex_addr) {
SharedPtr<Thread> highest_priority_thread;
std::shared_ptr<Thread> highest_priority_thread;
u32 num_waiters = 0;
for (const auto& thread : current_thread->GetMutexWaitingThreads()) {
@@ -45,14 +45,14 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
}
/// Update the mutex owner field of all threads waiting on the mutex to point to the new owner.
static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_thread,
SharedPtr<Thread> new_owner) {
static void TransferMutexOwnership(VAddr mutex_addr, std::shared_ptr<Thread> current_thread,
std::shared_ptr<Thread> new_owner) {
const auto threads = current_thread->GetMutexWaitingThreads();
for (const auto& thread : threads) {
if (thread->GetMutexWaitAddress() != mutex_addr)
continue;
ASSERT(thread->GetLockOwner() == current_thread);
ASSERT(thread->GetLockOwner() == current_thread.get());
current_thread->RemoveMutexWaiter(thread);
if (new_owner != thread)
new_owner->AddMutexWaiter(thread);
@@ -70,9 +70,10 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
}
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
Thread* const current_thread = system.CurrentScheduler().GetCurrentThread();
SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
SharedPtr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle);
std::shared_ptr<Thread> current_thread =
SharedFrom(system.CurrentScheduler().GetCurrentThread());
std::shared_ptr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
std::shared_ptr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle);
// TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another
// thread.
@@ -110,7 +111,8 @@ ResultCode Mutex::Release(VAddr address) {
return ERR_INVALID_ADDRESS;
}
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
std::shared_ptr<Thread> current_thread =
SharedFrom(system.CurrentScheduler().GetCurrentThread());
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address);
// There are no more threads waiting for the mutex, release it completely.

View File

@@ -5,10 +5,9 @@
#pragma once
#include <atomic>
#include <memory>
#include <string>
#include <boost/smart_ptr/intrusive_ptr.hpp>
#include "common/common_types.h"
namespace Kernel {
@@ -32,7 +31,7 @@ enum class HandleType : u32 {
ServerSession,
};
class Object : NonCopyable {
class Object : NonCopyable, public std::enable_shared_from_this<Object> {
public:
explicit Object(KernelCore& kernel);
virtual ~Object();
@@ -61,35 +60,24 @@ protected:
KernelCore& kernel;
private:
friend void intrusive_ptr_add_ref(Object*);
friend void intrusive_ptr_release(Object*);
std::atomic<u32> ref_count{0};
std::atomic<u32> object_id{0};
};
// Special functions used by boost::instrusive_ptr to do automatic ref-counting
inline void intrusive_ptr_add_ref(Object* object) {
object->ref_count.fetch_add(1, std::memory_order_relaxed);
}
inline void intrusive_ptr_release(Object* object) {
if (object->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
delete object;
}
}
template <typename T>
using SharedPtr = boost::intrusive_ptr<T>;
std::shared_ptr<T> SharedFrom(T* raw) {
if (raw == nullptr)
return nullptr;
return std::static_pointer_cast<T>(raw->shared_from_this());
}
/**
* Attempts to downcast the given Object pointer to a pointer to T.
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
*/
template <typename T>
inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) {
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
return boost::static_pointer_cast<T>(object);
return std::static_pointer_cast<T>(object);
}
return nullptr;
}

View File

@@ -38,7 +38,7 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) {
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0,
owner_process.GetIdealCore(), stack_top, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap();
// Register 1 must be a handle to the main thread
const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
@@ -100,10 +100,10 @@ private:
std::bitset<num_slot_entries> is_slot_used;
};
SharedPtr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) {
std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) {
auto& kernel = system.Kernel();
SharedPtr<Process> process(new Process(system));
std::shared_ptr<Process> process = std::make_shared<Process>(system);
process->name = std::move(name);
process->resource_limit = kernel.GetSystemResourceLimit();
process->status = ProcessStatus::Created;
@@ -121,7 +121,7 @@ SharedPtr<Process> Process::Create(Core::System& system, std::string name, Proce
return process;
}
SharedPtr<ResourceLimit> Process::GetResourceLimit() const {
std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const {
return resource_limit;
}
@@ -142,6 +142,49 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
}
void Process::InsertConditionVariableThread(std::shared_ptr<Thread> thread) {
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
auto it = thread_list.begin();
while (it != thread_list.end()) {
const std::shared_ptr<Thread> current_thread = *it;
if (current_thread->GetPriority() > thread->GetPriority()) {
thread_list.insert(it, thread);
return;
}
++it;
}
thread_list.push_back(thread);
}
void Process::RemoveConditionVariableThread(std::shared_ptr<Thread> thread) {
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
auto it = thread_list.begin();
while (it != thread_list.end()) {
const std::shared_ptr<Thread> current_thread = *it;
if (current_thread.get() == thread.get()) {
thread_list.erase(it);
return;
}
++it;
}
UNREACHABLE();
}
std::vector<std::shared_ptr<Thread>> Process::GetConditionVariableThreads(
const VAddr cond_var_addr) {
std::vector<std::shared_ptr<Thread>> result{};
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
auto it = thread_list.begin();
while (it != thread_list.end()) {
std::shared_ptr<Thread> current_thread = *it;
result.push_back(current_thread);
++it;
}
return result;
}
void Process::RegisterThread(const Thread* thread) {
thread_list.push_back(thread);
}
@@ -197,12 +240,12 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
void Process::PrepareForTermination() {
ChangeStatus(ProcessStatus::Exiting);
const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) {
const auto stop_threads = [this](const std::vector<std::shared_ptr<Thread>>& thread_list) {
for (auto& thread : thread_list) {
if (thread->GetOwnerProcess() != this)
continue;
if (thread == system.CurrentScheduler().GetCurrentThread())
if (thread.get() == system.CurrentScheduler().GetCurrentThread())
continue;
// TODO(Subv): When are the other running/ready threads terminated?

View File

@@ -8,6 +8,7 @@
#include <cstddef>
#include <list>
#include <string>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "core/hle/kernel/address_arbiter.h"
@@ -61,6 +62,9 @@ enum class ProcessStatus {
class Process final : public WaitObject {
public:
explicit Process(Core::System& system);
~Process() override;
enum : u64 {
/// Lowest allowed process ID for a kernel initial process.
InitialKIPIDMin = 1,
@@ -81,7 +85,8 @@ public:
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
static SharedPtr<Process> Create(Core::System& system, std::string name, ProcessType type);
static std::shared_ptr<Process> Create(Core::System& system, std::string name,
ProcessType type);
std::string GetTypeName() const override {
return "Process";
@@ -156,7 +161,7 @@ public:
}
/// Gets the resource limit descriptor for this process
SharedPtr<ResourceLimit> GetResourceLimit() const;
std::shared_ptr<ResourceLimit> GetResourceLimit() const;
/// Gets the ideal CPU core ID for this process
u8 GetIdealCore() const {
@@ -232,6 +237,15 @@ public:
return thread_list;
}
/// Insert a thread into the condition variable wait container
void InsertConditionVariableThread(std::shared_ptr<Thread> thread);
/// Remove a thread from the condition variable wait container
void RemoveConditionVariableThread(std::shared_ptr<Thread> thread);
/// Obtain all condition variable threads waiting for some address
std::vector<std::shared_ptr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr);
/// Registers a thread as being created under this process,
/// adding it to this process' thread list.
void RegisterThread(const Thread* thread);
@@ -287,9 +301,6 @@ public:
void FreeTLSRegion(VAddr tls_address);
private:
explicit Process(Core::System& system);
~Process() override;
/// Checks if the specified thread should wait until this process is available.
bool ShouldWait(const Thread* thread) const override;
@@ -328,7 +339,7 @@ private:
u32 system_resource_size = 0;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
std::shared_ptr<ResourceLimit> resource_limit;
/// The ideal CPU core for this process, threads are scheduled on this core by default.
u8 ideal_core = 0;
@@ -375,6 +386,9 @@ private:
/// List of threads that are running with this process as their owner.
std::list<const Thread*> thread_list;
/// List of threads waiting for a condition variable
std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads;
/// System context
Core::System& system;

View File

@@ -16,8 +16,8 @@ constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
ResourceLimit::~ResourceLimit() = default;
SharedPtr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
return new ResourceLimit(kernel);
std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
return std::make_shared<ResourceLimit>(kernel);
}
s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {

View File

@@ -31,8 +31,11 @@ constexpr bool IsValidResourceType(ResourceType type) {
class ResourceLimit final : public Object {
public:
explicit ResourceLimit(KernelCore& kernel);
~ResourceLimit() override;
/// Creates a resource limit object.
static SharedPtr<ResourceLimit> Create(KernelCore& kernel);
static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel);
std::string GetTypeName() const override {
return "ResourceLimit";
@@ -76,9 +79,6 @@ public:
ResultCode SetLimitValue(ResourceType resource, s64 value);
private:
explicit ResourceLimit(KernelCore& kernel);
~ResourceLimit() override;
// TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
// functions
//

View File

@@ -26,11 +26,11 @@ GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {}
GlobalScheduler::~GlobalScheduler() = default;
void GlobalScheduler::AddThread(SharedPtr<Thread> thread) {
void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) {
thread_list.push_back(std::move(thread));
}
void GlobalScheduler::RemoveThread(const Thread* thread) {
void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) {
thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
thread_list.end());
}
@@ -42,11 +42,11 @@ void GlobalScheduler::UnloadThread(std::size_t core) {
void GlobalScheduler::SelectThread(std::size_t core) {
const auto update_thread = [](Thread* thread, Scheduler& sched) {
if (thread != sched.selected_thread) {
if (thread != sched.selected_thread.get()) {
if (thread == nullptr) {
++sched.idle_selection_count;
}
sched.selected_thread = thread;
sched.selected_thread = SharedFrom(thread);
}
sched.is_context_switch_pending = sched.selected_thread != sched.current_thread;
std::atomic_thread_fence(std::memory_order_seq_cst);
@@ -446,7 +446,7 @@ void Scheduler::SwitchContext() {
// Cancel any outstanding wakeup events for this thread
new_thread->CancelWakeupTimer();
current_thread = new_thread;
current_thread = SharedFrom(new_thread);
new_thread->SetStatus(ThreadStatus::Running);
new_thread->SetIsRunning(true);

View File

@@ -28,13 +28,13 @@ public:
~GlobalScheduler();
/// Adds a new thread to the scheduler
void AddThread(SharedPtr<Thread> thread);
void AddThread(std::shared_ptr<Thread> thread);
/// Removes a thread from the scheduler
void RemoveThread(const Thread* thread);
void RemoveThread(std::shared_ptr<Thread> thread);
/// Returns a list of all threads managed by the scheduler
const std::vector<SharedPtr<Thread>>& GetThreadList() const {
const std::vector<std::shared_ptr<Thread>>& GetThreadList() const {
return thread_list;
}
@@ -157,7 +157,7 @@ private:
std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};
/// Lists all thread ids that aren't deleted/etc.
std::vector<SharedPtr<Thread>> thread_list;
std::vector<std::shared_ptr<Thread>> thread_list;
Core::System& system;
};
@@ -213,8 +213,8 @@ private:
*/
void UpdateLastContextSwitchTime(Thread* thread, Process* process);
SharedPtr<Thread> current_thread = nullptr;
SharedPtr<Thread> selected_thread = nullptr;
std::shared_ptr<Thread> current_thread = nullptr;
std::shared_ptr<Thread> selected_thread = nullptr;
Core::System& system;
Core::ARM_Interface& cpu_core;

View File

@@ -16,7 +16,7 @@ namespace Kernel {
ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {}
ServerPort::~ServerPort() = default;
ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
if (pending_sessions.empty()) {
return ERR_NOT_FOUND;
}
@@ -26,7 +26,7 @@ ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
return MakeResult(std::move(session));
}
void ServerPort::AppendPendingSession(SharedPtr<ServerSession> pending_session) {
void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) {
pending_sessions.push_back(std::move(pending_session));
}
@@ -41,8 +41,8 @@ void ServerPort::Acquire(Thread* thread) {
ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions,
std::string name) {
SharedPtr<ServerPort> server_port(new ServerPort(kernel));
SharedPtr<ClientPort> client_port(new ClientPort(kernel));
std::shared_ptr<ServerPort> server_port = std::make_shared<ServerPort>(kernel);
std::shared_ptr<ClientPort> client_port = std::make_shared<ClientPort>(kernel);
server_port->name = name + "_Server";
client_port->name = name + "_Client";

View File

@@ -22,8 +22,11 @@ class SessionRequestHandler;
class ServerPort final : public WaitObject {
public:
explicit ServerPort(KernelCore& kernel);
~ServerPort() override;
using HLEHandler = std::shared_ptr<SessionRequestHandler>;
using PortPair = std::pair<SharedPtr<ServerPort>, SharedPtr<ClientPort>>;
using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>;
/**
* Creates a pair of ServerPort and an associated ClientPort.
@@ -52,7 +55,7 @@ public:
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
* return ERR_NO_PENDING_SESSIONS.
*/
ResultVal<SharedPtr<ServerSession>> Accept();
ResultVal<std::shared_ptr<ServerSession>> Accept();
/// Whether or not this server port has an HLE handler available.
bool HasHLEHandler() const {
@@ -74,17 +77,14 @@ public:
/// Appends a ServerSession to the collection of ServerSessions
/// waiting to be accepted by this port.
void AppendPendingSession(SharedPtr<ServerSession> pending_session);
void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
bool ShouldWait(const Thread* thread) const override;
void Acquire(Thread* thread) override;
private:
explicit ServerPort(KernelCore& kernel);
~ServerPort() override;
/// ServerSessions waiting to be accepted by the port
std::vector<SharedPtr<ServerSession>> pending_sessions;
std::vector<std::shared_ptr<ServerSession>> pending_sessions;
/// This session's HLE request handler template (optional)
/// ServerSessions created from this port inherit a reference to this handler.

View File

@@ -31,12 +31,11 @@ ServerSession::~ServerSession() {
if (parent->port) {
parent->port->ConnectionClosed();
}
parent->server = nullptr;
}
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelCore& kernel, std::string name) {
SharedPtr<ServerSession> server_session(new ServerSession(kernel));
ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,
std::string name) {
std::shared_ptr<ServerSession> server_session = std::make_shared<ServerSession>(kernel);
server_session->name = std::move(name);
server_session->parent = nullptr;
@@ -45,11 +44,13 @@ ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelCore& kernel, st
}
bool ServerSession::ShouldWait(const Thread* thread) const {
// Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
if (parent->client == nullptr)
return false;
// Wait if we have no pending requests, or if we're currently handling a request.
return pending_requesting_threads.empty() || currently_handling != nullptr;
if (auto client = parent->client.lock()) {
return pending_requesting_threads.empty() || currently_handling != nullptr;
}
// Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
return {};
}
void ServerSession::Acquire(Thread* thread) {
@@ -69,7 +70,7 @@ void ServerSession::ClientDisconnected() {
if (handler) {
// Note that after this returns, this server session's hle_handler is
// invalidated (set to null).
handler->ClientDisconnected(this);
handler->ClientDisconnected(SharedFrom(this));
}
// Clean up the list of client threads with pending requests, they are unneeded now that the
@@ -126,11 +127,11 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
return RESULT_SUCCESS;
}
ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
// The ServerSession received a sync request, this means that there's new data available
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
// similar.
Kernel::HLERequestContext context(this, thread);
Kernel::HLERequestContext context(SharedFrom(this), thread);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
@@ -186,14 +187,14 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel,
const std::string& name,
SharedPtr<ClientPort> port) {
std::shared_ptr<ClientPort> port) {
auto server_session = ServerSession::Create(kernel, name + "_Server").Unwrap();
SharedPtr<ClientSession> client_session(new ClientSession(kernel));
std::shared_ptr<ClientSession> client_session = std::make_shared<ClientSession>(kernel);
client_session->name = name + "_Client";
std::shared_ptr<Session> parent(new Session);
parent->client = client_session.get();
parent->server = server_session.get();
std::shared_ptr<Session> parent = std::make_shared<Session>();
parent->client = client_session;
parent->server = server_session;
parent->port = std::move(port);
client_session->parent = parent;

View File

@@ -38,6 +38,9 @@ class Thread;
*/
class ServerSession final : public WaitObject {
public:
explicit ServerSession(KernelCore& kernel);
~ServerSession() override;
std::string GetTypeName() const override {
return "ServerSession";
}
@@ -59,7 +62,7 @@ public:
return parent.get();
}
using SessionPair = std::pair<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
using SessionPair = std::pair<std::shared_ptr<ServerSession>, std::shared_ptr<ClientSession>>;
/**
* Creates a pair of ServerSession and an associated ClientSession.
@@ -69,7 +72,7 @@ public:
* @return The created session tuple
*/
static SessionPair CreateSessionPair(KernelCore& kernel, const std::string& name = "Unknown",
SharedPtr<ClientPort> client_port = nullptr);
std::shared_ptr<ClientPort> client_port = nullptr);
/**
* Sets the HLE handler for the session. This handler will be called to service IPC requests
@@ -85,7 +88,7 @@ public:
* @param thread Thread that initiated the request.
* @returns ResultCode from the operation.
*/
ResultCode HandleSyncRequest(SharedPtr<Thread> thread);
ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread);
bool ShouldWait(const Thread* thread) const override;
@@ -118,9 +121,6 @@ public:
}
private:
explicit ServerSession(KernelCore& kernel);
~ServerSession() override;
/**
* Creates a server session. The server session can have an optional HLE handler,
* which will be invoked to handle the IPC requests that this session receives.
@@ -128,8 +128,8 @@ private:
* @param name Optional name of the server session.
* @return The created server session
*/
static ResultVal<SharedPtr<ServerSession>> Create(KernelCore& kernel,
std::string name = "Unknown");
static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel,
std::string name = "Unknown");
/// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
/// object handle.
@@ -147,12 +147,12 @@ private:
/// List of threads that are pending a response after a sync request. This list is processed in
/// a LIFO manner, thus, the last request will be dispatched first.
/// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test.
std::vector<SharedPtr<Thread>> pending_requesting_threads;
std::vector<std::shared_ptr<Thread>> pending_requesting_threads;
/// Thread whose request is currently being handled. A request is considered "handled" when a
/// response is sent via svcReplyAndReceive.
/// TODO(Subv): Find a better name for this.
SharedPtr<Thread> currently_handling;
std::shared_ptr<Thread> currently_handling;
/// When set to True, converts the session to a domain at the end of the command
bool convert_to_domain{};

View File

@@ -20,8 +20,8 @@ class ServerSession;
*/
class Session final {
public:
ClientSession* client = nullptr; ///< The client endpoint of the session.
ServerSession* server = nullptr; ///< The server endpoint of the session.
SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional).
std::weak_ptr<ClientSession> client; ///< The client endpoint of the session.
std::weak_ptr<ServerSession> server; ///< The server endpoint of the session.
std::shared_ptr<ClientPort> port; ///< The port that this session is associated with (optional).
};
} // namespace Kernel

View File

@@ -15,11 +15,12 @@ namespace Kernel {
SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {}
SharedMemory::~SharedMemory() = default;
SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process, u64 size,
MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address,
MemoryRegion region, std::string name) {
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
std::shared_ptr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process,
u64 size, MemoryPermission permissions,
MemoryPermission other_permissions,
VAddr address, MemoryRegion region,
std::string name) {
std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel);
shared_memory->owner_process = owner_process;
shared_memory->name = std::move(name);
@@ -58,10 +59,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
return shared_memory;
}
SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
std::shared_ptr<SharedMemory> SharedMemory::CreateForApplet(
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
u64 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel);
shared_memory->owner_process = nullptr;
shared_memory->name = std::move(name);

View File

@@ -33,6 +33,9 @@ enum class MemoryPermission : u32 {
class SharedMemory final : public Object {
public:
explicit SharedMemory(KernelCore& kernel);
~SharedMemory() override;
/**
* Creates a shared memory object.
* @param kernel The kernel instance to create a shared memory instance under.
@@ -46,11 +49,12 @@ public:
* linear heap.
* @param name Optional object name, used for debugging purposes.
*/
static SharedPtr<SharedMemory> Create(KernelCore& kernel, Process* owner_process, u64 size,
MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address = 0,
MemoryRegion region = MemoryRegion::BASE,
std::string name = "Unknown");
static std::shared_ptr<SharedMemory> Create(KernelCore& kernel, Process* owner_process,
u64 size, MemoryPermission permissions,
MemoryPermission other_permissions,
VAddr address = 0,
MemoryRegion region = MemoryRegion::BASE,
std::string name = "Unknown");
/**
* Creates a shared memory object from a block of memory managed by an HLE applet.
@@ -63,7 +67,7 @@ public:
* block.
* @param name Optional object name, used for debugging purposes.
*/
static SharedPtr<SharedMemory> CreateForApplet(
static std::shared_ptr<SharedMemory> CreateForApplet(
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
u64 size, MemoryPermission permissions, MemoryPermission other_permissions,
std::string name = "Unknown Applet");
@@ -130,9 +134,6 @@ public:
const u8* GetPointer(std::size_t offset = 0) const;
private:
explicit SharedMemory(KernelCore& kernel);
~SharedMemory() override;
/// Backing memory for this shared memory block.
std::shared_ptr<PhysicalMemory> backing_block;
/// Offset into the backing block for this shared memory.

View File

@@ -17,6 +17,7 @@
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/kernel/address_arbiter.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -358,7 +359,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
auto client_port = it->second;
SharedPtr<ClientSession> client_session;
std::shared_ptr<ClientSession> client_session;
CASCADE_RESULT(client_session, client_port->Connect());
// Return the client session
@@ -370,7 +371,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
/// Makes a blocking IPC call to an OS service.
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle);
std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
if (!session) {
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -390,7 +391,7 @@ static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle threa
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle);
return ERR_INVALID_HANDLE;
@@ -405,13 +406,13 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const SharedPtr<Process> process = handle_table.Get<Process>(handle);
const std::shared_ptr<Process> process = handle_table.Get<Process>(handle);
if (process) {
*process_id = process->GetProcessID();
return RESULT_SUCCESS;
}
const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
if (thread) {
const Process* const owner_process = thread->GetOwnerProcess();
if (!owner_process) {
@@ -430,8 +431,8 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
}
/// Default thread wakeup callback for WaitSynchronization
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, std::size_t index) {
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index) {
ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
if (reason == ThreadWakeupReason::Timeout) {
@@ -505,8 +506,13 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
return RESULT_TIMEOUT;
}
if (thread->IsSyncCancelled()) {
thread->SetSyncCancelled(false);
return ERR_SYNCHRONIZATION_CANCELED;
}
for (auto& object : objects) {
object->AddWaitingThread(thread);
object->AddWaitingThread(SharedFrom(thread));
}
thread->SetWaitObjects(std::move(objects));
@@ -526,7 +532,7 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand
LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
thread_handle);
@@ -935,7 +941,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
const auto& core_timing = system.CoreTiming();
const auto& scheduler = system.CurrentScheduler();
const auto* const current_thread = scheduler.GetCurrentThread();
const bool same_thread = current_thread == thread;
const bool same_thread = current_thread == thread.get();
const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks();
u64 out_ticks = 0;
@@ -1045,7 +1051,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
}
const auto* current_process = system.Kernel().CurrentProcess();
const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -1061,7 +1067,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
return ERR_INVALID_HANDLE;
}
if (thread == system.CurrentScheduler().GetCurrentThread()) {
if (thread.get() == system.CurrentScheduler().GetCurrentThread()) {
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
return ERR_BUSY;
}
@@ -1077,7 +1083,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
const auto* current_process = system.Kernel().CurrentProcess();
const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -1093,7 +1099,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
return ERR_INVALID_HANDLE;
}
if (thread == system.CurrentScheduler().GetCurrentThread()) {
if (thread.get() == system.CurrentScheduler().GetCurrentThread()) {
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
return ERR_BUSY;
}
@@ -1118,7 +1124,7 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle
LOG_TRACE(Kernel_SVC, "called");
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -1142,7 +1148,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
const auto* const current_process = system.Kernel().CurrentProcess();
SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
return ERR_INVALID_HANDLE;
@@ -1262,7 +1268,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add
VAddr address) {
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle);
if (!process) {
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
process_handle);
@@ -1490,7 +1496,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
}
auto& kernel = system.Kernel();
CASCADE_RESULT(SharedPtr<Thread> thread,
CASCADE_RESULT(std::shared_ptr<Thread> thread,
Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top,
*current_process));
@@ -1516,7 +1522,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
thread_handle);
@@ -1540,7 +1546,7 @@ static void ExitThread(Core::System& system) {
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
current_thread->Stop();
system.GlobalScheduler().RemoveThread(current_thread);
system.GlobalScheduler().RemoveThread(SharedFrom(current_thread));
system.PrepareReschedule();
}
@@ -1612,7 +1618,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
auto* const current_process = system.Kernel().CurrentProcess();
const auto& handle_table = current_process->GetHandleTable();
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
ASSERT(thread);
const auto release_result = current_process->GetMutex().Release(mutex_addr);
@@ -1620,12 +1626,13 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
return release_result;
}
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
Thread* current_thread = system.CurrentScheduler().GetCurrentThread();
current_thread->SetCondVarWaitAddress(condition_variable_addr);
current_thread->SetMutexWaitAddress(mutex_addr);
current_thread->SetWaitHandle(thread_handle);
current_thread->SetStatus(ThreadStatus::WaitCondVar);
current_thread->InvalidateWakeupCallback();
current_process->InsertConditionVariableThread(SharedFrom(current_thread));
current_thread->WakeAfterDelay(nano_seconds);
@@ -1644,38 +1651,23 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var
ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4));
// Retrieve a list of all threads that are waiting for this condition variable.
std::vector<SharedPtr<Thread>> waiting_threads;
const auto& scheduler = system.GlobalScheduler();
const auto& thread_list = scheduler.GetThreadList();
auto* const current_process = system.Kernel().CurrentProcess();
std::vector<std::shared_ptr<Thread>> waiting_threads =
current_process->GetConditionVariableThreads(condition_variable_addr);
for (const auto& thread : thread_list) {
if (thread->GetCondVarWaitAddress() == condition_variable_addr) {
waiting_threads.push_back(thread);
}
}
// Sort them by priority, such that the highest priority ones come first.
std::sort(waiting_threads.begin(), waiting_threads.end(),
[](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
return lhs->GetPriority() < rhs->GetPriority();
});
// Only process up to 'target' threads, unless 'target' is -1, in which case process
// Only process up to 'target' threads, unless 'target' is less equal 0, in which case process
// them all.
std::size_t last = waiting_threads.size();
if (target != -1)
if (target > 0)
last = std::min(waiting_threads.size(), static_cast<std::size_t>(target));
// If there are no threads waiting on this condition variable, just exit
if (last == 0)
return RESULT_SUCCESS;
for (std::size_t index = 0; index < last; ++index) {
auto& thread = waiting_threads[index];
ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr);
// liberate Cond Var Thread.
current_process->RemoveConditionVariableThread(thread);
thread->SetCondVarWaitAddress(0);
const std::size_t current_core = system.CurrentCoreIndex();
@@ -1786,7 +1778,9 @@ static u64 GetSystemTick(Core::System& system) {
LOG_TRACE(Kernel_SVC, "called");
auto& core_timing = system.CoreTiming();
const u64 result{core_timing.GetTicks()};
// Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick)
const u64 result{Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks())};
// Advance time to defeat dumb games that busy-wait for the frame to end.
core_timing.AddTicks(400);
@@ -1975,7 +1969,7 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
thread_handle);
@@ -2034,7 +2028,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
}
const auto& handle_table = current_process->GetHandleTable();
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
if (!thread) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
thread_handle);

View File

@@ -50,7 +50,7 @@ void Thread::Stop() {
// Clean up any dangling references in objects that this thread was waiting for
for (auto& wait_object : wait_objects) {
wait_object->RemoveWaitingThread(this);
wait_object->RemoveWaitingThread(SharedFrom(this));
}
wait_objects.clear();
@@ -120,8 +120,11 @@ void Thread::ResumeFromWait() {
}
void Thread::CancelWait() {
ASSERT(GetStatus() == ThreadStatus::WaitSynch);
ClearWaitObjects();
if (GetSchedulingStatus() != ThreadSchedStatus::Paused) {
is_sync_cancelled = true;
return;
}
is_sync_cancelled = false;
SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED);
ResumeFromWait();
}
@@ -144,9 +147,10 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd
context.fpcr = 0x03C00000;
}
ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
u32 priority, u64 arg, s32 processor_id,
VAddr stack_top, Process& owner_process) {
ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::string name,
VAddr entry_point, u32 priority, u64 arg,
s32 processor_id, VAddr stack_top,
Process& owner_process) {
// Check if priority is in ranged. Lowest priority -> highest priority id.
if (priority > THREADPRIO_LOWEST) {
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
@@ -165,7 +169,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
}
auto& system = Core::System::GetInstance();
SharedPtr<Thread> thread(new Thread(kernel));
std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel);
thread->thread_id = kernel.CreateNewThreadID();
thread->status = ThreadStatus::Dormant;
@@ -194,7 +198,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
// to initialize the context
ResetThreadContext(thread->context, stack_top, entry_point, arg);
return MakeResult<SharedPtr<Thread>>(std::move(thread));
return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
}
void Thread::SetPriority(u32 priority) {
@@ -212,7 +216,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
context.cpu_registers[1] = output;
}
s32 Thread::GetWaitObjectIndex(const WaitObject* object) const {
s32 Thread::GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const {
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
@@ -252,8 +256,8 @@ void Thread::SetStatus(ThreadStatus new_status) {
status = new_status;
}
void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
if (thread->lock_owner == this) {
void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) {
if (thread->lock_owner.get() == this) {
// If the thread is already waiting for this thread to release the mutex, ensure that the
// waiters list is consistent and return without doing anything.
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
@@ -273,13 +277,13 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
wait_mutex_threads.begin(), wait_mutex_threads.end(),
[&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); });
wait_mutex_threads.insert(insertion_point, thread);
thread->lock_owner = this;
thread->lock_owner = SharedFrom(this);
UpdatePriority();
}
void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) {
ASSERT(thread->lock_owner == this);
void Thread::RemoveMutexWaiter(std::shared_ptr<Thread> thread) {
ASSERT(thread->lock_owner.get() == this);
// Ensure that the thread is in the list of mutex waiters
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
@@ -306,16 +310,24 @@ void Thread::UpdatePriority() {
return;
}
if (GetStatus() == ThreadStatus::WaitCondVar) {
owner_process->RemoveConditionVariableThread(SharedFrom(this));
}
SetCurrentPriority(new_priority);
if (GetStatus() == ThreadStatus::WaitCondVar) {
owner_process->InsertConditionVariableThread(SharedFrom(this));
}
if (!lock_owner) {
return;
}
// Ensure that the thread is within the correct location in the waiting list.
auto old_owner = lock_owner;
lock_owner->RemoveMutexWaiter(this);
old_owner->AddMutexWaiter(this);
lock_owner->RemoveMutexWaiter(SharedFrom(this));
old_owner->AddMutexWaiter(SharedFrom(this));
// Recursively update the priority of the thread that depends on the priority of this one.
lock_owner->UpdatePriority();
@@ -328,11 +340,11 @@ void Thread::ChangeCore(u32 core, u64 mask) {
bool Thread::AllWaitObjectsReady() const {
return std::none_of(
wait_objects.begin(), wait_objects.end(),
[this](const SharedPtr<WaitObject>& object) { return object->ShouldWait(this); });
[this](const std::shared_ptr<WaitObject>& object) { return object->ShouldWait(this); });
}
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, std::size_t index) {
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index) {
ASSERT(wakeup_callback);
return wakeup_callback(reason, std::move(thread), std::move(object), index);
}

View File

@@ -97,14 +97,18 @@ enum class ThreadSchedMasks : u32 {
class Thread final : public WaitObject {
public:
using MutexWaitingThreads = std::vector<SharedPtr<Thread>>;
explicit Thread(KernelCore& kernel);
~Thread() override;
using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>;
using ThreadContext = Core::ARM_Interface::ThreadContext;
using ThreadWaitObjects = std::vector<SharedPtr<WaitObject>>;
using ThreadWaitObjects = std::vector<std::shared_ptr<WaitObject>>;
using WakeupCallback = std::function<bool(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, std::size_t index)>;
using WakeupCallback =
std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index)>;
/**
* Creates and returns a new thread. The new thread is immediately scheduled
@@ -118,10 +122,10 @@ public:
* @param owner_process The parent process for the thread
* @return A shared pointer to the newly created thread
*/
static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name,
VAddr entry_point, u32 priority, u64 arg,
s32 processor_id, VAddr stack_top,
Process& owner_process);
static ResultVal<std::shared_ptr<Thread>> Create(KernelCore& kernel, std::string name,
VAddr entry_point, u32 priority, u64 arg,
s32 processor_id, VAddr stack_top,
Process& owner_process);
std::string GetName() const override {
return name;
@@ -166,10 +170,10 @@ public:
void SetPriority(u32 priority);
/// Adds a thread to the list of threads that are waiting for a lock held by this thread.
void AddMutexWaiter(SharedPtr<Thread> thread);
void AddMutexWaiter(std::shared_ptr<Thread> thread);
/// Removes a thread from the list of threads that are waiting for a lock held by this thread.
void RemoveMutexWaiter(SharedPtr<Thread> thread);
void RemoveMutexWaiter(std::shared_ptr<Thread> thread);
/// Recalculates the current priority taking into account priority inheritance.
void UpdatePriority();
@@ -229,7 +233,7 @@ public:
*
* @param object Object to query the index of.
*/
s32 GetWaitObjectIndex(const WaitObject* object) const;
s32 GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const;
/**
* Stops a thread, invalidating it from further use
@@ -320,7 +324,7 @@ public:
void ClearWaitObjects() {
for (const auto& waiting_object : wait_objects) {
waiting_object->RemoveWaitingThread(this);
waiting_object->RemoveWaitingThread(SharedFrom(this));
}
wait_objects.clear();
}
@@ -336,7 +340,7 @@ public:
return lock_owner.get();
}
void SetLockOwner(SharedPtr<Thread> owner) {
void SetLockOwner(std::shared_ptr<Thread> owner) {
lock_owner = std::move(owner);
}
@@ -390,8 +394,8 @@ public:
* @pre A valid wakeup callback has been set. Violating this precondition
* will cause an assertion to trigger.
*/
bool InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, std::size_t index);
bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index);
u32 GetIdealCore() const {
return ideal_core;
@@ -440,10 +444,15 @@ public:
is_running = value;
}
private:
explicit Thread(KernelCore& kernel);
~Thread() override;
bool IsSyncCancelled() const {
return is_sync_cancelled;
}
void SetSyncCancelled(bool value) {
is_sync_cancelled = value;
}
private:
void SetSchedulingStatus(ThreadSchedStatus new_status);
void SetCurrentPriority(u32 new_priority);
ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
@@ -491,7 +500,7 @@ private:
MutexWaitingThreads wait_mutex_threads;
/// Thread that owns the lock that this thread is waiting for.
SharedPtr<Thread> lock_owner;
std::shared_ptr<Thread> lock_owner;
/// If waiting on a ConditionVariable, this is the ConditionVariable address
VAddr condvar_wait_address = 0;
@@ -524,6 +533,7 @@ private:
u32 scheduling_state = 0;
bool is_running = false;
bool is_sync_cancelled = false;
std::string name;
};

View File

@@ -14,9 +14,9 @@ namespace Kernel {
TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
TransferMemory::~TransferMemory() = default;
SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size,
MemoryPermission permissions) {
SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
u64 size, MemoryPermission permissions) {
std::shared_ptr<TransferMemory> transfer_memory{std::make_shared<TransferMemory>(kernel)};
transfer_memory->base_address = base_address;
transfer_memory->memory_size = size;

View File

@@ -27,10 +27,13 @@ enum class MemoryPermission : u32;
///
class TransferMemory final : public Object {
public:
explicit TransferMemory(KernelCore& kernel);
~TransferMemory() override;
static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size,
MemoryPermission permissions);
static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size,
MemoryPermission permissions);
TransferMemory(const TransferMemory&) = delete;
TransferMemory& operator=(const TransferMemory&) = delete;
@@ -79,9 +82,6 @@ public:
ResultCode UnmapMemory(VAddr address, u64 size);
private:
explicit TransferMemory(KernelCore& kernel);
~TransferMemory() override;
/// Memory block backing this instance.
std::shared_ptr<PhysicalMemory> backing_block;

View File

@@ -18,13 +18,13 @@ namespace Kernel {
WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {}
WaitObject::~WaitObject() = default;
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
if (itr == waiting_threads.end())
waiting_threads.push_back(std::move(thread));
}
void WaitObject::RemoveWaitingThread(Thread* thread) {
void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
// If a thread passed multiple handles to the same object,
// the kernel might attempt to remove the thread from the object's
@@ -33,7 +33,7 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
waiting_threads.erase(itr);
}
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
Thread* candidate = nullptr;
u32 candidate_priority = THREADPRIO_LOWEST + 1;
@@ -64,10 +64,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
}
}
return candidate;
return SharedFrom(candidate);
}
void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
ASSERT(!ShouldWait(thread.get()));
if (!thread) {
@@ -83,7 +83,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
Acquire(thread.get());
}
const std::size_t index = thread->GetWaitObjectIndex(this);
const std::size_t index = thread->GetWaitObjectIndex(SharedFrom(this));
thread->ClearWaitObjects();
@@ -91,7 +91,8 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
bool resume = true;
if (thread->HasWakeupCallback()) {
resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index);
resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, SharedFrom(this),
index);
}
if (resume) {
thread->ResumeFromWait();
@@ -105,7 +106,7 @@ void WaitObject::WakeupAllWaitingThreads() {
}
}
const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const {
const std::vector<std::shared_ptr<Thread>>& WaitObject::GetWaitingThreads() const {
return waiting_threads;
}

View File

@@ -33,13 +33,13 @@ public:
* Add a thread to wait on this object
* @param thread Pointer to thread to add
*/
void AddWaitingThread(SharedPtr<Thread> thread);
void AddWaitingThread(std::shared_ptr<Thread> thread);
/**
* Removes a thread from waiting on this object (e.g. if it was resumed already)
* @param thread Pointer to thread to remove
*/
void RemoveWaitingThread(Thread* thread);
void RemoveWaitingThread(std::shared_ptr<Thread> thread);
/**
* Wake up all threads waiting on this object that can be awoken, in priority order,
@@ -51,24 +51,24 @@ public:
* Wakes up a single thread waiting on this object.
* @param thread Thread that is waiting on this object to wakeup.
*/
void WakeupWaitingThread(SharedPtr<Thread> thread);
void WakeupWaitingThread(std::shared_ptr<Thread> thread);
/// Obtains the highest priority thread that is ready to run from this object's waiting list.
SharedPtr<Thread> GetHighestPriorityReadyThread() const;
std::shared_ptr<Thread> GetHighestPriorityReadyThread() const;
/// Get a const reference to the waiting threads list for debug use
const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const;
const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const;
private:
/// Threads waiting for this object to become available
std::vector<SharedPtr<Thread>> waiting_threads;
std::vector<std::shared_ptr<Thread>> waiting_threads;
};
// Specialization of DynamicObjectCast for WaitObjects
template <>
inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) {
inline std::shared_ptr<WaitObject> DynamicObjectCast<WaitObject>(std::shared_ptr<Object> object) {
if (object != nullptr && object->IsWaitable()) {
return boost::static_pointer_cast<WaitObject>(object);
return std::static_pointer_cast<WaitObject>(object);
}
return nullptr;
}

View File

@@ -16,8 +16,8 @@ WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
WritableEvent::~WritableEvent() = default;
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
std::shared_ptr<WritableEvent> writable_event(new WritableEvent(kernel));
std::shared_ptr<ReadableEvent> readable_event(new ReadableEvent(kernel));
writable_event->name = name + ":Writable";
writable_event->readable = readable_event;
@@ -27,7 +27,7 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
return {std::move(readable_event), std::move(writable_event)};
}
SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const {
std::shared_ptr<ReadableEvent> WritableEvent::GetReadableEvent() const {
return readable;
}

View File

@@ -13,8 +13,8 @@ class ReadableEvent;
class WritableEvent;
struct EventPair {
SharedPtr<ReadableEvent> readable;
SharedPtr<WritableEvent> writable;
std::shared_ptr<ReadableEvent> readable;
std::shared_ptr<WritableEvent> writable;
};
class WritableEvent final : public Object {
@@ -40,7 +40,7 @@ public:
return HANDLE_TYPE;
}
SharedPtr<ReadableEvent> GetReadableEvent() const;
std::shared_ptr<ReadableEvent> GetReadableEvent() const;
void Signal();
void Clear();
@@ -49,7 +49,7 @@ public:
private:
explicit WritableEvent(KernelCore& kernel);
SharedPtr<ReadableEvent> readable;
std::shared_ptr<ReadableEvent> readable;
std::string name; ///< Name of event (optional)
};

View File

@@ -28,6 +28,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
{106, nullptr, "GetProfileSyncNotifier"},
{110, nullptr, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},
@@ -44,6 +45,8 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
{206, nullptr, "CompleteUserRegistrationForcibly"},
{210, nullptr, "CreateFloatingRegistrationRequest"},
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
{230, nullptr, "AuthenticateServiceAsync"},
{250, nullptr, "GetBaasAccountAdministrator"},
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},

View File

@@ -28,6 +28,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{103, nullptr, "GetProfileUpdateNotifier"},
{104, nullptr, "CheckNetworkServiceAvailabilityAsync"},
{105, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{106, nullptr, "GetProfileSyncNotifier"},
{110, nullptr, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},

View File

@@ -229,7 +229,15 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
{20, nullptr, "InvalidateTransitionLayer"},
{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
{40, nullptr, "GetAppletResourceUsageInfo"},
{41, nullptr, "SetCpuBoostModeForApplet"},
{100, nullptr, "SetCpuBoostModeForApplet"},
{110, nullptr, "PushToAppletBoundChannelForDebug"},
{111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
{120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
{121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"},
{122, nullptr, "AlarmSettingNotificationPushAppEventNotify"},
{130, nullptr, "FriendInvitationSetApplicationParameter"},
{131, nullptr, "FriendInvitationClearApplicationParameter"},
{132, nullptr, "FriendInvitationPushApplicationParameter"},
};
// clang-format on
@@ -278,10 +286,12 @@ ISelfController::ISelfController(Core::System& system,
{69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
{70, nullptr, "ReportMultimediaError"},
{71, nullptr, "GetCurrentIlluminanceEx"},
{72, nullptr, "SetInputDetectionPolicy"},
{80, nullptr, "SetWirelessPriorityMode"},
{90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
{91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
{100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
{110, nullptr, "SetApplicationAlbumUserData"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
@@ -531,12 +541,11 @@ AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
AppletMessageQueue::~AppletMessageQueue() = default;
const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent()
const {
const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent() const {
return on_new_message.readable;
}
const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
const {
return on_operation_mode_changed.readable;
}
@@ -613,6 +622,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system,
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
{91, nullptr, "GetCurrentPerformanceConfiguration"},
{200, nullptr, "GetOperationModeSystemInfo"},
{300, nullptr, "GetSettingsPlatformRegion"},
};
// clang-format on
@@ -1076,12 +1086,18 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"},
{101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"},
{102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
{110, nullptr, "QueryApplicationPlayStatistics"},
{110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"},
{111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"},
{120, nullptr, "ExecuteProgram"},
{121, nullptr, "ClearUserChannel"},
{122, nullptr, "UnpopToUserChannel"},
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
{140, nullptr, "GetFriendInvitationStorageChannelEvent"},
{141, nullptr, "TryPopFromFriendInvitationStorageChannel"},
{150, nullptr, "GetNotificationStorageChannelEvent"},
{151, nullptr, "TryPopFromNotificationStorageChannel"},
{160, nullptr, "GetHealthWarningDisappearedSystemEvent"},
{170, nullptr, "SetHdcpAuthenticationActivated"},
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
{1000, nullptr, "CreateMovieMaker"},
{1001, nullptr, "PrepareForJit"},
@@ -1336,12 +1352,16 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
}
void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
struct Parameters {
FileSys::SaveDataType type;
u128 user_id;
u64 new_normal_size;
u64 new_journal_size;
};
static_assert(sizeof(Parameters) == 40);
IPC::RequestParser rp{ctx};
const auto type{rp.PopRaw<FileSys::SaveDataType>()};
rp.Skip(1, false);
const auto user_id{rp.PopRaw<u128>()};
const auto new_normal_size{rp.PopRaw<u64>()};
const auto new_journal_size{rp.PopRaw<u64>()};
const auto [type, user_id, new_normal_size, new_journal_size] = rp.PopRaw<Parameters>();
LOG_DEBUG(Service_AM,
"called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, "
@@ -1360,10 +1380,14 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
}
void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
struct Parameters {
FileSys::SaveDataType type;
u128 user_id;
};
static_assert(sizeof(Parameters) == 24);
IPC::RequestParser rp{ctx};
const auto type{rp.PopRaw<FileSys::SaveDataType>()};
rp.Skip(1, false);
const auto user_id{rp.PopRaw<u128>()};
const auto [type, user_id] = rp.PopRaw<Parameters>();
LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type),
user_id[1], user_id[0]);
@@ -1377,12 +1401,12 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
rb.Push(size.journal);
}
void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) {
void IApplicationFunctions::QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(gpu_error_detected_event.readable);
rb.Push<u32>(0);
}
void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx) {
@@ -1393,6 +1417,14 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque
rb.Push<u32>(0);
}
void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(gpu_error_detected_event.readable);
}
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) {
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
@@ -1418,6 +1450,8 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions"
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
{31, nullptr, "GetWriterLockAccessorEx"},
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
{110, nullptr, "IsForceTerminateApplicationDisabledForDebug"},
{200, nullptr, "LaunchDevMenu"},
};
// clang-format on

View File

@@ -54,8 +54,8 @@ public:
explicit AppletMessageQueue(Kernel::KernelCore& kernel);
~AppletMessageQueue();
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const;
const std::shared_ptr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
const std::shared_ptr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const;
void PushMessage(AppletMessage msg);
AppletMessage PopMessage();
std::size_t GetMessageCount() const;
@@ -255,8 +255,9 @@ private:
void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx);
void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx);
void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx);
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx);
void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx);
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
bool launch_popped_application_specific = false;
bool launch_popped_account_preselect = false;

View File

@@ -108,15 +108,15 @@ void AppletDataBroker::SignalStateChanged() const {
state_changed_event.writable->Signal();
}
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
return pop_out_data_event.readable;
}
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
return pop_interactive_out_data_event.readable;
}
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
return state_changed_event.readable;
}

View File

@@ -86,9 +86,9 @@ public:
void SignalStateChanged() const;
Kernel::SharedPtr<Kernel::ReadableEvent> GetNormalDataEvent() const;
Kernel::SharedPtr<Kernel::ReadableEvent> GetInteractiveDataEvent() const;
Kernel::SharedPtr<Kernel::ReadableEvent> GetStateChangedEvent() const;
std::shared_ptr<Kernel::ReadableEvent> GetNormalDataEvent() const;
std::shared_ptr<Kernel::ReadableEvent> GetInteractiveDataEvent() const;
std::shared_ptr<Kernel::ReadableEvent> GetStateChangedEvent() const;
private:
// Queues are named from applet's perspective

View File

@@ -10,7 +10,7 @@ IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetAutoPowerDownEvent"},
{1, nullptr, "Unknown1"},
{1, nullptr, "IsAutoPowerDownRequested"},
{2, nullptr, "Unknown2"},
{3, nullptr, "SetHandlingContext"},
{4, nullptr, "LoadAndApplySettings"},

View File

@@ -35,6 +35,8 @@ OMM::OMM() : ServiceFramework{"omm"} {
{23, nullptr, "GetHdcpState"},
{24, nullptr, "ShowCardUpdateProcessing"},
{25, nullptr, "SetApplicationCecSettingsAndNotifyChanged"},
{26, nullptr, "GetOperationModeSystemInfo"},
{27, nullptr, "GetAppletFullAwakingSystemEvent"},
};
// clang-format on

View File

@@ -61,6 +61,7 @@ AOC_U::AOC_U(Core::System& system)
{7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"},
{8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"},
{100, nullptr, "CreateEcPurchasedEventManager"},
{101, nullptr, "CreatePermanentEcPurchasedEventManager"},
};
// clang-format on

View File

@@ -38,6 +38,7 @@ AudCtl::AudCtl() : ServiceFramework{"audctl"} {
{24, nullptr, "GetSystemOutputMasterVolume"},
{25, nullptr, "GetAudioVolumeDataForPlayReport"},
{26, nullptr, "UpdateHeadphoneSettings"},
{27, nullptr, "SetVolumeMappingTableForDev"},
};
// clang-format on

View File

@@ -16,7 +16,7 @@ ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
}
Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
std::shared_ptr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
return event.readable;
}

View File

@@ -98,7 +98,7 @@ public:
private:
explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent() const;
std::shared_ptr<Kernel::ReadableEvent> GetEvent() const;
DeliveryCacheProgressImpl& GetImpl();
void SignalUpdate() const;

View File

@@ -87,7 +87,7 @@ struct DeliveryCacheDirectoryEntry {
class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
public:
IDeliveryCacheProgressService(Kernel::SharedPtr<Kernel::ReadableEvent> event,
IDeliveryCacheProgressService(std::shared_ptr<Kernel::ReadableEvent> event,
const DeliveryCacheProgressImpl& impl)
: ServiceFramework{"IDeliveryCacheProgressService"}, event(std::move(event)), impl(impl) {
// clang-format off
@@ -118,7 +118,7 @@ private:
rb.Push(RESULT_SUCCESS);
}
Kernel::SharedPtr<Kernel::ReadableEvent> event;
std::shared_ptr<Kernel::ReadableEvent> event;
const DeliveryCacheProgressImpl& impl;
};
@@ -137,14 +137,20 @@ public:
{10200, nullptr, "CancelSyncDeliveryCacheRequest"},
{20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"},
{20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"},
{20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"},
{20301, nullptr, "RequestSuspendDeliveryTask"},
{20400, nullptr, "RegisterSystemApplicationDeliveryTask"},
{20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
{30100, &IBcatService::SetPassphrase, "SetPassphrase"},
{30200, nullptr, "RegisterBackgroundDeliveryTask"},
{30201, nullptr, "UnregisterBackgroundDeliveryTask"},
{30202, nullptr, "BlockDeliveryTask"},
{30203, nullptr, "UnblockDeliveryTask"},
{30300, nullptr, "RegisterSystemApplicationDeliveryTasks"},
{90100, nullptr, "EnumerateBackgroundDeliveryTask"},
{90200, nullptr, "GetDeliveryList"},
{90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"},
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
{90300, nullptr, "GetPushNotificationLog"},
};
// clang-format on

View File

@@ -155,6 +155,7 @@ public:
{98, nullptr, "SetLeScanParameter"},
{256, nullptr, "GetIsManufacturingMode"},
{257, nullptr, "EmulateBluetoothCrash"},
{258, nullptr, "GetBleChannelMap"},
};
// clang-format on

View File

@@ -24,6 +24,8 @@ public:
{6, nullptr, "SubmitMultipleCategoryContext"},
{7, nullptr, "UpdateApplicationLaunchTime"},
{8, nullptr, "ClearApplicationLaunchTime"},
{9, nullptr, "SubmitAttachment"},
{10, nullptr, "CreateReportWithAttachments"},
};
// clang-format on
@@ -38,6 +40,7 @@ public:
static const FunctionInfo functions[] = {
{0, nullptr, "OpenReport"},
{1, nullptr, "OpenManager"},
{2, nullptr, "OpenAttachment"},
};
// clang-format on

View File

@@ -52,6 +52,8 @@ public:
{34, nullptr, "GetEncryptedTicketSize"},
{35, nullptr, "GetEncryptedTicketData"},
{36, nullptr, "DeleteAllInactiveELicenseRequiredPersonalizedTicket"},
{37, nullptr, "OwnTicket2"},
{38, nullptr, "OwnTicket3"},
{503, nullptr, "GetTitleKey"},
};
// clang-format on

View File

@@ -680,6 +680,7 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
{33, nullptr, "DeleteCacheStorage"},
{34, nullptr, "GetCacheStorageSize"},
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
{36, nullptr, "OpenHostFileSystemWithOption"},
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
@@ -694,11 +695,14 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
{66, nullptr, "WriteSaveDataFileSystemExtraData2"},
{67, nullptr, "FindSaveDataWithFilter"},
{68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"},
{69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"},
{70, nullptr, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"},
{80, nullptr, "OpenSaveDataMetaFile"},
{81, nullptr, "OpenSaveDataTransferManager"},
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
{83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
{85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"},
{100, nullptr, "OpenImageDirectoryFileSystem"},
{110, nullptr, "OpenContentStorageFileSystem"},
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
@@ -756,6 +760,8 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
{1009, nullptr, "GetAndClearMemoryReportInfo"},
{1010, nullptr, "SetDataStorageRedirectTarget"},
{1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
{1012, nullptr, "GetFsStackUsage"},
{1013, nullptr, "UnsetSaveDataRootPath"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
{1200, nullptr, "OpenMultiCommitManager"},

View File

@@ -60,6 +60,9 @@ public:
{20801, nullptr, "SyncUserSetting"},
{20900, nullptr, "RequestListSummaryOverlayNotification"},
{21000, nullptr, "GetExternalApplicationCatalog"},
{22000, nullptr, "GetReceivedFriendInvitationList"},
{22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"},
{22010, nullptr, "GetReceivedFriendInvitationCountCache"},
{30100, nullptr, "DropFriendNewlyFlags"},
{30101, nullptr, "DeleteFriend"},
{30110, nullptr, "DropFriendNewlyFlag"},
@@ -91,6 +94,8 @@ public:
{30812, nullptr, "ChangePlayLogPermission"},
{30820, nullptr, "IssueFriendCode"},
{30830, nullptr, "ClearPlayLog"},
{30900, nullptr, "SendFriendInvitation"},
{30910, nullptr, "ReadFriendInvitation"},
{49900, nullptr, "DeleteNetworkServiceAccountCache"},
};
// clang-format on

View File

@@ -501,8 +501,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
last_processed_vibration = vibrations.back();
}
Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(
u32 npad_id) const {
std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const {
// TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
// be signalled at least once, and signaled after a new controller is connected?
const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];

View File

@@ -109,7 +109,7 @@ public:
void VibrateController(const std::vector<u32>& controller_ids,
const std::vector<Vibration>& vibrations);
Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
Vibration GetLastVibration() const;
void AddNewController(NPadControllerType controller);

View File

@@ -215,6 +215,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
{133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
{134, nullptr, "SetNpadAnalogStickUseCenterClamp"},
{135, nullptr, "SetNpadCaptureButtonAssignment"},
{136, nullptr, "ClearNpadCaptureButtonAssignment"},
{200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
{201, &Hid::SendVibrationValue, "SendVibrationValue"},
{202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
@@ -245,6 +247,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{404, nullptr, "HasLeftRightBattery"},
{405, nullptr, "GetNpadInterfaceType"},
{406, nullptr, "GetNpadLeftRightInterfaceType"},
{407, nullptr, "GetNpadOfHighestBatteryLevelForJoyLeft"},
{408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
{500, nullptr, "GetPalmaConnectionHandle"},
{501, nullptr, "InitializePalma"},
{502, nullptr, "AcquirePalmaOperationCompleteEvent"},
@@ -272,8 +276,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{524, nullptr, "PairPalma"},
{525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
{526, nullptr, "CancelWritePalmaWaveEntry"},
{527, nullptr, "EnablePalmaBoostMode"},
{528, nullptr, "GetPalmaBluetoothAddress"},
{529, nullptr, "SetDisallowedPalmaConnection"},
{1000, nullptr, "SetNpadCommunicationMode"},
{1001, nullptr, "GetNpadCommunicationMode"},
{1002, nullptr, "SetTouchScreenConfiguration"},
{1003, nullptr, "IsFirmwareUpdateNeededForNotification"},
};
// clang-format on
@@ -969,6 +978,9 @@ public:
{310, nullptr, "GetMaskedSupportedNpadStyleSet"},
{311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
{312, nullptr, "SetSupportedNpadStyleSetAll"},
{313, nullptr, "GetNpadCaptureButtonAssignment"},
{314, nullptr, "GetAppletFooterUiType"},
{315, nullptr, "GetAppletDetailedUiType"},
{321, nullptr, "GetUniquePadsFromNpad"},
{322, nullptr, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
@@ -984,6 +996,8 @@ public:
{513, nullptr, "EndPermitVibrationSession"},
{520, nullptr, "EnableHandheldHids"},
{521, nullptr, "DisableHandheldHids"},
{522, nullptr, "SetJoyConRailEnabled"},
{523, nullptr, "IsJoyConRailEnabled"},
{540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
@@ -1010,6 +1024,7 @@ public:
{809, nullptr, "GetUniquePadSerialNumber"},
{810, nullptr, "GetUniquePadControllerNumber"},
{811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
{812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
{821, nullptr, "StartAnalogStickManualCalibration"},
{822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
{823, nullptr, "CancelAnalogStickManualCalibration"},
@@ -1020,6 +1035,8 @@ public:
{828, nullptr, "IsAnalogStickInReleasePosition"},
{829, nullptr, "IsAnalogStickInCircumference"},
{830, nullptr, "SetNotificationLedPattern"},
{831, nullptr, "SetNotificationLedPatternWithTimeout"},
{832, nullptr, "PrepareHidsForNotificationWake"},
{850, nullptr, "IsUsbFullKeyControllerEnabled"},
{851, nullptr, "EnableUsbFullKeyController"},
{852, nullptr, "IsUsbConnected"},
@@ -1049,6 +1066,13 @@ public:
{1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
{1133, nullptr, "StartUsbFirmwareUpdate"},
{1134, nullptr, "GetUsbFirmwareUpdateState"},
{1150, nullptr, "SetTouchScreenMagnification"},
{1151, nullptr, "GetTouchScreenFirmwareVersion"},
{1152, nullptr, "SetTouchScreenDefaultConfiguration"},
{1153, nullptr, "GetTouchScreenDefaultConfiguration"},
{1154, nullptr, "IsFirmwareAvailableForNotification"},
{1155, nullptr, "SetForceHandheldStyleVibration"},
{1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
};
// clang-format on

View File

@@ -67,7 +67,7 @@ private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(u64 userdata, s64 cycles_late);
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
std::shared_ptr<Kernel::SharedMemory> shared_mem;
Core::Timing::EventType* pad_update_event;
Core::System& system;

View File

@@ -37,7 +37,7 @@ private:
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
std::shared_ptr<Kernel::SharedMemory> shared_mem;
const u32 device_handle{0xABCD};
Core::System& system;
};

View File

@@ -50,6 +50,8 @@ public:
{21, &IDatabaseService::GetIndex, "GetIndex"},
{22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"},
{23, nullptr, "Convert"},
{24, nullptr, "ConvertCoreDataToCharInfo"},
{25, nullptr, "ConvertCharInfoToCoreData"},
};
// clang-format on

View File

@@ -61,7 +61,8 @@ public:
{5, nullptr, "RegisterHtmlDocumentPath"},
{6, nullptr, "UnregisterHtmlDocumentPath"},
{7, nullptr, "RedirectHtmlDocumentPath"},
{8, nullptr, ""},
{8, nullptr, "Refresh"},
{9, nullptr, "RefreshExcluding"},
};
// clang-format on
@@ -77,6 +78,8 @@ public:
{0, nullptr, "ResolveAddOnContentPath"},
{1, nullptr, "RegisterAddOnContentStorage"},
{2, nullptr, "UnregisterAllAddOnContentPath"},
{3, nullptr, "RefreshApplicationAddOnContent"},
{4, nullptr, "UnregisterApplicationAddOnContent"},
};
// clang-format on
@@ -118,6 +121,7 @@ public:
{10, nullptr, "InactivateContentStorage"},
{11, nullptr, "ActivateContentMetaDatabase"},
{12, nullptr, "InactivateContentMetaDatabase"},
{13, nullptr, "InvalidateRightsIdCache"},
};
// clang-format on

View File

@@ -215,6 +215,7 @@ public:
{411, nullptr, "AttachActivateEvent"},
{412, nullptr, "AttachDeactivateEvent"},
{500, nullptr, "SetNfcEnabled"},
{510, nullptr, "OutputTestWave"},
{1000, nullptr, "ReadMifare"},
{1001, nullptr, "WriteMifare"},
{1300, nullptr, "SendCommandByPassThrough"},

View File

@@ -342,7 +342,7 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
return true;
}
const Kernel::SharedPtr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const {
const std::shared_ptr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const {
return nfc_tag_load.readable;
}

View File

@@ -34,7 +34,7 @@ public:
void CreateUserInterface(Kernel::HLERequestContext& ctx);
bool LoadAmiibo(const std::vector<u8>& buffer);
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetNFCEvent() const;
const std::shared_ptr<Kernel::ReadableEvent>& GetNFCEvent() const;
const AmiiboFile& GetAmiiboBuffer() const;
private:

View File

@@ -208,6 +208,7 @@ private:
IGeneralService::IGeneralService(Core::System& system)
: ServiceFramework("IGeneralService"), system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
@@ -246,7 +247,14 @@ IGeneralService::IGeneralService(Core::System& system)
{36, nullptr, "GetCurrentAccessPoint"},
{37, nullptr, "Shutdown"},
{38, nullptr, "GetAllowedChannels"},
{39, nullptr, "NotifyApplicationSuspended"},
{40, nullptr, "SetAcceptableNetworkTypeFlag"},
{41, nullptr, "GetAcceptableNetworkTypeFlag"},
{42, nullptr, "NotifyConnectionStateChanged"},
{43, nullptr, "SetWowlDelayedWakeTime"},
};
// clang-format on
RegisterHandlers(functions);
}

View File

@@ -116,6 +116,8 @@ public:
{500, nullptr, "RequestSyncTicket"},
{501, nullptr, "RequestDownloadTicket"},
{502, nullptr, "RequestDownloadTicketForPrepurchasedContents"},
{503, nullptr, "RequestSyncTicket"},
{504, nullptr, "RequestDownloadTicketForPrepurchasedContents2"},
};
// clang-format on

View File

@@ -44,6 +44,10 @@ public:
{113, nullptr, "DestroyJid"},
{114, nullptr, "AttachJid"},
{115, nullptr, "DetachJid"},
{120, nullptr, "CreateNotificationReceiver"},
{151, nullptr, "GetStateWithHandover"},
{152, nullptr, "GetStateChangeEventWithHandover"},
{153, nullptr, "GetDropEventWithHandover"},
{201, nullptr, "RequestChangeStateForceTimed"},
{202, nullptr, "RequestChangeStateForceAsync"},
};
@@ -74,6 +78,9 @@ public:
{104, nullptr, "GetStatistics"},
{111, nullptr, "GetJid"},
{120, nullptr, "CreateNotificationReceiver"},
{151, nullptr, "GetStateWithHandover"},
{152, nullptr, "GetStateChangeEventWithHandover"},
{153, nullptr, "GetDropEventWithHandover"},
};
// clang-format on

View File

@@ -106,6 +106,7 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{96, nullptr, "AcquireApplicationLaunchInfo"},
{97, nullptr, "GetMainApplicationProgramIndex2"},
{98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{99, nullptr, "LaunchDevMenu"},
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
@@ -130,6 +131,8 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{404, nullptr, "InvalidateApplicationControlCache"},
{405, nullptr, "ListApplicationControlCacheEntryInfo"},
{406, nullptr, "GetApplicationControlProperty"},
{407, nullptr, "ListApplicationTitle"},
{408, nullptr, "ListApplicationIcon"},
{502, nullptr, "RequestCheckGameCardRegistration"},
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
{504, nullptr, "RequestRegisterGameCard"},
@@ -138,6 +141,7 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{507, nullptr, "EnsureGameCardAccess"},
{508, nullptr, "GetLastGameCardMountFailureResult"},
{509, nullptr, "ListApplicationIdOnGameCard"},
{510, nullptr, "GetGameCardPlatformRegion"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{602, nullptr, "ListAvailableAddOnContent"},
@@ -168,6 +172,9 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{910, nullptr, "HasApplicationRecord"},
{911, nullptr, "SetPreInstalledApplication"},
{912, nullptr, "ClearPreInstalledApplicationFlag"},
{913, nullptr, "ListAllApplicationRecord"},
{914, nullptr, "HideApplicationRecord"},
{915, nullptr, "ShowApplicationRecord"},
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
@@ -190,12 +197,14 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
{1504, nullptr, "InsertSdCard"},
{1505, nullptr, "RemoveSdCard"},
{1506, nullptr, "GetSdCardStartupStatus"},
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
{1701, nullptr, "GetApplicationView"},
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
{1704, nullptr, "GetApplicationViewWithPromotionInfo"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
@@ -223,6 +232,7 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{2017, nullptr, "CreateDownloadTask"},
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
{2050, nullptr, "GetApplicationRightsOnClient"},
{2051, nullptr, "InvalidateRightsIdCache"},
{2100, nullptr, "GetApplicationTerminateResult"},
{2101, nullptr, "GetRawApplicationTerminateResult"},
{2150, nullptr, "CreateRightsEnvironment"},
@@ -230,6 +240,8 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{2152, nullptr, "ActivateRightsEnvironment"},
{2153, nullptr, "DeactivateRightsEnvironment"},
{2154, nullptr, "ForceActivateRightsContextForExit"},
{2155, nullptr, "UpdateRightsEnvironmentStatus"},
{2156, nullptr, "CreateRightsEnvironmentForPreomia"},
{2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
{2161, nullptr, "SetUsersToRightsEnvironment"},
{2170, nullptr, "GetRightsEnvironmentStatus"},
@@ -243,6 +255,20 @@ IApplicationManagerInterface::IApplicationManagerInterface()
{2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
{2250, nullptr, "RequestReportActiveELicence"},
{2300, nullptr, "ListEventLog"},
{2350, nullptr, "PerformAutoUpdateByApplicationId"},
{2351, nullptr, "RequestNoDownloadRightsErrorResolution"},
{2352, nullptr, "RequestResolveNoDownloadRightsError"},
{2400, nullptr, "GetPromotionInfo"},
{2401, nullptr, "CountPromotionInfo"},
{2402, nullptr, "ListPromotionInfo"},
{2403, nullptr, "ImportPromotionJsonForDebug"},
{2404, nullptr, "ClearPromotionInfoForDebug"},
{2500, nullptr, "ConfirmAvailableTime"},
{2510, nullptr, "CreateApplicationResource"},
{2511, nullptr, "GetApplicationResource"},
{2513, nullptr, "LaunchPreomia"},
{2514, nullptr, "ClearTaskOfAsyncTaskManager"},
{2800, nullptr, "GetApplicationIdOfPreomia"},
};
// clang-format on
@@ -463,6 +489,7 @@ IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterfa
{3, nullptr, "RequestSyncRights"},
{4, nullptr, "RequestUnlinkDevice"},
{5, nullptr, "RequestRevokeAllELicense"},
{6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"},
};
// clang-format on

View File

@@ -141,7 +141,7 @@ struct PL_U::Impl {
}
/// Handle to shared memory region designated for a shared font
Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
std::shared_ptr<Kernel::SharedMemory> shared_font_mem;
/// Backing memory for the shared font data
std::shared_ptr<Kernel::PhysicalMemory> shared_font;
@@ -152,7 +152,7 @@ struct PL_U::Impl {
PL_U::PL_U(Core::System& system)
: ServiceFramework("pl:u"), impl{std::make_unique<Impl>()}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &PL_U::RequestLoad, "RequestLoad"},
{1, &PL_U::GetLoadState, "GetLoadState"},
@@ -160,7 +160,13 @@ PL_U::PL_U(Core::System& system)
{3, &PL_U::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"},
{4, &PL_U::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
{5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"},
{6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"},
{100, nullptr, "RequestApplicationFunctionAuthorization"},
{101, nullptr, "RequestApplicationFunctionAuthorizationForSystem"},
{1000, nullptr, "LoadNgWordDataForPlatformRegionChina"},
{1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"},
};
// clang-format on
RegisterHandlers(functions);
auto& fsc = system.GetFileSystemController();

View File

@@ -61,7 +61,7 @@ void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) {
if (ctrl.must_delay) {
ctrl.fresh_call = false;
ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout,
[=](Kernel::SharedPtr<Kernel::Thread> thread,
[=](std::shared_ptr<Kernel::Thread> thread,
Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) {
IoctlCtrl ctrl2{ctrl};

View File

@@ -100,11 +100,11 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
}
}
Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const {
std::shared_ptr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const {
return events_interface.events[event_id].readable;
}
Kernel::SharedPtr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const {
std::shared_ptr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const {
return events_interface.events[event_id].writable;
}

View File

@@ -114,9 +114,9 @@ public:
void SignalSyncpt(const u32 syncpoint_id, const u32 value);
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(u32 event_id) const;
std::shared_ptr<Kernel::ReadableEvent> GetEvent(u32 event_id) const;
Kernel::SharedPtr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const;
std::shared_ptr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const;
private:
/// Id to use for the next open file descriptor.

View File

@@ -117,11 +117,11 @@ u32 BufferQueue::Query(QueryType type) {
return 0;
}
Kernel::SharedPtr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
std::shared_ptr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
return buffer_wait_event.writable;
}
Kernel::SharedPtr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const {
std::shared_ptr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const {
return buffer_wait_event.readable;
}

View File

@@ -93,9 +93,9 @@ public:
return id;
}
Kernel::SharedPtr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const;
std::shared_ptr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const;
Kernel::SharedPtr<Kernel::ReadableEvent> GetBufferWaitEvent() const;
std::shared_ptr<Kernel::ReadableEvent> GetBufferWaitEvent() const;
private:
u32 id;

View File

@@ -98,7 +98,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
return layer->GetBufferQueue().GetId();
}
Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
auto* const display = FindDisplay(display_id);
if (display == nullptr) {

View File

@@ -62,7 +62,7 @@ public:
/// Gets the vsync event for the specified display.
///
/// If an invalid display ID is provided, then nullptr is returned.
Kernel::SharedPtr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
/// Obtains a buffer queue identified by the ID.
BufferQueue& FindBufferQueue(u32 id);

View File

@@ -16,9 +16,9 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
constexpr u64 NO_PROCESS_FOUND_PID{0};
std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list,
std::function<bool(const Kernel::SharedPtr<Kernel::Process>&)> predicate) {
std::optional<std::shared_ptr<Kernel::Process>> SearchProcessList(
const std::vector<std::shared_ptr<Kernel::Process>>& process_list,
std::function<bool(const std::shared_ptr<Kernel::Process>&)> predicate) {
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
if (iter == process_list.end()) {
@@ -29,7 +29,7 @@ std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
}
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list) {
const std::vector<std::shared_ptr<Kernel::Process>>& process_list) {
const auto process = SearchProcessList(process_list, [](const auto& process) {
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
});
@@ -124,7 +124,7 @@ private:
class Info final : public ServiceFramework<Info> {
public:
explicit Info(const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list)
explicit Info(const std::vector<std::shared_ptr<Kernel::Process>>& process_list)
: ServiceFramework{"pm:info"}, process_list(process_list) {
static const FunctionInfo functions[] = {
{0, &Info::GetTitleId, "GetTitleId"},
@@ -154,7 +154,7 @@ private:
rb.Push((*process)->GetTitleID());
}
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list;
const std::vector<std::shared_ptr<Kernel::Process>>& process_list;
};
class Shell final : public ServiceFramework<Shell> {
@@ -172,7 +172,7 @@ public:
{6, &Shell::GetApplicationPid, "GetApplicationPid"},
{7, nullptr, "BoostSystemMemoryResourceLimit"},
{8, nullptr, "EnableAdditionalSystemThreads"},
{9, nullptr, "GetUnimplementedEventHandle"},
{9, nullptr, "GetBootFinishedEventHandle"},
};
// clang-format on

View File

@@ -25,6 +25,7 @@ public:
{10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
{10200, nullptr, "RequestImmediateTransmission"},
{10300, nullptr, "GetTransmissionStatus"},
{10400, nullptr, "GetSystemSessionId"},
{20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
{20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
{20200, nullptr, "SetOperationMode"},

View File

@@ -116,7 +116,7 @@ void ServiceFrameworkBase::InstallAsNamedPort() {
port_installed = true;
}
Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
std::shared_ptr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
ASSERT(!port_installed);
auto& kernel = Core::System::GetInstance().Kernel();

View File

@@ -65,7 +65,7 @@ public:
/// Creates a port pair and registers it on the kernel's global port registry.
void InstallAsNamedPort();
/// Creates and returns an unregistered port for the service.
Kernel::SharedPtr<Kernel::ClientPort> CreatePort();
std::shared_ptr<Kernel::ClientPort> CreatePort();
void InvokeRequest(Kernel::HLERequestContext& ctx);

View File

@@ -124,6 +124,7 @@ SET::SET() : ServiceFramework("set") {
{7, nullptr, "GetKeyCodeMap"},
{8, &SET::GetQuestFlag, "GetQuestFlag"},
{9, nullptr, "GetKeyCodeMap2"},
{10, nullptr, "GetFirmwareVersionForDebug"},
};
// clang-format on

View File

@@ -7,6 +7,7 @@
namespace Service::Set {
SET_CAL::SET_CAL() : ServiceFramework("set:cal") {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetBluetoothBdAddress"},
{1, nullptr, "GetConfigurationId1"},
@@ -40,8 +41,18 @@ SET_CAL::SET_CAL() : ServiceFramework("set:cal") {
{30, nullptr, "GetAmiiboEcqvBlsCertificate"},
{31, nullptr, "GetAmiiboEcqvBlsRootCertificate"},
{32, nullptr, "GetUsbTypeCPowerSourceCircuitVersion"},
{33, nullptr, "GetAnalogStickModuleTypeL"},
{34, nullptr, "GetAnalogStickModelParameterL"},
{35, nullptr, "GetAnalogStickFactoryCalibrationL"},
{36, nullptr, "GetAnalogStickModuleTypeR"},
{37, nullptr, "GetAnalogStickModelParameterR"},
{38, nullptr, "GetAnalogStickFactoryCalibrationR"},
{39, nullptr, "GetConsoleSixAxisSensorModuleType"},
{40, nullptr, "GetConsoleSixAxisSensorHorizontalOffset"},
{41, nullptr, "GetBatteryVersion"},
};
// clang-format on
RegisterHandlers(functions);
}

View File

@@ -7,6 +7,7 @@
namespace Service::Set {
SET_FD::SET_FD() : ServiceFramework("set:fd") {
// clang-format off
static const FunctionInfo functions[] = {
{2, nullptr, "SetSettingsItemValue"},
{3, nullptr, "ResetSettingsItemValue"},
@@ -16,7 +17,10 @@ SET_FD::SET_FD() : ServiceFramework("set:fd") {
{20, nullptr, "SetWebInspectorFlag"},
{21, nullptr, "SetAllowedSslHosts"},
{22, nullptr, "SetHostFsMountPoint"},
{23, nullptr, "SetMemoryUsageRateFlag"},
};
// clang-format on
RegisterHandlers(functions);
}

View File

@@ -273,10 +273,21 @@ SET_SYS::SET_SYS() : ServiceFramework("set:sys") {
{171, nullptr, "SetChineseTraditionalInputMethod"},
{172, nullptr, "GetPtmCycleCountReliability"},
{173, nullptr, "SetPtmCycleCountReliability"},
{174, nullptr, "GetHomeMenuScheme"},
{175, nullptr, "GetThemeSettings"},
{176, nullptr, "SetThemeSettings"},
{177, nullptr, "GetThemeKey"},
{178, nullptr, "SetThemeKey"},
{179, nullptr, "GetZoomFlag"},
{180, nullptr, "SetZoomFlag"},
{181, nullptr, "GetT"},
{182, nullptr, "SetT"},
{183, nullptr, "GetPlatformRegion"},
{184, nullptr, "SetPlatformRegion"},
{185, nullptr, "GetHomeMenuSchemeModel"},
{186, nullptr, "GetMemoryUsageRateFlag"},
{187, nullptr, "GetTouchScreenMode"},
{188, nullptr, "SetTouchScreenMode"},
};
// clang-format on

View File

@@ -30,7 +30,7 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(RESULT_SUCCESS);
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client};
std::shared_ptr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client};
rb.PushMoveObjects(session);
LOG_DEBUG(Service, "session={}", session->GetObjectId());

View File

@@ -45,7 +45,7 @@ void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) {
self->controller_interface = std::make_unique<Controller>();
}
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService(
ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
std::string name, unsigned int max_sessions) {
CASCADE_CODE(ValidateServiceName(name));
@@ -72,7 +72,7 @@ ResultCode ServiceManager::UnregisterService(const std::string& name) {
return RESULT_SUCCESS;
}
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort(
ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
const std::string& name) {
CASCADE_CODE(ValidateServiceName(name));
@@ -84,7 +84,7 @@ ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort(
return MakeResult(it->second);
}
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ServiceManager::ConnectToService(
ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService(
const std::string& name) {
CASCADE_RESULT(auto client_port, GetServicePort(name));

View File

@@ -48,11 +48,11 @@ public:
ServiceManager();
~ServiceManager();
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name,
unsigned int max_sessions);
ResultVal<std::shared_ptr<Kernel::ServerPort>> RegisterService(std::string name,
unsigned int max_sessions);
ResultCode UnregisterService(const std::string& name);
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> GetServicePort(const std::string& name);
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ConnectToService(const std::string& name);
ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);
ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name);
template <typename T>
std::shared_ptr<T> GetService(const std::string& service_name) const {
@@ -77,7 +77,7 @@ private:
std::unique_ptr<Controller> controller_interface;
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> registered_services;
std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services;
};
} // namespace Service::SM

View File

@@ -7,6 +7,7 @@
namespace Service::Sockets {
NSD::NSD(const char* name) : ServiceFramework(name) {
// clang-format off
static const FunctionInfo functions[] = {
{10, nullptr, "GetSettingName"},
{11, nullptr, "GetEnvironmentIdentifier"},
@@ -22,10 +23,14 @@ NSD::NSD(const char* name) : ServiceFramework(name) {
{42, nullptr, "GetNasApiFqdn"},
{43, nullptr, "GetNasApiFqdnEx"},
{50, nullptr, "GetCurrentSetting"},
{51, nullptr, "WriteTestParameter"},
{52, nullptr, "ReadTestParameter"},
{60, nullptr, "ReadSaveDataFromFsForTest"},
{61, nullptr, "WriteSaveDataToFsForTest"},
{62, nullptr, "DeleteSaveDataOfFsForTest"},
};
// clang-format on
RegisterHandlers(functions);
}

View File

@@ -13,6 +13,7 @@ namespace Service::SSL {
class ISslConnection final : public ServiceFramework<ISslConnection> {
public:
ISslConnection() : ServiceFramework("ISslConnection") {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SetSocketDescriptor"},
{1, nullptr, "SetHostName"},
@@ -40,7 +41,11 @@ public:
{23, nullptr, "GetOption"},
{24, nullptr, "GetVerifyCertErrors"},
{25, nullptr, "GetCipherInfo"},
{26, nullptr, "SetNextAlpnProto"},
{27, nullptr, "GetNextAlpnProto"},
};
// clang-format on
RegisterHandlers(functions);
}
};

View File

@@ -21,6 +21,7 @@ Time::Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_me
{30, nullptr, "GetStandardNetworkClockOperationEventReadableHandle"},
{31, nullptr, "GetEphemeralNetworkClockOperationEventReadableHandle"},
{50, nullptr, "SetStandardSteadyClockInternalOffset"},
{51, nullptr, "GetStandardSteadyClockRtcValue"},
{100, &Time::IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
{101, &Time::SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
{102, nullptr, "GetStandardUserSystemClockInitialYear"},

View File

@@ -74,15 +74,17 @@ public:
ISystemClock(std::shared_ptr<Service::Time::SharedMemory> shared_memory,
ClockContextType clock_type)
: ServiceFramework("ISystemClock"), shared_memory(shared_memory), clock_type(clock_type) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
{1, nullptr, "SetCurrentTime"},
{2, &ISystemClock::GetSystemClockContext, "GetSystemClockContext"},
{3, nullptr, "SetSystemClockContext"},
{4, nullptr, "GetOperationEventReadableHandle"},
};
RegisterHandlers(functions);
// clang-format on
RegisterHandlers(functions);
UpdateSharedMemoryContext(system_clock_context);
}
@@ -162,6 +164,7 @@ private:
class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
public:
ITimeZoneService() : ServiceFramework("ITimeZoneService") {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
{1, nullptr, "SetDeviceLocationName"},
@@ -169,11 +172,17 @@ public:
{3, nullptr, "LoadLocationNameList"},
{4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},
{5, nullptr, "GetTimeZoneRuleVersion"},
{6, nullptr, "GetDeviceLocationNameAndUpdatedTime"},
{7, nullptr, "SetDeviceLocationNameWithTimeZoneRule"},
{8, nullptr, "ParseTimeZoneBinary"},
{20, nullptr, "GetDeviceLocationNameOperationEventReadableHandle"},
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
{201, &ITimeZoneService::ToPosixTime, "ToPosixTime"},
{202, &ITimeZoneService::ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"},
};
// clang-format on
RegisterHandlers(functions);
}

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