Skip to content

Commit

Permalink
Let users cap enve memory usage.
Browse files Browse the repository at this point in the history
  • Loading branch information
MaurycyLiebner committed Dec 14, 2019
1 parent 17a24d8 commit a6afe91
Show file tree
Hide file tree
Showing 352 changed files with 416 additions and 89 deletions.
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ build/Release/*
/Boxes
/icons
/recent

third_party/*
!third_party/skia.tar.xz
!third_party/libmypaint.tar.xz
!third_party/skiaInstructions
!third_party/libmypaintInstructions
!third_party/gperftools-2.7/*
/settings

*.creator.user*
*.pro.user*
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ install:
- sudo make
- cd ..
- # build gperftools
- cd gperftools-2.7
- cd gperftools-2.7-enve-mod
- ./autogen.sh
- ./configure --prefix /usr
- make
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ cd ..
```

#### gperftools
Install packages needed to build gperftools:
```
sudo apt-get install autoconf automake libtool
sudo apt-get install libunwind-dev
```

Build gperftools:
```
cd gperftools-2.7
cd gperftools-2.7-enve-mod
./autogen.sh
./configure --prefix /usr
make
Expand Down
50 changes: 31 additions & 19 deletions src/app/GUI/settingsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,34 @@ SettingsDialog::SettingsDialog(QWidget * const parent) :
// cpuCapSett->addWidget(mCpuThreadsCapSpin);
// mainLauout->addLayout(cpuCapSett);

// QHBoxLayout* ramCapSett = new QHBoxLayout;
QHBoxLayout* ramCapSett = new QHBoxLayout;

// mRamBytesCapCheck = new QCheckBox("RAM MB cap", this);
// mRamBytesCapSpin = new QSpinBox(this);
// mRamBytesCapSpin->setRange(500, HardwareInfo::sRamKB()/1000);
// connect(mRamBytesCapCheck, &QCheckBox::toggled,
// mRamBytesCapSpin, &QWidget::setEnabled);
mRamMBCapCheck = new QCheckBox("Process RAM MB cap", this);
mRamMBCapSpin = new QSpinBox(this);
mRamMBCapSpin->setRange(250, intMB(HardwareInfo::sRamKB()).fValue);

// ramCapSett->addWidget(mRamBytesCapCheck);
// ramCapSett->addWidget(mRamBytesCapSpin);
// mainLauout->addLayout(ramCapSett);
mRamMBCapSlider = new QSlider(Qt::Horizontal);
mRamMBCapSlider->setRange(250, intMB(HardwareInfo::sRamKB()).fValue);

// const auto line0 = new QFrame();
// line0->setFrameShape(QFrame::HLine);
// line0->setFrameShadow(QFrame::Sunken);
// mainLauout->addWidget(line0);
connect(mRamMBCapCheck, &QCheckBox::toggled,
mRamMBCapSpin, &QWidget::setEnabled);
connect(mRamMBCapCheck, &QCheckBox::toggled,
mRamMBCapSlider, &QWidget::setEnabled);

connect(mRamMBCapSpin, qOverload<int>(&QSpinBox::valueChanged),
mRamMBCapSlider, &QSlider::setValue);
connect(mRamMBCapSlider, &QSlider::valueChanged,
mRamMBCapSpin, &QSpinBox::setValue);

ramCapSett->addWidget(mRamMBCapCheck);
ramCapSett->addWidget(mRamMBCapSpin);
mainLauout->addLayout(ramCapSett);
mainLauout->addWidget(mRamMBCapSlider);

const auto line0 = new QFrame();
line0->setFrameShape(QFrame::HLine);
line0->setFrameShadow(QFrame::Sunken);
mainLauout->addWidget(line0);


mAccPreferenceLabel = new QLabel("Acceleration preference:");
Expand Down Expand Up @@ -117,8 +129,8 @@ SettingsDialog::SettingsDialog(QWidget * const parent) :
eSettings& sett = *eSettings::sInstance;
// sett.fCpuThreadsCap = mCpuThreadsCapCheck->isChecked() ?
// mCpuThreadsCapSpin->value() : 0;
// sett.fRamMBCap = mRamBytesCapCheck->isChecked() ?
// mRamBytesCapSpin->value() : 0;
sett.fRamMBCap = intMB(mRamMBCapCheck->isChecked() ?
mRamMBCapSpin->value() : 0);
sett.fAccPreference = static_cast<AccPreference>(
mAccPreferenceSlider->value());
sett.fPathGpuAcc = mPathGpuAccCheck->isChecked();
Expand All @@ -144,10 +156,10 @@ void SettingsDialog::updateSettings() {
// mCpuThreadsCapSpin->setValue(sett.fCpuThreadsCap);
// mCpuThreadsCapSpin->setEnabled(sett.fCpuThreadsCap > 0);

// mRamBytesCapCheck->setChecked(sett.fRamMBCap > 500);
// mRamBytesCapSpin->setRange(500, HardwareInfo::sRamKB()/1000);
// mRamBytesCapSpin->setValue(sett.fRamMBCap);
// mRamBytesCapSpin->setEnabled(sett.fRamMBCap > 500);
mRamMBCapCheck->setChecked(sett.fRamMBCap.fValue > 250);
mRamMBCapSpin->setValue(sett.fRamMBCap.fValue);
mRamMBCapSpin->setEnabled(sett.fRamMBCap.fValue > 250);
mRamMBCapSlider->setValue(sett.fRamMBCap.fValue);

mAccPreferenceSlider->setValue(static_cast<int>(sett.fAccPreference));
updateAccPreferenceDesc();
Expand Down
5 changes: 3 additions & 2 deletions src/app/GUI/settingsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ class SettingsDialog : public QDialog {
QCheckBox* mCpuThreadsCapCheck = nullptr;
QSpinBox* mCpuThreadsCapSpin = nullptr;

QCheckBox* mRamBytesCapCheck = nullptr;
QSpinBox* mRamBytesCapSpin = nullptr;
QCheckBox* mRamMBCapCheck = nullptr;
QSpinBox* mRamMBCapSpin = nullptr;
QSlider* mRamMBCapSlider = nullptr;

QLabel* mAccPreferenceLabel = nullptr;
QLabel* mAccPreferenceDescLabel = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.pro
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ CONFIG += c++14
ENVE_FOLDER = $$PWD/../..
SKIA_FOLDER = $$ENVE_FOLDER/third_party/skia
LIBMYPAINT_FOLDER = $$ENVE_FOLDER/third_party/libmypaint-1.3.0
GPERFTOOLS_FOLDER = $$ENVE_FOLDER/third_party/gperftools-2.7
GPERFTOOLS_FOLDER = $$ENVE_FOLDER/third_party/gperftools-2.7-enve-mod

INCLUDEPATH += ../core
DEPENDPATH += ../core
Expand Down
16 changes: 7 additions & 9 deletions src/app/hardwareinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@

int HardwareInfo::mCpuThreads = -1;

long HardwareInfo::mRamBytes = -1;
int HardwareInfo::mRamKB = -1;
intKB HardwareInfo::mRamKB(0);

GpuVendor HardwareInfo::mGpuVendor = GpuVendor::unrecognized;

long getTotalRamBytes() {
intKB getTotalRamBytes() {
FILE * const meminfo = fopen("/proc/meminfo", "r");
if(meminfo) {
char line[256];

while(fgets(line, sizeof(line), meminfo)) {
int ram;
if(sscanf(line, "MemTotal: %d kB", &ram) == 1) {
intKB memTotal(0);
if(sscanf(line, "MemTotal: %d kB", &memTotal.fValue) == 1) {
fclose(meminfo);
return static_cast<long>(ram)*1000;
return memTotal;
}
}
fclose(meminfo);
Expand Down Expand Up @@ -72,10 +71,9 @@ GpuVendor gpuVendor() {

void HardwareInfo::sUpdateInfo() {
mCpuThreads = QThread::idealThreadCount();
mRamBytes = getTotalRamBytes();
mRamKB = static_cast<int>(mRamBytes/1000);
mRamKB = getTotalRamBytes();
mGpuVendor = gpuVendor();
eSettings::sInstance->fRamBytes = mRamBytes;
eSettings::sInstance->fRamKB = mRamKB;
eSettings::sInstance->fCpuThreads = mCpuThreads;
eSettings::sInstance->fGpuVendor = mGpuVendor;
}
8 changes: 2 additions & 6 deletions src/app/hardwareinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@ class HardwareInfo {
static void sUpdateInfo();
static int sCpuThreads() { return mCpuThreads; }

static long sRamBytes() { return mRamBytes; }
static int sRamKB() { return mRamKB; }
static intKB sRamKB() { return mRamKB; }
private:
static int mCpuThreads;

static long mRamBytes;
static int mRamKB;

static intKB mRamKB;
static GpuVendor mGpuVendor;
};

Expand Down
56 changes: 35 additions & 21 deletions src/app/memorychecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,48 @@ MemoryChecker *MemoryChecker::mInstance;
MemoryChecker::MemoryChecker(QObject * const parent) : QObject(parent) {
mInstance = this;

mVeryLowFreeBytes = 15*HardwareInfo::sRamBytes()/100;
mLowFreeBytes = 20*HardwareInfo::sRamBytes()/100;
mLowFreeKB = HardwareInfo::sRamKB();
mLowFreeKB.fValue *= 20; mLowFreeKB.fValue /= 100;
mVeryLowFreeKB = HardwareInfo::sRamKB();
mVeryLowFreeKB.fValue *= 15; mVeryLowFreeKB.fValue /= 100;
}

char MemoryChecker::sLine[256];

long MemoryChecker::sGetFreeBytes() {
void MemoryChecker::sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB) {
size_t allocatedB = 0;
size_t unmappedB = 0;
MallocExtension::instance()->GetNumericProperty(
"tcmalloc.pageheap_unmapped_bytes", &unmappedB);
MallocExtension::instance()->GetAllocatedAndUnmapped(&allocatedB, &unmappedB);
const auto usageCap = eSettings::sInstance->fRamMBCap;
procFreeKB = HardwareInfo::sRamKB();
if(usageCap.fValue > 0) {
const longB enveUsedB(static_cast<long>(allocatedB));
procFreeKB = intKB(usageCap) - intKB(enveUsedB);
qDebug() << intMB(usageCap).fValue << intMB(enveUsedB).fValue;
}

FILE * const meminfo = fopen("/proc/meminfo", "r");
if(meminfo) {
ulong ramKB = 0;
intKB ramKB(0);
int found = 0;
while(fgets(sLine, sizeof(sLine), meminfo)) {
uint ramPartKB;
int ramPartKB;
if(sscanf(sLine, "MemFree: %d kB", &ramPartKB) == 1) {
ramKB += ramPartKB;
ramKB.fValue += ramPartKB;
found++;
} else if(sscanf(sLine, "Cached: %d kB", &ramPartKB) == 1) {
ramKB += ramPartKB;
ramKB.fValue += ramPartKB;
found++;
} else if(sscanf(sLine, "Buffers: %d kB", &ramPartKB) == 1) {
ramKB += ramPartKB;
ramKB.fValue += ramPartKB;
found++;
}

if(found >= 3) {
fclose(meminfo);
return static_cast<long>(ramKB)*1000 +
static_cast<long>(unmappedB);
const intKB unmappedKB = intKB(longB(static_cast<long>(unmappedB)));
sysFreeKB = ramKB + unmappedKB;
return;
}
}
fclose(meminfo);
Expand All @@ -73,22 +83,26 @@ long MemoryChecker::sGetFreeBytes() {
}

void MemoryChecker::checkMemory() {
const long freeBytes = sGetFreeBytes();
intKB procFreeKB;
intKB sysFreeKB;
sGetFreeKB(procFreeKB, sysFreeKB);

if(freeBytes < mLowFreeBytes) {
const long toFree = mLowFreeBytes - freeBytes;
if(freeBytes < mVeryLowFreeBytes) {
emit handleMemoryState(VERY_LOW_MEMORY_STATE, toFree);
if(sysFreeKB < mLowFreeKB) {
const intKB toFree = mLowFreeKB - sysFreeKB;
if(sysFreeKB < mVeryLowFreeKB) {
emit handleMemoryState(VERY_LOW_MEMORY_STATE, longB(toFree));
mLastMemoryState = VERY_LOW_MEMORY_STATE;
} else {
emit handleMemoryState(LOW_MEMORY_STATE, toFree);
emit handleMemoryState(LOW_MEMORY_STATE, longB(toFree));
mLastMemoryState = LOW_MEMORY_STATE;
}
} else if(procFreeKB.fValue < 0) {
emit handleMemoryState(LOW_MEMORY_STATE, longB(-procFreeKB));
mLastMemoryState = LOW_MEMORY_STATE;
} else if(mLastMemoryState != NORMAL_MEMORY_STATE) {
emit handleMemoryState(NORMAL_MEMORY_STATE, 0);
emit handleMemoryState(NORMAL_MEMORY_STATE, longB(0));
mLastMemoryState = NORMAL_MEMORY_STATE;
}

emit memoryCheckedKB(static_cast<int>(freeBytes/1000),
HardwareInfo::sRamKB());
emit memoryCheckedKB(sysFreeKB, HardwareInfo::sRamKB());
}
11 changes: 6 additions & 5 deletions src/app/memorychecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <QObject>
#include <QTimer>
#include "Private/memorystructs.h"

enum MemoryState {
NORMAL_MEMORY_STATE,
Expand All @@ -35,18 +36,18 @@ class MemoryChecker : public QObject {

void checkMemory();
private:
static long sGetFreeBytes();
void sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB);
static char sLine[256];

MemoryState mLastMemoryState = NORMAL_MEMORY_STATE;

long mLowFreeBytes = 0;
long mVeryLowFreeBytes = 0;
intKB mLowFreeKB = intKB(0);
intKB mVeryLowFreeKB = intKB(0);

static MemoryChecker *mInstance;
signals:
void memoryCheckedKB(int, int);
void handleMemoryState(MemoryState, long bytesToFree);
void memoryCheckedKB(intKB, intKB);
void handleMemoryState(MemoryState, longB bytesToFree);
};

#endif // MEMORYCHECKER_H
16 changes: 10 additions & 6 deletions src/app/memoryhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

MemoryHandler *MemoryHandler::sInstance = nullptr;
Q_DECLARE_METATYPE(MemoryState)
Q_DECLARE_METATYPE(longB)
Q_DECLARE_METATYPE(intKB)

MemoryHandler::MemoryHandler(QObject * const parent) : QObject(parent) {
Q_ASSERT(!sInstance);
Expand All @@ -33,8 +35,10 @@ MemoryHandler::MemoryHandler(QObject * const parent) : QObject(parent) {
mMemoryChecker = new MemoryChecker();
mMemoryChecker->moveToThread(mMemoryChekerThread);
qRegisterMetaType<MemoryState>();
qRegisterMetaType<longB>();
connect(mMemoryChecker, &MemoryChecker::handleMemoryState,
this, &MemoryHandler::freeMemory);
qRegisterMetaType<intKB>();
connect(mMemoryChecker, &MemoryChecker::memoryCheckedKB,
this, &MemoryHandler::memoryChecked);

Expand All @@ -53,7 +57,7 @@ MemoryHandler::~MemoryHandler() {
}

void MemoryHandler::freeMemory(const MemoryState &state,
const long &minFreeBytes) {
const longB &minFreeBytes) {
if(state != mCurrentMemoryState) {
if(state == NORMAL_MEMORY_STATE) {
mTimer->setInterval(1000);
Expand All @@ -63,8 +67,8 @@ void MemoryHandler::freeMemory(const MemoryState &state,
mCurrentMemoryState = state;
}

if(minFreeBytes <= 0) return;
long memToFree = minFreeBytes;
if(minFreeBytes.fValue <= 0) return;
long memToFree = minFreeBytes.fValue;
while(memToFree > 0 && !mDataHandler.isEmpty()) {
const auto cont = mDataHandler.takeFirst();
memToFree -= cont->free_RAM_k();
Expand All @@ -73,10 +77,10 @@ void MemoryHandler::freeMemory(const MemoryState &state,
emit memoryFreed();
}

void MemoryHandler::memoryChecked(const int memKb, const int totMemKb) {
void MemoryHandler::memoryChecked(const intKB memKb, const intKB totMemKb) {
if(!MainWindow::sGetInstance()) return;
const auto usageWidget = MainWindow::sGetInstance()->getUsageWidget();
if(!usageWidget) return;
usageWidget->setTotalRam(totMemKb/1000000.);
usageWidget->setRamUsage((totMemKb - memKb)/1000000.);
usageWidget->setTotalRam(totMemKb.fValue/(1024*1024));
usageWidget->setRamUsage((totMemKb - memKb).fValue/(1024*1024));
}
4 changes: 2 additions & 2 deletions src/app/memoryhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class MemoryHandler : public QObject {
void allMemoryUsed();
void memoryFreed();
private:
void freeMemory(const MemoryState &state, const long &minFreeBytes);
void memoryChecked(const int memKb, const int totMemKb);
void freeMemory(const MemoryState &state, const longB &minFreeBytes);
void memoryChecked(const intKB memKb, const intKB totMemKb);

MemoryDataHandler mDataHandler;
MemoryState mCurrentMemoryState = NORMAL_MEMORY_STATE;
Expand Down
Loading

0 comments on commit a6afe91

Please sign in to comment.