Browse Source

Add option to control qBittorrent process memory priority

This is to avoid Windows swapping out other application data from
OS cache and put in torrent data which hinders other program
responsiveness.

The default value "Below normal" is choosen because casual users have
other higher priority apps (such as browser) running and they don't
expect OS to swap out its data. Dedicated seeders most probably will not
have other app running on their system and would expect qbt has
priority over other background services.

The option only has effect on Windows >= 8.
adaptive-webui-19844
Chocobo1 5 years ago
parent
commit
0f60121b94
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 61
      src/base/bittorrent/session.cpp
  2. 22
      src/base/bittorrent/session.h
  3. 52
      src/gui/advancedsettings.cpp
  4. 2
      src/gui/advancedsettings.h

61
src/base/bittorrent/session.cpp

@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
#include <utility>
#ifdef Q_OS_WIN
#include <Windows.h>
#include <wincrypt.h>
#include <iphlpapi.h>
#endif
@ -344,6 +345,9 @@ Session::Session(QObject *parent) @@ -344,6 +345,9 @@ Session::Session(QObject *parent)
return tmp;
}
)
#if defined(Q_OS_WIN)
, m_OSMemoryPriority(BITTORRENT_KEY("OSMemoryPriority"), OSMemoryPriority::BelowNormal)
#endif
, m_resumeFolderLock {new QFile {this}}
, m_refreshTimer {new QTimer {this}}
, m_seedingLimitTimer {new QTimer {this}}
@ -930,6 +934,10 @@ void Session::configureComponents() @@ -930,6 +934,10 @@ void Session::configureComponents()
disableIPFilter();
m_IPFilteringConfigured = true;
}
#if defined(Q_OS_WIN)
applyOSMemoryPriority();
#endif
}
void Session::initializeNativeSession()
@ -2753,6 +2761,59 @@ QStringList Session::bannedIPs() const @@ -2753,6 +2761,59 @@ QStringList Session::bannedIPs() const
return m_bannedIPs;
}
#if defined(Q_OS_WIN)
OSMemoryPriority Session::getOSMemoryPriority() const
{
return m_OSMemoryPriority;
}
void Session::setOSMemoryPriority(const OSMemoryPriority priority)
{
if (m_OSMemoryPriority == priority)
return;
m_OSMemoryPriority = priority;
configureDeferred();
}
void Session::applyOSMemoryPriority() const
{
using SETPROCESSINFORMATION = BOOL (WINAPI *)(HANDLE, PROCESS_INFORMATION_CLASS, LPVOID, DWORD);
const auto setProcessInformation = Utils::Misc::loadWinAPI<SETPROCESSINFORMATION>("Kernel32.dll", "SetProcessInformation");
if (!setProcessInformation) // only available on Windows >= 8
return;
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
// this dummy struct is required to compile successfully when targeting older Windows version
struct MEMORY_PRIORITY_INFORMATION
{
ULONG MemoryPriority;
};
#endif
MEMORY_PRIORITY_INFORMATION prioInfo {};
switch (getOSMemoryPriority()) {
case OSMemoryPriority::Normal:
default:
prioInfo.MemoryPriority = MEMORY_PRIORITY_NORMAL;
break;
case OSMemoryPriority::BelowNormal:
prioInfo.MemoryPriority = MEMORY_PRIORITY_BELOW_NORMAL;
break;
case OSMemoryPriority::Medium:
prioInfo.MemoryPriority = MEMORY_PRIORITY_MEDIUM;
break;
case OSMemoryPriority::Low:
prioInfo.MemoryPriority = MEMORY_PRIORITY_LOW;
break;
case OSMemoryPriority::VeryLow:
prioInfo.MemoryPriority = MEMORY_PRIORITY_VERY_LOW;
break;
}
setProcessInformation(::GetCurrentProcess(), ProcessMemoryPriority, &prioInfo, sizeof(prioInfo));
}
#endif
int Session::maxConnectionsPerTorrent() const
{
return m_maxConnectionsPerTorrent;

22
src/base/bittorrent/session.h

@ -132,6 +132,18 @@ namespace BitTorrent @@ -132,6 +132,18 @@ namespace BitTorrent
AntiLeech = 2
};
Q_ENUM_NS(SeedChokingAlgorithm)
#if defined(Q_OS_WIN)
enum class OSMemoryPriority : int
{
Normal = 0,
BelowNormal = 1,
Medium = 2,
Low = 3,
VeryLow = 4
};
Q_ENUM_NS(OSMemoryPriority)
#endif
}
using namespace SessionSettingsEnums;
@ -387,6 +399,10 @@ namespace BitTorrent @@ -387,6 +399,10 @@ namespace BitTorrent
void setTrackerFilteringEnabled(bool enabled);
QStringList bannedIPs() const;
void setBannedIPs(const QStringList &newList);
#if defined(Q_OS_WIN)
OSMemoryPriority getOSMemoryPriority() const;
void setOSMemoryPriority(OSMemoryPriority priority);
#endif
void startUpTorrents();
TorrentHandle *findTorrent(const InfoHash &hash) const;
@ -530,6 +546,9 @@ namespace BitTorrent @@ -530,6 +546,9 @@ namespace BitTorrent
void populateAdditionalTrackers();
void enableIPFilter();
void disableIPFilter();
#if defined(Q_OS_WIN)
void applyOSMemoryPriority() const;
#endif
bool addTorrent_impl(CreateTorrentParams params, const MagnetUri &magnetUri,
TorrentInfo torrentInfo = TorrentInfo(),
@ -661,6 +680,9 @@ namespace BitTorrent @@ -661,6 +680,9 @@ namespace BitTorrent
CachedSettingValue<bool> m_isDisableAutoTMMWhenCategorySavePathChanged;
CachedSettingValue<bool> m_isTrackerEnabled;
CachedSettingValue<QStringList> m_bannedIPs;
#if defined(Q_OS_WIN)
CachedSettingValue<OSMemoryPriority> m_OSMemoryPriority;
#endif
// Order is important. This needs to be declared after its CachedSettingsValue
// counterpart, because it uses it for initialization in the constructor

52
src/gui/advancedsettings.cpp

@ -61,6 +61,9 @@ enum AdvSettingsRows @@ -61,6 +61,9 @@ enum AdvSettingsRows
{
// qBittorrent section
QBITTORRENT_HEADER,
#if defined(Q_OS_WIN)
OS_MEMORY_PRIORITY,
#endif
// network interface
NETWORK_IFACE,
//Optional network address
@ -151,6 +154,28 @@ void AdvancedSettings::saveAdvancedSettings() @@ -151,6 +154,28 @@ void AdvancedSettings::saveAdvancedSettings()
Preferences *const pref = Preferences::instance();
BitTorrent::Session *const session = BitTorrent::Session::instance();
#if defined(Q_OS_WIN)
BitTorrent::OSMemoryPriority prio = BitTorrent::OSMemoryPriority::Normal;
switch (m_comboBoxOSMemoryPriority.currentIndex()) {
case 0:
default:
prio = BitTorrent::OSMemoryPriority::Normal;
break;
case 1:
prio = BitTorrent::OSMemoryPriority::BelowNormal;
break;
case 2:
prio = BitTorrent::OSMemoryPriority::Medium;
break;
case 3:
prio = BitTorrent::OSMemoryPriority::Low;
break;
case 4:
prio = BitTorrent::OSMemoryPriority::VeryLow;
break;
}
session->setOSMemoryPriority(prio);
#endif
// Async IO threads
session->setAsyncIOThreads(m_spinBoxAsyncIOThreads.value());
// File pool size
@ -321,6 +346,33 @@ void AdvancedSettings::loadAdvancedSettings() @@ -321,6 +346,33 @@ void AdvancedSettings::loadAdvancedSettings()
addRow(LIBTORRENT_HEADER, QString("<b>%1</b>").arg(tr("libtorrent Section")), labelLibtorrentLink);
static_cast<QLabel *>(cellWidget(LIBTORRENT_HEADER, PROPERTY))->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
#if defined(Q_OS_WIN)
m_comboBoxOSMemoryPriority.addItems({tr("Normal"), tr("Below normal"), tr("Medium"), tr("Low"), tr("Very low")});
int OSMemoryPriorityIndex = 0;
switch (session->getOSMemoryPriority()) {
default:
case BitTorrent::OSMemoryPriority::Normal:
OSMemoryPriorityIndex = 0;
break;
case BitTorrent::OSMemoryPriority::BelowNormal:
OSMemoryPriorityIndex = 1;
break;
case BitTorrent::OSMemoryPriority::Medium:
OSMemoryPriorityIndex = 2;
break;
case BitTorrent::OSMemoryPriority::Low:
OSMemoryPriorityIndex = 3;
break;
case BitTorrent::OSMemoryPriority::VeryLow:
OSMemoryPriorityIndex = 4;
break;
}
m_comboBoxOSMemoryPriority.setCurrentIndex(OSMemoryPriorityIndex);
addRow(OS_MEMORY_PRIORITY, (tr("Process memory priority (Windows >= 8 only)")
+ ' ' + makeLink("https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-memory_priority_information", "(?)"))
, &m_comboBoxOSMemoryPriority);
#endif
// Async IO threads
m_spinBoxAsyncIOThreads.setMinimum(1);
m_spinBoxAsyncIOThreads.setMaximum(1024);

2
src/gui/advancedsettings.h

@ -71,6 +71,8 @@ private: @@ -71,6 +71,8 @@ private:
// OS dependent settings
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
QCheckBox m_checkBoxUseIconTheme;
#elif defined(Q_OS_WIN)
QComboBox m_comboBoxOSMemoryPriority;
#endif
};

Loading…
Cancel
Save