From be1954e04cb5a0c3a526f78ed5490a5e65310280 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 15 Oct 2020 14:49:45 -0400 Subject: core: Fix clang build Recent changes to the build system that made more warnings be flagged as errors caused building via clang to break. Fixes #4795 --- src/core/hle/kernel/physical_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index d7a7a951c..6cb59d0fc 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -34,7 +34,7 @@ public: PhysicalCore& operator=(const PhysicalCore&) = delete; PhysicalCore(PhysicalCore&&) = default; - PhysicalCore& operator=(PhysicalCore&&) = default; + PhysicalCore& operator=(PhysicalCore&&) = delete; void Idle(); /// Interrupt this physical core. -- cgit v1.2.3 From 3d592972dc3fd61cc88771b889eff237e4e03e0f Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Oct 2020 19:07:39 -0700 Subject: Revert "core: Fix clang build" --- externals/microprofile/microprofile.h | 4 +- src/audio_core/CMakeLists.txt | 5 +- src/audio_core/algorithm/interpolate.cpp | 6 +- src/audio_core/audio_renderer.cpp | 4 +- src/audio_core/codec.cpp | 6 +- src/audio_core/command_generator.cpp | 212 +++++++++------------ src/audio_core/command_generator.h | 4 +- src/audio_core/cubeb_sink.cpp | 2 +- src/audio_core/cubeb_sink.h | 2 +- src/audio_core/info_updater.cpp | 4 +- src/audio_core/mix_context.cpp | 17 +- src/audio_core/sink_context.cpp | 5 +- src/audio_core/splitter_context.cpp | 60 +++--- src/audio_core/time_stretch.h | 10 +- src/audio_core/voice_context.cpp | 47 ++--- src/common/fiber.h | 4 +- src/common/file_util.h | 3 +- src/common/math_util.h | 4 +- src/common/multi_level_queue.h | 2 +- src/common/spin_lock.h | 8 - src/common/swap.h | 10 +- src/common/thread_queue_list.h | 4 +- src/core/CMakeLists.txt | 5 +- src/core/arm/arm_interface.cpp | 24 +-- src/core/arm/arm_interface.h | 8 +- src/core/arm/cpu_interrupt_handler.h | 4 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 10 +- src/core/arm/dynarmic/arm_dynarmic_32.h | 8 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 10 +- src/core/arm/dynarmic/arm_dynarmic_64.h | 8 +- src/core/arm/unicorn/arm_unicorn.cpp | 42 ++-- src/core/arm/unicorn/arm_unicorn.h | 8 +- src/core/core_timing.cpp | 13 +- src/core/core_timing_util.cpp | 42 ++-- src/core/core_timing_util.h | 4 +- src/core/crypto/key_manager.cpp | 7 +- src/core/crypto/partition_data_manager.cpp | 2 +- src/core/file_sys/content_archive.cpp | 4 +- src/core/file_sys/fsmitm_romfsbuild.cpp | 2 +- src/core/file_sys/ips_layer.cpp | 41 ++-- src/core/file_sys/kernel_executable.cpp | 6 +- src/core/file_sys/nca_patch.cpp | 7 +- src/core/frontend/applets/controller.cpp | 2 +- src/core/frontend/applets/profile_select.cpp | 3 +- src/core/gdbstub/gdbstub.cpp | 47 +---- src/core/gdbstub/gdbstub.h | 2 +- src/core/hle/ipc_helpers.h | 4 +- src/core/hle/kernel/address_arbiter.cpp | 4 +- src/core/hle/kernel/handle_table.cpp | 2 +- src/core/hle/kernel/hle_ipc.cpp | 2 +- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/memory/address_space_info.cpp | 2 - src/core/hle/kernel/memory/memory_manager.cpp | 4 +- src/core/hle/kernel/memory/page_heap.cpp | 17 +- src/core/hle/kernel/memory/page_heap.h | 18 +- src/core/hle/kernel/memory/page_table.cpp | 6 +- src/core/hle/kernel/physical_core.h | 2 +- src/core/hle/kernel/process.cpp | 17 +- src/core/hle/kernel/resource_limit.cpp | 4 +- src/core/hle/kernel/scheduler.cpp | 72 ++----- src/core/hle/kernel/svc.cpp | 7 +- src/core/hle/kernel/svc_wrap.h | 17 +- src/core/hle/kernel/synchronization.cpp | 4 +- src/core/hle/kernel/thread.cpp | 2 +- src/core/hle/kernel/thread.h | 6 +- src/core/hle/service/acc/profile_manager.cpp | 13 +- src/core/hle/service/am/am.cpp | 2 +- src/core/hle/service/am/applets/controller.cpp | 26 +-- src/core/hle/service/audio/audout_u.cpp | 7 +- src/core/hle/service/audio/hwopus.cpp | 29 ++- src/core/hle/service/bcat/backend/backend.h | 8 +- src/core/hle/service/bcat/backend/boxcat.cpp | 9 - src/core/hle/service/bcat/module.cpp | 3 +- src/core/hle/service/filesystem/fsp_srv.cpp | 8 +- src/core/hle/service/hid/controllers/debug_pad.cpp | 8 +- src/core/hle/service/hid/controllers/gesture.cpp | 8 +- src/core/hle/service/hid/controllers/keyboard.cpp | 8 +- src/core/hle/service/hid/controllers/mouse.cpp | 8 +- src/core/hle/service/hid/controllers/npad.cpp | 69 +++---- src/core/hle/service/hid/controllers/stubbed.cpp | 12 +- .../hle/service/hid/controllers/touchscreen.cpp | 9 +- src/core/hle/service/hid/controllers/touchscreen.h | 2 +- src/core/hle/service/hid/controllers/xpad.cpp | 8 +- src/core/hle/service/ldr/ldr.cpp | 4 +- src/core/hle/service/mii/manager.cpp | 20 +- src/core/hle/service/nfp/nfp.cpp | 2 +- src/core/hle/service/ns/ns.cpp | 2 +- src/core/hle/service/ns/pl_u.cpp | 12 +- .../hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 48 ++--- src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 12 +- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 8 +- src/core/hle/service/nvdrv/interface.cpp | 8 +- src/core/hle/service/nvflinger/nvflinger.cpp | 2 +- src/core/hle/service/service.cpp | 4 +- src/core/hle/service/set/set.cpp | 6 +- src/core/hle/service/sockets/bsd.cpp | 72 +++---- src/core/hle/service/sockets/bsd.h | 3 - src/core/hle/service/sockets/sockets_translate.cpp | 1 - src/core/hle/service/time/time_zone_manager.cpp | 118 ++++++------ src/core/hle/service/time/time_zone_service.cpp | 4 +- src/core/loader/elf.cpp | 35 ++-- src/core/memory.cpp | 2 +- src/core/network/network.cpp | 31 ++- src/core/network/network.h | 12 +- src/core/network/sockets.h | 6 +- 105 files changed, 667 insertions(+), 906 deletions(-) (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h index d22f92868..85d5bd5de 100644 --- a/externals/microprofile/microprofile.h +++ b/externals/microprofile/microprofile.h @@ -857,7 +857,7 @@ inline int64_t MicroProfileLogTickDifference(MicroProfileLogEntry Start, MicroPr { uint64_t nStart = Start; uint64_t nEnd = End; - auto nDifference = static_cast((nEnd << 16) - (nStart << 16)); + int64_t nDifference = ((nEnd<<16) - (nStart<<16)); return nDifference >> 16; } @@ -868,7 +868,7 @@ inline int64_t MicroProfileLogGetTick(MicroProfileLogEntry e) inline int64_t MicroProfileLogSetTick(MicroProfileLogEntry e, int64_t nTick) { - return static_cast((MP_LOG_TICK_MASK & static_cast(nTick)) | (e & static_cast(~MP_LOG_TICK_MASK))); + return (MP_LOG_TICK_MASK & nTick) | (e & ~MP_LOG_TICK_MASK); } template diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 74c1453aa..54940a034 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -51,9 +51,8 @@ if (NOT MSVC) -Werror=implicit-fallthrough -Werror=reorder -Werror=sign-compare - -Werror=sign-conversion - $<$:-Werror=unused-but-set-parameter> - $<$:-Werror=unused-but-set-variable> + -Werror=unused-but-set-parameter + -Werror=unused-but-set-variable -Werror=unused-variable ) endif() diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp index 587ee5b7b..699fcb84c 100644 --- a/src/audio_core/algorithm/interpolate.cpp +++ b/src/audio_core/algorithm/interpolate.cpp @@ -167,8 +167,8 @@ std::vector Interpolate(InterpolationState& state, std::vector input, output.reserve(static_cast(static_cast(input.size()) / ratio + InterpolationState::taps)); - for (std::size_t frame = 0; frame < num_frames; ++frame) { - const auto lut_index{static_cast(state.fraction >> 8) * InterpolationState::taps}; + for (std::size_t frame{}; frame < num_frames; ++frame) { + const std::size_t lut_index{(state.fraction >> 8) * InterpolationState::taps}; std::rotate(state.history.begin(), state.history.end() - 1, state.history.end()); state.history[0][0] = input[frame * 2 + 0]; @@ -225,7 +225,7 @@ void Resample(s32* output, const s32* input, s32 pitch, s32& fraction, std::size output[i] = (l0 * s0 + l1 * s1 + l2 * s2 + l3 * s3) >> 15; fraction += pitch; - index += static_cast(fraction >> 15); + index += (fraction >> 15); fraction &= 0x7fff; } } diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 094bace9c..a7e851bb8 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -187,8 +187,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { const auto& in_params = final_mix.GetInParams(); std::vector mix_buffers(channel_count); for (std::size_t i = 0; i < channel_count; i++) { - mix_buffers[i] = command_generator.GetMixBuffer( - static_cast(in_params.buffer_offset) + buffer_offsets[i]); + mix_buffers[i] = + command_generator.GetMixBuffer(in_params.buffer_offset + buffer_offsets[i]); } for (std::size_t i = 0; i < BUFFER_SIZE; i++) { diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp index d89f94ea2..2fb91c13a 100644 --- a/src/audio_core/codec.cpp +++ b/src/audio_core/codec.cpp @@ -32,7 +32,7 @@ std::vector DecodeADPCM(const u8* const data, std::size_t size, const ADPCM for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) { const int frame_header = data[framei * FRAME_LEN]; const int scale = 1 << (frame_header & 0xF); - const auto idx = static_cast((frame_header >> 4) & 0x7); + const int idx = (frame_header >> 4) & 0x7; // Coefficients are fixed point with 11 bits fractional part. const int coef1 = coeff[idx * 2 + 0]; @@ -57,11 +57,11 @@ std::vector DecodeADPCM(const u8* const data, std::size_t size, const ADPCM std::size_t outputi = framei * SAMPLES_PER_FRAME; std::size_t datai = framei * FRAME_LEN + 1; for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { - const s16 sample1 = decode_sample(SIGNED_NIBBLES[static_cast(data[datai] >> 4)]); + const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]); ret[outputi] = sample1; outputi++; - const s16 sample2 = decode_sample(SIGNED_NIBBLES[static_cast(data[datai] & 0xF)]); + const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]); ret[outputi] = sample2; outputi++; diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index c0edb625d..fb8700ccf 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -15,8 +15,8 @@ constexpr std::size_t MIX_BUFFER_SIZE = 0x3f00; constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL; template -void ApplyMix(s32* output, const s32* input, s32 gain, std::size_t sample_count) { - for (std::size_t i = 0; i < sample_count; i += N) { +void ApplyMix(s32* output, const s32* input, s32 gain, s32 sample_count) { + for (std::size_t i = 0; i < static_cast(sample_count); i += N) { for (std::size_t j = 0; j < N; j++) { output[i + j] += static_cast((static_cast(input[i + j]) * gain + 0x4000) >> 15); @@ -111,8 +111,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { const auto channel_count = in_params.channel_count; for (s32 channel = 0; channel < channel_count; channel++) { - const auto resource_id = - static_cast(in_params.voice_channel_resource_id[static_cast(channel)]); + const auto resource_id = in_params.voice_channel_resource_id[channel]; auto& dsp_state = voice_context.GetDspSharedState(resource_id); auto& channel_resource = voice_context.GetChannelResource(resource_id); @@ -133,15 +132,14 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { if (in_params.mix_id != AudioCommon::NO_MIX) { // If we're using a mix id - auto& mix_info = mix_context.GetInfo(static_cast(in_params.mix_id)); + auto& mix_info = mix_context.GetInfo(in_params.mix_id); const auto& dest_mix_params = mix_info.GetInParams(); // Voice Mixing GenerateVoiceMixCommand( channel_resource.GetCurrentMixVolume(), channel_resource.GetLastMixVolume(), - dsp_state, static_cast(dest_mix_params.buffer_offset), - static_cast(dest_mix_params.buffer_count), - worker_params.mix_buffer_count + static_cast(channel), in_params.node_id); + dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count, + worker_params.mix_buffer_count + channel, in_params.node_id); // Update last mix volumes channel_resource.UpdateLastMixVolumes(); @@ -158,15 +156,12 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { continue; } - const auto& mix_info = - mix_context.GetInfo(static_cast(destination_data->GetMixId())); + const auto& mix_info = mix_context.GetInfo(destination_data->GetMixId()); const auto& dest_mix_params = mix_info.GetInParams(); GenerateVoiceMixCommand( destination_data->CurrentMixVolumes(), destination_data->LastMixVolumes(), - dsp_state, static_cast(dest_mix_params.buffer_offset), - static_cast(dest_mix_params.buffer_count), - worker_params.mix_buffer_count + static_cast(channel), - in_params.node_id); + dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count, + worker_params.mix_buffer_count + channel, in_params.node_id); destination_data->MarkDirty(); } } @@ -224,10 +219,9 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo if (depop) { if (in_params.mix_id != AudioCommon::NO_MIX) { - auto& mix_info = mix_context.GetInfo(static_cast(in_params.mix_id)); + auto& mix_info = mix_context.GetInfo(in_params.mix_id); const auto& mix_in = mix_info.GetInParams(); - GenerateDepopPrepareCommand(dsp_state, static_cast(mix_in.buffer_count), - static_cast(mix_in.buffer_offset)); + GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset); } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) { s32 index{}; while (const auto* destination = @@ -235,24 +229,23 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo if (!destination->IsConfigured()) { continue; } - auto& mix_info = mix_context.GetInfo(static_cast(destination->GetMixId())); + auto& mix_info = mix_context.GetInfo(destination->GetMixId()); const auto& mix_in = mix_info.GetInParams(); - GenerateDepopPrepareCommand(dsp_state, static_cast(mix_in.buffer_count), - static_cast(mix_in.buffer_offset)); + GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset); } } } else { switch (in_params.sample_format) { case SampleFormat::Pcm16: DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, - static_cast(worker_params.sample_rate), - static_cast(worker_params.sample_count), in_params.node_id); + worker_params.sample_rate, worker_params.sample_count, + in_params.node_id); break; case SampleFormat::Adpcm: ASSERT(channel == 0 && in_params.channel_count == 1); DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0, - static_cast(worker_params.sample_rate), - static_cast(worker_params.sample_count), in_params.node_id); + worker_params.sample_rate, worker_params.sample_count, + in_params.node_id); break; default: UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); @@ -262,7 +255,7 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, VoiceState& dsp_state, - u32 mix_buffer_count, s32 channel) { + s32 mix_buffer_count, s32 channel) { for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) { const auto& in_params = voice_info.GetInParams(); auto& biquad_filter = in_params.biquad_filter[i]; @@ -342,8 +335,8 @@ void CommandGenerator::GenerateDepopForMixBuffersCommand(std::size_t mix_buffer_ continue; } - depop_buffer[i] = ApplyMixDepop(GetMixBuffer(i), depop_buffer[i], delta, - static_cast(worker_params.sample_count)); + depop_buffer[i] = + ApplyMixDepop(GetMixBuffer(i), depop_buffer[i], delta, worker_params.sample_count); } } @@ -355,7 +348,7 @@ void CommandGenerator::GenerateEffectCommand(ServerMixInfo& mix_info) { if (index == AudioCommon::NO_EFFECT_ORDER) { break; } - auto* info = effect_context.GetInfo(static_cast(index)); + auto* info = effect_context.GetInfo(index); const auto type = info->GetType(); // TODO(ogniK): Finish remaining effects @@ -384,11 +377,11 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E } const auto& params = dynamic_cast(info)->GetParams(); const auto channel_count = params.channel_count; - for (size_t i = 0; i < channel_count; i++) { + for (s32 i = 0; i < channel_count; i++) { // TODO(ogniK): Actually implement reverb if (params.input[i] != params.output[i]) { - const auto* input = GetMixBuffer(static_cast(mix_buffer_offset + params.input[i])); - auto* output = GetMixBuffer(static_cast(mix_buffer_offset + params.output[i])); + const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); + auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); ApplyMix<1>(output, input, 32768, worker_params.sample_count); } } @@ -399,14 +392,13 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset, if (!enabled) { return; } - const auto& params = dynamic_cast(info)->GetParams(); - const auto channel_count = static_cast(params.channel_count); - for (size_t i = 0; i < channel_count; i++) { + const auto channel_count = params.channel_count; + for (s32 i = 0; i < channel_count; i++) { // TODO(ogniK): Actually implement biquad filter if (params.input[i] != params.output[i]) { - const auto* input = GetMixBuffer(static_cast(mix_buffer_offset + params.input[i])); - auto* output = GetMixBuffer(static_cast(mix_buffer_offset + params.output[i])); + const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); + auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); ApplyMix<1>(output, input, 32768, worker_params.sample_count); } } @@ -433,30 +425,26 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf memory.ReadBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP)); memory.ReadBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); - WriteAuxBuffer(send_info, aux->GetSendBuffer(), - static_cast(params.sample_count), - GetMixBuffer(static_cast(input_index)), - worker_params.sample_count, offset, write_count); + WriteAuxBuffer(send_info, aux->GetSendBuffer(), params.sample_count, + GetMixBuffer(input_index), worker_params.sample_count, offset, + write_count); memory.WriteBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP)); const auto samples_read = ReadAuxBuffer( - recv_info, aux->GetRecvBuffer(), static_cast(params.sample_count), - GetMixBuffer(static_cast(output_index)), worker_params.sample_count, - offset, write_count); + recv_info, aux->GetRecvBuffer(), params.sample_count, + GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); if (samples_read != static_cast(worker_params.sample_count) && samples_read <= params.sample_count) { - std::memset(GetMixBuffer(static_cast(output_index)), 0, - static_cast(params.sample_count - samples_read)); + std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); } } else { AuxInfoDSP empty{}; memory.WriteBlock(aux->GetSendInfo(), &empty, sizeof(AuxInfoDSP)); memory.WriteBlock(aux->GetRecvInfo(), &empty, sizeof(AuxInfoDSP)); if (output_index != input_index) { - std::memcpy(GetMixBuffer(static_cast(output_index)), - GetMixBuffer(static_cast(input_index)), + std::memcpy(GetMixBuffer(output_index), GetMixBuffer(input_index), worker_params.sample_count * sizeof(s32)); } } @@ -470,8 +458,7 @@ ServerSplitterDestinationData* CommandGenerator::GetDestinationData(s32 splitter if (splitter_id == AudioCommon::NO_SPLITTER) { return nullptr; } - return splitter_context.GetDestinationData(static_cast(splitter_id), - static_cast(index)); + return splitter_context.GetDestinationData(splitter_id, index); } s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples, @@ -501,7 +488,7 @@ s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u3 if (write_count != 0) { dsp_info.write_offset = (dsp_info.write_offset + write_count) % max_samples; } - return static_cast(sample_count); + return sample_count; } s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u32 max_samples, @@ -531,7 +518,7 @@ s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u3 if (read_count != 0) { recv_info.read_offset = (recv_info.read_offset + read_count) % max_samples; } - return static_cast(sample_count); + return sample_count; } void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float current_volume, @@ -550,15 +537,15 @@ void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float curren } // Apply generic gain on samples ApplyGain(GetChannelMixBuffer(channel), GetChannelMixBuffer(channel), last, delta, - static_cast(worker_params.sample_count)); + worker_params.sample_count); } void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes, const MixVolumeBuffer& last_mix_volumes, - VoiceState& dsp_state, u32 mix_buffer_offset, - u32 mix_buffer_count, u32 voice_index, s32 node_id) { + VoiceState& dsp_state, s32 mix_buffer_offset, + s32 mix_buffer_count, s32 voice_index, s32 node_id) { // Loop all our mix buffers - for (size_t i = 0; i < mix_buffer_count; i++) { + for (s32 i = 0; i < mix_buffer_count; i++) { if (last_mix_volumes[i] != 0.0f || mix_volumes[i] != 0.0f) { const auto delta = static_cast((mix_volumes[i] - last_mix_volumes[i])) / static_cast(worker_params.sample_count); @@ -571,9 +558,9 @@ void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volume mix_volumes[i]); } - dsp_state.previous_samples[i] = ApplyMixRamp( - GetMixBuffer(mix_buffer_offset + i), GetMixBuffer(voice_index), last_mix_volumes[i], - delta, static_cast(worker_params.sample_count)); + dsp_state.previous_samples[i] = + ApplyMixRamp(GetMixBuffer(mix_buffer_offset + i), GetMixBuffer(voice_index), + last_mix_volumes[i], delta, worker_params.sample_count); } else { dsp_state.previous_samples[i] = 0; } @@ -585,8 +572,7 @@ void CommandGenerator::GenerateSubMixCommand(ServerMixInfo& mix_info) { LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand"); } const auto& in_params = mix_info.GetInParams(); - GenerateDepopForMixBuffersCommand(static_cast(in_params.buffer_count), - static_cast(in_params.buffer_offset), + GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset, in_params.sample_rate); GenerateEffectCommand(mix_info); @@ -600,18 +586,18 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) { } const auto& in_params = mix_info.GetInParams(); if (in_params.dest_mix_id != AudioCommon::NO_MIX) { - const auto& dest_mix = mix_context.GetInfo(static_cast(in_params.dest_mix_id)); + const auto& dest_mix = mix_context.GetInfo(in_params.dest_mix_id); const auto& dest_in_params = dest_mix.GetInParams(); - const auto buffer_count = static_cast(in_params.buffer_count); + const auto buffer_count = in_params.buffer_count; - for (u32 i = 0; i < buffer_count; i++) { - for (u32 j = 0; j < static_cast(dest_in_params.buffer_count); j++) { + for (s32 i = 0; i < buffer_count; i++) { + for (s32 j = 0; j < dest_in_params.buffer_count; j++) { const auto mixed_volume = in_params.volume * in_params.mix_volume[i][j]; if (mixed_volume != 0.0f) { - GenerateMixCommand(static_cast(dest_in_params.buffer_offset) + j, - static_cast(in_params.buffer_offset) + i, - mixed_volume, static_cast(in_params.node_id)); + GenerateMixCommand(dest_in_params.buffer_offset + j, + in_params.buffer_offset + i, mixed_volume, + in_params.node_id); } } } @@ -622,17 +608,15 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) { continue; } - const auto& dest_mix = - mix_context.GetInfo(static_cast(destination_data->GetMixId())); + const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); const auto& dest_in_params = dest_mix.GetInParams(); const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; for (std::size_t i = 0; i < static_cast(dest_in_params.buffer_count); i++) { const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); if (mixed_volume != 0.0f) { - GenerateMixCommand(static_cast(dest_in_params.buffer_offset) + i, - static_cast(mix_index), mixed_volume, - static_cast(in_params.node_id)); + GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, + in_params.node_id); } } } @@ -651,8 +635,7 @@ void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t auto* output = GetMixBuffer(output_offset); const auto* input = GetMixBuffer(input_offset); - const auto gain = static_cast(volume * 32768.0f); - + const s32 gain = static_cast(volume * 32768.0f); // Mix with loop unrolling if (worker_params.sample_count % 4 == 0) { ApplyMix<4>(output, input, gain, worker_params.sample_count); @@ -670,8 +653,7 @@ void CommandGenerator::GenerateFinalMixCommand() { auto& mix_info = mix_context.GetFinalMixInfo(); const auto& in_params = mix_info.GetInParams(); - GenerateDepopForMixBuffersCommand(static_cast(in_params.buffer_count), - static_cast(in_params.buffer_offset), + GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset, in_params.sample_rate); GenerateEffectCommand(mix_info); @@ -685,16 +667,16 @@ void CommandGenerator::GenerateFinalMixCommand() { in_params.node_id, in_params.buffer_offset + i, in_params.buffer_offset + i, in_params.volume); } - ApplyGainWithoutDelta(GetMixBuffer(static_cast(in_params.buffer_offset + i)), - GetMixBuffer(static_cast(in_params.buffer_offset + i)), gain, - static_cast(worker_params.sample_count)); + ApplyGainWithoutDelta(GetMixBuffer(in_params.buffer_offset + i), + GetMixBuffer(in_params.buffer_offset + i), gain, + worker_params.sample_count); } } s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_count, s32 channel, std::size_t mix_offset) { const auto& in_params = voice_info.GetInParams(); - const auto& wave_buffer = in_params.wave_buffer[static_cast(dsp_state.wave_buffer_index)]; + const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; if (wave_buffer.buffer_address == 0) { return 0; } @@ -707,26 +689,24 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s const auto samples_remaining = (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) - dsp_state.offset; const auto start_offset = - static_cast((wave_buffer.start_sample_offset + dsp_state.offset) * - in_params.channel_count) * + ((wave_buffer.start_sample_offset + dsp_state.offset) * in_params.channel_count) * sizeof(s16); const auto buffer_pos = wave_buffer.buffer_address + start_offset; const auto samples_processed = std::min(sample_count, samples_remaining); if (in_params.channel_count == 1) { - std::vector buffer(static_cast(samples_processed)); + std::vector buffer(samples_processed); memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); for (std::size_t i = 0; i < buffer.size(); i++) { sample_buffer[mix_offset + i] = buffer[i]; } } else { const auto channel_count = in_params.channel_count; - std::vector buffer(static_cast(samples_processed * channel_count)); + std::vector buffer(samples_processed * channel_count); memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); for (std::size_t i = 0; i < static_cast(samples_processed); i++) { - sample_buffer[mix_offset + i] = - buffer[i * static_cast(channel_count) + static_cast(channel)]; + sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; } } @@ -736,7 +716,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_count, s32 channel, std::size_t mix_offset) { const auto& in_params = voice_info.GetInParams(); - const auto& wave_buffer = in_params.wave_buffer[static_cast(dsp_state.wave_buffer_index)]; + const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; if (wave_buffer.buffer_address == 0) { return 0; } @@ -756,7 +736,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s constexpr std::size_t SAMPLES_PER_FRAME = 14; auto frame_header = dsp_state.context.header; - auto idx = static_cast((frame_header >> 4) & 0xf); + s32 idx = (frame_header >> 4) & 0xf; s32 scale = frame_header & 0xf; s16 yn1 = dsp_state.context.yn1; s16 yn2 = dsp_state.context.yn2; @@ -773,10 +753,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s const auto samples_processed = std::min(sample_count, samples_remaining); const auto sample_pos = wave_buffer.start_sample_offset + dsp_state.offset; - const auto samples_remaining_in_frame = static_cast(sample_pos) % SAMPLES_PER_FRAME; - auto position_in_frame = - ((static_cast(sample_pos) / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) + - samples_remaining_in_frame + (samples_remaining_in_frame != 0 ? 2 : 0); + const auto samples_remaining_in_frame = sample_pos % SAMPLES_PER_FRAME; + auto position_in_frame = ((sample_pos / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) + + samples_remaining_in_frame + (samples_remaining_in_frame != 0 ? 2 : 0); const auto decode_sample = [&](const int nibble) -> s16 { const int xn = nibble * (1 << scale); @@ -795,7 +774,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s std::size_t buffer_offset{}; std::vector buffer( - std::max((static_cast(samples_processed) / FRAME_LEN) * SAMPLES_PER_FRAME, FRAME_LEN)); + std::max((samples_processed / FRAME_LEN) * SAMPLES_PER_FRAME, FRAME_LEN)); memory.ReadBlock(wave_buffer.buffer_address + (position_in_frame / 2), buffer.data(), buffer.size()); std::size_t cur_mix_offset = mix_offset; @@ -805,7 +784,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s if (position_in_frame % NIBBLES_PER_SAMPLE == 0) { // Read header frame_header = buffer[buffer_offset++]; - idx = static_cast((frame_header >> 4) & 0xf); + idx = (frame_header >> 4) & 0xf; scale = frame_header & 0xf; coef1 = coeffs[idx * 2]; coef2 = coeffs[idx * 2 + 1]; @@ -815,8 +794,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s if (remaining_samples >= static_cast(SAMPLES_PER_FRAME)) { for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { // Sample 1 - const s32 s0 = SIGNED_NIBBLES[static_cast(buffer[buffer_offset] >> 4)]; - const s32 s1 = SIGNED_NIBBLES[static_cast(buffer[buffer_offset++] & 0xf)]; + const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4]; + const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf]; const s16 sample_1 = decode_sample(s0); const s16 sample_2 = decode_sample(s1); sample_buffer[cur_mix_offset++] = sample_1; @@ -828,14 +807,14 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s } } // Decode mid frame - auto current_nibble = static_cast(buffer[buffer_offset]); - if ((position_in_frame++ & 1) != 0) { + s32 current_nibble = buffer[buffer_offset]; + if (position_in_frame++ & 0x1) { current_nibble &= 0xf; buffer_offset++; } else { current_nibble >>= 4; } - const s16 sample = decode_sample(SIGNED_NIBBLES[static_cast(current_nibble)]); + const s16 sample = decode_sample(SIGNED_NIBBLES[current_nibble]); sample_buffer[cur_mix_offset++] = sample; remaining_samples--; } @@ -856,7 +835,7 @@ const s32* CommandGenerator::GetMixBuffer(std::size_t index) const { } std::size_t CommandGenerator::GetMixChannelBufferOffset(s32 channel) const { - return worker_params.mix_buffer_count + static_cast(channel); + return worker_params.mix_buffer_count + channel; } std::size_t CommandGenerator::GetTotalMixBufferCount() const { @@ -864,11 +843,11 @@ std::size_t CommandGenerator::GetTotalMixBufferCount() const { } s32* CommandGenerator::GetChannelMixBuffer(s32 channel) { - return GetMixBuffer(worker_params.mix_buffer_count + static_cast(channel)); + return GetMixBuffer(worker_params.mix_buffer_count + channel); } const s32* CommandGenerator::GetChannelMixBuffer(s32 channel) const { - return GetMixBuffer(worker_params.mix_buffer_count + static_cast(channel)); + return GetMixBuffer(worker_params.mix_buffer_count + channel); } void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output, @@ -916,10 +895,9 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o s32 samples_read{}; while (samples_read < samples_to_read) { - const auto& wave_buffer = - in_params.wave_buffer[static_cast(dsp_state.wave_buffer_index)]; + const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; // No more data can be read - if (!dsp_state.is_wave_buffer_valid[static_cast(dsp_state.wave_buffer_index)]) { + if (!dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index]) { is_buffer_completed = true; break; } @@ -943,7 +921,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); } - temp_mix_offset += static_cast(samples_decoded); + temp_mix_offset += samples_decoded; samples_read += samples_decoded; dsp_state.offset += samples_decoded; dsp_state.played_sample_count += samples_decoded; @@ -966,12 +944,10 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o } else { // Update our wave buffer states - dsp_state.is_wave_buffer_valid[static_cast(dsp_state.wave_buffer_index)] = - false; + dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index] = false; dsp_state.wave_buffer_consumed++; dsp_state.wave_buffer_index = - static_cast(dsp_state.wave_buffer_index + 1) % - AudioCommon::MAX_WAVE_BUFFERS; + (dsp_state.wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS; if (wave_buffer.end_of_stream) { dsp_state.played_sample_count = 0; } @@ -981,20 +957,16 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) { // No need to resample - std::memcpy(output, sample_buffer.data(), - static_cast(samples_read) * sizeof(s32)); + std::memcpy(output, sample_buffer.data(), samples_read * sizeof(s32)); } else { - { - const auto begin = sample_buffer.begin() + static_cast(temp_mix_offset); - const auto end = begin + (samples_to_read - samples_read); - std::fill(begin, end, 0); - } + std::fill(sample_buffer.begin() + temp_mix_offset, + sample_buffer.begin() + temp_mix_offset + (samples_to_read - samples_read), + 0); AudioCore::Resample(output, sample_buffer.data(), resample_rate, dsp_state.fraction, - static_cast(samples_to_output)); + samples_to_output); // Resample for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) { - dsp_state.sample_history[i] = - sample_buffer[static_cast(samples_to_read) + i]; + dsp_state.sample_history[i] = sample_buffer[samples_to_read + i]; } } output += samples_to_output; diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 6cba70ae3..53e57748b 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h @@ -50,12 +50,12 @@ public: private: void GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 channel); void GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, VoiceState& dsp_state, - u32 mix_buffer_count, s32 channel); + s32 mix_buffer_count, s32 channel); void GenerateVolumeRampCommand(float last_volume, float current_volume, s32 channel, s32 node_id); void GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes, const MixVolumeBuffer& last_mix_volumes, VoiceState& dsp_state, - u32 mix_buffer_offset, u32 mix_buffer_count, u32 voice_index, + s32 mix_buffer_offset, s32 mix_buffer_count, s32 voice_index, s32 node_id); void GenerateSubMixCommand(ServerMixInfo& mix_info); void GenerateMixCommands(ServerMixInfo& mix_info); diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index a20b6ad5f..6eaa60815 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -202,7 +202,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const } const std::size_t num_channels = impl->GetNumChannels(); - const std::size_t samples_to_write = num_channels * static_cast(num_frames); + const std::size_t samples_to_write = num_channels * num_frames; std::size_t samples_written; /* diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h index c50d0b7bd..7ce850f47 100644 --- a/src/audio_core/cubeb_sink.h +++ b/src/audio_core/cubeb_sink.h @@ -27,7 +27,7 @@ private: std::vector sink_streams; #ifdef _WIN32 - s32 com_init_result = 0; + u32 com_init_result = 0; #endif }; diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index f999a8b17..2940e53a9 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp @@ -350,7 +350,7 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf std::size_t total_buffer_count{}; for (std::size_t i = 0; i < mix_count; i++) { const auto& in = mix_in_params[i]; - total_buffer_count += static_cast(in.buffer_count); + total_buffer_count += in.buffer_count; if (static_cast(in.dest_mix_id) > mix_count && in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) { LOG_ERROR( @@ -379,7 +379,7 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf const auto& mix_in = mix_in_params[i]; std::size_t target_mix{}; if (behavior_info.IsMixInParameterDirtyOnlyUpdateSupported()) { - target_mix = static_cast(mix_in.mix_id); + target_mix = mix_in.mix_id; } else { // Non dirty supported games just use i instead of the actual mix_id target_mix = i; diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp index c28bee453..4bca72eb0 100644 --- a/src/audio_core/mix_context.cpp +++ b/src/audio_core/mix_context.cpp @@ -62,7 +62,7 @@ void MixContext::UpdateDistancesFromFinalMix() { distance_to_final_mix = AudioCommon::NO_FINAL_MIX; break; } else { - const auto& dest_mix = GetInfo(static_cast(mix_id)); + const auto& dest_mix = GetInfo(mix_id); const auto dest_mix_distance = dest_mix.GetInParams().final_mix_distance; if (dest_mix_distance == AudioCommon::NO_FINAL_MIX) { @@ -129,7 +129,7 @@ bool MixContext::TsortInfo(SplitterContext& splitter_context) { std::size_t info_id{}; for (auto itr = sorted_list.rbegin(); itr != sorted_list.rend(); ++itr) { // Set our sorted info - sorted_info[info_id++] = &GetInfo(static_cast(*itr)); + sorted_info[info_id++] = &GetInfo(*itr); } // Calculate the mix buffer offset @@ -218,8 +218,7 @@ bool ServerMixInfo::Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix for (std::size_t i = 0; i < effect_count; i++) { auto* effect_info = effect_context.GetInfo(i); if (effect_info->GetMixID() == in_params.mix_id) { - const auto processing_order = static_cast(effect_info->GetProcessingOrder()); - effect_processing_order[processing_order] = static_cast(i); + effect_processing_order[effect_info->GetProcessingOrder()] = static_cast(i); } } @@ -266,7 +265,7 @@ bool ServerMixInfo::UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InP if (in_params.dest_mix_id == mix_in.dest_mix_id && in_params.splitter_id == mix_in.splitter_id && ((in_params.splitter_id == AudioCommon::NO_SPLITTER) || - !splitter_context.GetInfo(static_cast(in_params.splitter_id)).HasNewConnection())) { + !splitter_context.GetInfo(in_params.splitter_id).HasNewConnection())) { return false; } // Remove current edges for mix id @@ -276,11 +275,11 @@ bool ServerMixInfo::UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InP edge_matrix.Connect(in_params.mix_id, mix_in.dest_mix_id); } else if (mix_in.splitter_id != AudioCommon::NO_SPLITTER) { // Recurse our splitter linked and set our edges - auto& splitter_info = splitter_context.GetInfo(static_cast(mix_in.splitter_id)); - const auto length = static_cast(splitter_info.GetLength()); - for (size_t i = 0; i < length; i++) { + auto& splitter_info = splitter_context.GetInfo(mix_in.splitter_id); + const auto length = splitter_info.GetLength(); + for (s32 i = 0; i < length; i++) { const auto* splitter_destination = - splitter_context.GetDestinationData(static_cast(mix_in.splitter_id), i); + splitter_context.GetDestinationData(mix_in.splitter_id, i); if (splitter_destination == nullptr) { continue; } diff --git a/src/audio_core/sink_context.cpp b/src/audio_core/sink_context.cpp index 3d713814a..0882b411a 100644 --- a/src/audio_core/sink_context.cpp +++ b/src/audio_core/sink_context.cpp @@ -23,9 +23,8 @@ bool SinkContext::InUse() const { } std::vector SinkContext::OutputBuffers() const { - const auto output_use_count = static_cast(use_count); - std::vector buffer_ret(output_use_count); - std::memcpy(buffer_ret.data(), buffers.data(), output_use_count); + std::vector buffer_ret(use_count); + std::memcpy(buffer_ret.data(), buffers.data(), use_count); return buffer_ret; } diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index f3e870648..f21b53147 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp @@ -109,7 +109,7 @@ std::size_t ServerSplitterInfo::Update(SplitterInfo::InInfoPrams& header) { new_connection = true; // We need to update the size here due to the splitter bug being present and providing an // incorrect size. We're suppose to also update the header here but we just ignore and continue - return (sizeof(s32_le) * static_cast(header.length - 1)) + (sizeof(s32_le) * 3); + return (sizeof(s32_le) * (header.length - 1)) + (sizeof(s32_le) * 3); } ServerSplitterDestinationData* ServerSplitterInfo::GetHead() { @@ -306,14 +306,13 @@ bool SplitterContext::UpdateInfo(const std::vector& input, std::size_t& inpu break; } - const auto send_id = static_cast(header.send_id); - if (header.send_id < 0 || send_id > info_count) { + if (header.send_id < 0 || static_cast(header.send_id) > info_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } UpdateOffsets(sizeof(SplitterInfo::InInfoPrams)); - auto& info = GetInfo(send_id); + auto& info = GetInfo(header.send_id); if (!RecomposeDestination(info, header, input, input_offset)) { LOG_ERROR(Audio, "Failed to recompose destination for splitter!"); return false; @@ -349,12 +348,11 @@ bool SplitterContext::UpdateData(const std::vector& input, std::size_t& inpu break; } - const auto splitter_id = static_cast(header.splitter_id); - if (header.splitter_id < 0 || splitter_id > data_count) { + if (header.splitter_id < 0 || static_cast(header.splitter_id) > data_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } - GetData(splitter_id).Update(header); + GetData(header.splitter_id).Update(header); } return true; } @@ -388,9 +386,9 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info, return true; } - auto* start_head = &GetData(static_cast(header.resource_id_base)); + auto* start_head = &GetData(header.resource_id_base); current_head = start_head; - std::vector resource_ids(static_cast(size - 1)); + std::vector resource_ids(size - 1); if (!AudioCommon::CanConsumeBuffer(input.size(), input_offset, resource_ids.size() * sizeof(s32_le))) { LOG_ERROR(Audio, "Buffer is an invalid size!"); @@ -399,8 +397,8 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info, std::memcpy(resource_ids.data(), input.data() + input_offset, resource_ids.size() * sizeof(s32_le)); - for (const auto resource_id : resource_ids) { - auto* head = &GetData(static_cast(resource_id)); + for (auto resource_id : resource_ids) { + auto* head = &GetData(resource_id); current_head->SetNextDestination(head); current_head = head; } @@ -446,7 +444,7 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { const auto node_id = static_cast(i); // If we don't have a state, send to our index stack for work - if (GetState(i) == State::NoState) { + if (GetState(i) == NodeStates::State::NoState) { index_stack.push(node_id); } @@ -455,19 +453,19 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { // Get the current node const auto current_stack_index = index_stack.top(); // Check if we've seen the node yet - const auto index_state = GetState(static_cast(current_stack_index)); - if (index_state == State::NoState) { + const auto index_state = GetState(current_stack_index); + if (index_state == NodeStates::State::NoState) { // Mark the node as seen - UpdateState(State::InFound, static_cast(current_stack_index)); - } else if (index_state == State::InFound) { + UpdateState(NodeStates::State::InFound, current_stack_index); + } else if (index_state == NodeStates::State::InFound) { // We've seen this node before, mark it as completed - UpdateState(State::InCompleted, static_cast(current_stack_index)); + UpdateState(NodeStates::State::InCompleted, current_stack_index); // Update our index list PushTsortResult(current_stack_index); // Pop the stack index_stack.pop(); continue; - } else if (index_state == State::InCompleted) { + } else if (index_state == NodeStates::State::InCompleted) { // If our node is already sorted, clear it index_stack.pop(); continue; @@ -481,11 +479,11 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { } // Check if our node exists - const auto node_state = GetState(static_cast(j)); - if (node_state == State::NoState) { + const auto node_state = GetState(j); + if (node_state == NodeStates::State::NoState) { // Add more work index_stack.push(j); - } else if (node_state == State::InFound) { + } else if (node_state == NodeStates::State::InFound) { UNREACHABLE_MSG("Node start marked as found"); ResetState(); return false; @@ -509,17 +507,17 @@ void NodeStates::ResetState() { } } -void NodeStates::UpdateState(State state, std::size_t i) { +void NodeStates::UpdateState(NodeStates::State state, std::size_t i) { switch (state) { - case State::NoState: + case NodeStates::State::NoState: was_node_found[i] = false; was_node_completed[i] = false; break; - case State::InFound: + case NodeStates::State::InFound: was_node_found[i] = true; was_node_completed[i] = false; break; - case State::InCompleted: + case NodeStates::State::InCompleted: was_node_found[i] = false; was_node_completed[i] = true; break; @@ -530,13 +528,13 @@ NodeStates::State NodeStates::GetState(std::size_t i) { ASSERT(i < node_count); if (was_node_found[i]) { // If our node exists in our found list - return State::InFound; + return NodeStates::State::InFound; } else if (was_node_completed[i]) { // If node is in the completed list - return State::InCompleted; + return NodeStates::State::InCompleted; } else { // If in neither - return State::NoState; + return NodeStates::State::NoState; } } @@ -603,16 +601,16 @@ std::size_t EdgeMatrix::GetNodeCount() const { void EdgeMatrix::SetState(s32 a, s32 b, bool state) { ASSERT(InRange(a, b)); - edge_matrix.at(static_cast(a) * node_count + static_cast(b)) = state; + edge_matrix.at(a * node_count + b) = state; } bool EdgeMatrix::GetState(s32 a, s32 b) { ASSERT(InRange(a, b)); - return edge_matrix.at(static_cast(a) * node_count + static_cast(b)); + return edge_matrix.at(a * node_count + b); } bool EdgeMatrix::InRange(s32 a, s32 b) const { - const std::size_t pos = static_cast(a) * node_count + static_cast(b); + const std::size_t pos = a * node_count + b; return pos < (node_count * node_count); } diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h index 3808e554d..bb2270b96 100644 --- a/src/audio_core/time_stretch.h +++ b/src/audio_core/time_stretch.h @@ -5,16 +5,8 @@ #pragma once #include -#include "common/common_types.h" - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-conversion" -#endif #include -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif +#include "common/common_types.h" namespace AudioCore { diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index 276b96ca4..c46ee55f1 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp @@ -98,7 +98,7 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in, BehaviorInfo& behavior_info) { in_params.in_use = voice_in.is_in_use; in_params.id = voice_in.id; - in_params.node_id = static_cast(voice_in.node_id); + in_params.node_id = voice_in.node_id; in_params.last_playstate = in_params.current_playstate; switch (voice_in.play_state) { case PlayState::Paused: @@ -220,10 +220,8 @@ void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer, if (sample_format == SampleFormat::Pcm16) { const auto buffer_size = in_wave_buffer.buffer_size; if (in_wave_buffer.start_sample_offset < 0 || in_wave_buffer.end_sample_offset < 0 || - (buffer_size < - (sizeof(s16) * static_cast(in_wave_buffer.start_sample_offset))) || - (buffer_size < - (sizeof(s16) * static_cast(in_wave_buffer.end_sample_offset)))) { + (buffer_size < (sizeof(s16) * in_wave_buffer.start_sample_offset)) || + (buffer_size < (sizeof(s16) * in_wave_buffer.end_sample_offset))) { // TODO(ogniK): Write error info return; } @@ -256,8 +254,8 @@ void ServerVoiceInfo::WriteOutStatus( voice_out.played_sample_count = 0; voice_out.voice_dropped = false; } else if (!in_params.is_new) { - voice_out.wave_buffer_consumed = static_cast(voice_states[0]->wave_buffer_consumed); - voice_out.played_sample_count = static_cast(voice_states[0]->played_sample_count); + voice_out.wave_buffer_consumed = voice_states[0]->wave_buffer_consumed; + voice_out.played_sample_count = voice_states[0]->played_sample_count; voice_out.voice_dropped = in_params.voice_drop_flag; } else { voice_out.wave_buffer_consumed = 0; @@ -295,8 +293,8 @@ bool ServerVoiceInfo::UpdateForCommandGeneration(VoiceContext& voice_context) { in_params.is_new = false; } - const auto channel_count = static_cast(in_params.channel_count); - for (size_t i = 0; i < channel_count; i++) { + const s32 channel_count = in_params.channel_count; + for (s32 i = 0; i < channel_count; i++) { const auto channel_resource = in_params.voice_channel_resource_id[i]; dsp_voice_states[i] = &voice_context.GetDspSharedState(static_cast(channel_resource)); @@ -305,9 +303,8 @@ bool ServerVoiceInfo::UpdateForCommandGeneration(VoiceContext& voice_context) { } void ServerVoiceInfo::ResetResources(VoiceContext& voice_context) { - const auto channel_count = static_cast(in_params.channel_count); - - for (size_t i = 0; i < channel_count; i++) { + const s32 channel_count = in_params.channel_count; + for (s32 i = 0; i < channel_count; i++) { const auto channel_resource = in_params.voice_channel_resource_id[i]; auto& dsp_state = voice_context.GetDspSharedState(static_cast(channel_resource)); @@ -328,9 +325,9 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration( switch (in_params.current_playstate) { case ServerPlayState::Play: { - for (size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) { + for (std::size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) { if (!in_params.wave_buffer[i].sent_to_dsp) { - for (size_t channel = 0; channel < static_cast(channel_count); channel++) { + for (s32 channel = 0; channel < channel_count; channel++) { dsp_voice_states[channel]->is_wave_buffer_valid[i] = true; } in_params.wave_buffer[i].sent_to_dsp = true; @@ -347,13 +344,12 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration( case ServerPlayState::RequestStop: { for (std::size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) { in_params.wave_buffer[i].sent_to_dsp = true; - for (std::size_t channel = 0; channel < static_cast(channel_count); channel++) { + for (s32 channel = 0; channel < channel_count; channel++) { auto* dsp_state = dsp_voice_states[channel]; if (dsp_state->is_wave_buffer_valid[i]) { dsp_state->wave_buffer_index = - static_cast(static_cast(dsp_state->wave_buffer_index + 1) % - AudioCommon::MAX_WAVE_BUFFERS); + (dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS; dsp_state->wave_buffer_consumed++; } @@ -361,7 +357,7 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration( } } - for (size_t channel = 0; channel < static_cast(channel_count); channel++) { + for (s32 channel = 0; channel < channel_count; channel++) { auto* dsp_state = dsp_voice_states[channel]; dsp_state->offset = 0; dsp_state->played_sample_count = 0; @@ -387,16 +383,15 @@ void ServerVoiceInfo::FlushWaveBuffers( auto wave_head = in_params.wave_bufffer_head; for (u8 i = 0; i < flush_count; i++) { - in_params.wave_buffer[static_cast(wave_head)].sent_to_dsp = true; - for (size_t channel = 0; channel < static_cast(channel_count); channel++) { + in_params.wave_buffer[wave_head].sent_to_dsp = true; + for (s32 channel = 0; channel < channel_count; channel++) { auto* dsp_state = dsp_voice_states[channel]; dsp_state->wave_buffer_consumed++; - dsp_state->is_wave_buffer_valid[static_cast(wave_head)] = false; - dsp_state->wave_buffer_index = static_cast( - static_cast(dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS); + dsp_state->is_wave_buffer_valid[wave_head] = false; + dsp_state->wave_buffer_index = + (dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS; } - wave_head = - static_cast(static_cast(wave_head + 1) % AudioCommon::MAX_WAVE_BUFFERS); + wave_head = (wave_head + 1) % AudioCommon::MAX_WAVE_BUFFERS; } } @@ -488,7 +483,7 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer, const auto samples_remaining = (wave_buffer->end_sample_offset - wave_buffer->start_sample_offset) - buffer_offset; const auto start_offset = (wave_buffer->start_sample_offset + buffer_offset) * channel_count; - const auto buffer_pos = wave_buffer->buffer_address + static_cast(start_offset); + const auto buffer_pos = wave_buffer->buffer_address + start_offset; s16* buffer_data = reinterpret_cast(memory.GetPointer(buffer_pos)); diff --git a/src/common/fiber.h b/src/common/fiber.h index bc1db1582..89dde5e36 100644 --- a/src/common/fiber.h +++ b/src/common/fiber.h @@ -41,8 +41,8 @@ public: Fiber(const Fiber&) = delete; Fiber& operator=(const Fiber&) = delete; - Fiber(Fiber&&) = delete; - Fiber& operator=(Fiber&&) = delete; + Fiber(Fiber&&) = default; + Fiber& operator=(Fiber&&) = default; /// Yields control from Fiber 'from' to Fiber 'to' /// Fiber 'from' must be the currently running fiber. diff --git a/src/common/file_util.h b/src/common/file_util.h index 508b7a10a..8b587320f 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -189,8 +189,7 @@ template return {}; } last = std::min(last, vector.size()); - return std::vector(vector.begin() + static_cast(first), - vector.begin() + static_cast(first + last)); + return std::vector(vector.begin() + first, vector.begin() + first + last); } enum class DirectorySeparator { diff --git a/src/common/math_util.h b/src/common/math_util.h index 4c38d8040..7cec80d57 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -27,7 +27,7 @@ struct Rectangle { if constexpr (std::is_floating_point_v) { return std::abs(right - left); } else { - return static_cast(std::abs(static_cast>(right - left))); + return std::abs(static_cast>(right - left)); } } @@ -35,7 +35,7 @@ struct Rectangle { if constexpr (std::is_floating_point_v) { return std::abs(bottom - top); } else { - return static_cast(std::abs(static_cast>(bottom - top))); + return std::abs(static_cast>(bottom - top)); } } diff --git a/src/common/multi_level_queue.h b/src/common/multi_level_queue.h index 71613f18b..4b305bf40 100644 --- a/src/common/multi_level_queue.h +++ b/src/common/multi_level_queue.h @@ -320,7 +320,7 @@ private: } const auto begin_range = list.begin(); - const auto end_range = std::next(begin_range, static_cast(shift)); + const auto end_range = std::next(begin_range, shift); list.splice(list.end(), list, begin_range, end_range); } diff --git a/src/common/spin_lock.h b/src/common/spin_lock.h index 06ac2f5bb..4f946a258 100644 --- a/src/common/spin_lock.h +++ b/src/common/spin_lock.h @@ -15,14 +15,6 @@ namespace Common { */ class SpinLock { public: - SpinLock() = default; - - SpinLock(const SpinLock&) = delete; - SpinLock& operator=(const SpinLock&) = delete; - - SpinLock(SpinLock&&) = delete; - SpinLock& operator=(SpinLock&&) = delete; - void lock(); void unlock(); [[nodiscard]] bool try_lock(); diff --git a/src/common/swap.h b/src/common/swap.h index 8c68c1f26..7665942a2 100644 --- a/src/common/swap.h +++ b/src/common/swap.h @@ -504,35 +504,35 @@ bool operator==(const S& p, const swap_struct_t v) { template struct swap_64_t { static T swap(T x) { - return static_cast(Common::swap64(static_cast(x))); + return static_cast(Common::swap64(x)); } }; template struct swap_32_t { static T swap(T x) { - return static_cast(Common::swap32(static_cast(x))); + return static_cast(Common::swap32(x)); } }; template struct swap_16_t { static T swap(T x) { - return static_cast(Common::swap16(static_cast(x))); + return static_cast(Common::swap16(x)); } }; template struct swap_float_t { static T swap(T x) { - return static_cast(Common::swapf(static_cast(x))); + return static_cast(Common::swapf(x)); } }; template struct swap_double_t { static T swap(T x) { - return static_cast(Common::swapd(static_cast(x))); + return static_cast(Common::swapd(x)); } }; diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 69c9193da..def9e5d8d 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -33,7 +33,7 @@ struct ThreadQueueList { } } - return static_cast(-1); + return -1; } [[nodiscard]] T get_first() const { @@ -156,7 +156,7 @@ private: void link(Priority priority) { Queue* cur = &queues[priority]; - for (auto i = static_cast(priority - 1); i >= 0; --i) { + for (int i = priority - 1; i >= 0; --i) { if (queues[i].next_nonempty != UnlinkedTag()) { cur->next_nonempty = queues[i].next_nonempty; queues[i].next_nonempty = cur; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9dc320f53..b6dc25f6b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -630,9 +630,8 @@ else() -Werror=implicit-fallthrough -Werror=reorder -Werror=sign-compare - -Werror=sign-conversion - $<$:-Werror=unused-but-set-parameter> - $<$:-Werror=unused-but-set-variable> + -Werror=unused-but-set-parameter + -Werror=unused-but-set-variable -Werror=unused-variable ) endif() diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index adc6aa5c5..d2295ed90 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -147,18 +147,10 @@ std::vector ARM_Interface::GetBacktraceFromContex auto fp = ctx.cpu_registers[29]; auto lr = ctx.cpu_registers[30]; while (true) { - out.push_back({ - .module = "", - .address = 0, - .original_address = lr, - .offset = 0, - .name = "", - }); - - if (fp == 0) { + out.push_back({"", 0, lr, 0}); + if (!fp) { break; } - lr = memory.Read64(fp + 8) - 4; fp = memory.Read64(fp); } @@ -211,18 +203,10 @@ std::vector ARM_Interface::GetBacktrace() const { auto fp = GetReg(29); auto lr = GetReg(30); while (true) { - out.push_back({ - .module = "", - .address = 0, - .original_address = lr, - .offset = 0, - .name = "", - }); - - if (fp == 0) { + out.push_back({"", 0, lr, 0, ""}); + if (!fp) { break; } - lr = memory.Read64(fp + 8) - 4; fp = memory.Read64(fp); } diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 9b86247e2..1f24051e4 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -93,14 +93,14 @@ public: * @param index Register index * @return Returns the value in the register */ - virtual u64 GetReg(std::size_t index) const = 0; + virtual u64 GetReg(int index) const = 0; /** * Set an ARM register * @param index Register index * @param value Value to set register to */ - virtual void SetReg(std::size_t index, u64 value) = 0; + virtual void SetReg(int index, u64 value) = 0; /** * Gets the value of a specified vector register. @@ -108,7 +108,7 @@ public: * @param index The index of the vector register. * @return the value within the vector register. */ - virtual u128 GetVectorReg(std::size_t index) const = 0; + virtual u128 GetVectorReg(int index) const = 0; /** * Sets a given value into a vector register. @@ -116,7 +116,7 @@ public: * @param index The index of the vector register. * @param value The new value to place in the register. */ - virtual void SetVectorReg(std::size_t index, u128 value) = 0; + virtual void SetVectorReg(int index, u128 value) = 0; /** * Get the current PSTATE register diff --git a/src/core/arm/cpu_interrupt_handler.h b/src/core/arm/cpu_interrupt_handler.h index c20c280f1..71e582f79 100644 --- a/src/core/arm/cpu_interrupt_handler.h +++ b/src/core/arm/cpu_interrupt_handler.h @@ -21,8 +21,8 @@ public: CPUInterruptHandler(const CPUInterruptHandler&) = delete; CPUInterruptHandler& operator=(const CPUInterruptHandler&) = delete; - CPUInterruptHandler(CPUInterruptHandler&&) = delete; - CPUInterruptHandler& operator=(CPUInterruptHandler&&) = delete; + CPUInterruptHandler(CPUInterruptHandler&&) = default; + CPUInterruptHandler& operator=(CPUInterruptHandler&&) = default; bool IsInterrupted() const { return is_interrupted; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index fab694fc2..b5f28a86e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -111,7 +111,7 @@ public: } return 0U; } - return static_cast(std::max(parent.system.CoreTiming().GetDowncount(), 0)); + return std::max(parent.system.CoreTiming().GetDowncount(), 0); } ARM_Dynarmic_32& parent; @@ -210,19 +210,19 @@ u64 ARM_Dynarmic_32::GetPC() const { return jit->Regs()[15]; } -u64 ARM_Dynarmic_32::GetReg(std::size_t index) const { +u64 ARM_Dynarmic_32::GetReg(int index) const { return jit->Regs()[index]; } -void ARM_Dynarmic_32::SetReg(std::size_t index, u64 value) { +void ARM_Dynarmic_32::SetReg(int index, u64 value) { jit->Regs()[index] = static_cast(value); } -u128 ARM_Dynarmic_32::GetVectorReg(std::size_t index) const { +u128 ARM_Dynarmic_32::GetVectorReg(int index) const { return {}; } -void ARM_Dynarmic_32::SetVectorReg(std::size_t index, u128 value) {} +void ARM_Dynarmic_32::SetVectorReg(int index, u128 value) {} u32 ARM_Dynarmic_32::GetPSTATE() const { return jit->Cpsr(); diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index ba646c623..2bab31b92 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -35,10 +35,10 @@ public: void SetPC(u64 pc) override; u64 GetPC() const override; - u64 GetReg(std::size_t index) const override; - void SetReg(std::size_t index, u64 value) override; - u128 GetVectorReg(std::size_t index) const override; - void SetVectorReg(std::size_t index, u128 value) override; + u64 GetReg(int index) const override; + void SetReg(int index, u64 value) override; + u128 GetVectorReg(int index) const override; + void SetVectorReg(int index, u128 value) override; u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; void Run() override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index a2c4c2f30..ce9968724 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -148,7 +148,7 @@ public: } return 0U; } - return static_cast(std::max(parent.system.CoreTiming().GetDowncount(), 0)); + return std::max(parent.system.CoreTiming().GetDowncount(), 0); } u64 GetCNTPCT() override { @@ -265,19 +265,19 @@ u64 ARM_Dynarmic_64::GetPC() const { return jit->GetPC(); } -u64 ARM_Dynarmic_64::GetReg(std::size_t index) const { +u64 ARM_Dynarmic_64::GetReg(int index) const { return jit->GetRegister(index); } -void ARM_Dynarmic_64::SetReg(std::size_t index, u64 value) { +void ARM_Dynarmic_64::SetReg(int index, u64 value) { jit->SetRegister(index, value); } -u128 ARM_Dynarmic_64::GetVectorReg(std::size_t index) const { +u128 ARM_Dynarmic_64::GetVectorReg(int index) const { return jit->GetVector(index); } -void ARM_Dynarmic_64::SetVectorReg(std::size_t index, u128 value) { +void ARM_Dynarmic_64::SetVectorReg(int index, u128 value) { jit->SetVector(index, value); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 2afb7e7a4..403c55961 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -33,10 +33,10 @@ public: void SetPC(u64 pc) override; u64 GetPC() const override; - u64 GetReg(std::size_t index) const override; - void SetReg(std::size_t index, u64 value) override; - u128 GetVectorReg(std::size_t index) const override; - void SetVectorReg(std::size_t index, u128 value) override; + u64 GetReg(int index) const override; + void SetReg(int index, u64 value) override; + u128 GetVectorReg(int index) const override; + void SetVectorReg(int index, u128 value) override; u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; void Run() override; diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index c1612d626..1df3f3ed1 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -96,35 +96,35 @@ u64 ARM_Unicorn::GetPC() const { return val; } -u64 ARM_Unicorn::GetReg(std::size_t index) const { +u64 ARM_Unicorn::GetReg(int regn) const { u64 val{}; auto treg = UC_ARM64_REG_SP; - if (index <= 28) { - treg = static_cast(UC_ARM64_REG_X0 + static_cast(index)); - } else if (index < 31) { - treg = static_cast(UC_ARM64_REG_X29 + static_cast(index) - 29); + if (regn <= 28) { + treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn); + } else if (regn < 31) { + treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29); } CHECKED(uc_reg_read(uc, treg, &val)); return val; } -void ARM_Unicorn::SetReg(std::size_t index, u64 value) { +void ARM_Unicorn::SetReg(int regn, u64 val) { auto treg = UC_ARM64_REG_SP; - if (index <= 28) { - treg = static_cast(UC_ARM64_REG_X0 + static_cast(index)); - } else if (index < 31) { - treg = static_cast(UC_ARM64_REG_X29 + static_cast(index) - 29); + if (regn <= 28) { + treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn); + } else if (regn < 31) { + treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29); } - CHECKED(uc_reg_write(uc, treg, &value)); + CHECKED(uc_reg_write(uc, treg, &val)); } -u128 ARM_Unicorn::GetVectorReg(std::size_t /*index*/) const { +u128 ARM_Unicorn::GetVectorReg(int /*index*/) const { UNIMPLEMENTED(); static constexpr u128 res{}; return res; } -void ARM_Unicorn::SetVectorReg(std::size_t /*index*/, u128 /*value*/) { +void ARM_Unicorn::SetVectorReg(int /*index*/, u128 /*value*/) { UNIMPLEMENTED(); } @@ -217,8 +217,8 @@ void ARM_Unicorn::SaveContext(ThreadContext64& ctx) { CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &ctx.pc)); CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &ctx.pstate)); - for (std::size_t i = 0; i < 29; ++i) { - uregs[i] = UC_ARM64_REG_X0 + static_cast(i); + for (auto i = 0; i < 29; ++i) { + uregs[i] = UC_ARM64_REG_X0 + i; tregs[i] = &ctx.cpu_registers[i]; } uregs[29] = UC_ARM64_REG_X29; @@ -228,8 +228,8 @@ void ARM_Unicorn::SaveContext(ThreadContext64& ctx) { CHECKED(uc_reg_read_batch(uc, uregs, tregs, 31)); - for (std::size_t i = 0; i < 32; ++i) { - uregs[i] = UC_ARM64_REG_Q0 + static_cast(i); + for (int i = 0; i < 32; ++i) { + uregs[i] = UC_ARM64_REG_Q0 + i; tregs[i] = &ctx.vector_registers[i]; } @@ -244,8 +244,8 @@ void ARM_Unicorn::LoadContext(const ThreadContext64& ctx) { CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &ctx.pc)); CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &ctx.pstate)); - for (std::size_t i = 0; i < 29; ++i) { - uregs[i] = UC_ARM64_REG_X0 + static_cast(i); + for (int i = 0; i < 29; ++i) { + uregs[i] = UC_ARM64_REG_X0 + i; tregs[i] = (void*)&ctx.cpu_registers[i]; } uregs[29] = UC_ARM64_REG_X29; @@ -255,8 +255,8 @@ void ARM_Unicorn::LoadContext(const ThreadContext64& ctx) { CHECKED(uc_reg_write_batch(uc, uregs, tregs, 31)); - for (std::size_t i = 0; i < 32; ++i) { - uregs[i] = UC_ARM64_REG_Q0 + static_cast(i); + for (auto i = 0; i < 32; ++i) { + uregs[i] = UC_ARM64_REG_Q0 + i; tregs[i] = (void*)&ctx.vector_registers[i]; } diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index 1183e9541..810aff311 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h @@ -26,10 +26,10 @@ public: void SetPC(u64 pc) override; u64 GetPC() const override; - u64 GetReg(std::size_t index) const override; - void SetReg(std::size_t index, u64 value) override; - u128 GetVectorReg(std::size_t index) const override; - void SetVectorReg(std::size_t index, u128 value) override; + u64 GetReg(int index) const override; + void SetReg(int index, u64 value) override; + u128 GetVectorReg(int index) const override; + void SetVectorReg(int index, u128 value) override; u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; VAddr GetTlsAddress() const override; diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 9b01f6293..e6c8461a5 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -140,8 +140,7 @@ void CoreTiming::AddTicks(u64 ticks) { void CoreTiming::Idle() { if (!event_queue.empty()) { const u64 next_event_time = event_queue.front().time; - const u64 next_ticks = - static_cast(nsToCycles(std::chrono::nanoseconds(next_event_time))) + 10; + const u64 next_ticks = nsToCycles(std::chrono::nanoseconds(next_event_time)) + 10U; if (next_ticks > ticks) { ticks = next_ticks; } @@ -188,7 +187,7 @@ void CoreTiming::RemoveEvent(const std::shared_ptr& event_type) { std::optional CoreTiming::Advance() { std::scoped_lock lock{advance_lock, basic_lock}; - global_timer = static_cast(GetGlobalTimeNs().count()); + global_timer = GetGlobalTimeNs().count(); while (!event_queue.empty() && event_queue.front().time <= global_timer) { Event evt = std::move(event_queue.front()); @@ -202,11 +201,11 @@ std::optional CoreTiming::Advance() { } basic_lock.lock(); - global_timer = static_cast(GetGlobalTimeNs().count()); + global_timer = GetGlobalTimeNs().count(); } if (!event_queue.empty()) { - const auto next_time = static_cast(event_queue.front().time - global_timer); + const s64 next_time = event_queue.front().time - global_timer; return next_time; } else { return std::nullopt; @@ -241,14 +240,14 @@ std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { if (is_multicore) { return clock->GetTimeNS(); } - return CyclesToNs(static_cast(ticks)); + return CyclesToNs(ticks); } std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { if (is_multicore) { return clock->GetTimeUS(); } - return CyclesToUs(static_cast(ticks)); + return CyclesToUs(ticks); } } // namespace Core::Timing diff --git a/src/core/core_timing_util.cpp b/src/core/core_timing_util.cpp index 5cd450714..8ce8e602e 100644 --- a/src/core/core_timing_util.cpp +++ b/src/core/core_timing_util.cpp @@ -21,9 +21,9 @@ s64 msToCycles(std::chrono::milliseconds ms) { } if (static_cast(ms.count()) > MAX_VALUE_TO_MULTIPLY) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); - return static_cast(Hardware::BASE_CLOCK_RATE * static_cast(ms.count() / 1000)); + return Hardware::BASE_CLOCK_RATE * (ms.count() / 1000); } - return static_cast((Hardware::BASE_CLOCK_RATE * static_cast(ms.count())) / 1000); + return (Hardware::BASE_CLOCK_RATE * ms.count()) / 1000; } s64 usToCycles(std::chrono::microseconds us) { @@ -33,55 +33,51 @@ s64 usToCycles(std::chrono::microseconds us) { } if (static_cast(us.count()) > MAX_VALUE_TO_MULTIPLY) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); - return static_cast(Hardware::BASE_CLOCK_RATE * static_cast(us.count() / 1000000)); + return Hardware::BASE_CLOCK_RATE * (us.count() / 1000000); } - return static_cast((Hardware::BASE_CLOCK_RATE * static_cast(us.count())) / 1000000); + return (Hardware::BASE_CLOCK_RATE * us.count()) / 1000000; } s64 nsToCycles(std::chrono::nanoseconds ns) { - const u128 temp = - Common::Multiply64Into128(static_cast(ns.count()), Hardware::BASE_CLOCK_RATE); - return static_cast(Common::Divide128On32(temp, static_cast(1000000000)).first); + const u128 temporal = Common::Multiply64Into128(ns.count(), Hardware::BASE_CLOCK_RATE); + return Common::Divide128On32(temporal, static_cast(1000000000)).first; } -u64 msToClockCycles(std::chrono::milliseconds ms) { - const auto count = static_cast(ms.count()); - const u128 temp = Common::Multiply64Into128(count, Hardware::CNTFREQ); +u64 msToClockCycles(std::chrono::milliseconds ns) { + const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); return Common::Divide128On32(temp, 1000).first; } -u64 usToClockCycles(std::chrono::microseconds us) { - const auto count = static_cast(us.count()); - const u128 temp = Common::Multiply64Into128(count, Hardware::CNTFREQ); +u64 usToClockCycles(std::chrono::microseconds ns) { + const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); return Common::Divide128On32(temp, 1000000).first; } u64 nsToClockCycles(std::chrono::nanoseconds ns) { - const auto count = static_cast(ns.count()); - const u128 temp = Common::Multiply64Into128(count, Hardware::CNTFREQ); + const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); return Common::Divide128On32(temp, 1000000000).first; } u64 CpuCyclesToClockCycles(u64 ticks) { - const u128 temp = Common::Multiply64Into128(ticks, Hardware::CNTFREQ); - return Common::Divide128On32(temp, static_cast(Hardware::BASE_CLOCK_RATE)).first; + const u128 temporal = Common::Multiply64Into128(ticks, Hardware::CNTFREQ); + return Common::Divide128On32(temporal, static_cast(Hardware::BASE_CLOCK_RATE)).first; } std::chrono::milliseconds CyclesToMs(s64 cycles) { - const u128 temp = Common::Multiply64Into128(static_cast(cycles), 1000); - const u64 ms = Common::Divide128On32(temp, static_cast(Hardware::BASE_CLOCK_RATE)).first; + const u128 temporal = Common::Multiply64Into128(cycles, 1000); + u64 ms = Common::Divide128On32(temporal, static_cast(Hardware::BASE_CLOCK_RATE)).first; return std::chrono::milliseconds(ms); } std::chrono::nanoseconds CyclesToNs(s64 cycles) { - const u128 temp = Common::Multiply64Into128(static_cast(cycles), 1000000000); - const u64 ns = Common::Divide128On32(temp, static_cast(Hardware::BASE_CLOCK_RATE)).first; + const u128 temporal = Common::Multiply64Into128(cycles, 1000000000); + u64 ns = Common::Divide128On32(temporal, static_cast(Hardware::BASE_CLOCK_RATE)).first; return std::chrono::nanoseconds(ns); } std::chrono::microseconds CyclesToUs(s64 cycles) { - const u128 temp = Common::Multiply64Into128(static_cast(cycles), 1000000); - const u64 us = Common::Divide128On32(temp, static_cast(Hardware::BASE_CLOCK_RATE)).first; + const u128 temporal = Common::Multiply64Into128(cycles, 1000000); + u64 us = Common::Divide128On32(temporal, static_cast(Hardware::BASE_CLOCK_RATE)).first; return std::chrono::microseconds(us); } diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h index 3be55e267..e4a046bf9 100644 --- a/src/core/core_timing_util.h +++ b/src/core/core_timing_util.h @@ -12,8 +12,8 @@ namespace Core::Timing { s64 msToCycles(std::chrono::milliseconds ms); s64 usToCycles(std::chrono::microseconds us); s64 nsToCycles(std::chrono::nanoseconds ns); -u64 msToClockCycles(std::chrono::milliseconds ms); -u64 usToClockCycles(std::chrono::microseconds us); +u64 msToClockCycles(std::chrono::milliseconds ns); +u64 usToClockCycles(std::chrono::microseconds ns); u64 nsToClockCycles(std::chrono::nanoseconds ns); std::chrono::milliseconds CyclesToMs(s64 cycles); std::chrono::nanoseconds CyclesToNs(s64 cycles); diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 1f0d3170b..da15f764a 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -143,7 +143,6 @@ u64 GetSignatureTypeDataSize(SignatureType type) { return 0x3C; } UNREACHABLE(); - return 0; } u64 GetSignatureTypePaddingSize(SignatureType type) { @@ -158,7 +157,6 @@ u64 GetSignatureTypePaddingSize(SignatureType type) { return 0x40; } UNREACHABLE(); - return 0; } SignatureType Ticket::GetSignatureType() const { @@ -173,7 +171,6 @@ SignatureType Ticket::GetSignatureType() const { } UNREACHABLE(); - return {}; } TicketData& Ticket::GetData() { @@ -351,7 +348,7 @@ std::optional DeriveSDSeed() { std::array buffer{}; std::size_t offset = 0; for (; offset + 0x10 < save_43.GetSize(); ++offset) { - if (!save_43.Seek(static_cast(offset), SEEK_SET)) { + if (!save_43.Seek(offset, SEEK_SET)) { return std::nullopt; } @@ -361,7 +358,7 @@ std::optional DeriveSDSeed() { } } - if (!save_43.Seek(static_cast(offset + 0x10), SEEK_SET)) { + if (!save_43.Seek(offset + 0x10, SEEK_SET)) { return std::nullopt; } diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index db54f71f4..5f1c86a09 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -161,7 +161,7 @@ static constexpr u8 CalculateMaxKeyblobSourceHash() { return true; }; - for (std::size_t i = 0x1F; i <= 0x1F; --i) { + for (s8 i = 0x1F; i >= 0; --i) { if (!is_zero(keyblob_source_hashes[i])) { return static_cast(i + 1); } diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 0917f6ebf..76af47ff9 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -201,9 +201,9 @@ bool NCA::HandlePotentialHeaderDecryption() { } std::vector NCA::ReadSectionHeaders() const { - const auto number_sections = static_cast( + const std::ptrdiff_t number_sections = std::count_if(std::begin(header.section_tables), std::end(header.section_tables), - [](NCASectionTableEntry entry) { return entry.media_offset > 0; })); + [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); std::vector sections(number_sections); const auto length_sections = SECTION_HEADER_SIZE * number_sections; diff --git a/src/core/file_sys/fsmitm_romfsbuild.cpp b/src/core/file_sys/fsmitm_romfsbuild.cpp index b2d38f01e..c52fafb6f 100644 --- a/src/core/file_sys/fsmitm_romfsbuild.cpp +++ b/src/core/file_sys/fsmitm_romfsbuild.cpp @@ -103,7 +103,7 @@ static u32 romfs_calc_path_hash(u32 parent, std::string_view path, u32 start, u32 hash = parent ^ 123456789; for (u32 i = 0; i < path_len; i++) { hash = (hash >> 5) | (hash << 27); - hash ^= static_cast(path[start + i]); + hash ^= path[start + i]; } return hash; diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp index 91dc69373..a6101f1c0 100644 --- a/src/core/file_sys/ips_layer.cpp +++ b/src/core/file_sys/ips_layer.cpp @@ -66,14 +66,12 @@ static bool IsEOF(IPSFileType type, const std::vector& data) { } VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { - if (in == nullptr || ips == nullptr) { + if (in == nullptr || ips == nullptr) return nullptr; - } const auto type = IdentifyMagic(ips->ReadBytes(0x5)); - if (type == IPSFileType::Error) { + if (type == IPSFileType::Error) return nullptr; - } auto in_data = in->ReadAllBytes(); @@ -86,46 +84,37 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { } u32 real_offset{}; - if (type == IPSFileType::IPS32) { - real_offset = static_cast(temp[0] << 24) | static_cast(temp[1] << 16) | - static_cast(temp[2] << 8) | temp[3]; - } else { - real_offset = - static_cast(temp[0] << 16) | static_cast(temp[1] << 8) | temp[2]; - } + if (type == IPSFileType::IPS32) + real_offset = (temp[0] << 24) | (temp[1] << 16) | (temp[2] << 8) | temp[3]; + else + real_offset = (temp[0] << 16) | (temp[1] << 8) | temp[2]; u16 data_size{}; - if (ips->ReadObject(&data_size, offset) != sizeof(u16)) { + if (ips->ReadObject(&data_size, offset) != sizeof(u16)) return nullptr; - } data_size = Common::swap16(data_size); offset += sizeof(u16); if (data_size == 0) { // RLE u16 rle_size{}; - if (ips->ReadObject(&rle_size, offset) != sizeof(u16)) { + if (ips->ReadObject(&rle_size, offset) != sizeof(u16)) return nullptr; - } rle_size = Common::swap16(rle_size); offset += sizeof(u16); const auto data = ips->ReadByte(offset++); - if (!data) { + if (!data) return nullptr; - } - if (real_offset + rle_size > in_data.size()) { + if (real_offset + rle_size > in_data.size()) rle_size = static_cast(in_data.size() - real_offset); - } std::memset(in_data.data() + real_offset, *data, rle_size); } else { // Standard Patch auto read = data_size; - if (real_offset + read > in_data.size()) { + if (real_offset + read > in_data.size()) read = static_cast(in_data.size() - real_offset); - } - if (ips->Read(in_data.data() + real_offset, read, offset) != data_size) { + if (ips->Read(in_data.data() + real_offset, read, offset) != data_size) return nullptr; - } offset += data_size; } } @@ -193,16 +182,14 @@ void IPSwitchCompiler::ParseFlag(const std::string& line) { void IPSwitchCompiler::Parse() { const auto bytes = patch_text->ReadAllBytes(); std::stringstream s; - s.write(reinterpret_cast(bytes.data()), - static_cast(bytes.size())); + s.write(reinterpret_cast(bytes.data()), bytes.size()); std::vector lines; std::string stream_line; while (std::getline(s, stream_line)) { // Remove a trailing \r - if (!stream_line.empty() && stream_line.back() == '\r') { + if (!stream_line.empty() && stream_line.back() == '\r') stream_line.pop_back(); - } lines.push_back(std::move(stream_line)); } diff --git a/src/core/file_sys/kernel_executable.cpp b/src/core/file_sys/kernel_executable.cpp index fa758b777..ef93ef3ed 100644 --- a/src/core/file_sys/kernel_executable.cpp +++ b/src/core/file_sys/kernel_executable.cpp @@ -36,14 +36,14 @@ bool DecompressBLZ(std::vector& data) { while (out_index > 0) { --index; auto control = data[index + start_offset]; - for (std::size_t i = 0; i < 8; ++i) { + for (size_t i = 0; i < 8; ++i) { if (((control << i) & 0x80) > 0) { if (index < 2) { return false; } index -= 2; - std::size_t segment_offset = static_cast(data[index + start_offset]) | - static_cast(data[index + start_offset + 1] << 8); + std::size_t segment_offset = + data[index + start_offset] | data[index + start_offset + 1] << 8; std::size_t segment_size = ((segment_offset >> 12) & 0xF) + 3; segment_offset &= 0xFFF; segment_offset += 3; diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp index 6d3472447..5990a2fd5 100644 --- a/src/core/file_sys/nca_patch.cpp +++ b/src/core/file_sys/nca_patch.cpp @@ -25,9 +25,9 @@ std::pair SearchBucketEntry(u64 offset, const BlockTyp ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block."); } - const auto bucket_id = static_cast(std::count_if( + std::size_t bucket_id = std::count_if( block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets, - [&offset](u64 base_offset) { return base_offset <= offset; })); + [&offset](u64 base_offset) { return base_offset <= offset; }); const auto& bucket = buckets[bucket_id]; @@ -53,7 +53,6 @@ std::pair SearchBucketEntry(u64 offset, const BlockTyp } UNREACHABLE_MSG("Offset could not be found in BKTR block."); - return {}; } } // Anonymous namespace @@ -137,7 +136,7 @@ std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const { const auto block_offset = section_offset & 0xF; if (block_offset != 0) { - auto block = bktr_romfs->ReadBytes(0x10, section_offset & ~0xFU); + auto block = bktr_romfs->ReadBytes(0x10, section_offset & ~0xF); cipher.Transcode(block.data(), block.size(), block.data(), Core::Crypto::Op::Decrypt); if (length + block_offset < 0x10) { std::memcpy(data, block.data() + block_offset, std::min(length, block.size())); diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp index fdc97d692..c5d65f2d0 100644 --- a/src/core/frontend/applets/controller.cpp +++ b/src/core/frontend/applets/controller.cpp @@ -30,7 +30,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function callb auto& players = Settings::values.players; const std::size_t min_supported_players = - parameters.enable_single_mode ? 1 : static_cast(parameters.min_players); + parameters.enable_single_mode ? 1 : parameters.min_players; // Disconnect Handheld first. npad.DisconnectNPadAtIndex(8); diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp index a17420823..4df3574d2 100644 --- a/src/core/frontend/applets/profile_select.cpp +++ b/src/core/frontend/applets/profile_select.cpp @@ -12,9 +12,8 @@ ProfileSelectApplet::~ProfileSelectApplet() = default; void DefaultProfileSelectApplet::SelectProfile( std::function)> callback) const { - const auto user_index = static_cast(Settings::values.current_user); Service::Account::ProfileManager manager; - callback(manager.GetUser(user_index).value_or(Common::UUID{})); + callback(manager.GetUser(Settings::values.current_user).value_or(Common::UUID{})); LOG_INFO(Service_ACC, "called, selecting current user instead of prompting..."); } diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 28a8a0f49..97ee65464 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -205,7 +205,7 @@ static Kernel::Thread* FindThreadById(s64 id) { const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList(); for (auto& thread : threads) { if (thread->GetThreadID() == static_cast(id)) { - current_core = static_cast(thread->GetProcessorID()); + current_core = thread->GetProcessorID(); return thread.get(); } } @@ -457,14 +457,7 @@ static u128 GdbHexToU128(const u8* src) { /// Read a byte from the gdb client. static u8 ReadByte() { u8 c; - -#ifdef WIN32 - const auto socket_id = static_cast(gdbserver_socket); -#else - const auto socket_id = gdbserver_socket; -#endif - - const auto received_size = recv(socket_id, reinterpret_cast(&c), 1, MSG_WAITALL); + std::size_t received_size = recv(gdbserver_socket, reinterpret_cast(&c), 1, MSG_WAITALL); if (received_size != 1) { LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size); Shutdown(); @@ -581,13 +574,7 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) { * @param packet Packet to be sent to client. */ static void SendPacket(const char packet) { -#ifdef WIN32 - const auto socket_id = static_cast(gdbserver_socket); -#else - const auto socket_id = gdbserver_socket; -#endif - - const auto sent_size = send(socket_id, &packet, 1, 0); + std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0); if (sent_size != 1) { LOG_ERROR(Debug_GDBStub, "send failed"); } @@ -624,13 +611,7 @@ static void SendReply(const char* reply) { u8* ptr = command_buffer; u32 left = command_length + 4; while (left > 0) { -#ifdef WIN32 - const auto socket_id = static_cast(gdbserver_socket); -#else - const auto socket_id = gdbserver_socket; -#endif - const auto sent_size = - send(socket_id, reinterpret_cast(ptr), static_cast(left), 0); + const auto sent_size = send(gdbserver_socket, reinterpret_cast(ptr), left, 0); if (sent_size < 0) { LOG_ERROR(Debug_GDBStub, "gdb: send failed"); return Shutdown(); @@ -1313,13 +1294,8 @@ static void Init(u16 port) { WSAStartup(MAKEWORD(2, 2), &InitData); #endif -#ifdef WIN32 - using socket_type = SOCKET; -#else - using socket_type = int; -#endif - const auto tmpsock = static_cast(socket(PF_INET, SOCK_STREAM, 0)); - if (tmpsock == static_cast(-1)) { + int tmpsock = static_cast(socket(PF_INET, SOCK_STREAM, 0)); + if (tmpsock == -1) { LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); } @@ -1359,7 +1335,7 @@ static void Init(u16 port) { } // Clean up temporary socket if it's still alive at this point. - if (tmpsock != static_cast(-1)) { + if (tmpsock != -1) { shutdown(tmpsock, SHUT_RDWR); } } @@ -1376,12 +1352,7 @@ void Shutdown() { LOG_INFO(Debug_GDBStub, "Stopping GDB ..."); if (gdbserver_socket != -1) { -#ifdef WIN32 - const auto tmpsock = static_cast(socket(PF_INET, SOCK_STREAM, 0)); -#else - const auto tmpsock = static_cast(socket(PF_INET, SOCK_STREAM, 0)); -#endif - shutdown(tmpsock, SHUT_RDWR); + shutdown(gdbserver_socket, SHUT_RDWR); gdbserver_socket = -1; } @@ -1412,7 +1383,7 @@ void SetCpuStepFlag(bool is_step) { step_loop = is_step; } -void SendTrap(Kernel::Thread* thread, u32 trap) { +void SendTrap(Kernel::Thread* thread, int trap) { if (!send_trap) { return; } diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index 23d80f367..8fe3c320b 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h @@ -110,5 +110,5 @@ void SetCpuStepFlag(bool is_step); * @param thread Sending thread. * @param trap Trap no. */ -void SendTrap(Kernel::Thread* thread, u32 trap); +void SendTrap(Kernel::Thread* thread, int trap); } // namespace GDBStub diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index fcb86c822..1c354037d 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -233,7 +233,7 @@ void ResponseBuilder::PushRaw(const T& value) { static_assert(std::is_trivially_copyable_v, "It's undefined behavior to use memcpy with non-trivially copyable objects"); std::memcpy(cmdbuf + index, &value, sizeof(T)); - index += static_cast((sizeof(T) + 3) / 4); // round up to word length + index += (sizeof(T) + 3) / 4; // round up to word length } template <> @@ -390,7 +390,7 @@ void RequestParser::PopRaw(T& value) { static_assert(std::is_trivially_copyable_v, "It's undefined behavior to use memcpy with non-trivially copyable objects"); std::memcpy(&value, cmdbuf + index, sizeof(T)); - index += static_cast((sizeof(T) + 3) / 4); // round up to word length + index += (sizeof(T) + 3) / 4; // round up to word length } template diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index b6ebc5329..b882eaa0f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -108,7 +108,7 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a auto& monitor = system.Monitor(); s32 updated_value; do { - updated_value = static_cast(monitor.ExclusiveRead32(current_core, address)); + updated_value = monitor.ExclusiveRead32(current_core, address); if (updated_value != value) { return ERR_INVALID_STATE; @@ -129,7 +129,7 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a updated_value = value; } } - } while (!monitor.ExclusiveWrite32(current_core, address, static_cast(updated_value))); + } while (!monitor.ExclusiveWrite32(current_core, address, updated_value)); WakeThreads(waiting_threads, num_to_wake); return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index fe4988f84..3e745c18b 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -68,7 +68,7 @@ ResultVal HandleTable::Create(std::shared_ptr obj) { generations[slot] = generation; objects[slot] = std::move(obj); - const auto handle = static_cast(generation | static_cast(slot << 15)); + Handle handle = generation | (slot << 15); return MakeResult(handle); } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 0a2de4270..81f85643b 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -58,7 +58,7 @@ std::shared_ptr HLERequestContext::SleepClientThread( { Handle event_handle = InvalidHandle; - SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), static_cast(timeout)); + SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout); thread->SetHLECallback( [context = *this, callback](std::shared_ptr thread) mutable -> bool { ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 56e14da6b..b2b5b8adf 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -171,7 +171,7 @@ struct KernelCore::Impl { const auto type = static_cast(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND); auto thread_res = - Thread::Create(system, type, std::move(name), 0, 0, 0, static_cast(i), 0, + Thread::Create(system, type, std::move(name), 0, 0, 0, static_cast(i), 0, nullptr, std::move(init_func), init_func_parameter); suspend_threads[i] = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp index 6cf43ba24..e4288cab4 100644 --- a/src/core/hle/kernel/memory/address_space_info.cpp +++ b/src/core/hle/kernel/memory/address_space_info.cpp @@ -96,7 +96,6 @@ u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) { return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address; } UNREACHABLE(); - return 0; } std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) { @@ -113,7 +112,6 @@ std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size; } UNREACHABLE(); - return 0; } } // namespace Kernel::Memory diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp index a96157c37..acf13585c 100644 --- a/src/core/hle/kernel/memory/memory_manager.cpp +++ b/src/core/hle/kernel/memory/memory_manager.cpp @@ -71,7 +71,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align } // If we allocated more than we need, free some - const auto allocated_pages{PageHeap::GetBlockNumPages(static_cast(heap_index))}; + const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; if (allocated_pages > num_pages) { chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); } @@ -112,7 +112,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa // Keep allocating until we've allocated all our pages for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { - const auto pages_per_alloc{PageHeap::GetBlockNumPages(static_cast(index))}; + const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; while (num_pages >= pages_per_alloc) { // Allocate a block diff --git a/src/core/hle/kernel/memory/page_heap.cpp b/src/core/hle/kernel/memory/page_heap.cpp index 7890b8c1a..0ab1f7205 100644 --- a/src/core/hle/kernel/memory/page_heap.cpp +++ b/src/core/hle/kernel/memory/page_heap.cpp @@ -33,12 +33,11 @@ void PageHeap::Initialize(VAddr address, std::size_t size, std::size_t metadata_ } VAddr PageHeap::AllocateBlock(s32 index) { - const auto u_index = static_cast(index); - const auto needed_size{blocks[u_index].GetSize()}; + const std::size_t needed_size{blocks[index].GetSize()}; - for (auto i = u_index; i < MemoryBlockPageShifts.size(); i++) { - if (const VAddr addr = blocks[i].PopBlock(); addr != 0) { - if (const std::size_t allocated_size = blocks[i].GetSize(); + for (s32 i{index}; i < static_cast(MemoryBlockPageShifts.size()); i++) { + if (const VAddr addr{blocks[i].PopBlock()}; addr) { + if (const std::size_t allocated_size{blocks[i].GetSize()}; allocated_size > needed_size) { Free(addr + needed_size, (allocated_size - needed_size) / PageSize); } @@ -51,7 +50,7 @@ VAddr PageHeap::AllocateBlock(s32 index) { void PageHeap::FreeBlock(VAddr block, s32 index) { do { - block = blocks[static_cast(index++)].PushBlock(block); + block = blocks[index++].PushBlock(block); } while (block != 0); } @@ -70,7 +69,7 @@ void PageHeap::Free(VAddr addr, std::size_t num_pages) { VAddr after_start{end}; VAddr after_end{end}; while (big_index >= 0) { - const std::size_t block_size{blocks[static_cast(big_index)].GetSize()}; + const std::size_t block_size{blocks[big_index].GetSize()}; const VAddr big_start{Common::AlignUp((start), block_size)}; const VAddr big_end{Common::AlignDown((end), block_size)}; if (big_start < big_end) { @@ -88,7 +87,7 @@ void PageHeap::Free(VAddr addr, std::size_t num_pages) { // Free space before the big blocks for (s32 i{big_index - 1}; i >= 0; i--) { - const std::size_t block_size{blocks[static_cast(i)].GetSize()}; + const std::size_t block_size{blocks[i].GetSize()}; while (before_start + block_size <= before_end) { before_end -= block_size; FreeBlock(before_end, i); @@ -97,7 +96,7 @@ void PageHeap::Free(VAddr addr, std::size_t num_pages) { // Free space after the big blocks for (s32 i{big_index - 1}; i >= 0; i--) { - const std::size_t block_size{blocks[static_cast(i)].GetSize()}; + const std::size_t block_size{blocks[i].GetSize()}; while (after_start + block_size <= after_end) { FreeBlock(after_start, i); after_start += block_size; diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h index 92a2bce04..22b0de860 100644 --- a/src/core/hle/kernel/memory/page_heap.h +++ b/src/core/hle/kernel/memory/page_heap.h @@ -34,9 +34,7 @@ public: static constexpr s32 GetBlockIndex(std::size_t num_pages) { for (s32 i{static_cast(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) { - const auto shift_index = static_cast(i); - if (num_pages >= - (static_cast(1) << MemoryBlockPageShifts[shift_index]) / PageSize) { + if (num_pages >= (static_cast(1) << MemoryBlockPageShifts[i]) / PageSize) { return i; } } @@ -88,7 +86,7 @@ private: // Set the bitmap pointers for (s32 depth{GetHighestDepthIndex()}; depth >= 0; depth--) { - bit_storages[static_cast(depth)] = storage; + bit_storages[depth] = storage; size = Common::AlignUp(size, 64) / 64; storage += size; } @@ -101,7 +99,7 @@ private: s32 depth{}; do { - const u64 v{bit_storages[static_cast(depth)][offset]}; + const u64 v{bit_storages[depth][offset]}; if (v == 0) { // Non-zero depth indicates that a previous level had a free block ASSERT(depth == 0); @@ -127,7 +125,7 @@ private: constexpr bool ClearRange(std::size_t offset, std::size_t count) { const s32 depth{GetHighestDepthIndex()}; const auto bit_ind{offset / 64}; - u64* bits{bit_storages[static_cast(depth)]}; + u64* bits{bit_storages[depth]}; if (count < 64) { const auto shift{offset % 64}; ASSERT(shift + count <= 64); @@ -179,11 +177,11 @@ private: const auto which{offset % 64}; const u64 mask{1ULL << which}; - u64* bit{std::addressof(bit_storages[static_cast(depth)][ind])}; + u64* bit{std::addressof(bit_storages[depth][ind])}; const u64 v{*bit}; ASSERT((v & mask) == 0); *bit = v | mask; - if (v != 0) { + if (v) { break; } offset = ind; @@ -197,12 +195,12 @@ private: const auto which{offset % 64}; const u64 mask{1ULL << which}; - u64* bit{std::addressof(bit_storages[static_cast(depth)][ind])}; + u64* bit{std::addressof(bit_storages[depth][ind])}; u64 v{*bit}; ASSERT((v & mask) != 0); v &= ~mask; *bit = v; - if (v != 0) { + if (v) { break; } offset = ind; diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 4f759d078..a3fadb533 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -414,8 +414,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { const std::size_t remaining_pages{remaining_size / PageSize}; if (process->GetResourceLimit() && - !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, - static_cast(remaining_size))) { + !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } @@ -779,8 +778,7 @@ ResultVal PageTable::SetHeapSize(std::size_t size) { auto process{system.Kernel().CurrentProcess()}; if (process->GetResourceLimit() && delta != 0 && - !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, - static_cast(delta))) { + !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 6cb59d0fc..d7a7a951c 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -34,7 +34,7 @@ public: PhysicalCore& operator=(const PhysicalCore&) = delete; PhysicalCore(PhysicalCore&&) = default; - PhysicalCore& operator=(PhysicalCore&&) = delete; + PhysicalCore& operator=(PhysicalCore&&) = default; void Idle(); /// Interrupt this physical core. diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0b39f2955..ff9d9248b 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -137,10 +137,9 @@ std::shared_ptr Process::GetResourceLimit() const { } u64 Process::GetTotalPhysicalMemoryAvailable() const { - const u64 capacity{ - static_cast(resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory)) + - page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + - main_thread_stack_size}; + const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + + page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + + main_thread_stack_size}; if (capacity < memory_usage_capacity) { return capacity; @@ -280,12 +279,12 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, // Set initial resource limits resource_limit->SetLimitValue( ResourceType::PhysicalMemory, - static_cast(kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application))); + kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); resource_limit->SetLimitValue(ResourceType::Threads, 608); resource_limit->SetLimitValue(ResourceType::Events, 700); resource_limit->SetLimitValue(ResourceType::TransferMemory, 128); resource_limit->SetLimitValue(ResourceType::Sessions, 894); - ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, static_cast(code_size))); + ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size)); // Create TLS region tls_region_address = CreateTLSRegion(); @@ -301,9 +300,9 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { ChangeStatus(ProcessStatus::Running); - SetupMainThread(system, *this, static_cast(main_thread_priority), main_thread_stack_top); + SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); resource_limit->Reserve(ResourceType::Threads, 1); - resource_limit->Reserve(ResourceType::PhysicalMemory, static_cast(main_thread_stack_size)); + resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); } void Process::PrepareForTermination() { @@ -364,7 +363,7 @@ VAddr Process::CreateTLSRegion() { ->AllocateAndMapMemory(1, Memory::PageSize, true, start, size / Memory::PageSize, Memory::MemoryState::ThreadLocal, Memory::MemoryPermission::ReadAndWrite, tls_map_addr) - .ValueOr(0U)}; + .ValueOr(0)}; ASSERT(tls_page_addr); diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index e94093f24..212e442f4 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -43,8 +43,8 @@ void ResourceLimit::Release(ResourceType resource, u64 amount) { void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) { const std::size_t index{ResourceTypeToIndex(resource)}; - current[index] -= static_cast(used_amount); - available[index] -= static_cast(available_amount); + current[index] -= used_amount; + available[index] -= available_amount; } std::shared_ptr ResourceLimit::Create(KernelCore& kernel) { diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 4a9a762f3..6b7db5372 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -89,11 +89,9 @@ u32 GlobalScheduler::SelectThreads() { while (iter != suggested_queue[core_id].end()) { suggested = *iter; iter++; - const s32 suggested_core_id = suggested->GetProcessorID(); - Thread* top_thread = suggested_core_id >= 0 - ? top_threads[static_cast(suggested_core_id)] - : nullptr; - + s32 suggested_core_id = suggested->GetProcessorID(); + Thread* top_thread = + suggested_core_id >= 0 ? top_threads[suggested_core_id] : nullptr; if (top_thread != suggested) { if (top_thread != nullptr && top_thread->GetPriority() < THREADPRIO_MAX_CORE_MIGRATION) { @@ -104,19 +102,16 @@ u32 GlobalScheduler::SelectThreads() { TransferToCore(suggested->GetPriority(), static_cast(core_id), suggested); break; } - suggested = nullptr; migration_candidates[num_candidates++] = suggested_core_id; } - // Step 3: Select a suggested thread from another core if (suggested == nullptr) { for (std::size_t i = 0; i < num_candidates; i++) { - const auto candidate_core = static_cast(migration_candidates[i]); + s32 candidate_core = migration_candidates[i]; suggested = top_threads[candidate_core]; auto it = scheduled_queue[candidate_core].begin(); - ++it; - + it++; Thread* next = it != scheduled_queue[candidate_core].end() ? *it : nullptr; if (next != nullptr) { TransferToCore(suggested->GetPriority(), static_cast(core_id), @@ -133,8 +128,7 @@ u32 GlobalScheduler::SelectThreads() { idle_cores &= ~(1U << core_id); } - - u32 cores_needing_context_switch = 0; + u32 cores_needing_context_switch{}; for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { Scheduler& sched = kernel.Scheduler(core); ASSERT(top_threads[core] == nullptr || @@ -192,16 +186,13 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { for (auto& thread : suggested_queue[core_id]) { const s32 source_core = thread->GetProcessorID(); if (source_core >= 0) { - const auto sanitized_source_core = static_cast(source_core); - - if (current_threads[sanitized_source_core] != nullptr) { - if (thread == current_threads[sanitized_source_core] || - current_threads[sanitized_source_core]->GetPriority() < min_regular_priority) { + if (current_threads[source_core] != nullptr) { + if (thread == current_threads[source_core] || + current_threads[source_core]->GetPriority() < min_regular_priority) { continue; } } } - if (next_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks() || next_thread->GetPriority() < thread->GetPriority()) { if (thread->GetPriority() <= priority) { @@ -249,25 +240,17 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread for (std::size_t i = 0; i < current_threads.size(); i++) { current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front(); } - for (auto& thread : suggested_queue[core_id]) { const s32 source_core = thread->GetProcessorID(); - if (source_core < 0) { - continue; - } - - const auto sanitized_source_core = static_cast(source_core); - if (thread == current_threads[sanitized_source_core]) { + if (source_core < 0 || thread == current_threads[source_core]) { continue; } - - if (current_threads[sanitized_source_core] == nullptr || - current_threads[sanitized_source_core]->GetPriority() >= min_regular_priority) { + if (current_threads[source_core] == nullptr || + current_threads[source_core]->GetPriority() >= min_regular_priority) { winner = thread; } break; } - if (winner != nullptr) { if (winner != yielding_thread) { TransferToCore(winner->GetPriority(), static_cast(core_id), winner); @@ -309,22 +292,17 @@ void GlobalScheduler::PreemptThreads() { if (thread->GetPriority() != priority) { continue; } - if (source_core >= 0) { - const auto sanitized_source_core = static_cast(source_core); - Thread* next_thread = scheduled_queue[sanitized_source_core].empty() + Thread* next_thread = scheduled_queue[source_core].empty() ? nullptr - : scheduled_queue[sanitized_source_core].front(); - + : scheduled_queue[source_core].front(); if (next_thread != nullptr && next_thread->GetPriority() < 2) { break; } - if (next_thread == thread) { continue; } } - if (current_thread != nullptr && current_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks()) { winner = thread; @@ -344,22 +322,17 @@ void GlobalScheduler::PreemptThreads() { if (thread->GetPriority() < priority) { continue; } - if (source_core >= 0) { - const auto sanitized_source_core = static_cast(source_core); - Thread* next_thread = scheduled_queue[sanitized_source_core].empty() + Thread* next_thread = scheduled_queue[source_core].empty() ? nullptr - : scheduled_queue[sanitized_source_core].front(); - + : scheduled_queue[source_core].front(); if (next_thread != nullptr && next_thread->GetPriority() < 2) { break; } - if (next_thread == thread) { continue; } } - if (current_thread != nullptr && current_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks()) { winner = thread; @@ -379,11 +352,11 @@ void GlobalScheduler::PreemptThreads() { void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule, Core::EmuThreadHandle global_thread) { - const u32 current_core = global_thread.host_handle; + u32 current_core = global_thread.host_handle; bool must_context_switch = global_thread.guest_handle != InvalidHandle && (current_core < Core::Hardware::NUM_CPU_CORES); while (cores_pending_reschedule != 0) { - const u32 core = Common::CountTrailingZeroes32(cores_pending_reschedule); + u32 core = Common::CountTrailingZeroes32(cores_pending_reschedule); ASSERT(core < Core::Hardware::NUM_CPU_CORES); if (!must_context_switch || core != current_core) { auto& phys_core = kernel.PhysicalCore(core); @@ -393,7 +366,6 @@ void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule, } cores_pending_reschedule &= ~(1U << core); } - if (must_context_switch) { auto& core_scheduler = kernel.CurrentScheduler(); kernel.ExitSVCProfile(); @@ -831,11 +803,9 @@ void Scheduler::Initialize() { std::string name = "Idle Thread Id:" + std::to_string(core_id); std::function init_func = Core::CpuManager::GetIdleThreadStartFunc(); void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); - const auto type = static_cast(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE); - auto thread_res = - Thread::Create(system, type, std::move(name), 0, 64, 0, static_cast(core_id), 0, - nullptr, std::move(init_func), init_func_parameter); - + ThreadType type = static_cast(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE); + auto thread_res = Thread::Create(system, type, name, 0, 64, 0, static_cast(core_id), 0, + nullptr, std::move(init_func), init_func_parameter); idle_thread = std::move(thread_res).Unwrap(); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b8623e831..bafd1ced7 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -482,8 +482,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, s32 handle_count, u32 timeout_high, Handle* index) { const s64 nano_seconds{(static_cast(timeout_high) << 32) | static_cast(timeout_low)}; - return WaitSynchronization(system, index, handles_address, static_cast(handle_count), - nano_seconds); + return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds); } /// Resumes a thread waiting on WaitSynchronization @@ -2003,7 +2002,7 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, return ERR_INVALID_HANDLE; } - *core = static_cast(thread->GetIdealCore()); + *core = thread->GetIdealCore(); *mask = thread->GetAffinityMask(); return RESULT_SUCCESS; @@ -2071,7 +2070,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, return ERR_INVALID_HANDLE; } - return thread->SetCoreAndAffinityMask(static_cast(core), affinity_mask); + return thread->SetCoreAndAffinityMask(core, affinity_mask); } static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle, u32 core, diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 9284a4c84..0b6dd9df0 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -11,11 +11,11 @@ namespace Kernel { -static inline u64 Param(const Core::System& system, std::size_t n) { +static inline u64 Param(const Core::System& system, int n) { return system.CurrentArmInterface().GetReg(n); } -static inline u32 Param32(const Core::System& system, std::size_t n) { +static inline u32 Param32(const Core::System& system, int n) { return static_cast(system.CurrentArmInterface().GetReg(n)); } @@ -29,7 +29,7 @@ static inline void FuncReturn(Core::System& system, u64 result) { } static inline void FuncReturn32(Core::System& system, u32 result) { - system.CurrentArmInterface().SetReg(0, static_cast(result)); + system.CurrentArmInterface().SetReg(0, (u64)result); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -386,10 +386,9 @@ template void SvcWrap32(Core::System& system) { Handle param_1 = 0; - const u32 retval = - func(system, ¶m_1, Param32(system, 0), Param32(system, 1), Param32(system, 2), - Param32(system, 3), static_cast(Param32(system, 4))) - .raw; + const u32 retval = func(system, ¶m_1, Param32(system, 0), Param32(system, 1), + Param32(system, 2), Param32(system, 3), Param32(system, 4)) + .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); @@ -543,8 +542,8 @@ void SvcWrap32(Core::System& system) { template void SvcWrap32(Core::System& system) { u32 param_1 = 0; - const u32 retval = func(system, Param32(system, 0), Param32(system, 1), - static_cast(Param32(system, 2)), Param32(system, 3), ¶m_1) + const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2), + Param32(system, 3), ¶m_1) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp index 653f722b3..8b875d853 100644 --- a/src/core/hle/kernel/synchronization.cpp +++ b/src/core/hle/kernel/synchronization.cpp @@ -51,7 +51,7 @@ std::pair Synchronization::WaitFor( // We found a ready object, acquire it and set the result value SynchronizationObject* object = itr->get(); object->Acquire(thread); - const auto index = static_cast(std::distance(sync_objects.begin(), itr)); + const u32 index = static_cast(std::distance(sync_objects.begin(), itr)); lock.CancelSleep(); return {RESULT_SUCCESS, index}; } @@ -105,7 +105,7 @@ std::pair Synchronization::WaitFor( }); ASSERT(itr != sync_objects.end()); signaling_object->Acquire(thread); - const auto index = static_cast(std::distance(sync_objects.begin(), itr)); + const u32 index = static_cast(std::distance(sync_objects.begin(), itr)); return {signaling_result, index}; } return {signaling_result, -1}; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 323e740e9..d132aba34 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -525,7 +525,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { if (old_affinity_mask != new_affinity_mask) { const s32 old_core = processor_id; if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) { - if (ideal_core < 0) { + if (static_cast(ideal_core) < 0) { processor_id = HighestSetCore(affinity_mask, Core::Hardware::NUM_CPU_CORES); } else { processor_id = ideal_core; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 21b22ca45..8daf79fac 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -470,7 +470,7 @@ public: bool InvokeHLECallback(std::shared_ptr thread); - s32 GetIdealCore() const { + u32 GetIdealCore() const { return ideal_core; } @@ -654,8 +654,8 @@ private: Scheduler* scheduler = nullptr; - s32 ideal_core = -1; - u64 affinity_mask = 1; + u32 ideal_core{0xFFFFFFFF}; + u64 affinity_mask{0x1}; s32 ideal_core_override = -1; u64 affinity_mask_override = 0x1; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 9c302043a..9b829e957 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -41,15 +41,12 @@ constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/ ProfileManager::ProfileManager() { ParseUserSaveFile(); - if (user_count == 0) { + if (user_count == 0) CreateNewUser(UUID::Generate(), "yuzu"); - } - auto current = static_cast( - std::clamp(Settings::values.current_user, 0, static_cast(MAX_USERS - 1))); - if (UserExistsIndex(current)) { + auto current = std::clamp(Settings::values.current_user, 0, MAX_USERS - 1); + if (UserExistsIndex(current)) current = 0; - } OpenUser(*GetUser(current)); } @@ -192,8 +189,8 @@ std::size_t ProfileManager::GetUserCount() const { /// booting std::size_t ProfileManager::GetOpenUserCount() const { - return static_cast(std::count_if(profiles.begin(), profiles.end(), - [](const ProfileInfo& p) { return p.is_open; })); + return std::count_if(profiles.begin(), profiles.end(), + [](const ProfileInfo& p) { return p.is_open; }); } /// Checks if a user id exists in our profile manager diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 995b7e5c6..d7a81f64a 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1311,7 +1311,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { params.is_account_selected = 1; Account::ProfileManager profile_manager{}; - const auto uuid = profile_manager.GetUser(static_cast(Settings::values.current_user)); + const auto uuid = profile_manager.GetUser(Settings::values.current_user); ASSERT(uuid); params.current_user = uuid->uuid; diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp index 17788d7a5..2151da783 100644 --- a/src/core/hle/service/am/applets/controller.cpp +++ b/src/core/hle/service/am/applets/controller.cpp @@ -178,23 +178,23 @@ void Controller::Execute() { } void Controller::ConfigurationComplete() { - const auto& players = Settings::values.players; - - const s8 player_count = - is_single_mode - ? 1 - : static_cast(std::count_if(players.begin(), players.end() - 2, - [](const auto& player) { return player.connected; })); + ControllerSupportResultInfo result_info{}; - const auto index = static_cast(std::distance( - players.begin(), std::find_if(players.begin(), players.end(), - [](const auto& player) { return player.connected; }))); + const auto& players = Settings::values.players; // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters. // Otherwise, only count connected players from P1-P8. - ControllerSupportResultInfo result_info{}; - result_info.player_count = player_count; - result_info.selected_id = HID::Controller_NPad::IndexToNPad(index); + result_info.player_count = + is_single_mode ? 1 + : static_cast(std::count_if( + players.begin(), players.end() - 2, + [](Settings::PlayerInput player) { return player.connected; })); + + result_info.selected_id = HID::Controller_NPad::IndexToNPad( + std::distance(players.begin(), + std::find_if(players.begin(), players.end(), + [](Settings::PlayerInput player) { return player.connected; }))); + result_info.result = 0; LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}", diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index a345a68e6..9b4910e53 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -69,10 +69,9 @@ public: buffer_event = Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased"); - stream = - audio_core.OpenStream(system.CoreTiming(), static_cast(audio_params.sample_rate), - audio_params.channel_count, std::move(unique_name), - [this] { buffer_event.writable->Signal(); }); + stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, + audio_params.channel_count, std::move(unique_name), + [this] { buffer_event.writable->Signal(); }); } private: diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 16a6deb7e..f1d81602c 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -50,8 +50,8 @@ public: Enabled, }; - explicit OpusDecoderState(OpusDecoderPtr decoder_, s32 sample_rate_, u32 channel_count_) - : decoder{std::move(decoder_)}, sample_rate{sample_rate_}, channel_count{channel_count_} {} + explicit OpusDecoderState(OpusDecoderPtr decoder, u32 sample_rate, u32 channel_count) + : decoder{std::move(decoder)}, sample_rate{sample_rate}, channel_count{channel_count} {} // Decodes interleaved Opus packets. Optionally allows reporting time taken to // perform the decoding, as well as any relevant extra behavior. @@ -113,16 +113,15 @@ private: return false; } - const auto* const frame = input.data() + sizeof(OpusPacketHeader); + const auto frame = input.data() + sizeof(OpusPacketHeader); const auto decoded_sample_count = opus_packet_get_nb_samples( - frame, static_cast(input.size() - sizeof(OpusPacketHeader)), sample_rate); - const auto decoded_size = - static_cast(decoded_sample_count) * channel_count * sizeof(u16); - if (decoded_size > raw_output_sz) { + frame, static_cast(input.size() - sizeof(OpusPacketHeader)), + static_cast(sample_rate)); + if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) { LOG_ERROR( Audio, "Decoded data does not fit into the output data, decoded_sz={}, raw_output_sz={}", - decoded_size, raw_output_sz); + decoded_sample_count * channel_count * sizeof(u16), raw_output_sz); return false; } @@ -138,11 +137,11 @@ private: } const auto end_time = std::chrono::high_resolution_clock::now() - start_time; - sample_count = static_cast(out_sample_count); + sample_count = out_sample_count; consumed = static_cast(sizeof(OpusPacketHeader) + hdr.size); if (out_performance_time != nullptr) { - *out_performance_time = static_cast( - std::chrono::duration_cast(end_time).count()); + *out_performance_time = + std::chrono::duration_cast(end_time).count(); } return true; @@ -155,7 +154,7 @@ private: } OpusDecoderPtr decoder; - s32 sample_rate; + u32 sample_rate; u32 channel_count; }; @@ -213,7 +212,7 @@ std::size_t WorkerBufferSize(u32 channel_count) { ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); constexpr int num_streams = 1; const int num_stereo_streams = channel_count == 2 ? 1 : 0; - return static_cast(opus_multistream_decoder_get_size(num_streams, num_stereo_streams)); + return opus_multistream_decoder_get_size(num_streams, num_stereo_streams); } // Creates the mapping table that maps the input channels to the particular @@ -245,7 +244,7 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { "Invalid sample rate"); ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); - const auto worker_buffer_sz = static_cast(WorkerBufferSize(channel_count)); + const u32 worker_buffer_sz = static_cast(WorkerBufferSize(channel_count)); LOG_DEBUG(Audio, "worker_buffer_sz={}", worker_buffer_sz); IPC::ResponseBuilder rb{ctx, 3}; @@ -255,7 +254,7 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto sample_rate = rp.Pop(); + const auto sample_rate = rp.Pop(); const auto channel_count = rp.Pop(); const auto buffer_sz = rp.Pop(); diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 1e5e93290..48bbbe66f 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h @@ -53,10 +53,10 @@ struct DeliveryCacheProgressImpl { ResultCode result = RESULT_SUCCESS; DirectoryName current_directory; FileName current_file; - u64 current_downloaded_bytes; ///< Bytes downloaded on current file. - u64 current_total_bytes; ///< Bytes total on current file. - u64 total_downloaded_bytes; ///< Bytes downloaded on overall download. - u64 total_bytes; ///< Bytes total on overall download. + s64 current_downloaded_bytes; ///< Bytes downloaded on current file. + s64 current_total_bytes; ///< Bytes total on current file. + s64 total_downloaded_bytes; ///< Bytes downloaded on overall download. + s64 total_bytes; ///< Bytes total on overall download. INSERT_PADDING_BYTES( 0x198); ///< Appears to be unused in official code, possibly reserved for future use. }; diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index e6cadf491..3b6f7498e 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -3,16 +3,7 @@ // Refer to the license.txt file included. #include - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-conversion" -#endif #include -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - #include #include #include "common/hex_util.h" diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 5a7e9f930..db0e06ca1 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp @@ -454,8 +454,7 @@ private: write_size = std::min(write_size, files.size()); std::vector entries(write_size); std::transform( - files.begin(), files.begin() + static_cast(write_size), entries.begin(), - [](const auto& file) { + files.begin(), files.begin() + write_size, entries.begin(), [](const auto& file) { FileName name{}; std::memcpy(name.data(), file->GetName().data(), std::min(file->GetName().size(), name.size())); diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 993686f1d..649128be4 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -94,8 +94,7 @@ private: } // Read the data from the Storage backend - const auto output = backend->ReadBytes(static_cast(length), static_cast(offset)); - + std::vector output = backend->ReadBytes(length, offset); // Write the data to memory ctx.WriteBuffer(output); @@ -152,7 +151,7 @@ private: } // Read the data from the Storage backend - const auto output = backend->ReadBytes(static_cast(length), static_cast(offset)); + std::vector output = backend->ReadBytes(length, offset); // Write the data to memory ctx.WriteBuffer(output); @@ -195,8 +194,7 @@ private: // Write the data to the Storage backend const auto write_size = static_cast(std::distance(data.begin(), data.begin() + length)); - const std::size_t written = - backend->Write(data.data(), write_size, static_cast(offset)); + const std::size_t written = backend->Write(data.data(), write_size, offset); ASSERT_MSG(static_cast(written) == length, "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length, diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index c2c1470a5..ad251ed4a 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -23,7 +23,7 @@ void Controller_DebugPad::OnRelease() {} void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { - shared_memory.header.timestamp = static_cast(core_timing.GetCPUTicks()); + shared_memory.header.timestamp = core_timing.GetCPUTicks(); shared_memory.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -33,11 +33,9 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, } shared_memory.header.entry_count = 16; - const auto& last_entry = - shared_memory.pad_states[static_cast(shared_memory.header.last_entry_index)]; + const auto& last_entry = shared_memory.pad_states[shared_memory.header.last_entry_index]; shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; - auto& cur_entry = - shared_memory.pad_states[static_cast(shared_memory.header.last_entry_index)]; + auto& cur_entry = shared_memory.pad_states[shared_memory.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 0618b2a05..b7b7bfeae 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -19,7 +19,7 @@ void Controller_Gesture::OnRelease() {} void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { - shared_memory.header.timestamp = static_cast(core_timing.GetCPUTicks()); + shared_memory.header.timestamp = core_timing.GetCPUTicks(); shared_memory.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -29,11 +29,9 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u } shared_memory.header.entry_count = 16; - const auto& last_entry = - shared_memory.gesture_states[static_cast(shared_memory.header.last_entry_index)]; + const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; - auto& cur_entry = - shared_memory.gesture_states[static_cast(shared_memory.header.last_entry_index)]; + auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 0624be316..59b694cd4 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -21,7 +21,7 @@ void Controller_Keyboard::OnRelease() {} void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { - shared_memory.header.timestamp = static_cast(core_timing.GetCPUTicks()); + shared_memory.header.timestamp = core_timing.GetCPUTicks(); shared_memory.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -31,11 +31,9 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, } shared_memory.header.entry_count = 16; - const auto& last_entry = - shared_memory.pad_states[static_cast(shared_memory.header.last_entry_index)]; + const auto& last_entry = shared_memory.pad_states[shared_memory.header.last_entry_index]; shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; - auto& cur_entry = - shared_memory.pad_states[static_cast(shared_memory.header.last_entry_index)]; + auto& cur_entry = shared_memory.pad_states[shared_memory.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 10e2373bc..ac40989c5 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -19,7 +19,7 @@ void Controller_Mouse::OnRelease() {} void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { - shared_memory.header.timestamp = static_cast(core_timing.GetCPUTicks()); + shared_memory.header.timestamp = core_timing.GetCPUTicks(); shared_memory.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -29,11 +29,9 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } shared_memory.header.entry_count = 16; - auto& last_entry = - shared_memory.mouse_states[static_cast(shared_memory.header.last_entry_index)]; + auto& last_entry = shared_memory.mouse_states[shared_memory.header.last_entry_index]; shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; - auto& cur_entry = - shared_memory.mouse_states[static_cast(shared_memory.header.last_entry_index)]; + auto& cur_entry = shared_memory.mouse_states[shared_memory.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 2422c0190..e311bc18c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -341,29 +341,26 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } for (std::size_t i = 0; i < shared_memory_entries.size(); i++) { auto& npad = shared_memory_entries[i]; - const std::array controller_npads{ - &npad.main_controller_states, - &npad.handheld_states, - &npad.dual_states, - &npad.left_joy_states, - &npad.right_joy_states, - &npad.pokeball_states, - &npad.libnx, - }; + const std::array controller_npads{&npad.main_controller_states, + &npad.handheld_states, + &npad.dual_states, + &npad.left_joy_states, + &npad.right_joy_states, + &npad.pokeball_states, + &npad.libnx}; for (auto* main_controller : controller_npads) { main_controller->common.entry_count = 16; main_controller->common.total_entry_count = 17; const auto& last_entry = - main_controller->npad[static_cast(main_controller->common.last_entry_index)]; + main_controller->npad[main_controller->common.last_entry_index]; - main_controller->common.timestamp = static_cast(core_timing.GetCPUTicks()); + main_controller->common.timestamp = core_timing.GetCPUTicks(); main_controller->common.last_entry_index = (main_controller->common.last_entry_index + 1) % 17; - auto& cur_entry = - main_controller->npad[static_cast(main_controller->common.last_entry_index)]; + auto& cur_entry = main_controller->npad[main_controller->common.last_entry_index]; cur_entry.timestamp = last_entry.timestamp + 1; cur_entry.timestamp2 = cur_entry.timestamp; @@ -374,29 +371,22 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { continue; } - const auto npad_index = static_cast(i); + const u32 npad_index = static_cast(i); RequestPadStateUpdate(npad_index); auto& pad_state = npad_pad_states[npad_index]; auto& main_controller = - npad.main_controller_states - .npad[static_cast(npad.main_controller_states.common.last_entry_index)]; + npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; auto& handheld_entry = - npad.handheld_states - .npad[static_cast(npad.handheld_states.common.last_entry_index)]; - auto& dual_entry = - npad.dual_states.npad[static_cast(npad.dual_states.common.last_entry_index)]; - auto& left_entry = - npad.left_joy_states - .npad[static_cast(npad.left_joy_states.common.last_entry_index)]; + npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; + auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; + auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; auto& right_entry = - npad.right_joy_states - .npad[static_cast(npad.right_joy_states.common.last_entry_index)]; + npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; auto& pokeball_entry = - npad.pokeball_states - .npad[static_cast(npad.pokeball_states.common.last_entry_index)]; - auto& libnx_entry = npad.libnx.npad[static_cast(npad.libnx.common.last_entry_index)]; + npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; + auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; libnx_entry.connection_status.raw = 0; libnx_entry.connection_status.IsConnected.Assign(1); @@ -510,14 +500,13 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing sixaxis_sensor->common.total_entry_count = 17; const auto& last_entry = - sixaxis_sensor->sixaxis[static_cast(sixaxis_sensor->common.last_entry_index)]; + sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; - sixaxis_sensor->common.timestamp = static_cast(core_timing.GetCPUTicks()); + sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks(); sixaxis_sensor->common.last_entry_index = (sixaxis_sensor->common.last_entry_index + 1) % 17; - auto& cur_entry = - sixaxis_sensor->sixaxis[static_cast(sixaxis_sensor->common.last_entry_index)]; + auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index]; cur_entry.timestamp = last_entry.timestamp + 1; cur_entry.timestamp2 = cur_entry.timestamp; @@ -540,21 +529,17 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } auto& full_sixaxis_entry = - npad.sixaxis_full.sixaxis[static_cast(npad.sixaxis_full.common.last_entry_index)]; + npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; auto& handheld_sixaxis_entry = - npad.sixaxis_handheld - .sixaxis[static_cast(npad.sixaxis_handheld.common.last_entry_index)]; + npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; auto& dual_left_sixaxis_entry = - npad.sixaxis_dual_left - .sixaxis[static_cast(npad.sixaxis_dual_left.common.last_entry_index)]; + npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index]; auto& dual_right_sixaxis_entry = - npad.sixaxis_dual_right - .sixaxis[static_cast(npad.sixaxis_dual_right.common.last_entry_index)]; + npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index]; auto& left_sixaxis_entry = - npad.sixaxis_left.sixaxis[static_cast(npad.sixaxis_left.common.last_entry_index)]; + npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index]; auto& right_sixaxis_entry = - npad.sixaxis_right - .sixaxis[static_cast(npad.sixaxis_right.common.last_entry_index)]; + npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index]; switch (controller_type) { case NPadControllerType::None: diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index f9cb61667..e7483bfa2 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp @@ -22,12 +22,12 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u return; } - const CommonHeader header{ - .timestamp = static_cast(core_timing.GetCPUTicks()), - .total_entry_count = 17, - .last_entry_index = 0, - .entry_count = 0, - }; + CommonHeader header{}; + header.timestamp = core_timing.GetCPUTicks(); + header.total_entry_count = 17; + header.entry_count = 0; + header.last_entry_index = 0; + std::memcpy(data + common_offset, &header, sizeof(CommonHeader)); } diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 06f4134a2..0df395e85 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -22,7 +22,7 @@ void Controller_Touchscreen::OnRelease() {} void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { - shared_memory.header.timestamp = static_cast(core_timing.GetCPUTicks()); + shared_memory.header.timestamp = core_timing.GetCPUTicks(); shared_memory.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -33,12 +33,9 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin shared_memory.header.entry_count = 16; const auto& last_entry = - shared_memory - .shared_memory_entries[static_cast(shared_memory.header.last_entry_index)]; + shared_memory.shared_memory_entries[shared_memory.header.last_entry_index]; shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17; - auto& cur_entry = - shared_memory - .shared_memory_entries[static_cast(shared_memory.header.last_entry_index)]; + auto& cur_entry = shared_memory.shared_memory_entries[shared_memory.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 746acbd1c..4d9042adc 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -69,6 +69,6 @@ private: TouchScreenSharedMemory shared_memory{}; std::unique_ptr touch_device; std::unique_ptr touch_btn_device; - u64_le last_touch{}; + s64_le last_touch{}; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index 60417abb8..2503ef241 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp @@ -20,7 +20,7 @@ void Controller_XPad::OnRelease() {} void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) { for (auto& xpad_entry : shared_memory.shared_memory_entries) { - xpad_entry.header.timestamp = static_cast(core_timing.GetCPUTicks()); + xpad_entry.header.timestamp = core_timing.GetCPUTicks(); xpad_entry.header.total_entry_count = 17; if (!IsControllerActivated()) { @@ -30,11 +30,9 @@ void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } xpad_entry.header.entry_count = 16; - const auto& last_entry = - xpad_entry.pad_states[static_cast(xpad_entry.header.last_entry_index)]; + const auto& last_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index]; xpad_entry.header.last_entry_index = (xpad_entry.header.last_entry_index + 1) % 17; - auto& cur_entry = - xpad_entry.pad_states[static_cast(xpad_entry.header.last_entry_index)]; + auto& cur_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index]; cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 9ad5bbf0d..d8cd10e31 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -23,7 +23,7 @@ namespace Service::LDR { constexpr ResultCode ERROR_INSUFFICIENT_ADDRESS_SPACE{ErrorModule::RO, 2}; -[[maybe_unused]] constexpr ResultCode ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51}; +constexpr ResultCode ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51}; constexpr ResultCode ERROR_INVALID_NRO{ErrorModule::Loader, 52}; constexpr ResultCode ERROR_INVALID_NRR{ErrorModule::Loader, 53}; constexpr ResultCode ERROR_MISSING_NRR_HASH{ErrorModule::Loader, 54}; @@ -33,7 +33,7 @@ constexpr ResultCode ERROR_ALREADY_LOADED{ErrorModule::Loader, 57}; constexpr ResultCode ERROR_INVALID_ALIGNMENT{ErrorModule::Loader, 81}; constexpr ResultCode ERROR_INVALID_SIZE{ErrorModule::Loader, 82}; constexpr ResultCode ERROR_INVALID_NRO_ADDRESS{ErrorModule::Loader, 84}; -[[maybe_unused]] constexpr ResultCode ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85}; +constexpr ResultCode ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85}; constexpr ResultCode ERROR_NOT_INITIALIZED{ErrorModule::Loader, 87}; constexpr std::size_t MAXIMUM_LOADED_RO{0x40}; diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp index 1b75c2ebe..d73b90015 100644 --- a/src/core/hle/service/mii/manager.cpp +++ b/src/core/hle/service/mii/manager.cpp @@ -240,10 +240,10 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.eye_type.Assign( eye_type_info.values[GetRandomValue(eye_type_info.values_count)]); - const auto eye_rotate_1{gender != Gender::Male ? 4U : 2U}; - const auto eye_rotate_2{gender != Gender::Male ? 3U : 4U}; - const auto eye_rotate_offset{32U - EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; - const auto eye_rotate{32U - EyeRotateLookup[bf.eye_type]}; + const auto eye_rotate_1{gender != Gender::Male ? 4 : 2}; + const auto eye_rotate_2{gender != Gender::Male ? 3 : 4}; + const auto eye_rotate_offset{32 - EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; + const auto eye_rotate{32 - EyeRotateLookup[bf.eye_type]}; bf.eye_color.Assign( EyeColorLookup[eye_color_info @@ -257,11 +257,11 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.eyebrow_type.Assign( eyebrow_type_info.values[GetRandomValue(eyebrow_type_info.values_count)]); - const auto eyebrow_rotate_1{race == Race::Asian ? 6U : 0U}; - const auto eyebrow_y{race == Race::Asian ? 9U : 10U}; - const auto eyebrow_rotate_offset{32U - EyebrowRotateLookup[eyebrow_rotate_1] + 6}; + const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; + const auto eyebrow_y{race == Race::Asian ? 9 : 10}; + const auto eyebrow_rotate_offset{32 - EyebrowRotateLookup[eyebrow_rotate_1] + 6}; const auto eyebrow_rotate{ - 32U - EyebrowRotateLookup[static_cast(bf.eyebrow_type.Value())]}; + 32 - EyebrowRotateLookup[static_cast(bf.eyebrow_type.Value())]}; bf.eyebrow_color.Assign(bf.hair_color); bf.eyebrow_scale.Assign(4); @@ -270,14 +270,14 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.eyebrow_x.Assign(2); bf.eyebrow_y.Assign(axis_y + eyebrow_y); - const auto nose_scale{gender == Gender::Female ? 3U : 4U}; + const auto nose_scale{gender == Gender::Female ? 3 : 4}; bf.nose_type.Assign( nose_type_info.values[GetRandomValue(nose_type_info.values_count)]); bf.nose_scale.Assign(nose_scale); bf.nose_y.Assign(axis_y + 9); - const auto mouth_color{gender == Gender::Female ? GetRandomValue(4) : 0U}; + const auto mouth_color{gender == Gender::Female ? GetRandomValue(4) : 0}; bf.mouth_type.Assign( mouth_type_info.values[GetRandomValue(mouth_type_info.values_count)]); diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 0dd23ec9e..a0469ffbd 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -217,7 +217,7 @@ private: const auto& amiibo = nfp_interface.GetAmiiboBuffer(); const TagInfo tag_info{ .uuid = amiibo.uuid, - .uuid_length = static_cast(amiibo.uuid.size()), + .uuid_length = static_cast(tag_info.uuid.size()), .padding_1 = {}, .protocol = 1, // TODO(ogniK): Figure out actual values .tag_type = 2, diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 3edee6303..58ee1f712 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -368,7 +368,7 @@ ResultVal IApplicationManagerInterface::GetApplicationDesiredLanguage( // Get language code from settings const auto language_code = - Set::GetLanguageCodeFromIndex(static_cast(Settings::values.language_index.GetValue())); + Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); // Convert to application language, get priority list const auto application_language = ConvertToApplicationLanguage(language_code); diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 5ccec2637..40838a225 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -50,9 +50,19 @@ constexpr std::array, 7> SHARED_FONTS{ std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf"), }; +constexpr std::array SHARED_FONTS_TTF{ + "FontStandard.ttf", + "FontChineseSimplified.ttf", + "FontExtendedChineseSimplified.ttf", + "FontChineseTraditional.ttf", + "FontKorean.ttf", + "FontNintendoExtended.ttf", + "FontNintendoExtended2.ttf", +}; + // The below data is specific to shared font data dumped from Switch on f/w 2.2 // Virtual address and offsets/sizes likely will vary by dump -[[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; +constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; constexpr u32 EXPECTED_RESULT{0x7f9a0218}; // What we expect the decrypted bfttf first 4 bytes to be constexpr u32 EXPECTED_MAGIC{0x36f81a1e}; // What we expect the encrypted bfttf first 4 bytes to be constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 3a5bebff3..f2529a12e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -155,7 +155,7 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou const auto object{nvmap_dev->GetObject(params.nvmap_handle)}; if (!object) { - LOG_ERROR(Service_NVDRV, "invalid nvmap_handle={:X}", params.nvmap_handle); + LOG_CRITICAL(Service_NVDRV, "invalid nvmap_handle={:X}", params.nvmap_handle); std::memcpy(output.data(), ¶ms, output.size()); return NvErrCodes::InvalidInput; } @@ -167,24 +167,21 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou auto& gpu = system.GPU(); u64 page_size{params.page_size}; - if (page_size == 0) { + if (!page_size) { page_size = object->align; } if ((params.flags & AddressSpaceFlags::Remap) != AddressSpaceFlags::None) { - const auto buffer_map = FindBufferMap(static_cast(params.offset)); - - if (buffer_map) { - const auto cpu_addr{ - static_cast(buffer_map->CpuAddr() + static_cast(params.buffer_offset))}; + if (const auto buffer_map{FindBufferMap(params.offset)}; buffer_map) { + const auto cpu_addr{static_cast(buffer_map->CpuAddr() + params.buffer_offset)}; const auto gpu_addr{static_cast(params.offset + params.buffer_offset)}; if (!gpu.MemoryManager().Map(cpu_addr, gpu_addr, params.mapping_size)) { - LOG_ERROR(Service_NVDRV, - "Remap failed, flags={:X}, nvmap_handle={:X}, buffer_offset={}, " - "mapping_size = {}, offset={}", - params.flags, params.nvmap_handle, params.buffer_offset, - params.mapping_size, params.offset); + LOG_CRITICAL(Service_NVDRV, + "remap failed, flags={:X}, nvmap_handle={:X}, buffer_offset={}, " + "mapping_size = {}, offset={}", + params.flags, params.nvmap_handle, params.buffer_offset, + params.mapping_size, params.offset); std::memcpy(output.data(), ¶ms, output.size()); return NvErrCodes::InvalidInput; @@ -193,7 +190,7 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou std::memcpy(output.data(), ¶ms, output.size()); return NvErrCodes::Success; } else { - LOG_ERROR(Service_NVDRV, "Address not mapped. offset={}", params.offset); + LOG_CRITICAL(Service_NVDRV, "address not mapped offset={}", params.offset); std::memcpy(output.data(), ¶ms, output.size()); return NvErrCodes::InvalidInput; @@ -203,27 +200,25 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou // We can only map objects that have already been assigned a CPU address. ASSERT(object->status == nvmap::Object::Status::Allocated); - const auto physical_address{object->addr + static_cast(params.buffer_offset)}; + const auto physical_address{object->addr + params.buffer_offset}; u64 size{params.mapping_size}; - if (size == 0) { + if (!size) { size = object->size; } const bool is_alloc{(params.flags & AddressSpaceFlags::FixedOffset) == AddressSpaceFlags::None}; if (is_alloc) { - params.offset = - static_cast(gpu.MemoryManager().MapAllocate(physical_address, size, page_size)); + params.offset = gpu.MemoryManager().MapAllocate(physical_address, size, page_size); } else { - params.offset = static_cast( - gpu.MemoryManager().Map(physical_address, static_cast(params.offset), size)); + params.offset = gpu.MemoryManager().Map(physical_address, params.offset, size); } auto result{NvErrCodes::Success}; - if (params.offset == 0) { - LOG_ERROR(Service_NVDRV, "Failed to map size={}", size); + if (!params.offset) { + LOG_CRITICAL(Service_NVDRV, "failed to map size={}", size); result = NvErrCodes::InvalidInput; } else { - AddBufferMap(static_cast(params.offset), size, physical_address, is_alloc); + AddBufferMap(params.offset, size, physical_address, is_alloc); } std::memcpy(output.data(), ¶ms, output.size()); @@ -234,13 +229,12 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector& input, std::vector& ou IoctlUnmapBuffer params{}; std::memcpy(¶ms, input.data(), input.size()); - const auto offset = static_cast(params.offset); - LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", offset); + LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); - if (const auto size{RemoveBufferMap(offset)}; size) { - system.GPU().MemoryManager().Unmap(offset, *size); + if (const auto size{RemoveBufferMap(params.offset)}; size) { + system.GPU().MemoryManager().Unmap(params.offset, *size); } else { - LOG_ERROR(Service_NVDRV, "invalid offset=0x{:X}", offset); + LOG_ERROR(Service_NVDRV, "invalid offset=0x{:X}", params.offset); } std::memcpy(output.data(), ¶ms, output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 07d851d0e..b27ee0502 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -63,7 +63,8 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& return NvResult::BadParameter; } - const u32 event_id = params.value & 0x00FF; + u32 event_id = params.value & 0x00FF; + if (event_id >= MaxNvEvents) { std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::BadParameter; @@ -77,17 +78,16 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& event.writable->Signal(); return NvResult::Success; } - auto lock = gpu.LockSync(); const u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id); - const s32 diff = static_cast(current_syncpoint_value - params.threshold); + const s32 diff = current_syncpoint_value - params.threshold; if (diff >= 0) { event.writable->Signal(); params.value = current_syncpoint_value; std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } - const u32 target_value = current_syncpoint_value - static_cast(diff); + const u32 target_value = current_syncpoint_value - diff; if (!is_async) { params.value = 0; @@ -98,7 +98,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& return NvResult::Timeout; } - const EventState status = events_interface.status[event_id]; + EventState status = events_interface.status[event_id]; if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) { events_interface.SetEventStatus(event_id, EventState::Waiting); events_interface.assigned_syncpt[event_id] = params.syncpt_id; @@ -114,7 +114,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& if (!is_async && ctrl.fresh_call) { ctrl.must_delay = true; ctrl.timeout = params.timeout; - ctrl.event_id = static_cast(event_id); + ctrl.event_id = event_id; return NvResult::Timeout; } std::memcpy(output.data(), ¶ms, sizeof(params)); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 5e51b37be..f1966ac0e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -127,7 +127,7 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector& input, std::vector& ou params.unk3); auto& gpu = system.GPU(); - params.fence_out.id = static_cast(assigned_syncpoints); + params.fence_out.id = assigned_syncpoints; params.fence_out.value = gpu.GetSyncpointValue(assigned_syncpoints); assigned_syncpoints++; std::memcpy(output.data(), ¶ms, output.size()); @@ -166,8 +166,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector& input, std::vector& outp UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); auto& gpu = system.GPU(); - const u32 current_syncpoint_value = - gpu.GetSyncpointValue(static_cast(params.fence_out.id)); + u32 current_syncpoint_value = gpu.GetSyncpointValue(params.fence_out.id); if (params.flags.increment.Value()) { params.fence_out.value += current_syncpoint_value; } else { @@ -201,8 +200,7 @@ u32 nvhost_gpu::KickoffPB(const std::vector& input, std::vector& output, UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); auto& gpu = system.GPU(); - const u32 current_syncpoint_value = - gpu.GetSyncpointValue(static_cast(params.fence_out.id)); + u32 current_syncpoint_value = gpu.GetSyncpointValue(params.fence_out.id); if (params.flags.increment.Value()) { params.fence_out.value += current_syncpoint_value; } else { diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index 2f4f73487..88fbfa9b0 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -61,9 +61,9 @@ void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) { if (ctrl.must_delay) { ctrl.fresh_call = false; ctx.SleepClientThread( - "NVServices::DelayedResponse", static_cast(ctrl.timeout), - [=, this](std::shared_ptr, Kernel::HLERequestContext& ctx_, - Kernel::ThreadWakeupReason) { + "NVServices::DelayedResponse", ctrl.timeout, + [=, this](std::shared_ptr thread, Kernel::HLERequestContext& ctx_, + Kernel::ThreadWakeupReason reason) { IoctlCtrl ctrl2{ctrl}; std::vector tmp_output = output; std::vector tmp_output2 = output2; @@ -77,7 +77,7 @@ void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) { rb.Push(RESULT_SUCCESS); rb.Push(ioctl_result); }, - nvdrv->GetEventWriteable(static_cast(ctrl.event_id))); + nvdrv->GetEventWriteable(ctrl.event_id)); } else { ctx.WriteBuffer(output); if (version == IoctlVersion::Version3) { diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 621a429bc..c64673dba 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -247,7 +247,7 @@ void NVFlinger::Compose() { guard->unlock(); for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { const auto& fence = multi_fence.fences[fence_id]; - gpu.WaitFence(static_cast(fence.id), fence.value); + gpu.WaitFence(fence.id, fence.value); } guard->lock(); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index bc7476a5b..ba9159ee0 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -80,10 +80,10 @@ namespace Service { std::string_view port_name, const u32* cmd_buff) { // Number of params == bits 0-5 + bits 6-11 - const u32 num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); + int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); std::string function_string = fmt::format("function '{}': port={}", name, port_name); - for (u32 i = 1; i <= num_params; ++i) { + for (int i = 1; i <= num_params; ++i) { function_string += fmt::format(", cmd_buff[{}]=0x{:X}", i, cmd_buff[i]); } return function_string; diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 82a7aecc7..e64777668 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -91,8 +91,7 @@ void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t m } void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) { - const auto language_code = - available_language_codes[static_cast(Settings::values.language_index.GetValue())]; + const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; const auto key_code = std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), [=](const auto& element) { return element.first == language_code; }); @@ -168,8 +167,7 @@ void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.PushEnum( - available_language_codes[static_cast(Settings::values.language_index.GetValue())]); + rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); } void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 7cb70064c..a74be9370 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -437,9 +437,9 @@ std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protoco UNIMPLEMENTED_MSG("SOCK_RAW errno management"); } - [[maybe_unused]] const bool unk_flag = (static_cast(type) & 0x20000000U) != 0; + [[maybe_unused]] const bool unk_flag = (static_cast(type) & 0x20000000) != 0; UNIMPLEMENTED_IF_MSG(unk_flag, "Unknown flag in type"); - type = static_cast(static_cast(type) & ~0x20000000U); + type = static_cast(static_cast(type) & ~0x20000000); const s32 fd = FindFreeFileDescriptorHandle(); if (fd < 0) { @@ -447,7 +447,7 @@ std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protoco return {-1, Errno::MFILE}; } - FileDescriptor& descriptor = GetFileDescriptor(fd).emplace(); + FileDescriptor& descriptor = file_descriptors[fd].emplace(); // ENONMEM might be thrown here LOG_INFO(Service, "New socket fd={}", fd); @@ -461,7 +461,7 @@ std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protoco std::pair BSD::PollImpl(std::vector& write_buffer, std::vector read_buffer, s32 nfds, s32 timeout) { - if (write_buffer.size() < static_cast(nfds) * sizeof(PollFD)) { + if (write_buffer.size() < nfds * sizeof(PollFD)) { return {-1, Errno::INVAL}; } @@ -471,7 +471,7 @@ std::pair BSD::PollImpl(std::vector& write_buffer, std::vector fds(static_cast(nfds)); + std::vector fds(nfds); std::memcpy(fds.data(), read_buffer.data(), length); if (timeout >= 0) { @@ -497,7 +497,7 @@ std::pair BSD::PollImpl(std::vector& write_buffer, std::vector& descriptor = GetFileDescriptor(pollfd.fd); + const std::optional& descriptor = file_descriptors[pollfd.fd]; if (!descriptor) { LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); pollfd.revents = POLL_NVAL; @@ -508,7 +508,7 @@ std::pair BSD::PollImpl(std::vector& write_buffer, std::vector host_pollfds(fds.size()); std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [this](PollFD pollfd) { Network::PollFD result; - result.socket = GetFileDescriptor(pollfd.fd)->socket.get(); + result.socket = file_descriptors[pollfd.fd]->socket.get(); result.events = TranslatePollEventsToHost(pollfd.events); result.revents = 0; return result; @@ -536,13 +536,13 @@ std::pair BSD::AcceptImpl(s32 fd, std::vector& write_buffer) { return {-1, Errno::MFILE}; } - FileDescriptor& descriptor = *GetFileDescriptor(fd); + FileDescriptor& descriptor = *file_descriptors[fd]; auto [result, bsd_errno] = descriptor.socket->Accept(); if (bsd_errno != Network::Errno::SUCCESS) { return {-1, Translate(bsd_errno)}; } - FileDescriptor& new_descriptor = GetFileDescriptor(new_fd).emplace(); + FileDescriptor& new_descriptor = file_descriptors[new_fd].emplace(); new_descriptor.socket = std::move(result.socket); new_descriptor.is_connection_based = descriptor.is_connection_based; @@ -561,7 +561,7 @@ Errno BSD::BindImpl(s32 fd, const std::vector& addr) { SockAddrIn addr_in; std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); - return Translate(GetFileDescriptor(fd)->socket->Bind(Translate(addr_in))); + return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); } Errno BSD::ConnectImpl(s32 fd, const std::vector& addr) { @@ -573,7 +573,7 @@ Errno BSD::ConnectImpl(s32 fd, const std::vector& addr) { SockAddrIn addr_in; std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); - return Translate(GetFileDescriptor(fd)->socket->Connect(Translate(addr_in))); + return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); } Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { @@ -581,7 +581,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { return Errno::BADF; } - const auto [addr_in, bsd_errno] = GetFileDescriptor(fd)->socket->GetPeerName(); + const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetPeerName(); if (bsd_errno != Network::Errno::SUCCESS) { return Translate(bsd_errno); } @@ -597,7 +597,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector& write_buffer) { return Errno::BADF; } - const auto [addr_in, bsd_errno] = GetFileDescriptor(fd)->socket->GetSockName(); + const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetSockName(); if (bsd_errno != Network::Errno::SUCCESS) { return Translate(bsd_errno); } @@ -612,7 +612,7 @@ Errno BSD::ListenImpl(s32 fd, s32 backlog) { if (!IsFileDescriptorValid(fd)) { return Errno::BADF; } - return Translate(GetFileDescriptor(fd)->socket->Listen(backlog)); + return Translate(file_descriptors[fd]->socket->Listen(backlog)); } std::pair BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) { @@ -620,14 +620,14 @@ std::pair BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) { return {-1, Errno::BADF}; } - FileDescriptor& descriptor = *GetFileDescriptor(fd); + FileDescriptor& descriptor = *file_descriptors[fd]; switch (cmd) { case FcntlCmd::GETFL: ASSERT(arg == 0); return {descriptor.flags, Errno::SUCCESS}; case FcntlCmd::SETFL: { - const bool enable = (static_cast(arg) & FLAG_O_NONBLOCK) != 0; + const bool enable = (arg & FLAG_O_NONBLOCK) != 0; const Errno bsd_errno = Translate(descriptor.socket->SetNonBlock(enable)); if (bsd_errno != Errno::SUCCESS) { return {-1, bsd_errno}; @@ -648,7 +648,7 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con return Errno::BADF; } - Network::Socket* const socket = GetFileDescriptor(fd)->socket.get(); + Network::Socket* const socket = file_descriptors[fd]->socket.get(); if (optname == OptName::LINGER) { ASSERT(optlen == sizeof(Linger)); @@ -689,14 +689,14 @@ Errno BSD::ShutdownImpl(s32 fd, s32 how) { return Errno::BADF; } const Network::ShutdownHow host_how = Translate(static_cast(how)); - return Translate(GetFileDescriptor(fd)->socket->Shutdown(host_how)); + return Translate(file_descriptors[fd]->socket->Shutdown(host_how)); } std::pair BSD::RecvImpl(s32 fd, u32 flags, std::vector& message) { if (!IsFileDescriptorValid(fd)) { return {-1, Errno::BADF}; } - return Translate(GetFileDescriptor(fd)->socket->Recv(flags, message)); + return Translate(file_descriptors[fd]->socket->Recv(flags, message)); } std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& message, @@ -705,7 +705,7 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess return {-1, Errno::BADF}; } - FileDescriptor& descriptor = *GetFileDescriptor(fd); + FileDescriptor& descriptor = *file_descriptors[fd]; Network::SockAddrIn addr_in{}; Network::SockAddrIn* p_addr_in = nullptr; @@ -719,7 +719,7 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess // Apply flags if ((flags & FLAG_MSG_DONTWAIT) != 0) { flags &= ~FLAG_MSG_DONTWAIT; - if ((static_cast(descriptor.flags) & FLAG_O_NONBLOCK) == 0) { + if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) { descriptor.socket->SetNonBlock(true); } } @@ -727,7 +727,7 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess const auto [ret, bsd_errno] = Translate(descriptor.socket->RecvFrom(flags, message, p_addr_in)); // Restore original state - if ((static_cast(descriptor.flags) & FLAG_O_NONBLOCK) == 0) { + if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) { descriptor.socket->SetNonBlock(false); } @@ -748,7 +748,7 @@ std::pair BSD::SendImpl(s32 fd, u32 flags, const std::vector& me if (!IsFileDescriptorValid(fd)) { return {-1, Errno::BADF}; } - return Translate(GetFileDescriptor(fd)->socket->Send(message, flags)); + return Translate(file_descriptors[fd]->socket->Send(message, flags)); } std::pair BSD::SendToImpl(s32 fd, u32 flags, const std::vector& message, @@ -767,8 +767,7 @@ std::pair BSD::SendToImpl(s32 fd, u32 flags, const std::vector& p_addr_in = &addr_in; } - const auto& descriptor = GetFileDescriptor(fd); - return Translate(descriptor->socket->SendTo(flags, message, p_addr_in)); + return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in)); } Errno BSD::CloseImpl(s32 fd) { @@ -776,21 +775,20 @@ Errno BSD::CloseImpl(s32 fd) { return Errno::BADF; } - auto& descriptor = GetFileDescriptor(fd); - const Errno bsd_errno = Translate(descriptor->socket->Close()); + const Errno bsd_errno = Translate(file_descriptors[fd]->socket->Close()); if (bsd_errno != Errno::SUCCESS) { return bsd_errno; } LOG_INFO(Service, "Close socket fd={}", fd); - descriptor.reset(); + file_descriptors[fd].reset(); return bsd_errno; } s32 BSD::FindFreeFileDescriptorHandle() noexcept { for (s32 fd = 0; fd < static_cast(file_descriptors.size()); ++fd) { - if (!GetFileDescriptor(fd)) { + if (!file_descriptors[fd]) { return fd; } } @@ -802,7 +800,7 @@ bool BSD::IsFileDescriptorValid(s32 fd) const noexcept { LOG_ERROR(Service, "Invalid file descriptor handle={}", fd); return false; } - if (!GetFileDescriptor(fd)) { + if (!file_descriptors[fd]) { LOG_ERROR(Service, "File descriptor handle={} is not allocated", fd); return false; } @@ -815,12 +813,10 @@ bool BSD::IsBlockingSocket(s32 fd) const noexcept { if (fd > static_cast(MAX_FD) || fd < 0) { return false; } - - const auto& descriptor = GetFileDescriptor(fd); - if (!descriptor) { + if (!file_descriptors[fd]) { return false; } - return (static_cast(descriptor->flags) & FLAG_O_NONBLOCK) != 0; + return (file_descriptors[fd]->flags & FLAG_O_NONBLOCK) != 0; } void BSD::BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) const noexcept { @@ -831,14 +827,6 @@ void BSD::BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) co rb.PushEnum(bsd_errno); } -std::optional& BSD::GetFileDescriptor(s32 fd) { - return file_descriptors[static_cast(fd)]; -} - -const std::optional& BSD::GetFileDescriptor(s32 fd) const { - return file_descriptors[static_cast(fd)]; -} - BSD::BSD(Core::System& system, const char* name) : ServiceFramework(name), worker_pool{system, this} { // clang-format off diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index ac9523d83..357531951 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -167,9 +167,6 @@ private: void BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) const noexcept; - std::optional& GetFileDescriptor(s32 fd); - const std::optional& GetFileDescriptor(s32 fd) const; - std::array, MAX_FD> file_descriptors; BlockingWorkerPool(type)); - return {}; } } diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index df0ed924d..bdf0439f2 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp @@ -117,8 +117,7 @@ static constexpr int GetMonthLength(bool is_leap_year, int month) { constexpr std::array month_lengths{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; constexpr std::array month_lengths_leap{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - const auto month_index = static_cast(month); - return is_leap_year ? month_lengths_leap[month_index] : month_lengths[month_index]; + return is_leap_year ? month_lengths_leap[month] : month_lengths[month]; } static constexpr bool IsDigit(char value) { @@ -321,7 +320,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { int dest_len{}; int dest_offset{}; const char* dest_name{name + offset}; - if (rule.chars.size() < static_cast(char_count)) { + if (rule.chars.size() < std::size_t(char_count)) { return {}; } @@ -344,7 +343,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { return {}; } char_count += dest_len + 1; - if (rule.chars.size() < static_cast(char_count)) { + if (rule.chars.size() < std::size_t(char_count)) { return {}; } if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') { @@ -387,7 +386,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { rule.default_type = 0; s64 jan_first{}; - u32 time_count{}; + int time_count{}; int jan_offset{}; int year_beginning{epoch_year}; do { @@ -415,7 +414,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { if (is_reversed || (start_time < end_time && (end_time - start_time < (year_seconds + (std_offset - dest_offset))))) { - if (rule.ats.size() - 2 < time_count) { + if (rule.ats.size() - 2 < std::size_t(time_count)) { break; } @@ -439,7 +438,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { } jan_offset = 0; } - rule.time_count = static_cast(time_count); + rule.time_count = time_count; if (time_count == 0) { rule.type_count = 1; } else if (years_per_repeat < year - year_beginning) { @@ -452,30 +451,26 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { } s64 their_std_offset{}; - for (u32 index = 0; index < static_cast(rule.time_count); ++index) { + for (int index{}; index < rule.time_count; ++index) { const s8 type{rule.types[index]}; - const auto& tti = rule.ttis[static_cast(type)]; - - if (tti.is_standard_time_daylight) { - their_std_offset = -tti.gmt_offset; + if (rule.ttis[type].is_standard_time_daylight) { + their_std_offset = -rule.ttis[type].gmt_offset; } } s64 their_offset{their_std_offset}; - for (u32 index = 0; index < static_cast(rule.time_count); ++index) { + for (int index{}; index < rule.time_count; ++index) { const s8 type{rule.types[index]}; - const auto& tti = rule.ttis[static_cast(type)]; - - rule.types[index] = tti.is_dst ? 1 : 0; - if (!tti.is_gmt) { - if (!tti.is_standard_time_daylight) { + rule.types[index] = rule.ttis[type].is_dst ? 1 : 0; + if (!rule.ttis[type].is_gmt) { + if (!rule.ttis[type].is_standard_time_daylight) { rule.ats[index] += dest_offset - their_std_offset; } else { rule.ats[index] += std_offset - their_std_offset; } } - their_offset = -tti.gmt_offset; - if (!tti.is_dst) { + their_offset = -rule.ttis[type].gmt_offset; + if (!rule.ttis[type].is_dst) { their_std_offset = their_offset; } } @@ -499,16 +494,16 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { } rule.char_count = char_count; - for (std::size_t index = 0; index < static_cast(std_len); ++index) { + for (int index{}; index < std_len; ++index) { rule.chars[index] = std_name[index]; } - rule.chars[static_cast(std_len++)] = '\0'; + rule.chars[std_len++] = '\0'; if (dest_len != 0) { - for (int index = 0; index < dest_len; ++index) { - rule.chars[static_cast(std_len + index)] = dest_name[index]; + for (int index{}; index < dest_len; ++index) { + rule.chars[std_len + index] = dest_name[index]; } - rule.chars[static_cast(std_len + dest_len)] = '\0'; + rule.chars[std_len + dest_len] = '\0'; } return true; @@ -536,33 +531,33 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi int time_count{}; u64 read_offset = sizeof(TzifHeader); - for (size_t index = 0; index < static_cast(time_zone_rule.time_count); ++index) { + for (int index{}; index < time_zone_rule.time_count; ++index) { s64_be at{}; vfs_file->ReadObject(&at, read_offset); time_zone_rule.types[index] = 1; - if (time_count != 0 && at <= time_zone_rule.ats[static_cast(time_count) - 1]) { - if (at < time_zone_rule.ats[static_cast(time_count) - 1]) { + if (time_count != 0 && at <= time_zone_rule.ats[time_count - 1]) { + if (at < time_zone_rule.ats[time_count - 1]) { return {}; } time_zone_rule.types[index - 1] = 0; time_count--; } - time_zone_rule.ats[static_cast(time_count++)] = at; + time_zone_rule.ats[time_count++] = at; read_offset += sizeof(s64_be); } time_count = 0; - for (size_t index = 0; index < static_cast(time_zone_rule.time_count); ++index) { - const auto type{static_cast(*vfs_file->ReadByte(read_offset))}; - read_offset += sizeof(s8); + for (int index{}; index < time_zone_rule.time_count; ++index) { + const u8 type{*vfs_file->ReadByte(read_offset)}; + read_offset += sizeof(u8); if (time_zone_rule.time_count <= type) { return {}; } if (time_zone_rule.types[index] != 0) { - time_zone_rule.types[static_cast(time_count++)] = type; + time_zone_rule.types[time_count++] = type; } } time_zone_rule.time_count = time_count; - for (size_t index = 0; index < static_cast(time_zone_rule.type_count); ++index) { + for (int index{}; index < time_zone_rule.type_count; ++index) { TimeTypeInfo& ttis{time_zone_rule.ttis[index]}; u32_be gmt_offset{}; vfs_file->ReadObject(&gmt_offset, read_offset); @@ -584,11 +579,10 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi ttis.abbreviation_list_index = abbreviation_list_index; } - vfs_file->ReadArray(time_zone_rule.chars.data(), static_cast(time_zone_rule.char_count), - read_offset); - time_zone_rule.chars[static_cast(time_zone_rule.char_count)] = '\0'; - read_offset += static_cast(time_zone_rule.char_count); - for (size_t index = 0; index < static_cast(time_zone_rule.type_count); ++index) { + vfs_file->ReadArray(time_zone_rule.chars.data(), time_zone_rule.char_count, read_offset); + time_zone_rule.chars[time_zone_rule.char_count] = '\0'; + read_offset += time_zone_rule.char_count; + for (int index{}; index < time_zone_rule.type_count; ++index) { if (header.ttis_std_count == 0) { time_zone_rule.ttis[index].is_standard_time_daylight = false; } else { @@ -601,7 +595,7 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi } } - for (size_t index = 0; index < static_cast(time_zone_rule.type_count); ++index) { + for (int index{}; index < time_zone_rule.type_count; ++index) { if (header.ttis_std_count == 0) { time_zone_rule.ttis[index].is_gmt = false; } else { @@ -625,14 +619,13 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi } std::array temp_name{}; - vfs_file->ReadArray(temp_name.data(), static_cast(bytes_read), read_offset); - if (bytes_read > 2 && temp_name[0] == '\n' && - temp_name[static_cast(bytes_read - 1)] == '\n' && - static_cast(time_zone_rule.type_count) + 2 <= time_zone_rule.ttis.size()) { - temp_name[static_cast(bytes_read - 1)] = '\0'; + vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset); + if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' && + std::size_t(time_zone_rule.type_count) + 2 <= time_zone_rule.ttis.size()) { + temp_name[bytes_read - 1] = '\0'; std::array name{}; - std::memcpy(name.data(), temp_name.data() + 1, static_cast(bytes_read - 1)); + std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1)); TimeZoneRule temp_rule; if (ParsePosixName(name.data(), temp_rule)) { @@ -649,24 +642,24 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi s32 default_type{}; for (default_type = 0; default_type < time_zone_rule.time_count; default_type++) { - if (time_zone_rule.types[static_cast(default_type)] == 0) { + if (time_zone_rule.types[default_type] == 0) { break; } } default_type = default_type < time_zone_rule.time_count ? -1 : 0; if (default_type < 0 && time_zone_rule.time_count > 0 && - time_zone_rule.ttis[static_cast(time_zone_rule.types[0])].is_dst) { + time_zone_rule.ttis[time_zone_rule.types[0]].is_dst) { default_type = time_zone_rule.types[0]; while (--default_type >= 0) { - if (!time_zone_rule.ttis[static_cast(default_type)].is_dst) { + if (!time_zone_rule.ttis[default_type].is_dst) { break; } } } if (default_type < 0) { default_type = 0; - while (time_zone_rule.ttis[static_cast(default_type)].is_dst) { + while (time_zone_rule.ttis[default_type].is_dst) { if (++default_type >= time_zone_rule.type_count) { default_type = 0; break; @@ -756,12 +749,12 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, CalendarTimeInternal& calendar_time, CalendarAdditionalInfo& calendar_additional_info) { if ((rules.go_ahead && time < rules.ats[0]) || - (rules.go_back && time > rules.ats[static_cast(rules.time_count - 1)])) { + (rules.go_back && time > rules.ats[rules.time_count - 1])) { s64 seconds{}; if (time < rules.ats[0]) { seconds = rules.ats[0] - time; } else { - seconds = time - rules.ats[static_cast(rules.time_count - 1)]; + seconds = time - rules.ats[rules.time_count - 1]; } seconds--; @@ -774,8 +767,7 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, } else { new_time -= seconds; } - if (new_time < rules.ats[0] && - new_time > rules.ats[static_cast(rules.time_count - 1)]) { + if (new_time < rules.ats[0] && new_time > rules.ats[rules.time_count - 1]) { return ERROR_TIME_NOT_FOUND; } if (const ResultCode result{ @@ -799,27 +791,25 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, s32 low{1}; s32 high{rules.time_count}; while (low < high) { - const s32 mid{(low + high) >> 1}; - if (time < rules.ats[static_cast(mid)]) { + s32 mid{(low + high) >> 1}; + if (time < rules.ats[mid]) { high = mid; } else { low = mid + 1; } } - tti_index = rules.types[static_cast(low - 1)]; + tti_index = rules.types[low - 1]; } - if (const ResultCode result{ - CreateCalendarTime(time, rules.ttis[static_cast(tti_index)].gmt_offset, - calendar_time, calendar_additional_info)}; + if (const ResultCode result{CreateCalendarTime(time, rules.ttis[tti_index].gmt_offset, + calendar_time, calendar_additional_info)}; result != RESULT_SUCCESS) { return result; } - const auto& tti = rules.ttis[static_cast(tti_index)]; - calendar_additional_info.is_dst = tti.is_dst; - const char* time_zone{&rules.chars[static_cast(tti.abbreviation_list_index)]}; - for (size_t index = 0; time_zone[index] != '\0'; ++index) { + calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst; + const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]}; + for (int index{}; time_zone[index] != '\0'; ++index) { calendar_additional_info.timezone_name[index] = time_zone[index]; } return RESULT_SUCCESS; diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp index 8a0227021..ff3a10b3e 100644 --- a/src/core/hle/service/time/time_zone_service.cpp +++ b/src/core/hle/service/time/time_zone_service.cpp @@ -49,12 +49,12 @@ void ITimeZoneService::LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { const auto raw_location_name{rp.PopRaw>()}; std::string location_name; - for (const auto byte : raw_location_name) { + for (const auto& byte : raw_location_name) { // Strip extra bytes if (byte == '\0') { break; } - location_name.push_back(static_cast(byte)); + location_name.push_back(byte); } LOG_DEBUG(Service_Time, "called, location_name={}", location_name); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 86d0527fc..dca1fcb18 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -220,19 +220,18 @@ public: } const char* GetSectionName(int section) const; const u8* GetSectionDataPtr(int section) const { - if (section < 0 || section >= header->e_shnum) { + if (section < 0 || section >= header->e_shnum) + return nullptr; + if (sections[section].sh_type != SHT_NOBITS) + return GetPtr(sections[section].sh_offset); + else return nullptr; - } - if (sections[section].sh_type != SHT_NOBITS) { - return GetPtr(static_cast(sections[section].sh_offset)); - } - return nullptr; } bool IsCodeSection(int section) const { return sections[section].sh_type == SHT_PROGBITS; } const u8* GetSegmentPtr(int segment) { - return GetPtr(static_cast(segments[segment].p_offset)); + return GetPtr(segments[segment].p_offset); } u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; @@ -259,14 +258,14 @@ ElfReader::ElfReader(void* ptr) { } const char* ElfReader::GetSectionName(int section) const { - if (sections[section].sh_type == SHT_NULL) { + if (sections[section].sh_type == SHT_NULL) return nullptr; - } - const auto name_offset = sections[section].sh_name; - if (const auto* ptr = reinterpret_cast(GetSectionDataPtr(header->e_shstrndx))) { + int name_offset = sections[section].sh_name; + const char* ptr = reinterpret_cast(GetSectionDataPtr(header->e_shstrndx)); + + if (ptr) return ptr + name_offset; - } return nullptr; } @@ -292,7 +291,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { for (unsigned int i = 0; i < header->e_phnum; ++i) { const Elf32_Phdr* p = &segments[i]; if (p->p_type == PT_LOAD) { - total_image_size += (p->p_memsz + 0xFFF) & ~0xFFFU; + total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; } } @@ -301,14 +300,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { Kernel::CodeSet codeset; - for (u32 i = 0; i < header->e_phnum; ++i) { + for (unsigned int i = 0; i < header->e_phnum; ++i) { const Elf32_Phdr* p = &segments[i]; LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { Kernel::CodeSet::Segment* codeset_segment; - const u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); + u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); if (permission_flags == (PF_R | PF_X)) { codeset_segment = &codeset.CodeSegment(); } else if (permission_flags == (PF_R)) { @@ -330,14 +329,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { } const VAddr segment_addr = base_addr + p->p_vaddr; - const u32 aligned_size = (p->p_memsz + 0xFFF) & ~0xFFFU; + const u32 aligned_size = (p->p_memsz + 0xFFF) & ~0xFFF; codeset_segment->offset = current_image_position; codeset_segment->addr = segment_addr; codeset_segment->size = aligned_size; - std::memcpy(program_image.data() + current_image_position, - GetSegmentPtr(static_cast(i)), p->p_filesz); + std::memcpy(program_image.data() + current_image_position, GetSegmentPtr(i), + p->p_filesz); current_image_position += aligned_size; } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 2ce12df88..b88aa5c40 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -197,7 +197,7 @@ struct Memory::Impl { std::string string; string.reserve(max_length); for (std::size_t i = 0; i < max_length; ++i) { - const auto c = static_cast(Read8(vaddr)); + const char c = Read8(vaddr); if (c == '\0') { break; } diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp index d280f7a28..4b3bb4366 100644 --- a/src/core/network/network.cpp +++ b/src/core/network/network.cpp @@ -96,7 +96,7 @@ int LastError() { bool EnableNonBlock(SOCKET fd, bool enable) { u_long value = enable ? 1 : 0; - return ioctlsocket(fd, static_cast(FIONBIO), &value) != SOCKET_ERROR; + return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR; } #elif __unix__ // ^ _WIN32 v __unix__ @@ -140,9 +140,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) { result.sin_port = htons(input.portno); - result.sin_addr.s_addr = static_cast( - input.ip[0] | static_cast(input.ip[1] << 8) | static_cast(input.ip[2] << 16) | - static_cast(input.ip[3] << 24)); + result.sin_addr.s_addr = input.ip[0] | input.ip[1] << 8 | input.ip[2] << 16 | input.ip[3] << 24; sockaddr addr; std::memcpy(&addr, &result, sizeof(addr)); @@ -150,7 +148,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) { } int WSAPoll(WSAPOLLFD* fds, ULONG nfds, int timeout) { - return poll(fds, static_cast(nfds), timeout); + return poll(fds, nfds, timeout); } int closesocket(SOCKET fd) { @@ -160,7 +158,7 @@ int closesocket(SOCKET fd) { linger MakeLinger(bool enable, u32 linger_value) { linger value; value.l_onoff = enable ? 1 : 0; - value.l_linger = static_cast(linger_value); + value.l_linger = linger_value; return value; } @@ -339,7 +337,7 @@ std::pair Poll(std::vector& pollfds, s32 timeout) { std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) { WSAPOLLFD result; result.fd = fd.socket->fd; - result.events = static_cast(TranslatePollEvents(fd.events)); + result.events = TranslatePollEvents(fd.events); result.revents = 0; return result; }); @@ -501,12 +499,12 @@ Errno Socket::Shutdown(ShutdownHow how) { } } -std::pair Socket::Recv(u32 flags, std::vector& message) { +std::pair Socket::Recv(int flags, std::vector& message) { ASSERT(flags == 0); ASSERT(message.size() < static_cast(std::numeric_limits::max())); - const auto result = recv(fd, reinterpret_cast(message.data()), - static_cast(message.size()), 0); + const auto result = + recv(fd, reinterpret_cast(message.data()), static_cast(message.size()), 0); if (result != SOCKET_ERROR) { return {static_cast(result), Errno::SUCCESS}; } @@ -524,7 +522,7 @@ std::pair Socket::Recv(u32 flags, std::vector& message) { } } -std::pair Socket::RecvFrom(u32 flags, std::vector& message, SockAddrIn* addr) { +std::pair Socket::RecvFrom(int flags, std::vector& message, SockAddrIn* addr) { ASSERT(flags == 0); ASSERT(message.size() < static_cast(std::numeric_limits::max())); @@ -534,7 +532,7 @@ std::pair Socket::RecvFrom(u32 flags, std::vector& message, Sock sockaddr* const p_addr_in = addr ? &addr_in : nullptr; const auto result = recvfrom(fd, reinterpret_cast(message.data()), - static_cast(message.size()), 0, p_addr_in, p_addrlen); + static_cast(message.size()), 0, p_addr_in, p_addrlen); if (result != SOCKET_ERROR) { if (addr) { ASSERT(addrlen == sizeof(addr_in)); @@ -556,12 +554,12 @@ std::pair Socket::RecvFrom(u32 flags, std::vector& message, Sock } } -std::pair Socket::Send(const std::vector& message, u32 flags) { +std::pair Socket::Send(const std::vector& message, int flags) { ASSERT(message.size() < static_cast(std::numeric_limits::max())); ASSERT(flags == 0); const auto result = send(fd, reinterpret_cast(message.data()), - static_cast(message.size()), 0); + static_cast(message.size()), 0); if (result != SOCKET_ERROR) { return {static_cast(result), Errno::SUCCESS}; } @@ -593,9 +591,8 @@ std::pair Socket::SendTo(u32 flags, const std::vector& message, to = &host_addr_in; } - const auto result = - sendto(fd, reinterpret_cast(message.data()), - static_cast(message.size()), 0, to, static_cast(tolen)); + const auto result = sendto(fd, reinterpret_cast(message.data()), + static_cast(message.size()), 0, to, tolen); if (result != SOCKET_ERROR) { return {static_cast(result), Errno::SUCCESS}; } diff --git a/src/core/network/network.h b/src/core/network/network.h index b95bf68f8..0622e4593 100644 --- a/src/core/network/network.h +++ b/src/core/network/network.h @@ -67,12 +67,12 @@ struct PollFD { u16 revents; }; -constexpr u32 POLL_IN = 1 << 0; -constexpr u32 POLL_PRI = 1 << 1; -constexpr u32 POLL_OUT = 1 << 2; -constexpr u32 POLL_ERR = 1 << 3; -constexpr u32 POLL_HUP = 1 << 4; -constexpr u32 POLL_NVAL = 1 << 5; +constexpr u16 POLL_IN = 1 << 0; +constexpr u16 POLL_PRI = 1 << 1; +constexpr u16 POLL_OUT = 1 << 2; +constexpr u16 POLL_ERR = 1 << 3; +constexpr u16 POLL_HUP = 1 << 4; +constexpr u16 POLL_NVAL = 1 << 5; class NetworkInstance { public: diff --git a/src/core/network/sockets.h b/src/core/network/sockets.h index 1682cbd4e..7bdff0fe4 100644 --- a/src/core/network/sockets.h +++ b/src/core/network/sockets.h @@ -56,11 +56,11 @@ public: Errno Shutdown(ShutdownHow how); - std::pair Recv(u32 flags, std::vector& message); + std::pair Recv(int flags, std::vector& message); - std::pair RecvFrom(u32 flags, std::vector& message, SockAddrIn* addr); + std::pair RecvFrom(int flags, std::vector& message, SockAddrIn* addr); - std::pair Send(const std::vector& message, u32 flags); + std::pair Send(const std::vector& message, int flags); std::pair SendTo(u32 flags, const std::vector& message, const SockAddrIn* addr); -- cgit v1.2.3 From 7b642c77811dc3887756f5abac5a9710564b098e Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 13 Nov 2020 11:11:12 -0800 Subject: hle: kernel: multicore: Replace n-JITs impl. with 4 JITs. --- src/core/arm/arm_interface.h | 3 +++ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 4 ++++ src/core/arm/dynarmic/arm_dynarmic_32.h | 1 + src/core/arm/dynarmic/arm_dynarmic_64.cpp | 4 ++++ src/core/arm/dynarmic/arm_dynarmic_64.h | 1 + src/core/core.cpp | 13 ++++------- src/core/cpu_manager.cpp | 16 +++++++------ src/core/hle/kernel/kernel.cpp | 23 ++++++++++++++----- src/core/hle/kernel/kernel.h | 3 +++ src/core/hle/kernel/physical_core.cpp | 38 ++++++++++++++++++++++++------- src/core/hle/kernel/physical_core.h | 29 +++++++++++++++++++---- src/core/hle/kernel/scheduler.cpp | 20 +++++++++------- src/core/hle/kernel/svc.cpp | 9 ++++++++ src/core/hle/kernel/thread.cpp | 27 ++-------------------- src/core/hle/kernel/thread.h | 5 ---- 15 files changed, 124 insertions(+), 72 deletions(-) (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 1f24051e4..b3d8ceaf8 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -64,6 +64,9 @@ public: /// Step CPU by one instruction virtual void Step() = 0; + /// Exits execution from a callback, the callback must rewind the stack + virtual void ExceptionalExit() = 0; + /// Clear all instruction cache virtual void ClearInstructionCache() = 0; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 6dc03f3b1..af23206f5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -189,6 +189,10 @@ void ARM_Dynarmic_32::Run() { jit->Run(); } +void ARM_Dynarmic_32::ExceptionalExit() { + jit->ExceptionalExit(); +} + void ARM_Dynarmic_32::Step() { jit->Step(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 2bab31b92..e16b689c8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -42,6 +42,7 @@ public: u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; void Run() override; + void ExceptionalExit() override; void Step() override; VAddr GetTlsAddress() const override; void SetTlsAddress(VAddr address) override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 5c2060d78..1c9fd18b5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -220,6 +220,10 @@ void ARM_Dynarmic_64::Run() { jit->Run(); } +void ARM_Dynarmic_64::ExceptionalExit() { + jit->ExceptionalExit(); +} + void ARM_Dynarmic_64::Step() { cb->InterpreterFallback(jit->GetPC(), 1); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 28e11a17d..aa0a5c424 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -40,6 +40,7 @@ public: void SetPSTATE(u32 pstate) override; void Run() override; void Step() override; + void ExceptionalExit() override; VAddr GetTlsAddress() const override; void SetTlsAddress(VAddr address) override; void SetTPIDR_EL0(u64 value) override; diff --git a/src/core/core.cpp b/src/core/core.cpp index 76a38ea2a..58368fe3c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -245,6 +245,7 @@ struct System::Impl { } AddGlueRegistrationForProcess(*app_loader, *main_process); kernel.MakeCurrentProcess(main_process.get()); + kernel.InitializeCores(); // Initialize cheat engine if (cheat_engine) { @@ -490,11 +491,11 @@ const TelemetrySession& System::TelemetrySession() const { } ARM_Interface& System::CurrentArmInterface() { - return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); + return impl->kernel.CurrentPhysicalCore().ArmInterface(); } const ARM_Interface& System::CurrentArmInterface() const { - return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); + return impl->kernel.CurrentPhysicalCore().ArmInterface(); } std::size_t System::CurrentCoreIndex() const { @@ -554,15 +555,11 @@ const Kernel::Process* System::CurrentProcess() const { } ARM_Interface& System::ArmInterface(std::size_t core_index) { - auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); - ASSERT(thread && !thread->IsHLEThread()); - return thread->ArmInterface(); + return impl->kernel.PhysicalCore(core_index).ArmInterface(); } const ARM_Interface& System::ArmInterface(std::size_t core_index) const { - auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); - ASSERT(thread && !thread->IsHLEThread()); - return thread->ArmInterface(); + return impl->kernel.PhysicalCore(core_index).ArmInterface(); } ExclusiveMonitor& System::Monitor() { diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index eeeb6e8df..0cff985e9 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -113,22 +113,23 @@ void CpuManager::MultiCoreRunGuestThread() { auto& sched = kernel.CurrentScheduler(); sched.OnThreadStart(); } + auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + auto& host_context = thread->GetHostContext(); + host_context->SetRewindPoint(GuestRewindFunction, this); MultiCoreRunGuestLoop(); } void CpuManager::MultiCoreRunGuestLoop() { auto& kernel = system.Kernel(); - auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - auto& arm_interface = thread->ArmInterface(); system.EnterDynarmicProfile(); while (!physical_core->IsInterrupted()) { - arm_interface.Run(); + physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } system.ExitDynarmicProfile(); - arm_interface.ClearExclusiveState(); auto& scheduler = kernel.CurrentScheduler(); scheduler.TryDoContextSwitch(); } @@ -209,6 +210,9 @@ void CpuManager::SingleCoreRunGuestThread() { auto& sched = kernel.CurrentScheduler(); sched.OnThreadStart(); } + auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + auto& host_context = thread->GetHostContext(); + host_context->SetRewindPoint(GuestRewindFunction, this); SingleCoreRunGuestLoop(); } @@ -217,17 +221,15 @@ void CpuManager::SingleCoreRunGuestLoop() { auto* thread = kernel.CurrentScheduler().GetCurrentThread(); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - auto& arm_interface = thread->ArmInterface(); system.EnterDynarmicProfile(); if (!physical_core->IsInterrupted()) { - arm_interface.Run(); + physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } system.ExitDynarmicProfile(); thread->SetPhantomMode(true); system.CoreTiming().Advance(); thread->SetPhantomMode(false); - arm_interface.ClearExclusiveState(); PreemptSingleCore(); auto& scheduler = kernel.Scheduler(current_core); scheduler.TryDoContextSwitch(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index bb3e312a7..4cf9cee42 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -68,6 +68,12 @@ struct KernelCore::Impl { InitializeSuspendThreads(); } + void InitializeCores() { + for (auto& core : cores) { + core.Initialize(current_process->Is64BitProcess()); + } + } + void Shutdown() { next_object_id = 0; next_kernel_process_id = Process::InitialKIPIDMin; @@ -116,7 +122,7 @@ struct KernelCore::Impl { Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { schedulers[i] = std::make_unique(system, i); - cores.emplace_back(system, i, *schedulers[i], interrupts[i]); + cores.emplace_back(i, system, *schedulers[i], interrupts); } } @@ -181,6 +187,7 @@ struct KernelCore::Impl { if (process == nullptr) { return; } + const u32 core_id = GetCurrentHostThreadID(); if (core_id < Core::Hardware::NUM_CPU_CORES) { system.Memory().SetCurrentPageTable(*process, core_id); @@ -372,6 +379,10 @@ void KernelCore::Initialize() { impl->Initialize(*this); } +void KernelCore::InitializeCores() { + impl->InitializeCores(); +} + void KernelCore::Shutdown() { impl->Shutdown(); } @@ -486,12 +497,12 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { } void KernelCore::InvalidateAllInstructionCaches() { - auto& threads = GlobalScheduler().GetThreadList(); - for (auto& thread : threads) { - if (!thread->IsHLEThread()) { - auto& arm_interface = thread->ArmInterface(); - arm_interface.ClearInstructionCache(); + if (!IsMulticore()) { + for (auto& physical_core : impl->cores) { + physical_core.ArmInterface().ClearInstructionCache(); } + } else { + ASSERT_MSG(false, "UNIMPLEMENTED!!!!!!!!!!!"); } } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 16285c3f0..a9fdc5860 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -74,6 +74,9 @@ public: /// Resets the kernel to a clean slate for use. void Initialize(); + /// Initializes the CPU cores. + void InitializeCores(); + /// Clears all resources in use by the kernel instance. void Shutdown(); diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index 6e04d025f..50aca5752 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -4,21 +4,43 @@ #include "common/spin_lock.h" #include "core/arm/cpu_interrupt_handler.h" +#include "core/arm/dynarmic/arm_dynarmic_32.h" +#include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/core.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/scheduler.h" namespace Kernel { -PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, - Core::CPUInterruptHandler& interrupt_handler) - : interrupt_handler{interrupt_handler}, - core_index{id}, scheduler{scheduler}, guard{std::make_unique()} {} +PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, + Kernel::Scheduler& scheduler, Core::CPUInterrupts& interrupts) + : core_index{core_index}, system{system}, scheduler{scheduler}, + interrupts{interrupts}, guard{std::make_unique()} {} PhysicalCore::~PhysicalCore() = default; +void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) { +#ifdef ARCHITECTURE_x86_64 + auto& kernel = system.Kernel(); + if (is_64_bit) { + arm_interface = std::make_unique( + system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); + } else { + arm_interface = std::make_unique( + system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); + } +#else +#error Platform not supported yet. +#endif +} + +void PhysicalCore::Run() { + arm_interface->Run(); +} + void PhysicalCore::Idle() { - interrupt_handler.AwaitInterrupt(); + interrupts[core_index].AwaitInterrupt(); } void PhysicalCore::Shutdown() { @@ -26,18 +48,18 @@ void PhysicalCore::Shutdown() { } bool PhysicalCore::IsInterrupted() const { - return interrupt_handler.IsInterrupted(); + return interrupts[core_index].IsInterrupted(); } void PhysicalCore::Interrupt() { guard->lock(); - interrupt_handler.SetInterrupt(true); + interrupts[core_index].SetInterrupt(true); guard->unlock(); } void PhysicalCore::ClearInterrupt() { guard->lock(); - interrupt_handler.SetInterrupt(false); + interrupts[core_index].SetInterrupt(false); guard->unlock(); } diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index d7a7a951c..ace058a5a 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -4,9 +4,12 @@ #pragma once +#include #include #include +#include "core/arm/arm_interface.h" + namespace Common { class SpinLock; } @@ -16,7 +19,6 @@ class Scheduler; } // namespace Kernel namespace Core { -class ARM_Interface; class CPUInterruptHandler; class ExclusiveMonitor; class System; @@ -26,8 +28,8 @@ namespace Kernel { class PhysicalCore { public: - PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, - Core::CPUInterruptHandler& interrupt_handler); + PhysicalCore(std::size_t core_index, Core::System& system, Kernel::Scheduler& scheduler, + Core::CPUInterrupts& interrupts); ~PhysicalCore(); PhysicalCore(const PhysicalCore&) = delete; @@ -36,7 +38,14 @@ public: PhysicalCore(PhysicalCore&&) = default; PhysicalCore& operator=(PhysicalCore&&) = default; + /// Initialize the core for the specified parameters. + void Initialize(bool is_64_bit); + + /// Execute current jit state + void Run(); + void Idle(); + /// Interrupt this physical core. void Interrupt(); @@ -49,6 +58,14 @@ public: // Shutdown this physical core. void Shutdown(); + Core::ARM_Interface& ArmInterface() { + return *arm_interface; + } + + const Core::ARM_Interface& ArmInterface() const { + return *arm_interface; + } + bool IsMainCore() const { return core_index == 0; } @@ -70,10 +87,12 @@ public: } private: - Core::CPUInterruptHandler& interrupt_handler; - std::size_t core_index; + const std::size_t core_index; + Core::System& system; Kernel::Scheduler& scheduler; + Core::CPUInterrupts& interrupts; std::unique_ptr guard; + std::unique_ptr arm_interface; }; } // namespace Kernel diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 6b7db5372..0805e9914 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -621,11 +621,14 @@ void Scheduler::OnThreadStart() { void Scheduler::Unload() { Thread* thread = current_thread.get(); if (thread) { - thread->SetContinuousOnSVC(false); thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); thread->SetIsRunning(false); + if (thread->IsContinuousOnSVC() && !thread->IsHLEThread()) { + system.ArmInterface(core_id).ExceptionalExit(); + thread->SetContinuousOnSVC(false); + } if (!thread->IsHLEThread() && !thread->HasExited()) { - Core::ARM_Interface& cpu_core = thread->ArmInterface(); + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); cpu_core.SaveContext(thread->GetContext32()); cpu_core.SaveContext(thread->GetContext64()); // Save the TPIDR_EL0 system register in case it was modified. @@ -652,12 +655,11 @@ void Scheduler::Reload() { system.Kernel().MakeCurrentProcess(thread_owner_process); } if (!thread->IsHLEThread()) { - Core::ARM_Interface& cpu_core = thread->ArmInterface(); + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); cpu_core.LoadContext(thread->GetContext32()); cpu_core.LoadContext(thread->GetContext64()); cpu_core.SetTlsAddress(thread->GetTLSAddress()); cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); - cpu_core.ChangeProcessorID(this->core_id); cpu_core.ClearExclusiveState(); } } @@ -679,12 +681,11 @@ void Scheduler::SwitchContextStep2() { system.Kernel().MakeCurrentProcess(thread_owner_process); } if (!selected_thread->IsHLEThread()) { - Core::ARM_Interface& cpu_core = selected_thread->ArmInterface(); + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); cpu_core.LoadContext(selected_thread->GetContext32()); cpu_core.LoadContext(selected_thread->GetContext64()); cpu_core.SetTlsAddress(selected_thread->GetTLSAddress()); cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0()); - cpu_core.ChangeProcessorID(this->core_id); cpu_core.ClearExclusiveState(); } } @@ -715,11 +716,14 @@ void Scheduler::SwitchContext() { if (new_thread != nullptr && new_thread->IsSuspendThread()) { previous_thread->SetWasRunning(true); } - previous_thread->SetContinuousOnSVC(false); previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); previous_thread->SetIsRunning(false); + if (previous_thread->IsContinuousOnSVC() && !previous_thread->IsHLEThread()) { + system.ArmInterface(core_id).ExceptionalExit(); + previous_thread->SetContinuousOnSVC(false); + } if (!previous_thread->IsHLEThread() && !previous_thread->HasExited()) { - Core::ARM_Interface& cpu_core = previous_thread->ArmInterface(); + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); cpu_core.SaveContext(previous_thread->GetContext32()); cpu_core.SaveContext(previous_thread->GetContext64()); // Save the TPIDR_EL0 system register in case it was modified. diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e3b770d66..95d6e2b4d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -2639,6 +2639,9 @@ void Call(Core::System& system, u32 immediate) { auto& kernel = system.Kernel(); kernel.EnterSVCProfile(); + auto* thread = system.CurrentScheduler().GetCurrentThread(); + thread->SetContinuousOnSVC(true); + const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) : GetSVCInfo32(immediate); if (info) { @@ -2652,6 +2655,12 @@ void Call(Core::System& system, u32 immediate) { } kernel.ExitSVCProfile(); + + if (!thread->IsContinuousOnSVC()) { + auto* host_context = thread->GetHostContext().get(); + host_context->Rewind(); + } + system.EnterDynarmicProfile(); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index da0cb26b6..3abe12810 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -12,7 +12,6 @@ #include "common/fiber.h" #include "common/logging/log.h" #include "common/thread_queue_list.h" -#include "core/arm/arm_interface.h" #include "core/core.h" #include "core/cpu_manager.h" #include "core/hardware_properties.h" @@ -62,7 +61,6 @@ void Thread::Stop() { // Mark the TLS slot in the thread's page as free. owner_process->FreeTLSRegion(tls_address); } - arm_interface.reset(); has_exited = true; } global_handle = 0; @@ -217,22 +215,9 @@ ResultVal> Thread::Create(Core::System& system, ThreadTy thread->tls_address = 0; } - thread->arm_interface.reset(); + // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used + // to initialize the context if ((type_flags & THREADTYPE_HLE) == 0) { -#ifdef ARCHITECTURE_x86_64 - if (owner_process && !owner_process->Is64BitProcess()) { - thread->arm_interface = std::make_unique( - system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(), - processor_id); - } else { - thread->arm_interface = std::make_unique( - system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(), - processor_id); - } -#else -#error Platform not supported yet. -#endif - ResetThreadContext32(thread->context_32, static_cast(stack_top), static_cast(entry_point), static_cast(arg)); ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); @@ -268,14 +253,6 @@ VAddr Thread::GetCommandBufferAddress() const { return GetTLSAddress() + command_header_offset; } -Core::ARM_Interface& Thread::ArmInterface() { - return *arm_interface; -} - -const Core::ARM_Interface& Thread::ArmInterface() const { - return *arm_interface; -} - void Thread::SetStatus(ThreadStatus new_status) { if (new_status == status) { return; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 8daf79fac..20e86fb81 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -248,10 +248,6 @@ public: void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); - Core::ARM_Interface& ArmInterface(); - - const Core::ARM_Interface& ArmInterface() const; - SynchronizationObject* GetSignalingObject() const { return signaling_object; } @@ -586,7 +582,6 @@ private: Common::SpinLock context_guard{}; ThreadContext32 context_32{}; ThreadContext64 context_64{}; - std::unique_ptr arm_interface{}; std::shared_ptr host_context{}; u64 thread_id = 0; -- cgit v1.2.3 From 63fd1bb50302867b233325f253b1e2abbc379875 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 13 Nov 2020 23:20:32 -0800 Subject: core: arm: Implement InvalidateCacheRange for CPU cache invalidation. --- src/core/arm/arm_interface.h | 19 +++++++++++++------ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 7 +++++++ src/core/arm/dynarmic/arm_dynarmic_32.h | 1 + src/core/arm/dynarmic/arm_dynarmic_64.cpp | 7 +++++++ src/core/arm/dynarmic/arm_dynarmic_64.h | 1 + src/core/core.cpp | 4 ++++ src/core/core.h | 2 ++ src/core/hle/kernel/kernel.cpp | 15 ++++++++++----- src/core/hle/kernel/kernel.h | 2 ++ src/core/hle/kernel/memory/page_table.cpp | 5 +++++ src/core/hle/kernel/physical_core.h | 4 ++++ src/core/hle/service/ldr/ldr.cpp | 5 ----- 12 files changed, 56 insertions(+), 16 deletions(-) (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index b3d8ceaf8..70098c526 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -70,12 +70,19 @@ public: /// Clear all instruction cache virtual void ClearInstructionCache() = 0; - /// Notifies CPU emulation that the current page table has changed. - /// - /// @param new_page_table The new page table. - /// @param new_address_space_size_in_bits The new usable size of the address space in bits. - /// This can be either 32, 36, or 39 on official software. - /// + /** + * Clear instruction cache range + * @param addr Start address of the cache range to clear + * @param size Size of the cache range to clear, starting at addr + */ + virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0; + + /** + * Notifies CPU emulation that the current page table has changed. + * @param new_page_table The new page table. + * @param new_address_space_size_in_bits The new usable size of the address space in bits. + * This can be either 32, 36, or 39 on official software. + */ virtual void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) = 0; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index af23206f5..193fd7d62 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -286,6 +286,13 @@ void ARM_Dynarmic_32::ClearInstructionCache() { jit->ClearCache(); } +void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) { + if (!jit) { + return; + } + jit->InvalidateCacheRange(static_cast(addr), size); +} + void ARM_Dynarmic_32::ClearExclusiveState() { jit->ClearExclusiveState(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index e16b689c8..35e9ced48 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -59,6 +59,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; + void InvalidateCacheRange(VAddr addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 1c9fd18b5..0f0585d0f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -322,6 +322,13 @@ void ARM_Dynarmic_64::ClearInstructionCache() { jit->ClearCache(); } +void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) { + if (!jit) { + return; + } + jit->InvalidateCacheRange(addr, size); +} + void ARM_Dynarmic_64::ClearExclusiveState() { jit->ClearExclusiveState(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index aa0a5c424..329b59a32 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -56,6 +56,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; + void InvalidateCacheRange(VAddr addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; diff --git a/src/core/core.cpp b/src/core/core.cpp index 58368fe3c..01e4faac8 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -457,6 +457,10 @@ void System::InvalidateCpuInstructionCaches() { impl->kernel.InvalidateAllInstructionCaches(); } +void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { + impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); +} + void System::Shutdown() { impl->Shutdown(); } diff --git a/src/core/core.h b/src/core/core.h index f642befc0..29b8fb92a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -166,6 +166,8 @@ public: */ void InvalidateCpuInstructionCaches(); + void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); + /// Shutdown the emulated system. void Shutdown(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index c426b6378..929db696d 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -497,12 +497,17 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { } void KernelCore::InvalidateAllInstructionCaches() { - if (!IsMulticore()) { - for (auto& physical_core : impl->cores) { - physical_core.ArmInterface().ClearInstructionCache(); + for (auto& physical_core : impl->cores) { + physical_core.ArmInterface().ClearInstructionCache(); + } +} + +void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { + for (auto& physical_core : impl->cores) { + if (!physical_core.IsInitialized()) { + continue; } - } else { - UNIMPLEMENTED(); + physical_core.ArmInterface().InvalidateCacheRange(addr, size); } } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a9fdc5860..a73a93039 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -156,6 +156,8 @@ public: void InvalidateAllInstructionCaches(); + void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); + /// Adds a port to the named port table void AddNamedPort(std::string name, std::shared_ptr port); diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index a3fadb533..f53a7be82 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -670,6 +670,11 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo return RESULT_SUCCESS; } + if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) { + // Memory execution state is changing, invalidate CPU cache range + system.InvalidateCpuInstructionCacheRange(addr, size); + } + const std::size_t num_pages{size / PageSize}; const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None ? OperationType::ChangePermissionsAndRefresh diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index ace058a5a..37513130a 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -58,6 +58,10 @@ public: // Shutdown this physical core. void Shutdown(); + bool IsInitialized() const { + return arm_interface != nullptr; + } + Core::ARM_Interface& ArmInterface() { return *arm_interface; } diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index fff68326b..9da786b4e 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -527,9 +527,6 @@ public: header.segment_headers[RO_INDEX].memory_size, header.segment_headers[DATA_INDEX].memory_size, nro_address}); - // Invalidate JIT caches for the newly mapped process code - system.InvalidateCpuInstructionCaches(); - IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(*map_result); @@ -590,8 +587,6 @@ public: const auto result{UnmapNro(iter->second)}; - system.InvalidateCpuInstructionCaches(); - nro.erase(iter); IPC::ResponseBuilder rb{ctx, 2}; -- cgit v1.2.3 From 9e29e36a784496f7290c03b6a42e400a164a5b1e Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 2 Dec 2020 18:08:35 -0800 Subject: hle: kernel: Rewrite scheduler implementation based on Mesopshere. --- src/core/CMakeLists.txt | 4 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 2 +- src/core/core.cpp | 26 +- src/core/core.h | 20 +- src/core/cpu_manager.cpp | 55 +- src/core/hle/kernel/address_arbiter.cpp | 6 +- src/core/hle/kernel/handle_table.cpp | 4 +- src/core/hle/kernel/hle_ipc.cpp | 2 +- src/core/hle/kernel/k_scheduler.cpp | 873 ++++++++++++++++++++++++++++++ src/core/hle/kernel/k_scheduler.h | 297 ++++++++++ src/core/hle/kernel/kernel.cpp | 59 +- src/core/hle/kernel/kernel.h | 17 +- src/core/hle/kernel/mutex.cpp | 6 +- src/core/hle/kernel/physical_core.cpp | 9 +- src/core/hle/kernel/physical_core.h | 13 +- src/core/hle/kernel/process.cpp | 6 +- src/core/hle/kernel/readable_event.cpp | 2 +- src/core/hle/kernel/scheduler.cpp | 819 ---------------------------- src/core/hle/kernel/scheduler.h | 320 ----------- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/svc.cpp | 57 +- src/core/hle/kernel/synchronization.cpp | 4 +- src/core/hle/kernel/thread.cpp | 50 +- src/core/hle/kernel/thread.h | 107 +++- src/core/hle/kernel/time_manager.cpp | 2 +- src/core/hle/service/time/time.cpp | 2 +- src/yuzu/debugger/wait_tree.cpp | 6 +- 27 files changed, 1381 insertions(+), 1389 deletions(-) create mode 100644 src/core/hle/kernel/k_scheduler.cpp create mode 100644 src/core/hle/kernel/k_scheduler.h delete mode 100644 src/core/hle/kernel/scheduler.cpp delete mode 100644 src/core/hle/kernel/scheduler.h (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2e60a8331..662839ff8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -154,6 +154,8 @@ add_library(core STATIC hle/kernel/hle_ipc.h hle/kernel/k_affinity_mask.h hle/kernel/k_priority_queue.h + hle/kernel/k_scheduler.cpp + hle/kernel/k_scheduler.h hle/kernel/k_scheduler_lock.h hle/kernel/kernel.cpp hle/kernel/kernel.h @@ -189,8 +191,6 @@ add_library(core STATIC hle/kernel/readable_event.h hle/kernel/resource_limit.cpp hle/kernel/resource_limit.h - hle/kernel/scheduler.cpp - hle/kernel/scheduler.h hle/kernel/server_port.cpp hle/kernel/server_port.h hle/kernel/server_session.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index b63f79915..7a4eb88a2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -15,8 +15,8 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" #include "core/settings.h" diff --git a/src/core/core.cpp b/src/core/core.cpp index 01e4faac8..77d21d41c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -27,10 +27,10 @@ #include "core/file_sys/vfs_real.h" #include "core/hardware_interrupt_manager.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/apm/controller.h" @@ -508,14 +508,6 @@ std::size_t System::CurrentCoreIndex() const { return core; } -Kernel::Scheduler& System::CurrentScheduler() { - return impl->kernel.CurrentScheduler(); -} - -const Kernel::Scheduler& System::CurrentScheduler() const { - return impl->kernel.CurrentScheduler(); -} - Kernel::PhysicalCore& System::CurrentPhysicalCore() { return impl->kernel.CurrentPhysicalCore(); } @@ -524,22 +516,14 @@ const Kernel::PhysicalCore& System::CurrentPhysicalCore() const { return impl->kernel.CurrentPhysicalCore(); } -Kernel::Scheduler& System::Scheduler(std::size_t core_index) { - return impl->kernel.Scheduler(core_index); -} - -const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { - return impl->kernel.Scheduler(core_index); -} - /// Gets the global scheduler -Kernel::GlobalScheduler& System::GlobalScheduler() { - return impl->kernel.GlobalScheduler(); +Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() { + return impl->kernel.GlobalSchedulerContext(); } /// Gets the global scheduler -const Kernel::GlobalScheduler& System::GlobalScheduler() const { - return impl->kernel.GlobalScheduler(); +const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const { + return impl->kernel.GlobalSchedulerContext(); } Kernel::Process* System::CurrentProcess() { diff --git a/src/core/core.h b/src/core/core.h index 29b8fb92a..579a774e4 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -26,11 +26,11 @@ class VfsFilesystem; } // namespace FileSys namespace Kernel { -class GlobalScheduler; +class GlobalSchedulerContext; class KernelCore; class PhysicalCore; class Process; -class Scheduler; +class KScheduler; } // namespace Kernel namespace Loader { @@ -213,12 +213,6 @@ public: /// Gets the index of the currently running CPU core [[nodiscard]] std::size_t CurrentCoreIndex() const; - /// Gets the scheduler for the CPU core that is currently running - [[nodiscard]] Kernel::Scheduler& CurrentScheduler(); - - /// Gets the scheduler for the CPU core that is currently running - [[nodiscard]] const Kernel::Scheduler& CurrentScheduler() const; - /// Gets the physical core for the CPU core that is currently running [[nodiscard]] Kernel::PhysicalCore& CurrentPhysicalCore(); @@ -261,17 +255,11 @@ public: /// Gets an immutable reference to the renderer. [[nodiscard]] const VideoCore::RendererBase& Renderer() const; - /// Gets the scheduler for the CPU core with the specified index - [[nodiscard]] Kernel::Scheduler& Scheduler(std::size_t core_index); - - /// Gets the scheduler for the CPU core with the specified index - [[nodiscard]] const Kernel::Scheduler& Scheduler(std::size_t core_index) const; - /// Gets the global scheduler - [[nodiscard]] Kernel::GlobalScheduler& GlobalScheduler(); + [[nodiscard]] Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); /// Gets the global scheduler - [[nodiscard]] const Kernel::GlobalScheduler& GlobalScheduler() const; + [[nodiscard]] const Kernel::GlobalSchedulerContext& GlobalSchedulerContext() const; /// Gets the manager for the guest device memory [[nodiscard]] Core::DeviceMemory& DeviceMemory(); diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 0cff985e9..179154348 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -10,9 +10,9 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/cpu_manager.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "video_core/gpu.h" @@ -109,11 +109,8 @@ void* CpuManager::GetStartFuncParamater() { void CpuManager::MultiCoreRunGuestThread() { auto& kernel = system.Kernel(); - { - auto& sched = kernel.CurrentScheduler(); - sched.OnThreadStart(); - } - auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + kernel.CurrentScheduler()->OnThreadStart(); + auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); auto& host_context = thread->GetHostContext(); host_context->SetRewindPoint(GuestRewindFunction, this); MultiCoreRunGuestLoop(); @@ -130,8 +127,8 @@ void CpuManager::MultiCoreRunGuestLoop() { physical_core = &kernel.CurrentPhysicalCore(); } system.ExitDynarmicProfile(); - auto& scheduler = kernel.CurrentScheduler(); - scheduler.TryDoContextSwitch(); + physical_core->ArmInterface().ClearExclusiveState(); + kernel.CurrentScheduler()->RescheduleCurrentCore(); } } @@ -140,25 +137,21 @@ void CpuManager::MultiCoreRunIdleThread() { while (true) { auto& physical_core = kernel.CurrentPhysicalCore(); physical_core.Idle(); - auto& scheduler = kernel.CurrentScheduler(); - scheduler.TryDoContextSwitch(); + kernel.CurrentScheduler()->RescheduleCurrentCore(); } } void CpuManager::MultiCoreRunSuspendThread() { auto& kernel = system.Kernel(); - { - auto& sched = kernel.CurrentScheduler(); - sched.OnThreadStart(); - } + kernel.CurrentScheduler()->OnThreadStart(); while (true) { auto core = kernel.GetCurrentHostThreadID(); - auto& scheduler = kernel.CurrentScheduler(); + auto& scheduler = *kernel.CurrentScheduler(); Kernel::Thread* current_thread = scheduler.GetCurrentThread(); Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[core].host_context); ASSERT(scheduler.ContextSwitchPending()); ASSERT(core == kernel.GetCurrentHostThreadID()); - scheduler.TryDoContextSwitch(); + scheduler.RescheduleCurrentCore(); } } @@ -206,11 +199,8 @@ void CpuManager::MultiCorePause(bool paused) { void CpuManager::SingleCoreRunGuestThread() { auto& kernel = system.Kernel(); - { - auto& sched = kernel.CurrentScheduler(); - sched.OnThreadStart(); - } - auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + kernel.CurrentScheduler()->OnThreadStart(); + auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); auto& host_context = thread->GetHostContext(); host_context->SetRewindPoint(GuestRewindFunction, this); SingleCoreRunGuestLoop(); @@ -218,7 +208,7 @@ void CpuManager::SingleCoreRunGuestThread() { void CpuManager::SingleCoreRunGuestLoop() { auto& kernel = system.Kernel(); - auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); system.EnterDynarmicProfile(); @@ -230,9 +220,10 @@ void CpuManager::SingleCoreRunGuestLoop() { thread->SetPhantomMode(true); system.CoreTiming().Advance(); thread->SetPhantomMode(false); + physical_core->ArmInterface().ClearExclusiveState(); PreemptSingleCore(); auto& scheduler = kernel.Scheduler(current_core); - scheduler.TryDoContextSwitch(); + scheduler.RescheduleCurrentCore(); } } @@ -244,24 +235,21 @@ void CpuManager::SingleCoreRunIdleThread() { system.CoreTiming().AddTicks(1000U); idle_count++; auto& scheduler = physical_core.Scheduler(); - scheduler.TryDoContextSwitch(); + scheduler.RescheduleCurrentCore(); } } void CpuManager::SingleCoreRunSuspendThread() { auto& kernel = system.Kernel(); - { - auto& sched = kernel.CurrentScheduler(); - sched.OnThreadStart(); - } + kernel.CurrentScheduler()->OnThreadStart(); while (true) { auto core = kernel.GetCurrentHostThreadID(); - auto& scheduler = kernel.CurrentScheduler(); + auto& scheduler = *kernel.CurrentScheduler(); Kernel::Thread* current_thread = scheduler.GetCurrentThread(); Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context); ASSERT(scheduler.ContextSwitchPending()); ASSERT(core == kernel.GetCurrentHostThreadID()); - scheduler.TryDoContextSwitch(); + scheduler.RescheduleCurrentCore(); } } @@ -280,12 +268,12 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) { } current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); system.CoreTiming().ResetTicks(); - scheduler.Unload(); + scheduler.Unload(scheduler.GetCurrentThread()); auto& next_scheduler = system.Kernel().Scheduler(current_core); Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); /// May have changed scheduler auto& current_scheduler = system.Kernel().Scheduler(current_core); - current_scheduler.Reload(); + current_scheduler.Reload(scheduler.GetCurrentThread()); auto* currrent_thread2 = current_scheduler.GetCurrentThread(); if (!currrent_thread2->IsIdleThread()) { idle_count = 0; @@ -369,8 +357,7 @@ void CpuManager::RunThread(std::size_t core) { return; } - auto& scheduler = system.Kernel().CurrentScheduler(); - Kernel::Thread* current_thread = scheduler.GetCurrentThread(); + auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); data.is_running = true; Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext()); data.is_running = false; diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 048acd30e..bc32be18b 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -12,8 +12,8 @@ #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/result.h" @@ -153,7 +153,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 bool should_decrement) { auto& memory = system.Memory(); auto& kernel = system.Kernel(); - Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); + Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread(); Handle event_handle = InvalidHandle; { @@ -223,7 +223,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { auto& memory = system.Memory(); auto& kernel = system.Kernel(); - Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); + Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread(); Handle event_handle = InvalidHandle; { diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 3e745c18b..40988b0fd 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -8,9 +8,9 @@ #include "core/core.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" namespace Kernel { @@ -105,7 +105,7 @@ bool HandleTable::IsValid(Handle handle) const { std::shared_ptr HandleTable::GetGeneric(Handle handle) const { if (handle == CurrentThread) { - return SharedFrom(kernel.CurrentScheduler().GetCurrentThread()); + return SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); } else if (handle == CurrentProcess) { return SharedFrom(kernel.CurrentProcess()); } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 81f85643b..7eda89786 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -17,11 +17,11 @@ #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/time_manager.h" diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp new file mode 100644 index 000000000..7f7da610d --- /dev/null +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -0,0 +1,873 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/bit_util.h" +#include "common/fiber.h" +#include "common/logging/log.h" +#include "core/arm/arm_interface.h" +#include "core/core.h" +#include "core/core_timing.h" +#include "core/cpu_manager.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/physical_core.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/time_manager.h" + +namespace Kernel { + +static void IncrementScheduledCount(Kernel::Thread* thread) { + if (auto process = thread->GetOwnerProcess(); process) { + process->IncrementScheduledCount(); + } +} + +GlobalSchedulerContext::GlobalSchedulerContext(KernelCore& kernel) + : kernel{kernel}, scheduler_lock{kernel} {} + +GlobalSchedulerContext::~GlobalSchedulerContext() = default; + +/*static*/ void KScheduler::RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedule, + Core::EmuThreadHandle global_thread) { + u32 current_core = global_thread.host_handle; + bool must_context_switch = global_thread.guest_handle != InvalidHandle && + (current_core < Core::Hardware::NUM_CPU_CORES); + + while (cores_pending_reschedule != 0) { + u32 core = Common::CountTrailingZeroes64(cores_pending_reschedule); + ASSERT(core < Core::Hardware::NUM_CPU_CORES); + if (!must_context_switch || core != current_core) { + auto& phys_core = kernel.PhysicalCore(core); + phys_core.Interrupt(); + } else { + must_context_switch = true; + } + cores_pending_reschedule &= ~(1ULL << core); + } + if (must_context_switch) { + auto core_scheduler = kernel.CurrentScheduler(); + kernel.ExitSVCProfile(); + core_scheduler->RescheduleCurrentCore(); + kernel.EnterSVCProfile(); + } +} + +u64 KScheduler::UpdateHighestPriorityThread(Thread* highest_thread) { + std::scoped_lock lock{guard}; + if (Thread* prev_highest_thread = this->state.highest_priority_thread; + prev_highest_thread != highest_thread) { + if (prev_highest_thread != nullptr) { + IncrementScheduledCount(prev_highest_thread); + prev_highest_thread->SetLastScheduledTick(system.CoreTiming().GetCPUTicks()); + } + if (this->state.should_count_idle) { + if (highest_thread != nullptr) { + // if (Process* process = highest_thread->GetOwnerProcess(); process != nullptr) { + // process->SetRunningThread(this->core_id, highest_thread, + // this->state.idle_count); + //} + } else { + this->state.idle_count++; + } + } + + this->state.highest_priority_thread = highest_thread; + this->state.needs_scheduling = true; + return (1ULL << this->core_id); + } else { + return 0; + } +} + +/*static*/ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + /* Clear that we need to update. */ + ClearSchedulerUpdateNeeded(kernel); + + u64 cores_needing_scheduling = 0, idle_cores = 0; + Thread* top_threads[Core::Hardware::NUM_CPU_CORES]; + auto& priority_queue = GetPriorityQueue(kernel); + + /* We want to go over all cores, finding the highest priority thread and determining if + * scheduling is needed for that core. */ + for (size_t core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + Thread* top_thread = priority_queue.GetScheduledFront((s32)core_id); + if (top_thread != nullptr) { + ///* If the thread has no waiters, we need to check if the process has a thread pinned. + ///*/ + // if (top_thread->GetNumKernelWaiters() == 0) { + // if (Process* parent = top_thread->GetOwnerProcess(); parent != nullptr) { + // if (Thread* pinned = parent->GetPinnedThread(core_id); + // pinned != nullptr && pinned != top_thread) { + // /* We prefer our parent's pinned thread if possible. However, we also + // don't + // * want to schedule un-runnable threads. */ + // if (pinned->GetRawState() == Thread::ThreadState_Runnable) { + // top_thread = pinned; + // } else { + // top_thread = nullptr; + // } + // } + // } + //} + } else { + idle_cores |= (1ULL << core_id); + } + + top_threads[core_id] = top_thread; + cores_needing_scheduling |= + kernel.Scheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]); + } + + /* Idle cores are bad. We're going to try to migrate threads to each idle core in turn. */ + while (idle_cores != 0) { + u32 core_id = Common::CountTrailingZeroes64(idle_cores); + if (Thread* suggested = priority_queue.GetSuggestedFront(core_id); suggested != nullptr) { + s32 migration_candidates[Core::Hardware::NUM_CPU_CORES]; + size_t num_candidates = 0; + + /* While we have a suggested thread, try to migrate it! */ + while (suggested != nullptr) { + /* Check if the suggested thread is the top thread on its core. */ + const s32 suggested_core = suggested->GetActiveCore(); + if (Thread* top_thread = + (suggested_core >= 0) ? top_threads[suggested_core] : nullptr; + top_thread != suggested) { + /* Make sure we're not dealing with threads too high priority for migration. */ + if (top_thread != nullptr && + top_thread->GetPriority() < HighestCoreMigrationAllowedPriority) { + break; + } + + /* The suggested thread isn't bound to its core, so we can migrate it! */ + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(suggested_core, suggested); + + top_threads[core_id] = suggested; + cores_needing_scheduling |= + kernel.Scheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]); + break; + } + + /* Note this core as a candidate for migration. */ + ASSERT(num_candidates < Core::Hardware::NUM_CPU_CORES); + migration_candidates[num_candidates++] = suggested_core; + suggested = priority_queue.GetSuggestedNext(core_id, suggested); + } + + /* If suggested is nullptr, we failed to migrate a specific thread. So let's try all our + * candidate cores' top threads. */ + if (suggested == nullptr) { + for (size_t i = 0; i < num_candidates; i++) { + /* Check if there's some other thread that can run on the candidate core. */ + const s32 candidate_core = migration_candidates[i]; + suggested = top_threads[candidate_core]; + if (Thread* next_on_candidate_core = + priority_queue.GetScheduledNext(candidate_core, suggested); + next_on_candidate_core != nullptr) { + /* The candidate core can run some other thread! We'll migrate its current + * top thread to us. */ + top_threads[candidate_core] = next_on_candidate_core; + cores_needing_scheduling |= + kernel.Scheduler(candidate_core) + .UpdateHighestPriorityThread(top_threads[candidate_core]); + + /* Perform the migration. */ + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(candidate_core, suggested); + + top_threads[core_id] = suggested; + cores_needing_scheduling |= + kernel.Scheduler(core_id).UpdateHighestPriorityThread( + top_threads[core_id]); + break; + } + } + } + } + + idle_cores &= ~(1ULL << core_id); + } + + return cores_needing_scheduling; +} + +void GlobalSchedulerContext::AddThread(std::shared_ptr thread) { + std::scoped_lock lock{global_list_guard}; + thread_list.push_back(std::move(thread)); +} + +void GlobalSchedulerContext::RemoveThread(std::shared_ptr thread) { + std::scoped_lock lock{global_list_guard}; + thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), + thread_list.end()); +} + +void GlobalSchedulerContext::PreemptThreads() { + // The priority levels at which the global scheduler preempts threads every 10 ms. They are + // ordered from Core 0 to Core 3. + std::array preemption_priorities = {59, 59, 59, 63}; + + ASSERT(IsLocked()); + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + const u32 priority = preemption_priorities[core_id]; + kernel.Scheduler(core_id).RotateScheduledQueue(core_id, priority); + } +} + +bool GlobalSchedulerContext::IsLocked() const { + return scheduler_lock.IsLockedByCurrentThread(); +} + +/*static*/ void KScheduler::OnThreadStateChanged(KernelCore& kernel, Thread* thread, + u32 old_state) { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + /* Check if the state has changed, because if it hasn't there's nothing to do. */ + const auto cur_state = thread->scheduling_state; + if (cur_state == old_state) { + return; + } + + /* Update the priority queues. */ + if (old_state == static_cast(ThreadSchedStatus::Runnable)) { + /* If we were previously runnable, then we're not runnable now, and we should remove. */ + GetPriorityQueue(kernel).Remove(thread); + IncrementScheduledCount(thread); + SetSchedulerUpdateNeeded(kernel); + } else if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { + /* If we're now runnable, then we weren't previously, and we should add. */ + GetPriorityQueue(kernel).PushBack(thread); + IncrementScheduledCount(thread); + SetSchedulerUpdateNeeded(kernel); + } +} + +/*static*/ void KScheduler::OnThreadPriorityChanged(KernelCore& kernel, Thread* thread, + Thread* current_thread, u32 old_priority) { + + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + /* If the thread is runnable, we want to change its priority in the queue. */ + if (thread->scheduling_state == static_cast(ThreadSchedStatus::Runnable)) { + GetPriorityQueue(kernel).ChangePriority( + old_priority, thread == kernel.CurrentScheduler()->GetCurrentThread(), thread); + IncrementScheduledCount(thread); + SetSchedulerUpdateNeeded(kernel); + } +} + +/*static*/ void KScheduler::OnThreadAffinityMaskChanged(KernelCore& kernel, Thread* thread, + const KAffinityMask& old_affinity, + s32 old_core) { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + /* If the thread is runnable, we want to change its affinity in the queue. */ + if (thread->scheduling_state == static_cast(ThreadSchedStatus::Runnable)) { + GetPriorityQueue(kernel).ChangeAffinityMask(old_core, old_affinity, thread); + IncrementScheduledCount(thread); + SetSchedulerUpdateNeeded(kernel); + } +} + +void KScheduler::RotateScheduledQueue(s32 core_id, s32 priority) { + ASSERT(system.GlobalSchedulerContext().IsLocked()); + + /* Get a reference to the priority queue. */ + auto& kernel = system.Kernel(); + auto& priority_queue = GetPriorityQueue(kernel); + + /* Rotate the front of the queue to the end. */ + Thread* top_thread = priority_queue.GetScheduledFront(core_id, priority); + Thread* next_thread = nullptr; + if (top_thread != nullptr) { + next_thread = priority_queue.MoveToScheduledBack(top_thread); + if (next_thread != top_thread) { + IncrementScheduledCount(top_thread); + IncrementScheduledCount(next_thread); + } + } + + /* While we have a suggested thread, try to migrate it! */ + { + Thread* suggested = priority_queue.GetSuggestedFront(core_id, priority); + while (suggested != nullptr) { + /* Check if the suggested thread is the top thread on its core. */ + const s32 suggested_core = suggested->GetActiveCore(); + if (Thread* top_on_suggested_core = + (suggested_core >= 0) ? priority_queue.GetScheduledFront(suggested_core) + : nullptr; + top_on_suggested_core != suggested) { + /* If the next thread is a new thread that has been waiting longer than our + * suggestion, we prefer it to our suggestion. */ + if (top_thread != next_thread && next_thread != nullptr && + next_thread->GetLastScheduledTick() < suggested->GetLastScheduledTick()) { + suggested = nullptr; + break; + } + + /* If we're allowed to do a migration, do one. */ + /* NOTE: Unlike migrations in UpdateHighestPriorityThread, this moves the suggestion + * to the front of the queue. */ + if (top_on_suggested_core == nullptr || + top_on_suggested_core->GetPriority() >= HighestCoreMigrationAllowedPriority) { + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(suggested_core, suggested, true); + IncrementScheduledCount(suggested); + break; + } + } + + /* Get the next suggestion. */ + suggested = priority_queue.GetSamePriorityNext(core_id, suggested); + } + } + + /* Now that we might have migrated a thread with the same priority, check if we can do better. + */ + { + Thread* best_thread = priority_queue.GetScheduledFront(core_id); + if (best_thread == GetCurrentThread()) { + best_thread = priority_queue.GetScheduledNext(core_id, best_thread); + } + + /* If the best thread we can choose has a priority the same or worse than ours, try to + * migrate a higher priority thread. */ + if (best_thread != nullptr && best_thread->GetPriority() >= static_cast(priority)) { + Thread* suggested = priority_queue.GetSuggestedFront(core_id); + while (suggested != nullptr) { + /* If the suggestion's priority is the same as ours, don't bother. */ + if (suggested->GetPriority() >= best_thread->GetPriority()) { + break; + } + + /* Check if the suggested thread is the top thread on its core. */ + const s32 suggested_core = suggested->GetActiveCore(); + if (Thread* top_on_suggested_core = + (suggested_core >= 0) ? priority_queue.GetScheduledFront(suggested_core) + : nullptr; + top_on_suggested_core != suggested) { + /* If we're allowed to do a migration, do one. */ + /* NOTE: Unlike migrations in UpdateHighestPriorityThread, this moves the + * suggestion to the front of the queue. */ + if (top_on_suggested_core == nullptr || + top_on_suggested_core->GetPriority() >= + HighestCoreMigrationAllowedPriority) { + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(suggested_core, suggested, true); + IncrementScheduledCount(suggested); + break; + } + } + + /* Get the next suggestion. */ + suggested = priority_queue.GetSuggestedNext(core_id, suggested); + } + } + } + + /* After a rotation, we need a scheduler update. */ + SetSchedulerUpdateNeeded(kernel); +} + +/*static*/ bool KScheduler::CanSchedule(KernelCore& kernel) { + return kernel.CurrentScheduler()->GetCurrentThread()->GetDisableDispatchCount() <= 1; +} + +/*static*/ bool KScheduler::IsSchedulerUpdateNeeded(const KernelCore& kernel) { + return kernel.GlobalSchedulerContext().scheduler_update_needed.load(std::memory_order_acquire); +} + +/*static*/ void KScheduler::SetSchedulerUpdateNeeded(KernelCore& kernel) { + kernel.GlobalSchedulerContext().scheduler_update_needed.store(true, std::memory_order_release); +} + +/*static*/ void KScheduler::ClearSchedulerUpdateNeeded(KernelCore& kernel) { + kernel.GlobalSchedulerContext().scheduler_update_needed.store(false, std::memory_order_release); +} + +/*static*/ void KScheduler::DisableScheduling(KernelCore& kernel) { + if (auto* scheduler = kernel.CurrentScheduler(); scheduler) { + ASSERT(scheduler->GetCurrentThread()->GetDisableDispatchCount() >= 0); + scheduler->GetCurrentThread()->DisableDispatch(); + } +} + +/*static*/ void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling, + Core::EmuThreadHandle global_thread) { + if (auto* scheduler = kernel.CurrentScheduler(); scheduler) { + scheduler->GetCurrentThread()->EnableDispatch(); + } + RescheduleCores(kernel, cores_needing_scheduling, global_thread); +} + +/*static*/ u64 KScheduler::UpdateHighestPriorityThreads(KernelCore& kernel) { + if (IsSchedulerUpdateNeeded(kernel)) { + return UpdateHighestPriorityThreadsImpl(kernel); + } else { + return 0; + } +} + +/*static*/ KSchedulerPriorityQueue& KScheduler::GetPriorityQueue(KernelCore& kernel) { + return kernel.GlobalSchedulerContext().priority_queue; +} + +void KScheduler::YieldWithoutCoreMigration() { + auto& kernel = system.Kernel(); + + /* Validate preconditions. */ + ASSERT(CanSchedule(kernel)); + ASSERT(kernel.CurrentProcess() != nullptr); + + /* Get the current thread and process. */ + Thread& cur_thread = *GetCurrentThread(); + Process& cur_process = *kernel.CurrentProcess(); + + /* If the thread's yield count matches, there's nothing for us to do. */ + if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { + return; + } + + /* Get a reference to the priority queue. */ + auto& priority_queue = GetPriorityQueue(kernel); + + /* Perform the yield. */ + { + SchedulerLock lock(kernel); + + const auto cur_state = cur_thread.scheduling_state; + if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { + /* Put the current thread at the back of the queue. */ + Thread* next_thread = priority_queue.MoveToScheduledBack(std::addressof(cur_thread)); + IncrementScheduledCount(std::addressof(cur_thread)); + + /* If the next thread is different, we have an update to perform. */ + if (next_thread != std::addressof(cur_thread)) { + SetSchedulerUpdateNeeded(kernel); + } else { + /* Otherwise, set the thread's yield count so that we won't waste work until the + * process is scheduled again. */ + cur_thread.SetYieldScheduleCount(cur_process.GetScheduledCount()); + } + } + } +} + +void KScheduler::YieldWithCoreMigration() { + auto& kernel = system.Kernel(); + + /* Validate preconditions. */ + ASSERT(CanSchedule(kernel)); + ASSERT(kernel.CurrentProcess() != nullptr); + + /* Get the current thread and process. */ + Thread& cur_thread = *GetCurrentThread(); + Process& cur_process = *kernel.CurrentProcess(); + + /* If the thread's yield count matches, there's nothing for us to do. */ + if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { + return; + } + + /* Get a reference to the priority queue. */ + auto& priority_queue = GetPriorityQueue(kernel); + + /* Perform the yield. */ + { + SchedulerLock lock(kernel); + + const auto cur_state = cur_thread.scheduling_state; + if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { + /* Get the current active core. */ + const s32 core_id = cur_thread.GetActiveCore(); + + /* Put the current thread at the back of the queue. */ + Thread* next_thread = priority_queue.MoveToScheduledBack(std::addressof(cur_thread)); + IncrementScheduledCount(std::addressof(cur_thread)); + + /* While we have a suggested thread, try to migrate it! */ + bool recheck = false; + Thread* suggested = priority_queue.GetSuggestedFront(core_id); + while (suggested != nullptr) { + /* Check if the suggested thread is the thread running on its core. */ + const s32 suggested_core = suggested->GetActiveCore(); + + if (Thread* running_on_suggested_core = + (suggested_core >= 0) + ? kernel.Scheduler(suggested_core).state.highest_priority_thread + : nullptr; + running_on_suggested_core != suggested) { + /* If the current thread's priority is higher than our suggestion's we prefer + * the next thread to the suggestion. */ + /* We also prefer the next thread when the current thread's priority is equal to + * the suggestions, but the next thread has been waiting longer. */ + if ((suggested->GetPriority() > cur_thread.GetPriority()) || + (suggested->GetPriority() == cur_thread.GetPriority() && + next_thread != std::addressof(cur_thread) && + next_thread->GetLastScheduledTick() < suggested->GetLastScheduledTick())) { + suggested = nullptr; + break; + } + + /* If we're allowed to do a migration, do one. */ + /* NOTE: Unlike migrations in UpdateHighestPriorityThread, this moves the + * suggestion to the front of the queue. */ + if (running_on_suggested_core == nullptr || + running_on_suggested_core->GetPriority() >= + HighestCoreMigrationAllowedPriority) { + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(suggested_core, suggested, true); + IncrementScheduledCount(suggested); + break; + } else { + /* We couldn't perform a migration, but we should check again on a future + * yield. */ + recheck = true; + } + } + + /* Get the next suggestion. */ + suggested = priority_queue.GetSuggestedNext(core_id, suggested); + } + + /* If we still have a suggestion or the next thread is different, we have an update to + * perform. */ + if (suggested != nullptr || next_thread != std::addressof(cur_thread)) { + SetSchedulerUpdateNeeded(kernel); + } else if (!recheck) { + /* Otherwise if we don't need to re-check, set the thread's yield count so that we + * won't waste work until the process is scheduled again. */ + cur_thread.SetYieldScheduleCount(cur_process.GetScheduledCount()); + } + } + } +} + +void KScheduler::YieldToAnyThread() { + auto& kernel = system.Kernel(); + + /* Validate preconditions. */ + ASSERT(CanSchedule(kernel)); + ASSERT(kernel.CurrentProcess() != nullptr); + + /* Get the current thread and process. */ + Thread& cur_thread = *GetCurrentThread(); + Process& cur_process = *kernel.CurrentProcess(); + + /* If the thread's yield count matches, there's nothing for us to do. */ + if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { + return; + } + + /* Get a reference to the priority queue. */ + auto& priority_queue = GetPriorityQueue(kernel); + + /* Perform the yield. */ + { + SchedulerLock lock(kernel); + + const auto cur_state = cur_thread.scheduling_state; + if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { + /* Get the current active core. */ + const s32 core_id = cur_thread.GetActiveCore(); + + /* Migrate the current thread to core -1. */ + cur_thread.SetActiveCore(-1); + priority_queue.ChangeCore(core_id, std::addressof(cur_thread)); + IncrementScheduledCount(std::addressof(cur_thread)); + + /* If there's nothing scheduled, we can try to perform a migration. */ + if (priority_queue.GetScheduledFront(core_id) == nullptr) { + /* While we have a suggested thread, try to migrate it! */ + Thread* suggested = priority_queue.GetSuggestedFront(core_id); + while (suggested != nullptr) { + /* Check if the suggested thread is the top thread on its core. */ + const s32 suggested_core = suggested->GetActiveCore(); + if (Thread* top_on_suggested_core = + (suggested_core >= 0) ? priority_queue.GetScheduledFront(suggested_core) + : nullptr; + top_on_suggested_core != suggested) { + /* If we're allowed to do a migration, do one. */ + if (top_on_suggested_core == nullptr || + top_on_suggested_core->GetPriority() >= + HighestCoreMigrationAllowedPriority) { + suggested->SetActiveCore(core_id); + priority_queue.ChangeCore(suggested_core, suggested); + IncrementScheduledCount(suggested); + } + + /* Regardless of whether we migrated, we had a candidate, so we're done. */ + break; + } + + /* Get the next suggestion. */ + suggested = priority_queue.GetSuggestedNext(core_id, suggested); + } + + /* If the suggestion is different from the current thread, we need to perform an + * update. */ + if (suggested != std::addressof(cur_thread)) { + SetSchedulerUpdateNeeded(kernel); + } else { + /* Otherwise, set the thread's yield count so that we won't waste work until the + * process is scheduled again. */ + cur_thread.SetYieldScheduleCount(cur_process.GetScheduledCount()); + } + } else { + /* Otherwise, we have an update to perform. */ + SetSchedulerUpdateNeeded(kernel); + } + } + } +} + +void GlobalSchedulerContext::Lock() { + scheduler_lock.Lock(); +} + +void GlobalSchedulerContext::Unlock() { + scheduler_lock.Unlock(); +} + +KScheduler::KScheduler(Core::System& system, std::size_t core_id) + : system(system), core_id(core_id) { + switch_fiber = std::make_shared(std::function(OnSwitch), this); + this->state.needs_scheduling = true; + this->state.interrupt_task_thread_runnable = false; + this->state.should_count_idle = false; + this->state.idle_count = 0; + this->state.idle_thread_stack = nullptr; + this->state.highest_priority_thread = nullptr; +} + +KScheduler::~KScheduler() = default; + +Thread* KScheduler::GetCurrentThread() const { + if (current_thread) { + return current_thread; + } + return idle_thread; +} + +u64 KScheduler::GetLastContextSwitchTicks() const { + return last_context_switch_time; +} + +void KScheduler::RescheduleCurrentCore() { + ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1); + + auto& phys_core = system.Kernel().PhysicalCore(core_id); + if (phys_core.IsInterrupted()) { + phys_core.ClearInterrupt(); + } + guard.lock(); + if (this->state.needs_scheduling) { + Schedule(); + } else { + guard.unlock(); + } +} + +void KScheduler::OnThreadStart() { + SwitchContextStep2(); +} + +void KScheduler::Unload(Thread* thread) { + if (thread) { + thread->SetIsRunning(false); + if (thread->IsContinuousOnSVC() && !thread->IsHLEThread()) { + system.ArmInterface(core_id).ExceptionalExit(); + thread->SetContinuousOnSVC(false); + } + if (!thread->IsHLEThread() && !thread->HasExited()) { + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); + cpu_core.SaveContext(thread->GetContext32()); + cpu_core.SaveContext(thread->GetContext64()); + // Save the TPIDR_EL0 system register in case it was modified. + thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); + cpu_core.ClearExclusiveState(); + } + thread->context_guard.unlock(); + } +} + +void KScheduler::Reload(Thread* thread) { + if (thread) { + ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, + "Thread must be runnable."); + + // Cancel any outstanding wakeup events for this thread + thread->SetIsRunning(true); + thread->SetWasRunning(false); + + auto* const thread_owner_process = thread->GetOwnerProcess(); + if (thread_owner_process != nullptr) { + system.Kernel().MakeCurrentProcess(thread_owner_process); + } + if (!thread->IsHLEThread()) { + Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); + cpu_core.LoadContext(thread->GetContext32()); + cpu_core.LoadContext(thread->GetContext64()); + cpu_core.SetTlsAddress(thread->GetTLSAddress()); + cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); + cpu_core.ClearExclusiveState(); + } + } +} + +void KScheduler::SwitchContextStep2() { + // Load context of new thread + Reload(current_thread); + + RescheduleCurrentCore(); +} + +void KScheduler::ScheduleImpl() { + Thread* previous_thread = current_thread; + current_thread = state.highest_priority_thread; + + this->state.needs_scheduling = false; + + if (current_thread == previous_thread) { + guard.unlock(); + return; + } + + Process* const previous_process = system.Kernel().CurrentProcess(); + + UpdateLastContextSwitchTime(previous_thread, previous_process); + + // Save context for previous thread + Unload(previous_thread); + + std::shared_ptr* old_context; + if (previous_thread != nullptr) { + old_context = &previous_thread->GetHostContext(); + } else { + old_context = &idle_thread->GetHostContext(); + } + guard.unlock(); + + Common::Fiber::YieldTo(*old_context, switch_fiber); + /// When a thread wakes up, the scheduler may have changed to other in another core. + auto& next_scheduler = *system.Kernel().CurrentScheduler(); + next_scheduler.SwitchContextStep2(); +} + +void KScheduler::OnSwitch(void* this_scheduler) { + KScheduler* sched = static_cast(this_scheduler); + sched->SwitchToCurrent(); +} + +void KScheduler::SwitchToCurrent() { + while (true) { + { + std::scoped_lock lock{guard}; + current_thread = state.highest_priority_thread; + this->state.needs_scheduling = false; + } + const auto is_switch_pending = [this] { + std::scoped_lock lock{guard}; + return !!this->state.needs_scheduling; + }; + do { + if (current_thread != nullptr && !current_thread->IsHLEThread()) { + current_thread->context_guard.lock(); + if (!current_thread->IsRunnable()) { + current_thread->context_guard.unlock(); + break; + } + if (static_cast(current_thread->GetProcessorID()) != core_id) { + current_thread->context_guard.unlock(); + break; + } + } + std::shared_ptr* next_context; + if (current_thread != nullptr) { + next_context = ¤t_thread->GetHostContext(); + } else { + next_context = &idle_thread->GetHostContext(); + } + Common::Fiber::YieldTo(switch_fiber, *next_context); + } while (!is_switch_pending()); + } +} + +void KScheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { + const u64 prev_switch_ticks = last_context_switch_time; + const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks(); + const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; + + if (thread != nullptr) { + thread->UpdateCPUTimeTicks(update_ticks); + } + + if (process != nullptr) { + process->UpdateCPUTimeTicks(update_ticks); + } + + last_context_switch_time = most_recent_switch_ticks; +} + +void KScheduler::Initialize() { + std::string name = "Idle Thread Id:" + std::to_string(core_id); + std::function init_func = Core::CpuManager::GetIdleThreadStartFunc(); + void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); + ThreadType type = static_cast(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE); + auto thread_res = Thread::Create(system, type, name, 0, 64, 0, static_cast(core_id), 0, + nullptr, std::move(init_func), init_func_parameter); + idle_thread = thread_res.Unwrap().get(); + + { + KScopedSchedulerLock lock{system.Kernel()}; + idle_thread->SetStatus(ThreadStatus::Ready); + } +} + +SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { + kernel.GlobalSchedulerContext().Lock(); +} + +SchedulerLock::~SchedulerLock() { + kernel.GlobalSchedulerContext().Unlock(); +} + +SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, + Thread* time_task, s64 nanoseconds) + : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{ + nanoseconds} { + event_handle = InvalidHandle; +} + +SchedulerLockAndSleep::~SchedulerLockAndSleep() { + if (sleep_cancelled) { + return; + } + auto& time_manager = kernel.TimeManager(); + time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); +} + +void SchedulerLockAndSleep::Release() { + if (sleep_cancelled) { + return; + } + auto& time_manager = kernel.TimeManager(); + time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); + sleep_cancelled = true; +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h new file mode 100644 index 000000000..535ee34b9 --- /dev/null +++ b/src/core/hle/kernel/k_scheduler.h @@ -0,0 +1,297 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include +#include +#include +#include + +#include "common/common_types.h" +#include "common/multi_level_queue.h" +#include "common/scope_exit.h" +#include "common/spin_lock.h" +#include "core/core_timing.h" +#include "core/hardware_properties.h" +#include "core/hle/kernel/k_priority_queue.h" +#include "core/hle/kernel/k_scheduler_lock.h" +#include "core/hle/kernel/thread.h" + +namespace Common { +class Fiber; +} + +namespace Core { +class ARM_Interface; +class System; +} // namespace Core + +namespace Kernel { + +class KernelCore; +class Process; +class SchedulerLock; + +using KSchedulerPriorityQueue = + KPriorityQueue; +static constexpr s32 HighestCoreMigrationAllowedPriority = 2; + +class GlobalSchedulerContext final { + friend class KScheduler; + +public: + explicit GlobalSchedulerContext(KernelCore& kernel); + ~GlobalSchedulerContext(); + + /// Adds a new thread to the scheduler + void AddThread(std::shared_ptr thread); + + /// Removes a thread from the scheduler + void RemoveThread(std::shared_ptr thread); + + /// Returns a list of all threads managed by the scheduler + const std::vector>& GetThreadList() const { + return thread_list; + } + + /** + * Rotates the scheduling queues of threads at a preemption priority and then does + * some core rebalancing. Preemption priorities can be found in the array + * 'preemption_priorities'. + * + * @note This operation happens every 10ms. + */ + void PreemptThreads(); + + u32 CpuCoresCount() const { + return Core::Hardware::NUM_CPU_CORES; + } + + bool IsLocked() const; + +private: + friend class SchedulerLock; + + /// Lock the scheduler to the current thread. + void Lock(); + + /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling + /// and reschedules current core if needed. + void Unlock(); + + using LockType = KAbstractSchedulerLock; + + KernelCore& kernel; + + std::atomic_bool scheduler_update_needed{}; + KSchedulerPriorityQueue priority_queue; + LockType scheduler_lock; + + /// Lists all thread ids that aren't deleted/etc. + std::vector> thread_list; + Common::SpinLock global_list_guard{}; +}; + +class KScheduler final { +public: + explicit KScheduler(Core::System& system, std::size_t core_id); + ~KScheduler(); + + /// Reschedules to the next available thread (call after current thread is suspended) + void RescheduleCurrentCore(); + + /// Reschedules cores pending reschedule, to be called on EnableScheduling. + static void RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedule, + Core::EmuThreadHandle global_thread); + + /// The next two are for SingleCore Only. + /// Unload current thread before preempting core. + void Unload(Thread* thread); + + /// Reload current thread after core preemption. + void Reload(Thread* thread); + + /// Gets the current running thread + Thread* GetCurrentThread() const; + + /// Gets the timestamp for the last context switch in ticks. + u64 GetLastContextSwitchTicks() const; + + bool ContextSwitchPending() const { + return this->state.needs_scheduling; + } + + void Initialize(); + + void OnThreadStart(); + + std::shared_ptr& ControlContext() { + return switch_fiber; + } + + const std::shared_ptr& ControlContext() const { + return switch_fiber; + } + + std::size_t CurrentCoreId() const { + return core_id; + } + + u64 UpdateHighestPriorityThread(Thread* highest_thread); + + /** + * Takes a thread and moves it to the back of the it's priority list. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. + */ + void YieldWithoutCoreMigration(); + + /** + * Takes a thread and moves it to the back of the it's priority list. + * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or + * a better priority than the next thread in the core. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. + */ + void YieldWithCoreMigration(); + + /** + * Takes a thread and moves it out of the scheduling queue. + * and into the suggested queue. If no thread can be scheduled afterwards in that core, + * a suggested thread is obtained instead. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. + */ + void YieldToAnyThread(); + + /// Notify the scheduler a thread's status has changed. + static void OnThreadStateChanged(KernelCore& kernel, Thread* thread, u32 old_state); + + /// Notify the scheduler a thread's priority has changed. + static void OnThreadPriorityChanged(KernelCore& kernel, Thread* thread, Thread* current_thread, + u32 old_priority); + + /// Notify the scheduler a thread's core and/or affinity mask has changed. + static void OnThreadAffinityMaskChanged(KernelCore& kernel, Thread* thread, + const KAffinityMask& old_affinity, s32 old_core); + +private: + /** + * Takes care of selecting the new scheduled threads in three steps: + * + * 1. First a thread is selected from the top of the priority queue. If no thread + * is obtained then we move to step two, else we are done. + * + * 2. Second we try to get a suggested thread that's not assigned to any core or + * that is not the top thread in that core. + * + * 3. Third is no suggested thread is found, we do a second pass and pick a running + * thread in another core and swap it with its current thread. + * + * returns the cores needing scheduling. + */ + static u64 UpdateHighestPriorityThreadsImpl(KernelCore& kernel); + + void RotateScheduledQueue(s32 core_id, s32 priority); + +public: + static bool CanSchedule(KernelCore& kernel); + static bool IsSchedulerUpdateNeeded(const KernelCore& kernel); + static void SetSchedulerUpdateNeeded(KernelCore& kernel); + static void ClearSchedulerUpdateNeeded(KernelCore& kernel); + static void DisableScheduling(KernelCore& kernel); + static void EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling, + Core::EmuThreadHandle global_thread); + static u64 UpdateHighestPriorityThreads(KernelCore& kernel); + +private: + friend class GlobalSchedulerContext; + + static KSchedulerPriorityQueue& GetPriorityQueue(KernelCore& kernel); + + void Schedule() { + ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1); + this->ScheduleImpl(); + } + + /// Switches the CPU's active thread context to that of the specified thread + void ScheduleImpl(); + void SwitchThread(Thread* next_thread); + + /// When a thread wakes up, it must run this through it's new scheduler + void SwitchContextStep2(); + + /** + * Called on every context switch to update the internal timestamp + * This also updates the running time ticks for the given thread and + * process using the following difference: + * + * ticks += most_recent_ticks - last_context_switch_ticks + * + * The internal tick timestamp for the scheduler is simply the + * most recent tick count retrieved. No special arithmetic is + * applied to it. + */ + void UpdateLastContextSwitchTime(Thread* thread, Process* process); + + static void OnSwitch(void* this_scheduler); + void SwitchToCurrent(); + +private: + Thread* current_thread{}; + Thread* idle_thread{}; + + std::shared_ptr switch_fiber{}; + + struct SchedulingState { + std::atomic needs_scheduling; + bool interrupt_task_thread_runnable{}; + bool should_count_idle{}; + u64 idle_count{}; + Thread* highest_priority_thread{}; + void* idle_thread_stack{}; + }; + + SchedulingState state; + + Core::System& system; + u64 last_context_switch_time{}; + const std::size_t core_id; + + Common::SpinLock guard{}; +}; + +class SchedulerLock { +public: + [[nodiscard]] explicit SchedulerLock(KernelCore& kernel); + ~SchedulerLock(); + +protected: + KernelCore& kernel; +}; + +class SchedulerLockAndSleep : public SchedulerLock { +public: + explicit SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task, + s64 nanoseconds); + ~SchedulerLockAndSleep(); + + void CancelSleep() { + sleep_cancelled = true; + } + + void Release(); + +private: + Handle& event_handle; + Thread* time_task; + s64 nanoseconds; + bool sleep_cancelled{}; +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 929db696d..b74e34c40 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -27,6 +27,7 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/memory_layout.h" #include "core/hle/kernel/memory/memory_manager.h" @@ -34,7 +35,6 @@ #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/synchronization.h" #include "core/hle/kernel/thread.h" @@ -49,17 +49,18 @@ namespace Kernel { struct KernelCore::Impl { explicit Impl(Core::System& system, KernelCore& kernel) - : global_scheduler{kernel}, synchronization{system}, time_manager{system}, - global_handle_table{kernel}, system{system} {} + : synchronization{system}, time_manager{system}, global_handle_table{kernel}, system{ + system} {} void SetMulticore(bool is_multicore) { this->is_multicore = is_multicore; } void Initialize(KernelCore& kernel) { - Shutdown(); RegisterHostThread(); + global_scheduler_context = std::make_unique(kernel); + InitializePhysicalCores(); InitializeSystemResourceLimit(kernel); InitializeMemoryLayout(); @@ -86,29 +87,20 @@ struct KernelCore::Impl { } } - for (std::size_t i = 0; i < cores.size(); i++) { - cores[i].Shutdown(); - schedulers[i].reset(); - } cores.clear(); process_list.clear(); + current_process = nullptr; system_resource_limit = nullptr; global_handle_table.Clear(); - preemption_event = nullptr; - global_scheduler.Shutdown(); + preemption_event = nullptr; named_ports.clear(); - for (auto& core : cores) { - core.Shutdown(); - } - cores.clear(); - exclusive_monitor.reset(); num_host_threads = 0; @@ -121,7 +113,7 @@ struct KernelCore::Impl { exclusive_monitor = Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - schedulers[i] = std::make_unique(system, i); + schedulers[i] = std::make_unique(system, i); cores.emplace_back(i, system, *schedulers[i], interrupts); } } @@ -155,7 +147,7 @@ struct KernelCore::Impl { "PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) { { SchedulerLock lock(kernel); - global_scheduler.PreemptThreads(); + global_scheduler_context->PreemptThreads(); } const auto time_interval = std::chrono::nanoseconds{ Core::Timing::msToCycles(std::chrono::milliseconds(10))}; @@ -245,7 +237,7 @@ struct KernelCore::Impl { if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { return result; } - const Kernel::Scheduler& sched = cores[result.host_handle].Scheduler(); + const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); const Kernel::Thread* current = sched.GetCurrentThread(); if (current != nullptr && !current->IsPhantomMode()) { result.guest_handle = current->GetGlobalHandle(); @@ -314,7 +306,7 @@ struct KernelCore::Impl { // Lists all processes that exist in the current session. std::vector> process_list; Process* current_process = nullptr; - Kernel::GlobalScheduler global_scheduler; + std::unique_ptr global_scheduler_context; Kernel::Synchronization synchronization; Kernel::TimeManager time_manager; @@ -355,7 +347,7 @@ struct KernelCore::Impl { std::array, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; std::array interrupts{}; - std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; + std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; bool is_multicore{}; std::thread::id single_core_thread_id{}; @@ -415,19 +407,19 @@ const std::vector>& KernelCore::GetProcessList() const return impl->process_list; } -Kernel::GlobalScheduler& KernelCore::GlobalScheduler() { - return impl->global_scheduler; +Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() { + return *impl->global_scheduler_context; } -const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { - return impl->global_scheduler; +const Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() const { + return *impl->global_scheduler_context; } -Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { +Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) { return *impl->schedulers[id]; } -const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { +const Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) const { return *impl->schedulers[id]; } @@ -451,16 +443,13 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { return impl->cores[core_id]; } -Kernel::Scheduler& KernelCore::CurrentScheduler() { +Kernel::KScheduler* KernelCore::CurrentScheduler() { u32 core_id = impl->GetCurrentHostThreadID(); - ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); - return *impl->schedulers[core_id]; -} - -const Kernel::Scheduler& KernelCore::CurrentScheduler() const { - u32 core_id = impl->GetCurrentHostThreadID(); - ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); - return *impl->schedulers[core_id]; + if (core_id >= Core::Hardware::NUM_CPU_CORES) { + // This is expected when called from not a guest thread + return {}; + } + return impl->schedulers[core_id].get(); } std::array& KernelCore::Interrupts() { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a73a93039..5846c3f39 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -35,12 +35,12 @@ class SlabHeap; class AddressArbiter; class ClientPort; -class GlobalScheduler; +class GlobalSchedulerContext; class HandleTable; class PhysicalCore; class Process; class ResourceLimit; -class Scheduler; +class KScheduler; class SharedMemory; class Synchronization; class Thread; @@ -102,16 +102,16 @@ public: const std::vector>& GetProcessList() const; /// Gets the sole instance of the global scheduler - Kernel::GlobalScheduler& GlobalScheduler(); + Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); /// Gets the sole instance of the global scheduler - const Kernel::GlobalScheduler& GlobalScheduler() const; + const Kernel::GlobalSchedulerContext& GlobalSchedulerContext() const; /// Gets the sole instance of the Scheduler assoviated with cpu core 'id' - Kernel::Scheduler& Scheduler(std::size_t id); + Kernel::KScheduler& Scheduler(std::size_t id); /// Gets the sole instance of the Scheduler assoviated with cpu core 'id' - const Kernel::Scheduler& Scheduler(std::size_t id) const; + const Kernel::KScheduler& Scheduler(std::size_t id) const; /// Gets the an instance of the respective physical CPU core. Kernel::PhysicalCore& PhysicalCore(std::size_t id); @@ -120,10 +120,7 @@ public: const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const; /// Gets the sole instance of the Scheduler at the current running core. - Kernel::Scheduler& CurrentScheduler(); - - /// Gets the sole instance of the Scheduler at the current running core. - const Kernel::Scheduler& CurrentScheduler() const; + Kernel::KScheduler* CurrentScheduler(); /// Gets the an instance of the current physical CPU core. Kernel::PhysicalCore& CurrentPhysicalCore(); diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 8f6c944d1..6299b1342 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -11,11 +11,11 @@ #include "core/core.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" @@ -73,7 +73,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, auto& kernel = system.Kernel(); std::shared_ptr current_thread = - SharedFrom(kernel.CurrentScheduler().GetCurrentThread()); + SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); { SchedulerLock lock(kernel); // The mutex address must be 4-byte aligned @@ -156,7 +156,7 @@ ResultCode Mutex::Release(VAddr address) { SchedulerLock lock(kernel); std::shared_ptr current_thread = - SharedFrom(kernel.CurrentScheduler().GetCurrentThread()); + SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); auto [result, new_owner] = Unlock(current_thread, address); diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index d6a5742bd..7fea45f96 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -7,14 +7,14 @@ #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/core.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/scheduler.h" namespace Kernel { PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, - Kernel::Scheduler& scheduler, Core::CPUInterrupts& interrupts) + Kernel::KScheduler& scheduler, Core::CPUInterrupts& interrupts) : core_index{core_index}, system{system}, scheduler{scheduler}, interrupts{interrupts}, guard{std::make_unique()} {} @@ -37,17 +37,12 @@ void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) { void PhysicalCore::Run() { arm_interface->Run(); - arm_interface->ClearExclusiveState(); } void PhysicalCore::Idle() { interrupts[core_index].AwaitInterrupt(); } -void PhysicalCore::Shutdown() { - scheduler.Shutdown(); -} - bool PhysicalCore::IsInterrupted() const { return interrupts[core_index].IsInterrupted(); } diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 37513130a..b4d3c15de 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -15,7 +15,7 @@ class SpinLock; } namespace Kernel { -class Scheduler; +class KScheduler; } // namespace Kernel namespace Core { @@ -28,7 +28,7 @@ namespace Kernel { class PhysicalCore { public: - PhysicalCore(std::size_t core_index, Core::System& system, Kernel::Scheduler& scheduler, + PhysicalCore(std::size_t core_index, Core::System& system, Kernel::KScheduler& scheduler, Core::CPUInterrupts& interrupts); ~PhysicalCore(); @@ -55,9 +55,6 @@ public: /// Check if this core is interrupted bool IsInterrupted() const; - // Shutdown this physical core. - void Shutdown(); - bool IsInitialized() const { return arm_interface != nullptr; } @@ -82,18 +79,18 @@ public: return core_index; } - Kernel::Scheduler& Scheduler() { + Kernel::KScheduler& Scheduler() { return scheduler; } - const Kernel::Scheduler& Scheduler() const { + const Kernel::KScheduler& Scheduler() const { return scheduler; } private: const std::size_t core_index; Core::System& system; - Kernel::Scheduler& scheduler; + Kernel::KScheduler& scheduler; Core::CPUInterrupts& interrupts; std::unique_ptr guard; std::unique_ptr arm_interface; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b17529dee..238c03a13 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -15,13 +15,13 @@ #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/memory_block_manager.h" #include "core/hle/kernel/memory/page_table.h" #include "core/hle/kernel/memory/slab_heap.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/lock.h" #include "core/memory.h" @@ -314,7 +314,7 @@ void Process::PrepareForTermination() { if (thread->GetOwnerProcess() != this) continue; - if (thread.get() == system.CurrentScheduler().GetCurrentThread()) + if (thread.get() == kernel.CurrentScheduler()->GetCurrentThread()) continue; // TODO(Subv): When are the other running/ready threads terminated? @@ -325,7 +325,7 @@ void Process::PrepareForTermination() { } }; - stop_threads(system.GlobalScheduler().GetThreadList()); + stop_threads(system.GlobalSchedulerContext().GetThreadList()); FreeTLSRegion(tls_region_address); tls_region_address = 0; diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index 6e286419e..927f88fed 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp @@ -6,10 +6,10 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" namespace Kernel { diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp deleted file mode 100644 index 9a969fdb5..000000000 --- a/src/core/hle/kernel/scheduler.cpp +++ /dev/null @@ -1,819 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -// -// SelectThreads, Yield functions originally by TuxSH. -// licensed under GPLv2 or later under exception provided by the author. - -#include -#include -#include -#include -#include - -#include "common/assert.h" -#include "common/bit_util.h" -#include "common/fiber.h" -#include "common/logging/log.h" -#include "core/arm/arm_interface.h" -#include "core/core.h" -#include "core/core_timing.h" -#include "core/cpu_manager.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" -#include "core/hle/kernel/time_manager.h" - -namespace Kernel { - -GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {} - -GlobalScheduler::~GlobalScheduler() = default; - -void GlobalScheduler::AddThread(std::shared_ptr thread) { - std::scoped_lock lock{global_list_guard}; - thread_list.push_back(std::move(thread)); -} - -void GlobalScheduler::RemoveThread(std::shared_ptr thread) { - std::scoped_lock lock{global_list_guard}; - thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), - thread_list.end()); -} - -u32 GlobalScheduler::SelectThreads() { - ASSERT(is_locked); - const auto update_thread = [](Thread* thread, Scheduler& sched) { - std::scoped_lock lock{sched.guard}; - if (thread != sched.selected_thread_set.get()) { - if (thread == nullptr) { - ++sched.idle_selection_count; - } - sched.selected_thread_set = SharedFrom(thread); - } - const bool reschedule_pending = - sched.is_context_switch_pending || (sched.selected_thread_set != sched.current_thread); - sched.is_context_switch_pending = reschedule_pending; - std::atomic_thread_fence(std::memory_order_seq_cst); - return reschedule_pending; - }; - if (!is_reselection_pending.load()) { - return 0; - } - std::array top_threads{}; - - u32 idle_cores{}; - - // Step 1: Get top thread in schedule queue. - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - Thread* top_thread = - scheduled_queue[core].empty() ? nullptr : scheduled_queue[core].front(); - if (top_thread != nullptr) { - // TODO(Blinkhawk): Implement Thread Pinning - } else { - idle_cores |= (1U << core); - } - top_threads[core] = top_thread; - } - - while (idle_cores != 0) { - u32 core_id = Common::CountTrailingZeroes32(idle_cores); - - if (!suggested_queue[core_id].empty()) { - std::array migration_candidates{}; - std::size_t num_candidates = 0; - auto iter = suggested_queue[core_id].begin(); - Thread* suggested = nullptr; - // Step 2: Try selecting a suggested thread. - while (iter != suggested_queue[core_id].end()) { - suggested = *iter; - iter++; - s32 suggested_core_id = suggested->GetProcessorID(); - Thread* top_thread = - suggested_core_id >= 0 ? top_threads[suggested_core_id] : nullptr; - if (top_thread != suggested) { - if (top_thread != nullptr && - top_thread->GetPriority() < THREADPRIO_MAX_CORE_MIGRATION) { - suggested = nullptr; - break; - // There's a too high thread to do core migration, cancel - } - TransferToCore(suggested->GetPriority(), static_cast(core_id), suggested); - break; - } - suggested = nullptr; - migration_candidates[num_candidates++] = suggested_core_id; - } - // Step 3: Select a suggested thread from another core - if (suggested == nullptr) { - for (std::size_t i = 0; i < num_candidates; i++) { - s32 candidate_core = migration_candidates[i]; - suggested = top_threads[candidate_core]; - auto it = scheduled_queue[candidate_core].begin(); - it++; - Thread* next = it != scheduled_queue[candidate_core].end() ? *it : nullptr; - if (next != nullptr) { - TransferToCore(suggested->GetPriority(), static_cast(core_id), - suggested); - top_threads[candidate_core] = next; - break; - } else { - suggested = nullptr; - } - } - } - top_threads[core_id] = suggested; - } - - idle_cores &= ~(1U << core_id); - } - u32 cores_needing_context_switch{}; - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - Scheduler& sched = kernel.Scheduler(core); - ASSERT(top_threads[core] == nullptr || - static_cast(top_threads[core]->GetProcessorID()) == core); - if (update_thread(top_threads[core], sched)) { - cores_needing_context_switch |= (1U << core); - } - } - return cores_needing_context_switch; -} - -bool GlobalScheduler::YieldThread(Thread* yielding_thread) { - ASSERT(is_locked); - // Note: caller should use critical section, etc. - if (!yielding_thread->IsRunnable()) { - // Normally this case shouldn't happen except for SetThreadActivity. - is_reselection_pending.store(true, std::memory_order_release); - return false; - } - const u32 core_id = static_cast(yielding_thread->GetProcessorID()); - const u32 priority = yielding_thread->GetPriority(); - - // Yield the thread - Reschedule(priority, core_id, yielding_thread); - const Thread* const winner = scheduled_queue[core_id].front(); - if (kernel.GetCurrentHostThreadID() != core_id) { - is_reselection_pending.store(true, std::memory_order_release); - } - - return AskForReselectionOrMarkRedundant(yielding_thread, winner); -} - -bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { - ASSERT(is_locked); - // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, - // etc. - if (!yielding_thread->IsRunnable()) { - // Normally this case shouldn't happen except for SetThreadActivity. - is_reselection_pending.store(true, std::memory_order_release); - return false; - } - const u32 core_id = static_cast(yielding_thread->GetProcessorID()); - const u32 priority = yielding_thread->GetPriority(); - - // Yield the thread - Reschedule(priority, core_id, yielding_thread); - - std::array current_threads; - for (std::size_t i = 0; i < current_threads.size(); i++) { - current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front(); - } - - Thread* next_thread = scheduled_queue[core_id].front(priority); - Thread* winner = nullptr; - for (auto& thread : suggested_queue[core_id]) { - const s32 source_core = thread->GetProcessorID(); - if (source_core >= 0) { - if (current_threads[source_core] != nullptr) { - if (thread == current_threads[source_core] || - current_threads[source_core]->GetPriority() < min_regular_priority) { - continue; - } - } - } - if (next_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks() || - next_thread->GetPriority() < thread->GetPriority()) { - if (thread->GetPriority() <= priority) { - winner = thread; - break; - } - } - } - - if (winner != nullptr) { - if (winner != yielding_thread) { - TransferToCore(winner->GetPriority(), s32(core_id), winner); - } - } else { - winner = next_thread; - } - - if (kernel.GetCurrentHostThreadID() != core_id) { - is_reselection_pending.store(true, std::memory_order_release); - } - - return AskForReselectionOrMarkRedundant(yielding_thread, winner); -} - -bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread) { - ASSERT(is_locked); - // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, - // etc. - if (!yielding_thread->IsRunnable()) { - // Normally this case shouldn't happen except for SetThreadActivity. - is_reselection_pending.store(true, std::memory_order_release); - return false; - } - Thread* winner = nullptr; - const u32 core_id = static_cast(yielding_thread->GetProcessorID()); - - // Remove the thread from its scheduled mlq, put it on the corresponding "suggested" one instead - TransferToCore(yielding_thread->GetPriority(), -1, yielding_thread); - - // If the core is idle, perform load balancing, excluding the threads that have just used this - // function... - if (scheduled_queue[core_id].empty()) { - // Here, "current_threads" is calculated after the ""yield"", unlike yield -1 - std::array current_threads; - for (std::size_t i = 0; i < current_threads.size(); i++) { - current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front(); - } - for (auto& thread : suggested_queue[core_id]) { - const s32 source_core = thread->GetProcessorID(); - if (source_core < 0 || thread == current_threads[source_core]) { - continue; - } - if (current_threads[source_core] == nullptr || - current_threads[source_core]->GetPriority() >= min_regular_priority) { - winner = thread; - } - break; - } - if (winner != nullptr) { - if (winner != yielding_thread) { - TransferToCore(winner->GetPriority(), static_cast(core_id), winner); - } - } else { - winner = yielding_thread; - } - } else { - winner = scheduled_queue[core_id].front(); - } - - if (kernel.GetCurrentHostThreadID() != core_id) { - is_reselection_pending.store(true, std::memory_order_release); - } - - return AskForReselectionOrMarkRedundant(yielding_thread, winner); -} - -void GlobalScheduler::PreemptThreads() { - ASSERT(is_locked); - for (std::size_t core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - const u32 priority = preemption_priorities[core_id]; - - if (scheduled_queue[core_id].size(priority) > 0) { - if (scheduled_queue[core_id].size(priority) > 1) { - scheduled_queue[core_id].front(priority)->IncrementYieldCount(); - } - scheduled_queue[core_id].yield(priority); - if (scheduled_queue[core_id].size(priority) > 1) { - scheduled_queue[core_id].front(priority)->IncrementYieldCount(); - } - } - - Thread* current_thread = - scheduled_queue[core_id].empty() ? nullptr : scheduled_queue[core_id].front(); - Thread* winner = nullptr; - for (auto& thread : suggested_queue[core_id]) { - const s32 source_core = thread->GetProcessorID(); - if (thread->GetPriority() != priority) { - continue; - } - if (source_core >= 0) { - Thread* next_thread = scheduled_queue[source_core].empty() - ? nullptr - : scheduled_queue[source_core].front(); - if (next_thread != nullptr && next_thread->GetPriority() < 2) { - break; - } - if (next_thread == thread) { - continue; - } - } - if (current_thread != nullptr && - current_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks()) { - winner = thread; - break; - } - } - - if (winner != nullptr) { - TransferToCore(winner->GetPriority(), s32(core_id), winner); - current_thread = - winner->GetPriority() <= current_thread->GetPriority() ? winner : current_thread; - } - - if (current_thread != nullptr && current_thread->GetPriority() > priority) { - for (auto& thread : suggested_queue[core_id]) { - const s32 source_core = thread->GetProcessorID(); - if (thread->GetPriority() < priority) { - continue; - } - if (source_core >= 0) { - Thread* next_thread = scheduled_queue[source_core].empty() - ? nullptr - : scheduled_queue[source_core].front(); - if (next_thread != nullptr && next_thread->GetPriority() < 2) { - break; - } - if (next_thread == thread) { - continue; - } - } - if (current_thread != nullptr && - current_thread->GetLastRunningTicks() >= thread->GetLastRunningTicks()) { - winner = thread; - break; - } - } - - if (winner != nullptr) { - TransferToCore(winner->GetPriority(), s32(core_id), winner); - current_thread = winner; - } - } - - is_reselection_pending.store(true, std::memory_order_release); - } -} - -void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule, - Core::EmuThreadHandle global_thread) { - u32 current_core = global_thread.host_handle; - bool must_context_switch = global_thread.guest_handle != InvalidHandle && - (current_core < Core::Hardware::NUM_CPU_CORES); - while (cores_pending_reschedule != 0) { - u32 core = Common::CountTrailingZeroes32(cores_pending_reschedule); - ASSERT(core < Core::Hardware::NUM_CPU_CORES); - if (!must_context_switch || core != current_core) { - auto& phys_core = kernel.PhysicalCore(core); - phys_core.Interrupt(); - } else { - must_context_switch = true; - } - cores_pending_reschedule &= ~(1U << core); - } - if (must_context_switch) { - auto& core_scheduler = kernel.CurrentScheduler(); - kernel.ExitSVCProfile(); - core_scheduler.TryDoContextSwitch(); - kernel.EnterSVCProfile(); - } -} - -void GlobalScheduler::Suggest(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - suggested_queue[core].add(thread, priority); -} - -void GlobalScheduler::Unsuggest(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - suggested_queue[core].remove(thread, priority); -} - -void GlobalScheduler::Schedule(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); - scheduled_queue[core].add(thread, priority); -} - -void GlobalScheduler::SchedulePrepend(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); - scheduled_queue[core].add(thread, priority, false); -} - -void GlobalScheduler::Reschedule(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - scheduled_queue[core].remove(thread, priority); - scheduled_queue[core].add(thread, priority); -} - -void GlobalScheduler::Unschedule(u32 priority, std::size_t core, Thread* thread) { - ASSERT(is_locked); - scheduled_queue[core].remove(thread, priority); -} - -void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread* thread) { - ASSERT(is_locked); - const bool schedulable = thread->GetPriority() < THREADPRIO_COUNT; - const s32 source_core = thread->GetProcessorID(); - if (source_core == destination_core || !schedulable) { - return; - } - thread->SetProcessorID(destination_core); - if (source_core >= 0) { - Unschedule(priority, static_cast(source_core), thread); - } - if (destination_core >= 0) { - Unsuggest(priority, static_cast(destination_core), thread); - Schedule(priority, static_cast(destination_core), thread); - } - if (source_core >= 0) { - Suggest(priority, static_cast(source_core), thread); - } -} - -bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, - const Thread* winner) { - if (current_thread == winner) { - current_thread->IncrementYieldCount(); - return true; - } else { - is_reselection_pending.store(true, std::memory_order_release); - return false; - } -} - -void GlobalScheduler::AdjustSchedulingOnStatus(Thread* thread, u32 old_flags) { - if (old_flags == thread->scheduling_state) { - return; - } - ASSERT(is_locked); - - if (old_flags == static_cast(ThreadSchedStatus::Runnable)) { - // In this case the thread was running, now it's pausing/exitting - if (thread->processor_id >= 0) { - Unschedule(thread->current_priority, static_cast(thread->processor_id), thread); - } - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (core != static_cast(thread->processor_id) && - thread->affinity_mask.GetAffinity(core)) { - Unsuggest(thread->current_priority, core, thread); - } - } - } else if (thread->scheduling_state == static_cast(ThreadSchedStatus::Runnable)) { - // The thread is now set to running from being stopped - if (thread->processor_id >= 0) { - Schedule(thread->current_priority, static_cast(thread->processor_id), thread); - } - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (core != static_cast(thread->processor_id) && - thread->affinity_mask.GetAffinity(core)) { - Suggest(thread->current_priority, core, thread); - } - } - } - - SetReselectionPending(); -} - -void GlobalScheduler::AdjustSchedulingOnPriority(Thread* thread, u32 old_priority) { - if (thread->scheduling_state != static_cast(ThreadSchedStatus::Runnable)) { - return; - } - ASSERT(is_locked); - if (thread->processor_id >= 0) { - Unschedule(old_priority, static_cast(thread->processor_id), thread); - } - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (core != static_cast(thread->processor_id) && - thread->affinity_mask.GetAffinity(core)) { - Unsuggest(old_priority, core, thread); - } - } - - if (thread->processor_id >= 0) { - if (thread == kernel.CurrentScheduler().GetCurrentThread()) { - SchedulePrepend(thread->current_priority, static_cast(thread->processor_id), - thread); - } else { - Schedule(thread->current_priority, static_cast(thread->processor_id), thread); - } - } - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (core != static_cast(thread->processor_id) && - thread->affinity_mask.GetAffinity(core)) { - Suggest(thread->current_priority, core, thread); - } - } - thread->IncrementYieldCount(); - SetReselectionPending(); -} - -void GlobalScheduler::AdjustSchedulingOnAffinity(Thread* thread, u64 old_affinity_mask, - s32 old_core) { - if (thread->scheduling_state != static_cast(ThreadSchedStatus::Runnable) || - thread->current_priority >= THREADPRIO_COUNT) { - return; - } - ASSERT(is_locked); - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (((old_affinity_mask >> core) & 1) != 0) { - if (core == static_cast(old_core)) { - Unschedule(thread->current_priority, core, thread); - } else { - Unsuggest(thread->current_priority, core, thread); - } - } - } - - for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - if (thread->affinity_mask.GetAffinity(core)) { - if (core == static_cast(thread->processor_id)) { - Schedule(thread->current_priority, core, thread); - } else { - Suggest(thread->current_priority, core, thread); - } - } - } - - thread->IncrementYieldCount(); - SetReselectionPending(); -} - -void GlobalScheduler::Shutdown() { - for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - scheduled_queue[core].clear(); - suggested_queue[core].clear(); - } - thread_list.clear(); -} - -void GlobalScheduler::Lock() { - Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadID(); - ASSERT(!current_thread.IsInvalid()); - if (current_thread == current_owner) { - ++scope_lock; - } else { - inner_lock.lock(); - is_locked = true; - current_owner = current_thread; - ASSERT(current_owner != Core::EmuThreadHandle::InvalidHandle()); - scope_lock = 1; - } -} - -void GlobalScheduler::Unlock() { - if (--scope_lock != 0) { - ASSERT(scope_lock > 0); - return; - } - u32 cores_pending_reschedule = SelectThreads(); - Core::EmuThreadHandle leaving_thread = current_owner; - current_owner = Core::EmuThreadHandle::InvalidHandle(); - scope_lock = 1; - is_locked = false; - inner_lock.unlock(); - EnableInterruptAndSchedule(cores_pending_reschedule, leaving_thread); -} - -Scheduler::Scheduler(Core::System& system, std::size_t core_id) : system(system), core_id(core_id) { - switch_fiber = std::make_shared(std::function(OnSwitch), this); -} - -Scheduler::~Scheduler() = default; - -bool Scheduler::HaveReadyThreads() const { - return system.GlobalScheduler().HaveReadyThreads(core_id); -} - -Thread* Scheduler::GetCurrentThread() const { - if (current_thread) { - return current_thread.get(); - } - return idle_thread.get(); -} - -Thread* Scheduler::GetSelectedThread() const { - return selected_thread.get(); -} - -u64 Scheduler::GetLastContextSwitchTicks() const { - return last_context_switch_time; -} - -void Scheduler::TryDoContextSwitch() { - auto& phys_core = system.Kernel().CurrentPhysicalCore(); - if (phys_core.IsInterrupted()) { - phys_core.ClearInterrupt(); - } - guard.lock(); - if (is_context_switch_pending) { - SwitchContext(); - } else { - guard.unlock(); - } -} - -void Scheduler::OnThreadStart() { - SwitchContextStep2(); -} - -void Scheduler::Unload(Thread* thread) { - if (thread) { - thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); - thread->SetIsRunning(false); - if (thread->IsContinuousOnSVC() && !thread->IsHLEThread()) { - system.ArmInterface(core_id).ExceptionalExit(); - thread->SetContinuousOnSVC(false); - } - if (!thread->IsHLEThread() && !thread->HasExited()) { - Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); - cpu_core.SaveContext(thread->GetContext32()); - cpu_core.SaveContext(thread->GetContext64()); - // Save the TPIDR_EL0 system register in case it was modified. - thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); - cpu_core.ClearExclusiveState(); - } - thread->context_guard.unlock(); - } -} - -void Scheduler::Unload() { - Unload(current_thread.get()); -} - -void Scheduler::Reload(Thread* thread) { - if (thread) { - ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, - "Thread must be runnable."); - - // Cancel any outstanding wakeup events for this thread - thread->SetIsRunning(true); - thread->SetWasRunning(false); - thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); - - auto* const thread_owner_process = thread->GetOwnerProcess(); - if (thread_owner_process != nullptr) { - system.Kernel().MakeCurrentProcess(thread_owner_process); - } - if (!thread->IsHLEThread()) { - Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); - cpu_core.LoadContext(thread->GetContext32()); - cpu_core.LoadContext(thread->GetContext64()); - cpu_core.SetTlsAddress(thread->GetTLSAddress()); - cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); - cpu_core.ClearExclusiveState(); - } - } -} - -void Scheduler::Reload() { - Reload(current_thread.get()); -} - -void Scheduler::SwitchContextStep2() { - // Load context of new thread - Reload(selected_thread.get()); - - TryDoContextSwitch(); -} - -void Scheduler::SwitchContext() { - current_thread_prev = current_thread; - selected_thread = selected_thread_set; - Thread* previous_thread = current_thread_prev.get(); - Thread* new_thread = selected_thread.get(); - current_thread = selected_thread; - - is_context_switch_pending = false; - - if (new_thread == previous_thread) { - guard.unlock(); - return; - } - - Process* const previous_process = system.Kernel().CurrentProcess(); - - UpdateLastContextSwitchTime(previous_thread, previous_process); - - // Save context for previous thread - Unload(previous_thread); - - std::shared_ptr* old_context; - if (previous_thread != nullptr) { - old_context = &previous_thread->GetHostContext(); - } else { - old_context = &idle_thread->GetHostContext(); - } - guard.unlock(); - - Common::Fiber::YieldTo(*old_context, switch_fiber); - /// When a thread wakes up, the scheduler may have changed to other in another core. - auto& next_scheduler = system.Kernel().CurrentScheduler(); - next_scheduler.SwitchContextStep2(); -} - -void Scheduler::OnSwitch(void* this_scheduler) { - Scheduler* sched = static_cast(this_scheduler); - sched->SwitchToCurrent(); -} - -void Scheduler::SwitchToCurrent() { - while (true) { - { - std::scoped_lock lock{guard}; - selected_thread = selected_thread_set; - current_thread = selected_thread; - is_context_switch_pending = false; - } - const auto is_switch_pending = [this] { - std::scoped_lock lock{guard}; - return is_context_switch_pending; - }; - do { - if (current_thread != nullptr && !current_thread->IsHLEThread()) { - current_thread->context_guard.lock(); - if (!current_thread->IsRunnable()) { - current_thread->context_guard.unlock(); - break; - } - if (static_cast(current_thread->GetProcessorID()) != core_id) { - current_thread->context_guard.unlock(); - break; - } - } - std::shared_ptr* next_context; - if (current_thread != nullptr) { - next_context = ¤t_thread->GetHostContext(); - } else { - next_context = &idle_thread->GetHostContext(); - } - Common::Fiber::YieldTo(switch_fiber, *next_context); - } while (!is_switch_pending()); - } -} - -void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { - const u64 prev_switch_ticks = last_context_switch_time; - const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks(); - const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; - - if (thread != nullptr) { - thread->UpdateCPUTimeTicks(update_ticks); - } - - if (process != nullptr) { - process->UpdateCPUTimeTicks(update_ticks); - } - - last_context_switch_time = most_recent_switch_ticks; -} - -void Scheduler::Initialize() { - std::string name = "Idle Thread Id:" + std::to_string(core_id); - std::function init_func = Core::CpuManager::GetIdleThreadStartFunc(); - void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); - ThreadType type = static_cast(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE); - auto thread_res = Thread::Create(system, type, name, 0, 64, 0, static_cast(core_id), 0, - nullptr, std::move(init_func), init_func_parameter); - idle_thread = std::move(thread_res).Unwrap(); -} - -void Scheduler::Shutdown() { - current_thread = nullptr; - selected_thread = nullptr; -} - -SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { - kernel.GlobalScheduler().Lock(); -} - -SchedulerLock::~SchedulerLock() { - kernel.GlobalScheduler().Unlock(); -} - -SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, - Thread* time_task, s64 nanoseconds) - : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{ - nanoseconds} { - event_handle = InvalidHandle; -} - -SchedulerLockAndSleep::~SchedulerLockAndSleep() { - if (sleep_cancelled) { - return; - } - auto& time_manager = kernel.TimeManager(); - time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); -} - -void SchedulerLockAndSleep::Release() { - if (sleep_cancelled) { - return; - } - auto& time_manager = kernel.TimeManager(); - time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); - sleep_cancelled = true; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h deleted file mode 100644 index 68db4a5ef..000000000 --- a/src/core/hle/kernel/scheduler.h +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include -#include - -#include "common/common_types.h" -#include "common/multi_level_queue.h" -#include "common/spin_lock.h" -#include "core/hardware_properties.h" -#include "core/hle/kernel/thread.h" - -namespace Common { -class Fiber; -} - -namespace Core { -class ARM_Interface; -class System; -} // namespace Core - -namespace Kernel { - -class KernelCore; -class Process; -class SchedulerLock; - -class GlobalScheduler final { -public: - explicit GlobalScheduler(KernelCore& kernel); - ~GlobalScheduler(); - - /// Adds a new thread to the scheduler - void AddThread(std::shared_ptr thread); - - /// Removes a thread from the scheduler - void RemoveThread(std::shared_ptr thread); - - /// Returns a list of all threads managed by the scheduler - const std::vector>& GetThreadList() const { - return thread_list; - } - - /// Notify the scheduler a thread's status has changed. - void AdjustSchedulingOnStatus(Thread* thread, u32 old_flags); - - /// Notify the scheduler a thread's priority has changed. - void AdjustSchedulingOnPriority(Thread* thread, u32 old_priority); - - /// Notify the scheduler a thread's core and/or affinity mask has changed. - void AdjustSchedulingOnAffinity(Thread* thread, u64 old_affinity_mask, s32 old_core); - - /** - * Takes care of selecting the new scheduled threads in three steps: - * - * 1. First a thread is selected from the top of the priority queue. If no thread - * is obtained then we move to step two, else we are done. - * - * 2. Second we try to get a suggested thread that's not assigned to any core or - * that is not the top thread in that core. - * - * 3. Third is no suggested thread is found, we do a second pass and pick a running - * thread in another core and swap it with its current thread. - * - * returns the cores needing scheduling. - */ - u32 SelectThreads(); - - bool HaveReadyThreads(std::size_t core_id) const { - return !scheduled_queue[core_id].empty(); - } - - /** - * Takes a thread and moves it to the back of the it's priority list. - * - * @note This operation can be redundant and no scheduling is changed if marked as so. - */ - bool YieldThread(Thread* thread); - - /** - * Takes a thread and moves it to the back of the it's priority list. - * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or - * a better priority than the next thread in the core. - * - * @note This operation can be redundant and no scheduling is changed if marked as so. - */ - bool YieldThreadAndBalanceLoad(Thread* thread); - - /** - * Takes a thread and moves it out of the scheduling queue. - * and into the suggested queue. If no thread can be scheduled afterwards in that core, - * a suggested thread is obtained instead. - * - * @note This operation can be redundant and no scheduling is changed if marked as so. - */ - bool YieldThreadAndWaitForLoadBalancing(Thread* thread); - - /** - * Rotates the scheduling queues of threads at a preemption priority and then does - * some core rebalancing. Preemption priorities can be found in the array - * 'preemption_priorities'. - * - * @note This operation happens every 10ms. - */ - void PreemptThreads(); - - u32 CpuCoresCount() const { - return Core::Hardware::NUM_CPU_CORES; - } - - void SetReselectionPending() { - is_reselection_pending.store(true, std::memory_order_release); - } - - bool IsReselectionPending() const { - return is_reselection_pending.load(std::memory_order_acquire); - } - - void Shutdown(); - -private: - friend class SchedulerLock; - - /// Lock the scheduler to the current thread. - void Lock(); - - /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling - /// and reschedules current core if needed. - void Unlock(); - - void EnableInterruptAndSchedule(u32 cores_pending_reschedule, - Core::EmuThreadHandle global_thread); - - /** - * Add a thread to the suggested queue of a cpu core. Suggested threads may be - * picked if no thread is scheduled to run on the core. - */ - void Suggest(u32 priority, std::size_t core, Thread* thread); - - /** - * Remove a thread to the suggested queue of a cpu core. Suggested threads may be - * picked if no thread is scheduled to run on the core. - */ - void Unsuggest(u32 priority, std::size_t core, Thread* thread); - - /** - * Add a thread to the scheduling queue of a cpu core. The thread is added at the - * back the queue in its priority level. - */ - void Schedule(u32 priority, std::size_t core, Thread* thread); - - /** - * Add a thread to the scheduling queue of a cpu core. The thread is added at the - * front the queue in its priority level. - */ - void SchedulePrepend(u32 priority, std::size_t core, Thread* thread); - - /// Reschedule an already scheduled thread based on a new priority - void Reschedule(u32 priority, std::size_t core, Thread* thread); - - /// Unschedules a thread. - void Unschedule(u32 priority, std::size_t core, Thread* thread); - - /** - * Transfers a thread into an specific core. If the destination_core is -1 - * it will be unscheduled from its source code and added into its suggested - * queue. - */ - void TransferToCore(u32 priority, s32 destination_core, Thread* thread); - - bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner); - - static constexpr u32 min_regular_priority = 2; - std::array, Core::Hardware::NUM_CPU_CORES> - scheduled_queue; - std::array, Core::Hardware::NUM_CPU_CORES> - suggested_queue; - std::atomic is_reselection_pending{false}; - - // The priority levels at which the global scheduler preempts threads every 10 ms. They are - // ordered from Core 0 to Core 3. - std::array preemption_priorities = {59, 59, 59, 62}; - - /// Scheduler lock mechanisms. - bool is_locked{}; - std::mutex inner_lock; - std::atomic scope_lock{}; - Core::EmuThreadHandle current_owner{Core::EmuThreadHandle::InvalidHandle()}; - - Common::SpinLock global_list_guard{}; - - /// Lists all thread ids that aren't deleted/etc. - std::vector> thread_list; - KernelCore& kernel; -}; - -class Scheduler final { -public: - explicit Scheduler(Core::System& system, std::size_t core_id); - ~Scheduler(); - - /// Returns whether there are any threads that are ready to run. - bool HaveReadyThreads() const; - - /// Reschedules to the next available thread (call after current thread is suspended) - void TryDoContextSwitch(); - - /// The next two are for SingleCore Only. - /// Unload current thread before preempting core. - void Unload(Thread* thread); - void Unload(); - /// Reload current thread after core preemption. - void Reload(Thread* thread); - void Reload(); - - /// Gets the current running thread - Thread* GetCurrentThread() const; - - /// Gets the currently selected thread from the top of the multilevel queue - Thread* GetSelectedThread() const; - - /// Gets the timestamp for the last context switch in ticks. - u64 GetLastContextSwitchTicks() const; - - bool ContextSwitchPending() const { - return is_context_switch_pending; - } - - void Initialize(); - - /// Shutdowns the scheduler. - void Shutdown(); - - void OnThreadStart(); - - std::shared_ptr& ControlContext() { - return switch_fiber; - } - - const std::shared_ptr& ControlContext() const { - return switch_fiber; - } - -private: - friend class GlobalScheduler; - - /// Switches the CPU's active thread context to that of the specified thread - void SwitchContext(); - - /// When a thread wakes up, it must run this through it's new scheduler - void SwitchContextStep2(); - - /** - * Called on every context switch to update the internal timestamp - * This also updates the running time ticks for the given thread and - * process using the following difference: - * - * ticks += most_recent_ticks - last_context_switch_ticks - * - * The internal tick timestamp for the scheduler is simply the - * most recent tick count retrieved. No special arithmetic is - * applied to it. - */ - void UpdateLastContextSwitchTime(Thread* thread, Process* process); - - static void OnSwitch(void* this_scheduler); - void SwitchToCurrent(); - - std::shared_ptr current_thread = nullptr; - std::shared_ptr selected_thread = nullptr; - std::shared_ptr current_thread_prev = nullptr; - std::shared_ptr selected_thread_set = nullptr; - std::shared_ptr idle_thread = nullptr; - - std::shared_ptr switch_fiber = nullptr; - - Core::System& system; - u64 last_context_switch_time = 0; - u64 idle_selection_count = 0; - const std::size_t core_id; - - Common::SpinLock guard{}; - - bool is_context_switch_pending = false; -}; - -class SchedulerLock { -public: - [[nodiscard]] explicit SchedulerLock(KernelCore& kernel); - ~SchedulerLock(); - -protected: - KernelCore& kernel; -}; - -class SchedulerLockAndSleep : public SchedulerLock { -public: - explicit SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task, - s64 nanoseconds); - ~SchedulerLockAndSleep(); - - void CancelSleep() { - sleep_cancelled = true; - } - - void Release(); - -private: - Handle& event_handle; - Thread* time_task; - s64 nanoseconds; - bool sleep_cancelled{}; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8c19f2534..bf2c90028 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -14,9 +14,9 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9742aaf4c..2612a6b0d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -24,6 +24,7 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/memory_block.h" #include "core/hle/kernel/memory/page_table.h" @@ -32,7 +33,6 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/resource_limit.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_types.h" @@ -332,7 +332,8 @@ static ResultCode ConnectToNamedPort32(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(); + auto& kernel = system.Kernel(); + const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); std::shared_ptr session = handle_table.Get(handle); if (!session) { LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); @@ -341,9 +342,9 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); - auto thread = system.CurrentScheduler().GetCurrentThread(); + auto thread = kernel.CurrentScheduler()->GetCurrentThread(); { - SchedulerLock lock(system.Kernel()); + SchedulerLock lock(kernel); thread->InvalidateHLECallback(); thread->SetStatus(ThreadStatus::WaitIPC); session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); @@ -352,12 +353,12 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { if (thread->HasHLECallback()) { Handle event_handle = thread->GetHLETimeEvent(); if (event_handle != InvalidHandle) { - auto& time_manager = system.Kernel().TimeManager(); + auto& time_manager = kernel.TimeManager(); time_manager.UnscheduleTimeEvent(event_handle); } { - SchedulerLock lock(system.Kernel()); + SchedulerLock lock(kernel); auto* sync_object = thread->GetHLESyncObject(); sync_object->RemoveWaitingThread(SharedFrom(thread)); } @@ -665,7 +666,7 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { handle_debug_buffer(info1, info2); - auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); + auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); const auto thread_processor_id = current_thread->GetProcessorID(); system.ArmInterface(static_cast(thread_processor_id)).LogBacktrace(); } @@ -917,7 +918,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& scheduler = *system.Kernel().CurrentScheduler(); const auto* const current_thread = scheduler.GetCurrentThread(); const bool same_thread = current_thread == thread.get(); @@ -1085,7 +1086,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act return ERR_INVALID_HANDLE; } - if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { + if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) { LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); return ERR_BUSY; } @@ -1118,7 +1119,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H return ERR_INVALID_HANDLE; } - if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { + if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) { LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); return ERR_BUSY; } @@ -1475,7 +1476,7 @@ static void ExitProcess(Core::System& system) { current_process->PrepareForTermination(); // Kill the current thread - system.CurrentScheduler().GetCurrentThread()->Stop(); + system.Kernel().CurrentScheduler()->GetCurrentThread()->Stop(); } static void ExitProcess32(Core::System& system) { @@ -1576,8 +1577,8 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) { static void ExitThread(Core::System& system) { LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); - auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); - system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); + auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); + system.GlobalSchedulerContext().RemoveThread(SharedFrom(current_thread)); current_thread->Stop(); } @@ -1590,37 +1591,31 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); enum class SleepType : s64 { - YieldWithoutLoadBalancing = 0, - YieldWithLoadBalancing = -1, + YieldWithoutCoreMigration = 0, + YieldWithCoreMigration = -1, YieldAndWaitForLoadBalancing = -2, }; - auto& scheduler = system.CurrentScheduler(); - auto* const current_thread = scheduler.GetCurrentThread(); - bool is_redundant = false; - + auto& scheduler = *system.Kernel().CurrentScheduler(); if (nanoseconds <= 0) { switch (static_cast(nanoseconds)) { - case SleepType::YieldWithoutLoadBalancing: { - auto pair = current_thread->YieldSimple(); - is_redundant = pair.second; + case SleepType::YieldWithoutCoreMigration: { + scheduler.YieldWithoutCoreMigration(); break; } - case SleepType::YieldWithLoadBalancing: { - auto pair = current_thread->YieldAndBalanceLoad(); - is_redundant = pair.second; + case SleepType::YieldWithCoreMigration: { + scheduler.YieldWithCoreMigration(); break; } case SleepType::YieldAndWaitForLoadBalancing: { - auto pair = current_thread->YieldAndWaitForLoadBalancing(); - is_redundant = pair.second; + scheduler.YieldToAnyThread(); break; } default: UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); } } else { - current_thread->Sleep(nanoseconds); + scheduler.GetCurrentThread()->Sleep(nanoseconds); } } @@ -1656,8 +1651,8 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); auto& kernel = system.Kernel(); Handle event_handle; - Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); - auto* const current_process = system.Kernel().CurrentProcess(); + Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread(); + auto* const current_process = kernel.CurrentProcess(); { SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); const auto& handle_table = current_process->GetHandleTable(); @@ -2627,7 +2622,7 @@ void Call(Core::System& system, u32 immediate) { auto& kernel = system.Kernel(); kernel.EnterSVCProfile(); - auto* thread = system.CurrentScheduler().GetCurrentThread(); + auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); thread->SetContinuousOnSVC(true); const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp index 8b875d853..342fb4516 100644 --- a/src/core/hle/kernel/synchronization.cpp +++ b/src/core/hle/kernel/synchronization.cpp @@ -5,8 +5,8 @@ #include "core/core.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/synchronization.h" #include "core/hle/kernel/synchronization_object.h" #include "core/hle/kernel/thread.h" @@ -37,7 +37,7 @@ void Synchronization::SignalObject(SynchronizationObject& obj) const { std::pair Synchronization::WaitFor( std::vector>& sync_objects, s64 nano_seconds) { auto& kernel = system.Kernel(); - auto* const thread = system.CurrentScheduler().GetCurrentThread(); + auto* const thread = kernel.CurrentScheduler()->GetCurrentThread(); Handle event_handle = InvalidHandle; { SchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 38b4a0987..804e07f2b 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -17,10 +17,10 @@ #include "core/hardware_properties.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/result.h" @@ -186,9 +186,11 @@ ResultVal> Thread::Create(Core::System& system, ThreadTy thread->status = ThreadStatus::Dormant; thread->entry_point = entry_point; thread->stack_top = stack_top; + thread->disable_count = 1; thread->tpidr_el0 = 0; thread->nominal_priority = thread->current_priority = priority; - thread->last_running_ticks = 0; + thread->schedule_count = -1; + thread->last_scheduled_tick = 0; thread->processor_id = processor_id; thread->ideal_core = processor_id; thread->affinity_mask.SetAffinity(processor_id, true); @@ -201,7 +203,7 @@ ResultVal> Thread::Create(Core::System& system, ThreadTy thread->owner_process = owner_process; thread->type = type_flags; if ((type_flags & THREADTYPE_IDLE) == 0) { - auto& scheduler = kernel.GlobalScheduler(); + auto& scheduler = kernel.GlobalSchedulerContext(); scheduler.AddThread(thread); } if (owner_process) { @@ -402,39 +404,12 @@ ResultCode Thread::Sleep(s64 nanoseconds) { return RESULT_SUCCESS; } -std::pair Thread::YieldSimple() { - bool is_redundant = false; - { - SchedulerLock lock(kernel); - is_redundant = kernel.GlobalScheduler().YieldThread(this); - } - return {RESULT_SUCCESS, is_redundant}; -} - -std::pair Thread::YieldAndBalanceLoad() { - bool is_redundant = false; - { - SchedulerLock lock(kernel); - is_redundant = kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); - } - return {RESULT_SUCCESS, is_redundant}; -} - -std::pair Thread::YieldAndWaitForLoadBalancing() { - bool is_redundant = false; - { - SchedulerLock lock(kernel); - is_redundant = kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); - } - return {RESULT_SUCCESS, is_redundant}; -} - void Thread::AddSchedulingFlag(ThreadSchedFlags flag) { const u32 old_state = scheduling_state; pausing_state |= static_cast(flag); const u32 base_scheduling = static_cast(GetSchedulingStatus()); scheduling_state = base_scheduling | pausing_state; - kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) { @@ -442,19 +417,20 @@ void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) { pausing_state &= ~static_cast(flag); const u32 base_scheduling = static_cast(GetSchedulingStatus()); scheduling_state = base_scheduling | pausing_state; - kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { const u32 old_state = scheduling_state; scheduling_state = (scheduling_state & static_cast(ThreadSchedMasks::HighMask)) | static_cast(new_status); - kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } void Thread::SetCurrentPriority(u32 new_priority) { const u32 old_priority = std::exchange(current_priority, new_priority); - kernel.GlobalScheduler().AdjustSchedulingOnPriority(this, old_priority); + KScheduler::OnThreadPriorityChanged(kernel, this, kernel.CurrentScheduler()->GetCurrentThread(), + old_priority); } ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { @@ -480,10 +456,10 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { if (use_override) { ideal_core_override = new_core; } else { - const auto old_affinity_mask = affinity_mask.GetAffinityMask(); + const auto old_affinity_mask = affinity_mask; affinity_mask.SetAffinityMask(new_affinity_mask); ideal_core = new_core; - if (old_affinity_mask != new_affinity_mask) { + if (old_affinity_mask.GetAffinityMask() != new_affinity_mask) { const s32 old_core = processor_id; if (processor_id >= 0 && !affinity_mask.GetAffinity(processor_id)) { if (static_cast(ideal_core) < 0) { @@ -493,7 +469,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { processor_id = ideal_core; } } - kernel.GlobalScheduler().AdjustSchedulingOnAffinity(this, old_affinity_mask, old_core); + KScheduler::OnThreadAffinityMaskChanged(kernel, this, old_affinity_mask, old_core); } } return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 5192ecff1..f1aa358a4 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -28,10 +28,10 @@ class System; namespace Kernel { -class GlobalScheduler; +class GlobalSchedulerContext; class KernelCore; class Process; -class Scheduler; +class KScheduler; enum ThreadPriority : u32 { THREADPRIO_HIGHEST = 0, ///< Highest thread priority @@ -346,8 +346,11 @@ public: void SetStatus(ThreadStatus new_status); - u64 GetLastRunningTicks() const { - return last_running_ticks; + constexpr s64 GetLastScheduledTick() const { + return this->last_scheduled_tick; + } + constexpr void SetLastScheduledTick(s64 tick) { + this->last_scheduled_tick = tick; } u64 GetTotalCPUTimeTicks() const { @@ -362,10 +365,18 @@ public: return processor_id; } + s32 GetActiveCore() const { + return GetProcessorID(); + } + void SetProcessorID(s32 new_core) { processor_id = new_core; } + void SetActiveCore(s32 new_core) { + processor_id = new_core; + } + Process* GetOwnerProcess() { return owner_process; } @@ -479,21 +490,11 @@ public: /// Sleeps this thread for the given amount of nanoseconds. ResultCode Sleep(s64 nanoseconds); - /// Yields this thread without rebalancing loads. - std::pair YieldSimple(); - - /// Yields this thread and does a load rebalancing. - std::pair YieldAndBalanceLoad(); - - /// Yields this thread and if the core is left idle, loads are rebalanced - std::pair YieldAndWaitForLoadBalancing(); - - void IncrementYieldCount() { - yield_count++; + constexpr s64 GetYieldScheduleCount() const { + return this->schedule_count; } - - u64 GetYieldCount() const { - return yield_count; + constexpr void SetYieldScheduleCount(s64 count) { + this->schedule_count = count; } ThreadSchedStatus GetSchedulingStatus() const { @@ -569,9 +570,62 @@ public: return has_exited; } + struct QueueEntry { + private: + Thread* prev; + Thread* next; + + public: + constexpr QueueEntry() : prev(nullptr), next(nullptr) { /* ... */ + } + + constexpr void Initialize() { + this->prev = nullptr; + this->next = nullptr; + } + + constexpr Thread* GetPrev() const { + return this->prev; + } + constexpr Thread* GetNext() const { + return this->next; + } + constexpr void SetPrev(Thread* t) { + this->prev = t; + } + constexpr void SetNext(Thread* t) { + this->next = t; + } + }; + + constexpr QueueEntry& GetPriorityQueueEntry(s32 core) { + return this->per_core_priority_queue_entry[core]; + } + constexpr const QueueEntry& GetPriorityQueueEntry(s32 core) const { + return this->per_core_priority_queue_entry[core]; + } + + s32 GetDisableDispatchCount() const { + return disable_count; + } + + void DisableDispatch() { + ASSERT(GetDisableDispatchCount() >= 0); + disable_count++; + } + + void EnableDispatch() { + ASSERT(GetDisableDispatchCount() > 0); + disable_count--; + } + + ThreadStatus status = ThreadStatus::Dormant; + u32 scheduling_state = 0; + private: - friend class GlobalScheduler; - friend class Scheduler; + friend class GlobalSchedulerContext; + friend class KScheduler; + friend class Process; void SetSchedulingStatus(ThreadSchedStatus new_status); void AddSchedulingFlag(ThreadSchedFlags flag); @@ -586,10 +640,9 @@ private: u64 thread_id = 0; - ThreadStatus status = ThreadStatus::Dormant; - VAddr entry_point = 0; VAddr stack_top = 0; + std::atomic_int disable_count = 0; ThreadType type; @@ -603,9 +656,8 @@ private: u32 current_priority = 0; u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. - u64 last_running_ticks = 0; ///< CPU tick when thread was last running - u64 yield_count = 0; ///< Number of redundant yields carried by this thread. - ///< a redundant yield is one where no scheduling is changed + s64 schedule_count{}; + s64 last_scheduled_tick{}; s32 processor_id = 0; @@ -647,7 +699,9 @@ private: Handle hle_time_event; SynchronizationObject* hle_object; - Scheduler* scheduler = nullptr; + KScheduler* scheduler = nullptr; + + QueueEntry per_core_priority_queue_entry[Core::Hardware::NUM_CPU_CORES]{}; u32 ideal_core{0xFFFFFFFF}; KAffinityMask affinity_mask{}; @@ -655,7 +709,6 @@ private: s32 ideal_core_override = -1; u32 affinity_override_count = 0; - u32 scheduling_state = 0; u32 pausing_state = 0; bool is_running = false; bool is_waiting_on_sync = false; diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index caf329bfb..8e4769694 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -7,8 +7,8 @@ #include "core/core_timing.h" #include "core/core_timing_util.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/time_manager.h" diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 7b7ac282d..abc753d5d 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -10,8 +10,8 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/service/time/interface.h" #include "core/hle/service/time/time.h" #include "core/hle/service/time/time_sharedmemory.h" diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index c4ae1d61f..546a2cd4d 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -13,10 +13,10 @@ #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/synchronization_object.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" @@ -101,7 +101,7 @@ std::vector> WaitTreeItem::MakeThreadItemList() }; const auto& system = Core::System::GetInstance(); - add_threads(system.GlobalScheduler().GetThreadList()); + add_threads(system.GlobalSchedulerContext().GetThreadList()); return item_list; } @@ -356,7 +356,7 @@ std::vector> WaitTreeThread::GetChildren() const { .arg(thread.GetPriority()) .arg(thread.GetNominalPriority()))); list.push_back(std::make_unique( - tr("last running ticks = %1").arg(thread.GetLastRunningTicks()))); + tr("last running ticks = %1").arg(thread.GetLastScheduledTick()))); const VAddr mutex_wait_address = thread.GetMutexWaitAddress(); if (mutex_wait_address != 0) { -- cgit v1.2.3 From e31cb50405daae5d7189a98da272ca6c08ca8e04 Mon Sep 17 00:00:00 2001 From: comex Date: Mon, 31 Aug 2020 10:38:58 -0400 Subject: Fix "explicitly defaulted but implicitly deleted" warning `PhysicalCore`'s move assignment operator was declared as `= default`, but was implicitly deleted because `PhysicalCore` has fields of reference type. Switch to explicitly deleting it to avoid a Clang warning. The move *constructor* is still defaulted, and is required to exist due to the use of `std::vector`. --- src/core/hle/kernel/physical_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/physical_core.h') diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 37513130a..801d24c28 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -36,7 +36,7 @@ public: PhysicalCore& operator=(const PhysicalCore&) = delete; PhysicalCore(PhysicalCore&&) = default; - PhysicalCore& operator=(PhysicalCore&&) = default; + PhysicalCore& operator=(PhysicalCore&&) = delete; /// Initialize the core for the specified parameters. void Initialize(bool is_64_bit); -- cgit v1.2.3