core: De-globalize HLE lock (#7212)
This commit is contained in:
parent
83b329f6e1
commit
6ec079ede8
18 changed files with 66 additions and 92 deletions
|
@ -37,8 +37,9 @@ void DspInterface::EnableStretching(bool enable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DspInterface::OutputFrame(StereoFrame16 frame) {
|
void DspInterface::OutputFrame(StereoFrame16 frame) {
|
||||||
if (!sink)
|
if (!sink) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fifo.Push(frame.data(), frame.size());
|
fifo.Push(frame.data(), frame.size());
|
||||||
|
|
||||||
|
@ -49,8 +50,9 @@ void DspInterface::OutputFrame(StereoFrame16 frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DspInterface::OutputSample(std::array<s16, 2> sample) {
|
void DspInterface::OutputSample(std::array<s16, 2> sample) {
|
||||||
if (!sink)
|
if (!sink) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fifo.Push(&sample, 1);
|
fifo.Push(&sample, 1);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/lock.h"
|
|
||||||
#include "core/hle/service/dsp/dsp_dsp.h"
|
#include "core/hle/service/dsp/dsp_dsp.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
@ -411,17 +410,15 @@ std::array<u8, Memory::DSP_RAM_SIZE>& DspLle::GetDspMemory() {
|
||||||
void DspLle::SetInterruptHandler(
|
void DspLle::SetInterruptHandler(
|
||||||
std::function<void(Service::DSP::InterruptType type, DspPipe pipe)> handler) {
|
std::function<void(Service::DSP::InterruptType type, DspPipe pipe)> handler) {
|
||||||
impl->teakra.SetRecvDataHandler(0, [this, handler]() {
|
impl->teakra.SetRecvDataHandler(0, [this, handler]() {
|
||||||
if (!impl->loaded)
|
if (!impl->loaded) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
handler(Service::DSP::InterruptType::Zero, static_cast<DspPipe>(0));
|
handler(Service::DSP::InterruptType::Zero, static_cast<DspPipe>(0));
|
||||||
});
|
});
|
||||||
impl->teakra.SetRecvDataHandler(1, [this, handler]() {
|
impl->teakra.SetRecvDataHandler(1, [this, handler]() {
|
||||||
if (!impl->loaded)
|
if (!impl->loaded) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
handler(Service::DSP::InterruptType::One, static_cast<DspPipe>(0));
|
handler(Service::DSP::InterruptType::One, static_cast<DspPipe>(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -450,7 +447,6 @@ void DspLle::SetInterruptHandler(
|
||||||
impl->ReadPipe(static_cast<u8>(pipe),
|
impl->ReadPipe(static_cast<u8>(pipe),
|
||||||
impl->GetPipeReadableSize(static_cast<u8>(pipe)));
|
impl->GetPipeReadableSize(static_cast<u8>(pipe)));
|
||||||
} else {
|
} else {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
handler(Service::DSP::InterruptType::Pipe, static_cast<DspPipe>(pipe));
|
handler(Service::DSP::InterruptType::Pipe, static_cast<DspPipe>(pipe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2118,6 +2118,7 @@ void GMainWindow::OnLoadAmiibo() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock{system.Kernel().GetHLELock()};
|
||||||
if (nfc->IsTagActive()) {
|
if (nfc->IsTagActive()) {
|
||||||
QMessageBox::warning(this, tr("Error opening amiibo data file"),
|
QMessageBox::warning(this, tr("Error opening amiibo data file"),
|
||||||
tr("A tag is already in use."));
|
tr("A tag is already in use."));
|
||||||
|
@ -2148,6 +2149,7 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock{system.Kernel().GetHLELock()};
|
||||||
if (!nfc->LoadAmiibo(filename.toStdString())) {
|
if (!nfc->LoadAmiibo(filename.toStdString())) {
|
||||||
QMessageBox::warning(this, tr("Error opening amiibo data file"),
|
QMessageBox::warning(this, tr("Error opening amiibo data file"),
|
||||||
tr("Unable to open amiibo file \"%1\" for reading.").arg(filename));
|
tr("Unable to open amiibo file \"%1\" for reading.").arg(filename));
|
||||||
|
@ -2164,6 +2166,7 @@ void GMainWindow::OnRemoveAmiibo() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock{system.Kernel().GetHLELock()};
|
||||||
nfc->RemoveAmiibo();
|
nfc->RemoveAmiibo();
|
||||||
ui->action_Remove_Amiibo->setEnabled(false);
|
ui->action_Remove_Amiibo->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,8 +182,6 @@ add_library(citra_core STATIC
|
||||||
hle/kernel/vm_manager.h
|
hle/kernel/vm_manager.h
|
||||||
hle/kernel/wait_object.cpp
|
hle/kernel/wait_object.cpp
|
||||||
hle/kernel/wait_object.h
|
hle/kernel/wait_object.h
|
||||||
hle/lock.cpp
|
|
||||||
hle/lock.h
|
|
||||||
hle/mii.h
|
hle/mii.h
|
||||||
hle/mii.cpp
|
hle/mii.cpp
|
||||||
hle/result.h
|
hle/result.h
|
||||||
|
|
|
@ -104,7 +104,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||||
Signal signal{Signal::None};
|
Signal signal{Signal::None};
|
||||||
u32 param{};
|
u32 param{};
|
||||||
{
|
{
|
||||||
std::lock_guard lock{signal_mutex};
|
std::scoped_lock lock{signal_mutex};
|
||||||
if (current_signal != Signal::None) {
|
if (current_signal != Signal::None) {
|
||||||
signal = current_signal;
|
signal = current_signal;
|
||||||
param = signal_param;
|
param = signal_param;
|
||||||
|
@ -242,7 +242,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::SendSignal(System::Signal signal, u32 param) {
|
bool System::SendSignal(System::Signal signal, u32 param) {
|
||||||
std::lock_guard lock{signal_mutex};
|
std::scoped_lock lock{signal_mutex};
|
||||||
if (current_signal != signal && current_signal != Signal::None) {
|
if (current_signal != signal && current_signal != Signal::None) {
|
||||||
LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, current_signal);
|
LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, current_signal);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -64,7 +64,7 @@ void FFmpegStream::WritePacket(AVPacket* packet) {
|
||||||
FFmpeg::av_packet_rescale_ts(packet, codec_context->time_base, stream->time_base);
|
FFmpeg::av_packet_rescale_ts(packet, codec_context->time_base, stream->time_base);
|
||||||
packet->stream_index = stream->index;
|
packet->stream_index = stream->index;
|
||||||
{
|
{
|
||||||
std::lock_guard lock{*format_context_mutex};
|
std::scoped_lock lock{*format_context_mutex};
|
||||||
FFmpeg::av_interleaved_write_frame(format_context, packet);
|
FFmpeg::av_interleaved_write_frame(format_context, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ void FFmpegMuxer::FlushAudio() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FFmpegMuxer::WriteTrailer() {
|
void FFmpegMuxer::WriteTrailer() {
|
||||||
std::lock_guard lock{format_context_mutex};
|
std::scoped_lock lock{format_context_mutex};
|
||||||
FFmpeg::av_interleaved_write_frame(format_context.get(), nullptr);
|
FFmpeg::av_interleaved_write_frame(format_context.get(), nullptr);
|
||||||
FFmpeg::av_write_trailer(format_context.get());
|
FFmpeg::av_write_trailer(format_context.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ private:
|
||||||
explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {}
|
explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {}
|
||||||
std::tuple<float, float, bool> GetStatus() const override {
|
std::tuple<float, float, bool> GetStatus() const override {
|
||||||
if (auto state = touch_state.lock()) {
|
if (auto state = touch_state.lock()) {
|
||||||
std::lock_guard guard{state->mutex};
|
std::scoped_lock guard{state->mutex};
|
||||||
return std::make_tuple(state->touch_x, state->touch_y, state->touch_pressed);
|
return std::make_tuple(state->touch_x, state->touch_y, state->touch_pressed);
|
||||||
}
|
}
|
||||||
return std::make_tuple(0.0f, 0.0f, false);
|
return std::make_tuple(0.0f, 0.0f, false);
|
||||||
|
@ -132,7 +132,7 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
|
||||||
framebuffer_x -=
|
framebuffer_x -=
|
||||||
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
||||||
}
|
}
|
||||||
std::lock_guard guard(touch_state->mutex);
|
std::scoped_lock guard(touch_state->mutex);
|
||||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
||||||
touch_state->touch_x =
|
touch_state->touch_x =
|
||||||
static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) /
|
static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) /
|
||||||
|
@ -157,7 +157,7 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow::TouchReleased() {
|
void EmuWindow::TouchReleased() {
|
||||||
std::lock_guard guard{touch_state->mutex};
|
std::scoped_lock guard{touch_state->mutex};
|
||||||
touch_state->touch_pressed = false;
|
touch_state->touch_pressed = false;
|
||||||
touch_state->touch_x = 0;
|
touch_state->touch_x = 0;
|
||||||
touch_state->touch_y = 0;
|
touch_state->touch_y = 0;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -322,6 +323,10 @@ public:
|
||||||
return n3ds_hw_caps;
|
return n3ds_hw_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::recursive_mutex& GetHLELock() {
|
||||||
|
return hle_lock;
|
||||||
|
}
|
||||||
|
|
||||||
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
|
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
|
||||||
std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports;
|
std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports;
|
||||||
|
|
||||||
|
@ -370,6 +375,15 @@ private:
|
||||||
MemoryMode memory_mode;
|
MemoryMode memory_mode;
|
||||||
New3dsHwCapabilities n3ds_hw_caps;
|
New3dsHwCapabilities n3ds_hw_caps;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
|
||||||
|
* application thread performs a syscall. It should be acquired by any host threads that read or
|
||||||
|
* modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or
|
||||||
|
* writes to the emulated memory is not protected by this mutex, and should be avoided in any
|
||||||
|
* threads other than the CPU thread.
|
||||||
|
*/
|
||||||
|
std::recursive_mutex hle_lock;
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int file_version);
|
void serialize(Archive& ar, const unsigned int file_version);
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
#include "core/hle/kernel/vm_manager.h"
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
#include "core/hle/lock.h"
|
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/plgldr/plgldr.h"
|
#include "core/hle/service/plgldr/plgldr.h"
|
||||||
|
|
||||||
|
@ -2300,8 +2299,8 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
void SVC::CallSVC(u32 immediate) {
|
void SVC::CallSVC(u32 immediate) {
|
||||||
MICROPROFILE_SCOPE(Kernel_SVC);
|
MICROPROFILE_SCOPE(Kernel_SVC);
|
||||||
|
|
||||||
// Lock the global kernel mutex when we enter the kernel HLE.
|
// Lock the kernel mutex when we enter the kernel HLE.
|
||||||
std::lock_guard lock{HLE::g_hle_lock};
|
std::scoped_lock lock{kernel.GetHLELock()};
|
||||||
|
|
||||||
DEBUG_ASSERT_MSG(kernel.GetCurrentProcess()->status == ProcessStatus::Running,
|
DEBUG_ASSERT_MSG(kernel.GetCurrentProcess()->status == ProcessStatus::Running,
|
||||||
"Running threads from exiting processes is unimplemented");
|
"Running threads from exiting processes is unimplemented");
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
// Copyright 2017 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "core/hle/lock.h"
|
|
||||||
|
|
||||||
namespace HLE {
|
|
||||||
std::recursive_mutex g_hle_lock;
|
|
||||||
} // namespace HLE
|
|
|
@ -1,18 +0,0 @@
|
||||||
// Copyright 2017 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
namespace HLE {
|
|
||||||
/*
|
|
||||||
* Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
|
|
||||||
* application thread performs a syscall. It should be acquired by any host threads that read or
|
|
||||||
* modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes
|
|
||||||
* to the emulated memory is not protected by this mutex, and should be avoided in any threads other
|
|
||||||
* than the CPU thread.
|
|
||||||
*/
|
|
||||||
extern std::recursive_mutex g_hle_lock;
|
|
||||||
} // namespace HLE
|
|
|
@ -395,7 +395,8 @@ DSP_DSP::DSP_DSP(Core::System& system)
|
||||||
semaphore_event->SetHLENotifier(
|
semaphore_event->SetHLENotifier(
|
||||||
[this]() { this->system.DSP().SetSemaphore(preset_semaphore); });
|
[this]() { this->system.DSP().SetSemaphore(preset_semaphore); });
|
||||||
|
|
||||||
system.DSP().SetInterruptHandler([dsp_ref = this](InterruptType type, DspPipe pipe) {
|
system.DSP().SetInterruptHandler([dsp_ref = this, &system](InterruptType type, DspPipe pipe) {
|
||||||
|
std::scoped_lock lock{system.Kernel().GetHLELock()};
|
||||||
if (dsp_ref) {
|
if (dsp_ref) {
|
||||||
dsp_ref->SignalInterrupt(type, pipe);
|
dsp_ref->SignalInterrupt(type, pipe);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/event.h"
|
|
||||||
#include "core/hle/lock.h"
|
|
||||||
#include "core/hle/service/nfc/nfc.h"
|
#include "core/hle/service/nfc/nfc.h"
|
||||||
#include "core/hle/service/nfc/nfc_m.h"
|
#include "core/hle/service/nfc/nfc_m.h"
|
||||||
#include "core/hle/service/nfc/nfc_u.h"
|
#include "core/hle/service/nfc/nfc_u.h"
|
||||||
|
@ -680,26 +678,21 @@ std::shared_ptr<Module> Module::Interface::GetModule() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::Interface::IsSearchingForAmiibos() {
|
bool Module::Interface::IsSearchingForAmiibos() {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
|
|
||||||
const auto state = nfc->device->GetCurrentState();
|
const auto state = nfc->device->GetCurrentState();
|
||||||
return state == DeviceState::SearchingForTag;
|
return state == DeviceState::SearchingForTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::Interface::IsTagActive() {
|
bool Module::Interface::IsTagActive() {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
|
|
||||||
const auto state = nfc->device->GetCurrentState();
|
const auto state = nfc->device->GetCurrentState();
|
||||||
return state == DeviceState::TagFound || state == DeviceState::TagMounted ||
|
return state == DeviceState::TagFound || state == DeviceState::TagMounted ||
|
||||||
state == DeviceState::TagPartiallyMounted;
|
state == DeviceState::TagPartiallyMounted;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::Interface::LoadAmiibo(const std::string& fullpath) {
|
bool Module::Interface::LoadAmiibo(const std::string& fullpath) {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
return nfc->device->LoadAmiibo(fullpath);
|
return nfc->device->LoadAmiibo(fullpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::RemoveAmiibo() {
|
void Module::Interface::RemoveAmiibo() {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
|
||||||
nfc->device->UnloadAmiibo();
|
nfc->device->UnloadAmiibo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <boost/serialization/binary_object.hpp>
|
#include <boost/serialization/binary_object.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/nfc/nfc_device.h"
|
#include "core/hle/service/nfc/nfc_device.h"
|
||||||
#include "core/hle/service/nfc/nfc_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
#include "core/hle/kernel/shared_page.h"
|
#include "core/hle/kernel/shared_page.h"
|
||||||
#include "core/hle/lock.h"
|
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/nwm/nwm_uds.h"
|
#include "core/hle/service/nwm/nwm_uds.h"
|
||||||
#include "core/hle/service/nwm/uds_beacon.h"
|
#include "core/hle/service/nwm/uds_beacon.h"
|
||||||
|
@ -56,7 +55,7 @@ constexpr u16 BroadcastNetworkNodeId = 0xFFFF;
|
||||||
constexpr u16 HostDestNodeId = 1;
|
constexpr u16 HostDestNodeId = 1;
|
||||||
|
|
||||||
std::list<Network::WifiPacket> NWM_UDS::GetReceivedBeacons(const MacAddress& sender) {
|
std::list<Network::WifiPacket> NWM_UDS::GetReceivedBeacons(const MacAddress& sender) {
|
||||||
std::lock_guard lock(beacon_mutex);
|
std::scoped_lock lock(beacon_mutex);
|
||||||
if (sender != Network::BroadcastMac) {
|
if (sender != Network::BroadcastMac) {
|
||||||
std::list<Network::WifiPacket> filtered_list;
|
std::list<Network::WifiPacket> filtered_list;
|
||||||
const auto beacon = std::find_if(received_beacons.begin(), received_beacons.end(),
|
const auto beacon = std::find_if(received_beacons.begin(), received_beacons.end(),
|
||||||
|
@ -123,7 +122,7 @@ void NWM_UDS::BroadcastNodeMap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWM_UDS::HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
||||||
LOG_DEBUG(Service_NWM, "Ignored NodeMapPacket since connection_status is host");
|
LOG_DEBUG(Service_NWM, "Ignored NodeMapPacket since connection_status is host");
|
||||||
return;
|
return;
|
||||||
|
@ -145,7 +144,7 @@ void NWM_UDS::HandleNodeMapPacket(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWM_UDS::HandleBeaconFrame(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleBeaconFrame(const Network::WifiPacket& packet) {
|
||||||
std::lock_guard lock(beacon_mutex);
|
std::scoped_lock lock(beacon_mutex);
|
||||||
const auto unique_beacon =
|
const auto unique_beacon =
|
||||||
std::find_if(received_beacons.begin(), received_beacons.end(),
|
std::find_if(received_beacons.begin(), received_beacons.end(),
|
||||||
[&packet](const Network::WifiPacket& new_packet) {
|
[&packet](const Network::WifiPacket& new_packet) {
|
||||||
|
@ -169,7 +168,7 @@ void NWM_UDS::HandleAssociationResponseFrame(const Network::WifiPacket& packet)
|
||||||
ASSERT_MSG(std::get<AssocStatus>(assoc_result) == AssocStatus::Successful,
|
ASSERT_MSG(std::get<AssocStatus>(assoc_result) == AssocStatus::Successful,
|
||||||
"Could not join network");
|
"Could not join network");
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::Connecting) {
|
if (connection_status.status != NetworkStatus::Connecting) {
|
||||||
LOG_DEBUG(Service_NWM,
|
LOG_DEBUG(Service_NWM,
|
||||||
"Ignored AssociationResponseFrame because connection status is {}",
|
"Ignored AssociationResponseFrame because connection status is {}",
|
||||||
|
@ -191,9 +190,7 @@ void NWM_UDS::HandleAssociationResponseFrame(const Network::WifiPacket& packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||||
std::unique_lock hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::scoped_lock lock{connection_status_mutex, system.Kernel().GetHLELock()};
|
||||||
std::unique_lock lock(connection_status_mutex, std::defer_lock);
|
|
||||||
std::lock(hle_lock, lock);
|
|
||||||
|
|
||||||
if (GetEAPoLFrameType(packet.data) == EAPoLStartMagic) {
|
if (GetEAPoLFrameType(packet.data) == EAPoLStartMagic) {
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
|
@ -323,10 +320,8 @@ void NWM_UDS::HandleEAPoLPacket(const Network::WifiPacket& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||||
auto secure_data = ParseSecureDataHeader(packet.data);
|
const auto secure_data = ParseSecureDataHeader(packet.data);
|
||||||
std::unique_lock hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::scoped_lock lock{connection_status_mutex, system.Kernel().GetHLELock()};
|
||||||
std::unique_lock lock(connection_status_mutex, std::defer_lock);
|
|
||||||
std::lock(hle_lock, lock);
|
|
||||||
|
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
||||||
connection_status.status != NetworkStatus::ConnectedAsClient) {
|
connection_status.status != NetworkStatus::ConnectedAsClient) {
|
||||||
|
@ -381,7 +376,7 @@ void NWM_UDS::HandleSecureDataPacket(const Network::WifiPacket& packet) {
|
||||||
// Add the received packet to the data queue.
|
// Add the received packet to the data queue.
|
||||||
channel_info->second.received_packets.emplace_back(packet.data);
|
channel_info->second.received_packets.emplace_back(packet.data);
|
||||||
|
|
||||||
// Signal the data event. We can do this directly because we locked g_hle_lock
|
// Signal the data event. We can do this directly because we locked hle_lock
|
||||||
channel_info->second.event->Signal();
|
channel_info->second.event->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +384,7 @@ void NWM_UDS::StartConnectionSequence(const MacAddress& server) {
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
WifiPacket auth_request;
|
WifiPacket auth_request;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
connection_status.status = NetworkStatus::Connecting;
|
connection_status.status = NetworkStatus::Connecting;
|
||||||
|
|
||||||
// TODO(Subv): Handle timeout.
|
// TODO(Subv): Handle timeout.
|
||||||
|
@ -409,7 +404,7 @@ void NWM_UDS::SendAssociationResponseFrame(const MacAddress& address) {
|
||||||
WifiPacket assoc_response;
|
WifiPacket assoc_response;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
LOG_ERROR(Service_NWM, "Connection sequence aborted, because connection status is {}",
|
LOG_ERROR(Service_NWM, "Connection sequence aborted, because connection status is {}",
|
||||||
static_cast<u32>(connection_status.status));
|
static_cast<u32>(connection_status.status));
|
||||||
|
@ -435,7 +430,7 @@ void NWM_UDS::HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
WifiPacket auth_request;
|
WifiPacket auth_request;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
LOG_ERROR(Service_NWM,
|
LOG_ERROR(Service_NWM,
|
||||||
"Connection sequence aborted, because connection status is {}",
|
"Connection sequence aborted, because connection status is {}",
|
||||||
|
@ -469,9 +464,8 @@ void NWM_UDS::HandleAuthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
|
|
||||||
void NWM_UDS::HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
void NWM_UDS::HandleDeauthenticationFrame(const Network::WifiPacket& packet) {
|
||||||
LOG_DEBUG(Service_NWM, "called");
|
LOG_DEBUG(Service_NWM, "called");
|
||||||
std::unique_lock hle_lock(HLE::g_hle_lock, std::defer_lock);
|
std::scoped_lock lock{connection_status_mutex, system.Kernel().GetHLELock()};
|
||||||
std::unique_lock lock(connection_status_mutex, std::defer_lock);
|
|
||||||
std::lock(hle_lock, lock);
|
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
LOG_ERROR(Service_NWM, "Got deauthentication frame but we are not the host");
|
LOG_ERROR(Service_NWM, "Got deauthentication frame but we are not the host");
|
||||||
return;
|
return;
|
||||||
|
@ -662,7 +656,7 @@ ResultVal<std::shared_ptr<Kernel::Event>> NWM_UDS::Initialize(
|
||||||
ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size.");
|
ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size.");
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
|
|
||||||
// Reset the connection status, it contains all zeros after initialization,
|
// Reset the connection status, it contains all zeros after initialization,
|
||||||
// except for the actual status value.
|
// except for the actual status value.
|
||||||
|
@ -715,7 +709,7 @@ void NWM_UDS::GetConnectionStatus(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
rb.PushRaw(connection_status);
|
rb.PushRaw(connection_status);
|
||||||
|
|
||||||
// Reset the bitmask of changed nodes after each call to this
|
// Reset the bitmask of changed nodes after each call to this
|
||||||
|
@ -740,7 +734,7 @@ void NWM_UDS::GetNodeInformation(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
auto itr = std::find_if(node_info.begin(), node_info.end(),
|
auto itr = std::find_if(node_info.begin(), node_info.end(),
|
||||||
[network_node_id](const NodeInfo& node) {
|
[network_node_id](const NodeInfo& node) {
|
||||||
return node.network_node_id == network_node_id;
|
return node.network_node_id == network_node_id;
|
||||||
|
@ -799,7 +793,7 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) {
|
||||||
// Create a new event for this bind node.
|
// Create a new event for this bind node.
|
||||||
auto event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot,
|
auto event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot,
|
||||||
"NWM::BindNodeEvent" + std::to_string(bind_node_id));
|
"NWM::BindNodeEvent" + std::to_string(bind_node_id));
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
|
|
||||||
ASSERT(channel_data.find(data_channel) == channel_data.end());
|
ASSERT(channel_data.find(data_channel) == channel_data.end());
|
||||||
// TODO(B3N30): Support more than one bind node per channel.
|
// TODO(B3N30): Support more than one bind node per channel.
|
||||||
|
@ -821,7 +815,7 @@ void NWM_UDS::Unbind(Kernel::HLERequestContext& ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
|
|
||||||
auto itr =
|
auto itr =
|
||||||
std::find_if(channel_data.begin(), channel_data.end(), [bind_node_id](const auto& data) {
|
std::find_if(channel_data.begin(), channel_data.end(), [bind_node_id](const auto& data) {
|
||||||
|
@ -848,7 +842,7 @@ ResultCode NWM_UDS::BeginHostingNetwork(std::span<const u8> network_info_buffer,
|
||||||
// TODO(Subv): Store the passphrase and verify it when attempting a connection.
|
// TODO(Subv): Store the passphrase and verify it when attempting a connection.
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
network_info = {};
|
network_info = {};
|
||||||
std::memcpy(&network_info, network_info_buffer.data(), network_info_buffer.size());
|
std::memcpy(&network_info, network_info_buffer.data(), network_info_buffer.size());
|
||||||
|
|
||||||
|
@ -961,7 +955,7 @@ void NWM_UDS::EjectClient(Kernel::HLERequestContext& ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
// Only the host can kick people.
|
// Only the host can kick people.
|
||||||
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||||
|
@ -1012,7 +1006,7 @@ void NWM_UDS::DestroyNetwork(Kernel::HLERequestContext& ctx) {
|
||||||
system.CoreTiming().UnscheduleEvent(beacon_broadcast_event, 0);
|
system.CoreTiming().UnscheduleEvent(beacon_broadcast_event, 0);
|
||||||
|
|
||||||
// Only a host can destroy
|
// Only a host can destroy
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, ErrorSummary::InvalidState,
|
rb.Push(ResultCode(ErrCodes::WrongStatus, ErrorModule::UDS, ErrorSummary::InvalidState,
|
||||||
|
@ -1050,7 +1044,7 @@ void NWM_UDS::DisconnectNetwork(Kernel::HLERequestContext& ctx) {
|
||||||
using Network::WifiPacket;
|
using Network::WifiPacket;
|
||||||
WifiPacket deauth;
|
WifiPacket deauth;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
if (connection_status.status == NetworkStatus::ConnectedAsHost) {
|
||||||
// A real 3ds makes strange things here. We do the same
|
// A real 3ds makes strange things here. We do the same
|
||||||
u16_le tmp_node_id = connection_status.network_node_id;
|
u16_le tmp_node_id = connection_status.network_node_id;
|
||||||
|
@ -1104,7 +1098,7 @@ void NWM_UDS::SendTo(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsClient &&
|
if (connection_status.status != NetworkStatus::ConnectedAsClient &&
|
||||||
connection_status.status != NetworkStatus::ConnectedAsHost) {
|
connection_status.status != NetworkStatus::ConnectedAsHost) {
|
||||||
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
rb.Push(ResultCode(ErrorDescription::NotAuthorized, ErrorModule::UDS,
|
||||||
|
@ -1176,7 +1170,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) {
|
||||||
// This size is hard coded into the uds module. We don't know the meaning yet.
|
// This size is hard coded into the uds module. We don't know the meaning yet.
|
||||||
u32 buff_size = std::min<u32>(max_out_buff_size_aligned, 0x172) << 2;
|
u32 buff_size = std::min<u32>(max_out_buff_size_aligned, 0x172) << 2;
|
||||||
|
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
if (connection_status.status != NetworkStatus::ConnectedAsHost &&
|
||||||
connection_status.status != NetworkStatus::ConnectedAsClient &&
|
connection_status.status != NetworkStatus::ConnectedAsClient &&
|
||||||
connection_status.status != NetworkStatus::ConnectedAsSpectator) {
|
connection_status.status != NetworkStatus::ConnectedAsSpectator) {
|
||||||
|
@ -1239,7 +1233,7 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx);
|
IPC::RequestParser rp(ctx);
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
|
|
||||||
std::lock_guard lock(connection_status_mutex);
|
std::scoped_lock lock(connection_status_mutex);
|
||||||
bool is_connected = connection_status.status != NetworkStatus::NotConnected;
|
bool is_connected = connection_status.status != NetworkStatus::NotConnected;
|
||||||
|
|
||||||
u8 channel = is_connected ? network_channel : 0;
|
u8 channel = is_connected ? network_channel : 0;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "core/hle/kernel/semaphore.h"
|
#include "core/hle/kernel/semaphore.h"
|
||||||
#include "core/hle/kernel/server_port.h"
|
#include "core/hle/kernel/server_port.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
#include "core/hle/kernel/server_session.h"
|
||||||
#include "core/hle/lock.h"
|
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/hle/service/sm/srv.h"
|
#include "core/hle/service/sm/srv.h"
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@ TEST_CASE("DSP LLE vs HLE", "[audio_core][hle]") {
|
||||||
|
|
||||||
Memory::MemorySystem lle_memory{system};
|
Memory::MemorySystem lle_memory{system};
|
||||||
Core::Timing lle_core_timing(1, 100);
|
Core::Timing lle_core_timing(1, 100);
|
||||||
|
Kernel::KernelSystem lle_kernel(
|
||||||
|
lle_memory, lle_core_timing, [] {}, Kernel::MemoryMode::Prod, 1,
|
||||||
|
Kernel::New3dsHwCapabilities{false, false, Kernel::New3dsMemoryMode::Legacy});
|
||||||
|
|
||||||
AudioCore::DspHle hle(system, hle_memory, hle_core_timing);
|
AudioCore::DspHle hle(system, hle_memory, hle_core_timing);
|
||||||
AudioCore::DspLle lle(system, lle_memory, lle_core_timing, true);
|
AudioCore::DspLle lle(system, lle_memory, lle_core_timing, true);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
TEST_CASE("DSP LLE Sanity", "[audio_core][lle]") {
|
TEST_CASE("DSP LLE Sanity", "[audio_core][lle]") {
|
||||||
|
|
Loading…
Reference in a new issue