Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ios raise qos of worker thread to high #660

Merged
merged 2 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions src/cli/cli_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,6 @@ Worker::Worker()
CRYPTO_library_init();

thread_ = std::make_unique<std::thread>([this] { WorkFunc(); });

asio::post(io_context_, [this]() {
if (!SetThreadName(thread_->native_handle(), "background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetThreadPriority(thread_->native_handle(), ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}
});
}

Worker::~Worker() {
Expand Down Expand Up @@ -158,6 +149,13 @@ int Worker::GetLocalPort() const {
}

void Worker::WorkFunc() {
if (!SetCurrentThreadName("background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetCurrentThreadPriority(ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}

LOG(INFO) << "background thread started";
while (!in_destroy_) {
work_guard_ = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(io_context_.get_executor());
Expand Down
6 changes: 2 additions & 4 deletions src/core/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,9 @@ enum class ThreadPriority : int {
TIME_CRITICAL,
};

bool SetThreadPriority(std::thread::native_handle_type handle,
ThreadPriority priority);
bool SetCurrentThreadPriority(ThreadPriority priority);

bool SetThreadName(std::thread::native_handle_type handle,
const std::string& name);
bool SetCurrentThreadName(const std::string& name);

// Lock memory to avoid page fault
bool MemoryLockAll();
Expand Down
11 changes: 3 additions & 8 deletions src/core/utils_freebsd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,12 @@
#include <time.h> // For clock_gettime

// TBD
bool SetThreadPriority(std::thread::native_handle_type /*handle*/,
ThreadPriority /*priority*/) {
bool SetCurrentThreadPriority(ThreadPriority /*priority*/) {
return true;
}

bool SetThreadName(std::thread::native_handle_type handle,
const std::string& name) {
if (handle == 0) {
handle = pthread_self();
}
pthread_set_name_np(handle, name.c_str());
bool SetCurrentThreadName(const std::string& name) {
pthread_set_name_np(pthread_self(), name.c_str());
return true;
}

Expand Down
27 changes: 19 additions & 8 deletions src/core/utils_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,30 @@
#include <sys/mman.h> // For mlockall.
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/prctl.h>

bool SetThreadPriority(std::thread::native_handle_type /*handle*/,
ThreadPriority /*priority*/) {
bool SetCurrentThreadPriority(ThreadPriority /*priority*/) {
// TBD: can be implemented with cgroup
return true;
}

bool SetThreadName(std::thread::native_handle_type handle,
const std::string& name) {
if (handle == 0) {
handle = pthread_self();
}
return pthread_setname_np(handle, name.c_str()) == 0;
bool SetCurrentThreadName(const std::string& name) {
// On linux we can get the thread names to show up in the debugger by setting
// the process name for the LWP. We don't want to do this for the main
// thread because that would rename the process, causing tools like killall
// to stop working.
if (static_cast<pid_t>(pthread_self()) == getpid())
return true;
// http://0pointer.de/blog/projects/name-your-threads.html
// Set the name for the LWP (which gets truncated to 15 characters).
// Note that glibc also has a 'pthread_setname_np' api, but it may not be
// available everywhere and it's only benefit over using prctl directly is
// that it can set the name of threads other than the current thread.
int err = prctl(PR_SET_NAME, name.c_str());
// We expect EPERM failures in sandboxed processes, just ignore those.
if (err < 0 && errno != EPERM)
PLOG(ERROR) << "prctl(PR_SET_NAME)";
return err == 0;
}

bool MemoryLockAll() {
Expand Down
6 changes: 2 additions & 4 deletions src/core/utils_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
#define VM_MEMORY_BTINFO 105
#endif // VM_MEMORY_BTINFO

bool SetThreadPriority(std::thread::native_handle_type handle,
ThreadPriority priority) {
bool SetCurrentThreadPriority(ThreadPriority priority) {
// Changing the priority of the main thread causes performance regressions.
// https://crbug.com/601270
DCHECK(!pthread_main_np());
Expand Down Expand Up @@ -71,8 +70,7 @@ bool SetThreadPriority(std::thread::native_handle_type handle,

}

bool SetThreadName(std::thread::native_handle_type handle,
const std::string& name) {
bool SetCurrentThreadName(const std::string& name) {
// pthread_setname() fails (harmlessly) in the sandbox, ignore when it does.
// See http://crbug.com/47058
return pthread_setname_np(name.c_str()) == 0;
Expand Down
24 changes: 2 additions & 22 deletions src/core/utils_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,8 @@ void SetNameInternal(DWORD thread_id, const char* name) {
} // namespace
#endif // COMPILER_MSVC

#ifdef COMPILER_MSVC
bool SetThreadPriority(std::thread::native_handle_type handle,
ThreadPriority priority) {
#else
bool SetThreadPriority(std::thread::native_handle_type,
ThreadPriority priority) {
bool SetCurrentThreadPriority(ThreadPriority priority) {
HANDLE handle = ::GetCurrentThread();
#endif // COMPILER_MSVC
int desired_priority = THREAD_PRIORITY_ERROR_RETURN;
switch (priority) {
case ThreadPriority::BACKGROUND:
Expand Down Expand Up @@ -149,14 +143,8 @@ bool SetThreadPriority(std::thread::native_handle_type,
return ret;
}

#ifdef COMPILER_MSVC
bool SetThreadName(std::thread::native_handle_type handle,
const std::string& name) {
#else
bool SetThreadName(std::thread::native_handle_type,
const std::string& name) {
bool SetCurrentThreadName(const std::string& name) {
HANDLE handle = ::GetCurrentThread();
#endif // COMPILER_MSVC
if (!IsWindowsVersionBNOrGreater(10, 0, 14393)) {
return true;
}
Expand All @@ -166,10 +154,6 @@ bool SetThreadName(std::thread::native_handle_type,
::GetModuleHandleW(L"Kernel32.dll"), "SetThreadDescription")));
HRESULT ret = E_NOTIMPL;

if (handle == HANDLE() || handle == INVALID_HANDLE_VALUE) {
handle = ::GetCurrentThread();
}

if (fPointer) {
ret = fPointer(handle, SysUTF8ToWide(name).c_str());
}
Expand All @@ -182,11 +166,7 @@ bool SetThreadName(std::thread::native_handle_type,
#ifdef COMPILER_MSVC
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadid
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadid
#if _WIN32_WINNT < 0x0600
SetNameInternal(::GetCurrentThreadId(), name.c_str());
#else
SetNameInternal(::GetThreadId(handle), name.c_str());
#endif
#endif // COMPILER_MSVC
return SUCCEEDED(ret);
}
Expand Down
2 changes: 0 additions & 2 deletions src/ios/YassAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#import <NetworkExtension/NetworkExtension.h>

#include <pthread.h>
#include <stdexcept>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -40,7 +39,6 @@ @implementation YassAppDelegate {

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
state_ = STOPPED;
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeVpnStatus:) name:NEVPNStatusDidChangeNotification object:nil];
return YES;
}
Expand Down
26 changes: 16 additions & 10 deletions src/ios/extensions/YassPacketTunnelProvider.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
@implementation YassPacketTunnelProvider {
std::atomic_bool stopped_;
Worker worker_;
std::unique_ptr<std::thread> worker_thread_;
std::unique_ptr<std::thread> tun2proxy_thread_;
struct Tun2Proxy_InitContext *context_;
}

Expand Down Expand Up @@ -80,7 +80,7 @@ - (void)startTunnelWithOptions:(NSDictionary *)options completionHandler:(void (
}

if (successed) {
NSLog(@"yass: init");
NSLog(@"worker started");
[self startTunnelWithOptionsOnCallback:completionHandler];
} else {
completionHandler([NSError errorWithDomain:@"it.gui.ios.yass" code:200
Expand Down Expand Up @@ -120,12 +120,18 @@ - (void)startTunnelWithOptionsOnCallback:(void (^)(NSError *))completionHandler
userInfo:@{@"Error reason": @"tun2proxy init failure"}]);
return;
}
NSLog(@"tun2proxy: inited with %s mtu %d dns_proxy %s", proxy_url.c_str(), DEFAULT_MTU, "true");
NSLog(@"tun2proxy inited with %s mtu %d dns_proxy %s", proxy_url.c_str(), DEFAULT_MTU, "true");
Tun2Proxy_InitContext *context = context_;
worker_thread_ = std::make_unique<std::thread>([context]{
NSLog(@"tun2proxy: worker thread begin");
tun2proxy_thread_ = std::make_unique<std::thread>([context]{
if (!SetCurrentThreadName("tun2proxy")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetCurrentThreadPriority(ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}
NSLog(@"tun2proxy thread begin");
Tun2Proxy_Run(context);
NSLog(@"tun2proxy: worker thread done");
NSLog(@"tun2proxy thread done");
});

NEPacketTunnelNetworkSettings *tunnelNetworkSettings = [[NEPacketTunnelNetworkSettings alloc] initWithTunnelRemoteAddress:remote_ips_v4[0]];
Expand Down Expand Up @@ -220,11 +226,11 @@ - (void)stopTunnelWithReason:(NEProviderStopReason)reason completionHandler:(voi
NSLog(@"tunnel: stop with reason %ld", reason);
stopped_ = true;
worker_.Stop([=]{
NSLog(@"yass: stopped");
NSLog(@"worker stopped");
Tun2Proxy_Destroy(context_);
NSLog(@"tun2proxy: destroyed");
worker_thread_->join();
worker_thread_.reset();
NSLog(@"tun2proxy destroyed");
tun2proxy_thread_->join();
tun2proxy_thread_.reset();
completionHandler();
});
}
Expand Down
3 changes: 0 additions & 3 deletions src/mac/YassAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "cli/cli_worker.hpp"

#include <pthread.h>
#include <stdexcept>
#include <string>

Expand Down Expand Up @@ -42,8 +41,6 @@ - (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
[viewController OnStart];
}

// https://developer.apple.com/documentation/apple-silicon/tuning-your-code-s-performance-for-apple-silicon
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
[NSApp activateIgnoringOtherApps:true];
}

Expand Down
19 changes: 7 additions & 12 deletions src/ss_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,24 +294,19 @@ class SsEndToEndBM : public benchmark::Fixture {

void StartWorkThread() {
thread_ = std::make_unique<std::thread>([this]() {
asio::error_code ec;
VLOG(1) << "background thread started";
if (!SetCurrentThreadName("background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetCurrentThreadPriority(ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}

VLOG(1) << "background thread started";
work_guard_ = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(io_context_.get_executor());
io_context_.run();
io_context_.restart();

VLOG(1) << "background thread stopped";
});

asio::post(io_context_, [this]() {
if (!SetThreadName(thread_->native_handle(), "background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetThreadPriority(thread_->native_handle(), ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}
});
}

public:
Expand Down
19 changes: 7 additions & 12 deletions src/ss_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,24 +366,19 @@ class EndToEndTest : public ::testing::TestWithParam<cipher_method> {

void StartWorkThread() {
thread_ = std::make_unique<std::thread>([this]() {
asio::error_code ec;
VLOG(1) << "background thread started";
if (!SetCurrentThreadName("background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetCurrentThreadPriority(ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}

VLOG(1) << "background thread started";
work_guard_ = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(io_context_.get_executor());
io_context_.run();
io_context_.restart();

VLOG(1) << "background thread stopped";
});

asio::post(io_context_, [this]() {
if (!SetThreadName(thread_->native_handle(), "background")) {
PLOG(WARNING) << "failed to set thread name";
}
if (!SetThreadPriority(thread_->native_handle(), ThreadPriority::ABOVE_NORMAL)) {
PLOG(WARNING) << "failed to set thread priority";
}
});
}

void SendRequestAndCheckResponse() {
Expand Down
Loading