Compare commits

..

2 Commits

Author SHA1 Message Date
lizzie 2c01298379 fixup stuffs 2026-08-31 20:03:10 +00:00
lizzie f8292b3414 [audio] Nuke Oboe and offer SDL3 on Android instead
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-08-31 20:01:28 +00:00
17 changed files with 136 additions and 484 deletions
+1 -1
View File
@@ -238,7 +238,7 @@ option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
# FreeBSD 15+ has libusb, versions below should disable it
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR LINUX OR FREEBSD OR APPLE" OFF)
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT (WIN32 AND ARCHITECTURE_arm64) AND NOT APPLE AND NOT ANDROID" OFF)
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT (WIN32 AND ARCHITECTURE_arm64) AND NOT APPLE" OFF)
mark_as_advanced(FORCE ENABLE_OPENGL)
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
-6
View File
@@ -179,12 +179,6 @@
"repo": "eden-emulator/oaknut",
"version": "v2.0.3"
},
"oboe": {
"bundled": true,
"hash": "ce4011afe7345370d4ead3b891cd69a5ef224b129535783586c0ca75051d303ed446e6c7f10bde8da31fff58d6e307f1732a3ffd03b249f9ef1fd48fd4132715",
"repo": "google/oboe",
"version": "1.10.0"
},
"openssl": {
"hash": "29002ce50cb95a4f4f1d0e9d3f684401fbd4eac34203dc2eef3b6334af5d44aa46bf788b63a6f5c139c383eafb7269ae87a58a9a3ad5912903b9773e545ccc0a",
"min_version": "3.0.0",
+1 -1
View File
@@ -76,7 +76,7 @@ The following options are desktop only.
- `ENABLE_LIBUSB` (ON) Enable the use of the libusb input backend (HIGHLY RECOMMENDED)
- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics backend
- Unavailable on Windows/ARM64 and on Android
- Unavailable on Windows/ARM64
- You probably shouldn't turn this off.
### Qt
-7
View File
@@ -388,13 +388,6 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
endif()
endif()
# oboe
if (ANDROID)
AddJsonPackage(oboe)
add_library(oboe::oboe ALIAS oboe)
endif()
if (APPLE)
# moltenvk
if (NOT YUZU_USE_BUNDLED_MOLTENVK)
@@ -799,10 +799,6 @@
<string name="theme_mode_light">روشن</string>
<string name="theme_mode_dark">تاریک</string>
<!-- Audio output engines -->
<string name="oboe">oboe</string>
<string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string>
<string name="multiplier_x4">x4</string>
@@ -465,14 +465,14 @@
<string-array name="outputEngineEntries">
<item>@string/auto</item>
<item>@string/oboe</item>
<item>@string/cubeb</item>
<item>@string/sdl3</item>
<item>@string/string_null</item>
</string-array>
<integer-array name="outputEngineValues">
<item>0</item>
<item>4</item>
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
@@ -1240,7 +1240,7 @@
<string name="theme_mode_dark">Dark</string>
<!-- Audio output engines -->
<string name="oboe" translatable="false">oboe</string>
<string name="sdl3" translatable="false">sdl3</string>
<string name="cubeb" translatable="false">cubeb</string>
<!-- Anisotropic filtering options -->
+5 -15
View File
@@ -238,20 +238,10 @@ if (ENABLE_CUBEB)
target_compile_definitions(audio_core PRIVATE HAVE_CUBEB=1)
endif()
if(ANDROID)
target_sources(audio_core PRIVATE
sink/oboe_sink.cpp
sink/oboe_sink.h)
target_link_libraries(audio_core PRIVATE oboe)
target_compile_definitions(audio_core PUBLIC HAVE_OBOE)
else()
target_sources(audio_core PRIVATE
sink/sdl3_sink.cpp
sink/sdl3_sink.h)
target_link_libraries(audio_core PRIVATE SDL3::SDL3)
target_compile_definitions(audio_core PRIVATE HAVE_SDL3)
endif()
target_sources(audio_core PRIVATE
sink/sdl3_sink.cpp
sink/sdl3_sink.h)
target_link_libraries(audio_core PRIVATE SDL3::SDL3)
target_compile_definitions(audio_core PRIVATE HAVE_SDL3)
create_target_directory_groups(audio_core)
-230
View File
@@ -1,230 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <span>
#include <vector>
#include <oboe/Oboe.h>
#include "audio_core/common/common.h"
#include "audio_core/sink/oboe_sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/logging.h"
#include "common/scope_exit.h"
#include "core/core.h"
namespace AudioCore::Sink {
class OboeSinkStream final : public SinkStream,
public oboe::AudioStreamDataCallback,
public oboe::AudioStreamErrorCallback {
public:
explicit OboeSinkStream(Core::System& system_, StreamType type_, const std::string& name_,
u32 system_channels_)
: SinkStream(system_, type_) {
name = name_;
system_channels = system_channels_;
this->OpenStream();
}
~OboeSinkStream() override {
LOG_INFO(Audio_Sink, "Destroyed Oboe stream");
}
void Finalize() override {
this->Stop();
m_stream.reset();
}
void Start(bool resume = false) override {
if (!m_stream || !paused) {
return;
}
paused = false;
if (m_stream->start() != oboe::Result::OK) {
LOG_CRITICAL(Audio_Sink, "Error starting Oboe stream");
}
}
void Stop() override {
if (!m_stream || paused) {
return;
}
this->SignalPause();
if (m_stream->stop() != oboe::Result::OK) {
LOG_CRITICAL(Audio_Sink, "Error stopping Oboe stream");
}
}
public:
static s32 QueryChannelCount(oboe::Direction direction) {
std::shared_ptr<oboe::AudioStream> temp_stream;
oboe::AudioStreamBuilder builder;
const auto result = ConfigureBuilder(builder, direction)->openStream(temp_stream);
if (result == oboe::Result::OK) {
return temp_stream->getChannelCount() >= 6 ? 6 : 2;
}
LOG_ERROR(Audio_Sink, "Failed to open {} stream. Using default channel count 2",
direction == oboe::Direction::Output ? "output" : "input");
return 2;
}
protected:
oboe::DataCallbackResult onAudioReady(oboe::AudioStream*, void* audio_data,
s32 num_buffer_frames) override {
const size_t num_channels = this->GetDeviceChannels();
const size_t frame_size = num_channels;
const size_t num_frames = static_cast<size_t>(num_buffer_frames);
if (type == StreamType::In) {
std::span<const s16> input_buffer{reinterpret_cast<const s16*>(audio_data),
num_frames * frame_size};
this->ProcessAudioIn(input_buffer, num_frames);
} else {
std::span<s16> output_buffer{reinterpret_cast<s16*>(audio_data),
num_frames * frame_size};
this->ProcessAudioOutAndRender(output_buffer, num_frames);
}
return oboe::DataCallbackResult::Continue;
}
void onErrorAfterClose(oboe::AudioStream*, oboe::Result) override {
LOG_INFO(Audio_Sink, "Audio stream closed, reinitializing");
if (this->OpenStream()) {
m_stream->start();
}
}
private:
static oboe::AudioStreamBuilder* ConfigureBuilder(oboe::AudioStreamBuilder& builder,
oboe::Direction direction) {
// TODO: investigate callback delay issues when using AAudio
return builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setAudioApi(oboe::AudioApi::OpenSLES)
->setDirection(direction)
->setSampleRate(TargetSampleRate)
->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::High)
->setFormat(oboe::AudioFormat::I16)
->setFormatConversionAllowed(true)
->setUsage(oboe::Usage::Game)
->setBufferCapacityInFrames(TargetSampleCount * 2);
}
bool OpenStream() {
const auto direction = [&]() {
switch (type) {
case StreamType::In:
return oboe::Direction::Input;
case StreamType::Out:
case StreamType::Render:
return oboe::Direction::Output;
default:
ASSERT(false);
return oboe::Direction::Output;
}
}();
const auto expected_channels = QueryChannelCount(direction);
const auto expected_mask = [&]() {
switch (expected_channels) {
case 1:
return oboe::ChannelMask::Mono;
case 2:
return oboe::ChannelMask::Stereo;
case 6:
return oboe::ChannelMask::CM5Point1;
default:
ASSERT(false);
return oboe::ChannelMask::Unspecified;
}
}();
oboe::AudioStreamBuilder builder;
const auto result = ConfigureBuilder(builder, direction)
->setChannelCount(expected_channels)
->setChannelMask(expected_mask)
->setChannelConversionAllowed(true)
->setDataCallback(this)
->setErrorCallback(this)
->openStream(m_stream);
ASSERT(result == oboe::Result::OK);
return result == oboe::Result::OK && this->SetStreamProperties();
}
bool SetStreamProperties() {
ASSERT(m_stream);
m_stream->setBufferSizeInFrames(TargetSampleCount * 2);
device_channels = m_stream->getChannelCount();
const auto sample_rate = m_stream->getSampleRate();
const auto buffer_capacity = m_stream->getBufferCapacityInFrames();
const auto stream_backend =
m_stream->getAudioApi() == oboe::AudioApi::AAudio ? "AAudio" : "OpenSLES";
LOG_INFO(Audio_Sink, "Opened Oboe {} stream with {} channels sample rate {} capacity {}",
stream_backend, device_channels, sample_rate, buffer_capacity);
return true;
}
std::shared_ptr<oboe::AudioStream> m_stream{};
};
OboeSink::OboeSink() {
// TODO: This is not generally knowable
// The channel count is distinct based on direction and can change
device_channels = OboeSinkStream::QueryChannelCount(oboe::Direction::Output);
}
OboeSink::~OboeSink() = default;
SinkStream* OboeSink::AcquireSinkStream(Core::System& system, u32 system_channels,
const std::string& name, StreamType type) {
SinkStreamPtr& stream = sink_streams.emplace_back(
std::make_unique<OboeSinkStream>(system, type, name, system_channels));
return stream.get();
}
void OboeSink::CloseStream(SinkStream* to_remove) {
sink_streams.remove_if([&](auto& stream) { return stream.get() == to_remove; });
}
void OboeSink::CloseStreams() {
sink_streams.clear();
}
f32 OboeSink::GetDeviceVolume() const {
if (sink_streams.empty()) {
return 1.0f;
}
return sink_streams.front()->GetDeviceVolume();
}
void OboeSink::SetDeviceVolume(f32 volume) {
for (auto& stream : sink_streams) {
stream->SetDeviceVolume(volume);
}
}
void OboeSink::SetSystemVolume(f32 volume) {
for (auto& stream : sink_streams) {
stream->SetSystemVolume(volume);
}
}
} // namespace AudioCore::Sink
-75
View File
@@ -1,75 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <list>
#include <string>
#include "audio_core/sink/sink.h"
namespace Core {
class System;
}
namespace AudioCore::Sink {
class SinkStream;
class OboeSink final : public Sink {
public:
explicit OboeSink();
~OboeSink() override;
/**
* Create a new sink stream.
*
* @param system - Core system.
* @param system_channels - Number of channels the audio system expects.
* May differ from the device's channel count.
* @param name - Name of this stream.
* @param type - Type of this stream, render/in/out.
*
* @return A pointer to the created SinkStream
*/
SinkStream* AcquireSinkStream(Core::System& system, u32 system_channels,
const std::string& name, StreamType type) override;
/**
* Close a given stream.
*
* @param stream - The stream to close.
*/
void CloseStream(SinkStream* stream) override;
/**
* Close all streams.
*/
void CloseStreams() override;
/**
* Get the device volume. Set from calls to the IAudioDevice service.
*
* @return Volume of the device.
*/
f32 GetDeviceVolume() const override;
/**
* Set the device volume. Set from calls to the IAudioDevice service.
*
* @param volume - New volume of the device.
*/
void SetDeviceVolume(f32 volume) override;
/**
* Set the system volume. Comes from the audio system using this stream.
*
* @param volume - New volume of the system.
*/
void SetSystemVolume(f32 volume) override;
private:
/// List of streams managed by this sink
std::list<SinkStreamPtr> sink_streams{};
};
} // namespace AudioCore::Sink
-13
View File
@@ -10,9 +10,6 @@
#include <vector>
#include "audio_core/sink/sink_details.h"
#ifdef HAVE_OBOE
#include "audio_core/sink/oboe_sink.h"
#endif
#ifdef HAVE_CUBEB
#include "audio_core/sink/cubeb_sink.h"
#endif
@@ -51,16 +48,6 @@ struct SinkDetails {
// sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details[] = {
#ifdef HAVE_OBOE
SinkDetails{
Settings::AudioEngine::Oboe,
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<OboeSink>();
},
[](bool capture) { return std::vector<std::string>{"Default"}; },
[]() { return 0u; },
},
#endif
#ifdef HAVE_CUBEB
SinkDetails{
Settings::AudioEngine::Cubeb,
+3 -3
View File
@@ -92,14 +92,14 @@ struct EnumMetadata {
// AudioEngine must be specified discretely due to having existing but slightly different
// canonicalizations
// TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id
enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, Oboe, };
enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, };
template<>
inline std::vector<std::pair<std::string_view, AudioEngine>> EnumMetadata<AudioEngine>::Canonicalizations() {
return {
{"auto", AudioEngine::Auto},
{"cubeb", AudioEngine::Cubeb},
{"sdl3", AudioEngine::Sdl3},
{"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe},
{"null", AudioEngine::Null},
};
}
/// @brief This is just a sufficiently large number that is more than the number of other enums declared here
@@ -113,7 +113,7 @@ inline AudioEngine EnumMetadata<AudioEngine>::GetFirst() {
}
template<>
inline AudioEngine EnumMetadata<AudioEngine>::GetLast() {
return AudioEngine::Oboe;
return AudioEngine::Null;
}
ENUM(AudioMode, Mono, Stereo, Surround);
+91 -91
View File
@@ -54,11 +54,11 @@ void PutValue(std::span<u8> buffer, const T& t) {
} // Anonymous namespace
void BSD_USA::PollWork::Execute(BSD_USA* bsd) {
void BSD::PollWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout);
}
void BSD_USA::PollWork::Response(HLERequestContext& ctx) {
void BSD::PollWork::Response(HLERequestContext& ctx) {
if (write_buffer.size() > 0) {
ctx.WriteBuffer(write_buffer);
}
@@ -69,11 +69,11 @@ void BSD_USA::PollWork::Response(HLERequestContext& ctx) {
rb.PushEnum(bsd_errno);
}
void BSD_USA::AcceptWork::Execute(BSD_USA* bsd) {
void BSD::AcceptWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer);
}
void BSD_USA::AcceptWork::Response(HLERequestContext& ctx) {
void BSD::AcceptWork::Response(HLERequestContext& ctx) {
if (write_buffer.size() > 0) {
ctx.WriteBuffer(write_buffer);
}
@@ -85,22 +85,22 @@ void BSD_USA::AcceptWork::Response(HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
}
void BSD_USA::ConnectWork::Execute(BSD_USA* bsd) {
void BSD::ConnectWork::Execute(BSD* bsd) {
bsd_errno = bsd->ConnectImpl(fd, addr);
}
void BSD_USA::ConnectWork::Response(HLERequestContext& ctx) {
void BSD::ConnectWork::Response(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
rb.PushEnum(bsd_errno);
}
void BSD_USA::RecvWork::Execute(BSD_USA* bsd) {
void BSD::RecvWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message);
}
void BSD_USA::RecvWork::Response(HLERequestContext& ctx) {
void BSD::RecvWork::Response(HLERequestContext& ctx) {
ctx.WriteBuffer(message);
IPC::ResponseBuilder rb{ctx, 4};
@@ -109,11 +109,11 @@ void BSD_USA::RecvWork::Response(HLERequestContext& ctx) {
rb.PushEnum(bsd_errno);
}
void BSD_USA::RecvFromWork::Execute(BSD_USA* bsd) {
void BSD::RecvFromWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr);
}
void BSD_USA::RecvFromWork::Response(HLERequestContext& ctx) {
void BSD::RecvFromWork::Response(HLERequestContext& ctx) {
ctx.WriteBuffer(message, 0);
if (!addr.empty()) {
ctx.WriteBuffer(addr, 1);
@@ -126,29 +126,29 @@ void BSD_USA::RecvFromWork::Response(HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(addr.size()));
}
void BSD_USA::SendWork::Execute(BSD_USA* bsd) {
void BSD::SendWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message);
}
void BSD_USA::SendWork::Response(HLERequestContext& ctx) {
void BSD::SendWork::Response(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<s32>(ret);
rb.PushEnum(bsd_errno);
}
void BSD_USA::SendToWork::Execute(BSD_USA* bsd) {
void BSD::SendToWork::Execute(BSD* bsd) {
std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr);
}
void BSD_USA::SendToWork::Response(HLERequestContext& ctx) {
void BSD::SendToWork::Response(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<s32>(ret);
rb.PushEnum(bsd_errno);
}
void BSD_USA::RegisterClient(HLERequestContext& ctx) {
void BSD::RegisterClient(HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
@@ -157,7 +157,7 @@ void BSD_USA::RegisterClient(HLERequestContext& ctx) {
rb.Push<s32>(0); // bsd errno
}
void BSD_USA::StartMonitoring(HLERequestContext& ctx) {
void BSD::StartMonitoring(HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
@@ -165,7 +165,7 @@ void BSD_USA::StartMonitoring(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
void BSD_USA::Socket(HLERequestContext& ctx) {
void BSD::Socket(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 domain = rp.Pop<u32>();
const u32 type = rp.Pop<u32>();
@@ -181,7 +181,7 @@ void BSD_USA::Socket(HLERequestContext& ctx) {
rb.PushEnum(bsd_errno);
}
void BSD_USA::SocketExempt(HLERequestContext& ctx) {
void BSD::SocketExempt(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 domain = rp.Pop<u32>();
const u32 type = rp.Pop<u32>();
@@ -200,7 +200,7 @@ void BSD_USA::SocketExempt(HLERequestContext& ctx) {
rb.PushEnum(bsd_errno);
}
void BSD_USA::Select(HLERequestContext& ctx) {
void BSD::Select(HLERequestContext& ctx) {
LOG_DEBUG(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
@@ -210,7 +210,7 @@ void BSD_USA::Select(HLERequestContext& ctx) {
rb.Push<u32>(0); // bsd errno
}
void BSD_USA::Poll(HLERequestContext& ctx) {
void BSD::Poll(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 nfds = rp.Pop<s32>();
const s32 timeout = rp.Pop<s32>();
@@ -225,7 +225,7 @@ void BSD_USA::Poll(HLERequestContext& ctx) {
});
}
void BSD_USA::Accept(HLERequestContext& ctx) {
void BSD::Accept(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -237,7 +237,7 @@ void BSD_USA::Accept(HLERequestContext& ctx) {
});
}
void BSD_USA::Bind(HLERequestContext& ctx) {
void BSD::Bind(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -245,7 +245,7 @@ void BSD_USA::Bind(HLERequestContext& ctx) {
BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
}
void BSD_USA::Connect(HLERequestContext& ctx) {
void BSD::Connect(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -257,7 +257,7 @@ void BSD_USA::Connect(HLERequestContext& ctx) {
});
}
void BSD_USA::GetPeerName(HLERequestContext& ctx) {
void BSD::GetPeerName(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -275,7 +275,7 @@ void BSD_USA::GetPeerName(HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
}
void BSD_USA::GetSockName(HLERequestContext& ctx) {
void BSD::GetSockName(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -293,7 +293,7 @@ void BSD_USA::GetSockName(HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
}
void BSD_USA::GetSockOpt(HLERequestContext& ctx) {
void BSD::GetSockOpt(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
const u32 level = rp.Pop<u32>();
@@ -315,7 +315,7 @@ void BSD_USA::GetSockOpt(HLERequestContext& ctx) {
rb.Push<u32>(static_cast<u32>(optval.size()));
}
void BSD_USA::Listen(HLERequestContext& ctx) {
void BSD::Listen(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
const s32 backlog = rp.Pop<s32>();
@@ -325,7 +325,7 @@ void BSD_USA::Listen(HLERequestContext& ctx) {
BuildErrnoResponse(ctx, ListenImpl(fd, backlog));
}
void BSD_USA::Fcntl(HLERequestContext& ctx) {
void BSD::Fcntl(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
const s32 cmd = rp.Pop<s32>();
@@ -341,7 +341,7 @@ void BSD_USA::Fcntl(HLERequestContext& ctx) {
rb.PushEnum(bsd_errno);
}
void BSD_USA::SetSockOpt(HLERequestContext& ctx) {
void BSD::SetSockOpt(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -355,7 +355,7 @@ void BSD_USA::SetSockOpt(HLERequestContext& ctx) {
BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
}
void BSD_USA::Shutdown(HLERequestContext& ctx) {
void BSD::Shutdown(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -366,7 +366,7 @@ void BSD_USA::Shutdown(HLERequestContext& ctx) {
BuildErrnoResponse(ctx, ShutdownImpl(fd, how));
}
void BSD_USA::Recv(HLERequestContext& ctx) {
void BSD::Recv(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -381,7 +381,7 @@ void BSD_USA::Recv(HLERequestContext& ctx) {
});
}
void BSD_USA::RecvFrom(HLERequestContext& ctx) {
void BSD::RecvFrom(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -398,7 +398,7 @@ void BSD_USA::RecvFrom(HLERequestContext& ctx) {
});
}
void BSD_USA::Send(HLERequestContext& ctx) {
void BSD::Send(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -413,7 +413,7 @@ void BSD_USA::Send(HLERequestContext& ctx) {
});
}
void BSD_USA::SendTo(HLERequestContext& ctx) {
void BSD::SendTo(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
const u32 flags = rp.Pop<u32>();
@@ -429,7 +429,7 @@ void BSD_USA::SendTo(HLERequestContext& ctx) {
});
}
void BSD_USA::Write(HLERequestContext& ctx) {
void BSD::Write(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -442,7 +442,7 @@ void BSD_USA::Write(HLERequestContext& ctx) {
});
}
void BSD_USA::Read(HLERequestContext& ctx) {
void BSD::Read(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -454,7 +454,7 @@ void BSD_USA::Read(HLERequestContext& ctx) {
rb.Push<u32>(0); // bsd errno
}
void BSD_USA::Close(HLERequestContext& ctx) {
void BSD::Close(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -464,7 +464,7 @@ void BSD_USA::Close(HLERequestContext& ctx) {
}
/// @brief Only bsd:s is able to dup()
void BSD_USA::DuplicateSocket(HLERequestContext& ctx) {
void BSD::DuplicateSocket(HLERequestContext& ctx) {
struct InputParameters {
s32 fd;
u64 reserved;
@@ -505,7 +505,7 @@ void BSD_USA::DuplicateSocket(HLERequestContext& ctx) {
}
}
void BSD_USA::EventFd(HLERequestContext& ctx) {
void BSD::EventFd(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 initval = rp.Pop<u64>();
const u32 flags = rp.Pop<u32>();
@@ -516,12 +516,12 @@ void BSD_USA::EventFd(HLERequestContext& ctx) {
}
template <typename Work>
void BSD_USA::ExecuteWork(HLERequestContext& ctx, Work work) {
void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
work.Execute(this);
work.Response(ctx);
}
std::pair<s32, Errno> BSD_USA::SocketImpl(Domain domain, Type type, Protocol protocol) {
std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protocol) {
// user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW
if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) {
if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) {
@@ -565,7 +565,7 @@ std::pair<s32, Errno> BSD_USA::SocketImpl(Domain domain, Type type, Protocol pro
return {fd, Errno::SUCCESS};
}
std::pair<s32, Errno> BSD_USA::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
s32 nfds, s32 timeout) {
if (nfds <= 0) {
// When no entries are provided, -1 is returned with errno zero
@@ -632,7 +632,7 @@ std::pair<s32, Errno> BSD_USA::PollImpl(std::vector<u8>& write_buffer, std::span
return Translate(result);
}
std::pair<s32, Errno> BSD_USA::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
}
@@ -660,7 +660,7 @@ std::pair<s32, Errno> BSD_USA::AcceptImpl(s32 fd, std::vector<u8>& write_buffer)
return {new_fd, Errno::SUCCESS};
}
Errno BSD_USA::BindImpl(s32 fd, std::span<const u8> addr) {
Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -675,7 +675,7 @@ Errno BSD_USA::BindImpl(s32 fd, std::span<const u8> addr) {
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
}
Errno BSD_USA::ConnectImpl(s32 fd, std::span<const u8> addr) {
Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -698,7 +698,7 @@ Errno BSD_USA::ConnectImpl(s32 fd, std::span<const u8> addr) {
return result;
}
Errno BSD_USA::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -720,7 +720,7 @@ Errno BSD_USA::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
return Translate(bsd_errno);
}
Errno BSD_USA::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -742,7 +742,7 @@ Errno BSD_USA::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
return Translate(bsd_errno);
}
Errno BSD_USA::ListenImpl(s32 fd, s32 backlog) {
Errno BSD::ListenImpl(s32 fd, s32 backlog) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -753,7 +753,7 @@ Errno BSD_USA::ListenImpl(s32 fd, s32 backlog) {
return Translate(file_descriptors[fd]->socket->Listen(backlog));
}
std::pair<s32, Errno> BSD_USA::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
std::pair<s32, Errno> BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
}
@@ -783,7 +783,7 @@ std::pair<s32, Errno> BSD_USA::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
}
}
Errno BSD_USA::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval) {
Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -818,7 +818,7 @@ Errno BSD_USA::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8
}
}
Errno BSD_USA::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -872,7 +872,7 @@ Errno BSD_USA::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<cons
}
}
Errno BSD_USA::ShutdownImpl(s32 fd, s32 how) {
Errno BSD::ShutdownImpl(s32 fd, s32 how) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -884,7 +884,7 @@ Errno BSD_USA::ShutdownImpl(s32 fd, s32 how) {
return Translate(file_descriptors[fd]->socket->Shutdown(host_how));
}
std::pair<s32, Errno> BSD_USA::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
std::pair<s32, Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
}
@@ -911,7 +911,7 @@ std::pair<s32, Errno> BSD_USA::RecvImpl(s32 fd, u32 flags, std::vector<u8>& mess
return {ret, bsd_errno};
}
std::pair<s32, Errno> BSD_USA::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
std::vector<u8>& addr) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
@@ -958,7 +958,7 @@ std::pair<s32, Errno> BSD_USA::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>&
return {ret, bsd_errno};
}
std::pair<s32, Errno> BSD_USA::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
std::pair<s32, Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
}
@@ -969,7 +969,7 @@ std::pair<s32, Errno> BSD_USA::SendImpl(s32 fd, u32 flags, std::span<const u8> m
return Translate(file_descriptors[fd]->socket->Send(message, flags));
}
std::pair<s32, Errno> BSD_USA::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF};
@@ -991,7 +991,7 @@ std::pair<s32, Errno> BSD_USA::SendToImpl(s32 fd, u32 flags, std::span<const u8>
return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in));
}
Errno BSD_USA::CloseImpl(s32 fd) {
Errno BSD::CloseImpl(s32 fd) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -1011,7 +1011,7 @@ Errno BSD_USA::CloseImpl(s32 fd) {
return bsd_errno;
}
std::variant<s32, Errno> BSD_USA::DuplicateSocketImpl(s32 fd) {
std::variant<s32, Errno> BSD::DuplicateSocketImpl(s32 fd) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -1030,7 +1030,7 @@ std::variant<s32, Errno> BSD_USA::DuplicateSocketImpl(s32 fd) {
return new_fd;
}
std::optional<std::shared_ptr<Network::SocketBase>> BSD_USA::GetSocket(s32 fd) {
std::optional<std::shared_ptr<Network::SocketBase>> BSD::GetSocket(s32 fd) {
if (!IsFileDescriptorValid(fd)) {
return std::nullopt;
}
@@ -1041,7 +1041,7 @@ std::optional<std::shared_ptr<Network::SocketBase>> BSD_USA::GetSocket(s32 fd) {
return file_descriptors[fd]->socket;
}
s32 BSD_USA::FindFreeFileDescriptorHandle() noexcept {
s32 BSD::FindFreeFileDescriptorHandle() noexcept {
for (s32 fd = 0; fd < static_cast<s32>(file_descriptors.size()); ++fd) {
if (!file_descriptors[fd]) {
return fd;
@@ -1050,7 +1050,7 @@ s32 BSD_USA::FindFreeFileDescriptorHandle() noexcept {
return -1;
}
bool BSD_USA::IsFileDescriptorValid(s32 fd) const noexcept {
bool BSD::IsFileDescriptorValid(s32 fd) const noexcept {
if (fd > static_cast<s32>(MAX_FD) || fd < 0) {
LOG_ERROR(Service, "Invalid file descriptor handle={}", fd);
return false;
@@ -1062,7 +1062,7 @@ bool BSD_USA::IsFileDescriptorValid(s32 fd) const noexcept {
return true;
}
void BSD_USA::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
@@ -1070,7 +1070,7 @@ void BSD_USA::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const
rb.PushEnum(bsd_errno);
}
void BSD_USA::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
for (auto& optional_descriptor : file_descriptors) {
if (!optional_descriptor.has_value()) {
continue;
@@ -1080,43 +1080,43 @@ void BSD_USA::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
}
}
BSD_USA::BSD_USA(Core::System& system_, const char* name, bool is_user_)
BSD::BSD(Core::System& system_, const char* name, bool is_user_)
: ServiceFramework{system_, name}
, is_user{is_user_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BSD_USA::RegisterClient, "RegisterClient"},
{1, &BSD_USA::StartMonitoring, "StartMonitoring"},
{2, &BSD_USA::Socket, "Socket"},
{3, &BSD_USA::SocketExempt, "SocketExempt"},
{0, &BSD::RegisterClient, "RegisterClient"},
{1, &BSD::StartMonitoring, "StartMonitoring"},
{2, &BSD::Socket, "Socket"},
{3, &BSD::SocketExempt, "SocketExempt"},
{4, nullptr, "Open"},
{5, &BSD_USA::Select, "Select"},
{6, &BSD_USA::Poll, "Poll"},
{5, &BSD::Select, "Select"},
{6, &BSD::Poll, "Poll"},
{7, nullptr, "Sysctl"},
{8, &BSD_USA::Recv, "Recv"},
{9, &BSD_USA::RecvFrom, "RecvFrom"},
{10, &BSD_USA::Send, "Send"},
{11, &BSD_USA::SendTo, "SendTo"},
{12, &BSD_USA::Accept, "Accept"},
{13, &BSD_USA::Bind, "Bind"},
{14, &BSD_USA::Connect, "Connect"},
{15, &BSD_USA::GetPeerName, "GetPeerName"},
{16, &BSD_USA::GetSockName, "GetSockName"},
{17, &BSD_USA::GetSockOpt, "GetSockOpt"},
{18, &BSD_USA::Listen, "Listen"},
{8, &BSD::Recv, "Recv"},
{9, &BSD::RecvFrom, "RecvFrom"},
{10, &BSD::Send, "Send"},
{11, &BSD::SendTo, "SendTo"},
{12, &BSD::Accept, "Accept"},
{13, &BSD::Bind, "Bind"},
{14, &BSD::Connect, "Connect"},
{15, &BSD::GetPeerName, "GetPeerName"},
{16, &BSD::GetSockName, "GetSockName"},
{17, &BSD::GetSockOpt, "GetSockOpt"},
{18, &BSD::Listen, "Listen"},
{19, nullptr, "Ioctl"},
{20, &BSD_USA::Fcntl, "Fcntl"},
{21, &BSD_USA::SetSockOpt, "SetSockOpt"},
{22, &BSD_USA::Shutdown, "Shutdown"},
{20, &BSD::Fcntl, "Fcntl"},
{21, &BSD::SetSockOpt, "SetSockOpt"},
{22, &BSD::Shutdown, "Shutdown"},
{23, nullptr, "ShutdownAllSockets"},
{24, &BSD_USA::Write, "Write"},
{25, &BSD_USA::Read, "Read"},
{26, &BSD_USA::Close, "Close"},
{27, &BSD_USA::DuplicateSocket, "DuplicateSocket"},
{24, &BSD::Write, "Write"},
{25, &BSD::Read, "Read"},
{26, &BSD::Close, "Close"},
{27, &BSD::DuplicateSocket, "DuplicateSocket"},
{28, nullptr, "GetResourceStatistics"},
{29, nullptr, "RecvMMsg"}, //3.0.0+
{30, nullptr, "SendMMsg"}, //3.0.0+
{31, &BSD_USA::EventFd, "EventFd"}, //7.0.0+
{31, &BSD::EventFd, "EventFd"}, //7.0.0+
{32, nullptr, "RegisterResourceStatisticsName"}, //7.0.0+
{33, nullptr, "RegisterClientShared"}, //10.0.0+
{34, nullptr, "GetSocketStatistics"}, //15.0.0+
@@ -1144,13 +1144,13 @@ BSD_USA::BSD_USA(Core::System& system_, const char* name, bool is_user_)
}
}
BSD_USA::~BSD_USA() {
BSD::~BSD() {
if (auto room_member = Network::GetRoomMember().lock()) {
room_member->Unbind(proxy_packet_received);
}
}
std::unique_lock<std::mutex> BSD_USA::LockService() noexcept {
std::unique_lock<std::mutex> BSD::LockService() noexcept {
return {};
}
+10 -10
View File
@@ -27,10 +27,10 @@ class Socket;
namespace Service::Sockets {
class BSD_USA final : public ServiceFramework<BSD_USA> {
class BSD final : public ServiceFramework<BSD> {
public:
explicit BSD_USA(Core::System& system_, const char* name, bool is_user);
~BSD_USA() override;
explicit BSD(Core::System& system_, const char* name, bool is_user);
~BSD() override;
// These methods are called from SSL; the first two are also called from
// this class for the corresponding IPC methods.
@@ -50,7 +50,7 @@ private:
};
struct PollWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 nfds;
@@ -62,7 +62,7 @@ private:
};
struct AcceptWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
@@ -72,7 +72,7 @@ private:
};
struct ConnectWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
@@ -81,7 +81,7 @@ private:
};
struct RecvWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
@@ -92,7 +92,7 @@ private:
};
struct RecvFromWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
@@ -104,7 +104,7 @@ private:
};
struct SendWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
@@ -115,7 +115,7 @@ private:
};
struct SendToWork {
void Execute(BSD_USA* bsd);
void Execute(BSD* bsd);
void Response(HLERequestContext& ctx);
s32 fd;
+3 -3
View File
@@ -66,9 +66,9 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD_USA>(system, "bsd:s", false));
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD_USA>(system, "bsd:u", true));
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD_USA>(system, "bsd:a", true));
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s", false));
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u", true));
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD>(system, "bsd:a", true));
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
+2 -2
View File
@@ -129,7 +129,7 @@ public:
LOG_ERROR(Service_SSL,
"do_not_close_socket was changed after setting socket; is this right?");
} else {
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD_USA>("bsd:u");
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
if (bsd) {
auto err = bsd->CloseImpl(fd);
if (err != Service::Sockets::Errno::SUCCESS) {
@@ -157,7 +157,7 @@ private:
Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
LOG_DEBUG(Service_SSL, "called, fd={}", fd);
ASSERT(!did_handshake);
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD_USA>("bsd:u");
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
ASSERT_OR_EXECUTE(bsd, { return ResultInternalError; });
auto const res_v = bsd->DuplicateSocketImpl(fd);
+17 -20
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -12,13 +9,13 @@
namespace VideoCommon {
class UsageTracker {
// PAGE_SHIFT is a macro on FreeBSD
static constexpr size_t BUFFER_BYTES_PER_BITSHIFT = 6;
static constexpr size_t BUFFER_PAGE_SHIFT = 6 + BUFFER_BYTES_PER_BITSHIFT;
static constexpr size_t BUFFER_PAGE_BYTES = 1 << BUFFER_PAGE_SHIFT;
static constexpr size_t BYTES_PER_BIT_SHIFT = 6;
static constexpr size_t PAGE_SHIFT = 6 + BYTES_PER_BIT_SHIFT;
static constexpr size_t PAGE_BYTES = 1 << PAGE_SHIFT;
public:
explicit UsageTracker(size_t size) {
const size_t num_pages = (size >> BUFFER_PAGE_SHIFT) + 1;
const size_t num_pages = (size >> PAGE_SHIFT) + 1;
pages.resize(num_pages, 0ULL);
}
@@ -27,8 +24,8 @@ public:
}
void Track(u64 offset, u64 size) noexcept {
const size_t page = offset >> BUFFER_PAGE_SHIFT;
const size_t page_end = (offset + size) >> BUFFER_PAGE_SHIFT;
const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> PAGE_SHIFT;
if (page_end < page || page_end >= pages.size()) {
return;
}
@@ -40,13 +37,13 @@ public:
pages[i] = ~u64{0};
}
const size_t offset_end = offset + size;
const size_t offset_end_page_aligned = Common::AlignDown(offset_end, BUFFER_PAGE_BYTES);
const size_t offset_end_page_aligned = Common::AlignDown(offset_end, PAGE_BYTES);
TrackPage(page_end, offset_end_page_aligned, offset_end - offset_end_page_aligned);
}
[[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept {
const size_t page = offset >> BUFFER_PAGE_SHIFT;
const size_t page_end = (offset + size) >> BUFFER_PAGE_SHIFT;
const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> PAGE_SHIFT;
if (page_end < page || page_end >= pages.size()) {
return false;
}
@@ -59,23 +56,23 @@ public:
}
}
const size_t offset_end = offset + size;
const size_t offset_end_page_aligned = Common::AlignDown(offset_end, BUFFER_PAGE_BYTES);
const size_t offset_end_page_aligned = Common::AlignDown(offset_end, PAGE_BYTES);
return IsPageUsed(page_end, offset_end_page_aligned, offset_end - offset_end_page_aligned);
}
private:
void TrackPage(u64 page, u64 offset, u64 size) noexcept {
const size_t offset_in_page = offset % BUFFER_PAGE_BYTES;
const size_t first_bit = offset_in_page >> BUFFER_BYTES_PER_BITSHIFT;
const size_t num_bits = std::min<size_t>(size, BUFFER_PAGE_BYTES) >> BUFFER_BYTES_PER_BITSHIFT;
const size_t offset_in_page = offset % PAGE_BYTES;
const size_t first_bit = offset_in_page >> BYTES_PER_BIT_SHIFT;
const size_t num_bits = std::min<size_t>(size, PAGE_BYTES) >> BYTES_PER_BIT_SHIFT;
const size_t mask = ~u64{0} >> (64 - num_bits);
pages[page] |= (~u64{0} & mask) << first_bit;
}
bool IsPageUsed(u64 page, u64 offset, u64 size) const noexcept {
const size_t offset_in_page = offset % BUFFER_PAGE_BYTES;
const size_t first_bit = offset_in_page >> BUFFER_BYTES_PER_BITSHIFT;
const size_t num_bits = std::min<size_t>(size, BUFFER_PAGE_BYTES) >> BUFFER_BYTES_PER_BITSHIFT;
const size_t offset_in_page = offset % PAGE_BYTES;
const size_t first_bit = offset_in_page >> BYTES_PER_BIT_SHIFT;
const size_t num_bits = std::min<size_t>(size, PAGE_BYTES) >> BYTES_PER_BIT_SHIFT;
const size_t mask = ~u64{0} >> (64 - num_bits);
const size_t mask2 = (~u64{0} & mask) << first_bit;
return (pages[page] & mask2) != 0;