Skip to content

Commit

Permalink
Merge branch 'mem_check'
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Jun 1, 2024
2 parents 9136a9d + e154fa8 commit 90105da
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 8 deletions.
60 changes: 58 additions & 2 deletions scanners/module_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "module_cache.h"
#include <psapi.h>

BYTE* pesieve::ModulesCache::loadCached(LPSTR szModName, size_t& module_size)
{
Expand All @@ -18,7 +19,7 @@ BYTE* pesieve::ModulesCache::loadCached(LPSTR szModName, size_t& module_size)
util::MutexLocker guard(cacheMutex);
size_t currCntr = usageBeforeCounter[szModName]++;
const size_t cachedModulesCntr = cachedModules.size();
const bool is_cache_available = cachedModulesCntr < MaxCachedModules;
const bool is_cache_available = isCacheAvailable(raw_size);
if (currCntr >= MinUsageCntr && is_cache_available) {
bool is_cached = false;
CachedModule* mod_cache = new(std::nothrow) CachedModule(raw_buf, raw_size);
Expand All @@ -40,10 +41,65 @@ BYTE* pesieve::ModulesCache::loadCached(LPSTR szModName, size_t& module_size)
}

// after adding file to the cache, wipe out the old ones:
prepareCacheSpace(force_free_cache);
prepareCacheSpace(raw_size, force_free_cache);

// return the mapped module:
mapped_pe = peconv::load_pe_module(raw_buf, raw_size, module_size, false, false);
peconv::free_file(raw_buf);
return mapped_pe;
}

bool pesieve::ModulesCache::isCacheAvailable(const size_t neededSize)
{
bool hasFree = false;
SIZE_T minSize = 0;
SIZE_T maxSize = 0;
DWORD info = 0;

if (!GetProcessWorkingSetSizeEx(GetCurrentProcess(), &minSize, &maxSize, &info)) {
return false;
}

MEMORYSTATUSEX memStatus = { 0 };
memStatus.dwLength = sizeof(MEMORYSTATUSEX);

if ((info & QUOTA_LIMITS_HARDWS_MAX_DISABLE) == QUOTA_LIMITS_HARDWS_MAX_DISABLE) { // The working set may exceed the maximum working set limit if there is abundant memory
if (GlobalMemoryStatusEx(&memStatus)) {
if (memStatus.ullAvailVirtual > (neededSize * 2) && (memStatus.dwMemoryLoad < 50)) {
hasFree = true;
}
}
}

PROCESS_MEMORY_COUNTERS ppsmemCounter = { 0 };
ppsmemCounter.cb = sizeof(PROCESS_MEMORY_COUNTERS);
GetProcessMemoryInfo(GetCurrentProcess(), &ppsmemCounter, sizeof(PROCESS_MEMORY_COUNTERS));

// hard limit is enabled, use it to calculate how much you can use
if (maxSize > ppsmemCounter.PeakWorkingSetSize) {
size_t freeMem = maxSize - ppsmemCounter.WorkingSetSize;
size_t percW1 = size_t(((double)ppsmemCounter.WorkingSetSize / (double)maxSize) * 100.0);
if (freeMem > (neededSize * 2) && (percW1 < 60)) {
hasFree = true;
}
}
size_t freeMemP = ppsmemCounter.PeakWorkingSetSize - ppsmemCounter.WorkingSetSize;
size_t percPeak = size_t(((double)ppsmemCounter.WorkingSetSize / (double)ppsmemCounter.PeakWorkingSetSize) * 100.0);

if (freeMemP > (neededSize * 2) && (percPeak < 70)) {
hasFree = true;
}

#ifdef _DEBUG
std::cout << "C: " << std::hex << ppsmemCounter.WorkingSetSize
<< "\tP: " << std::hex << ppsmemCounter.PeakWorkingSetSize
<< "\tMin: " << minSize
<< "\tMax: " << maxSize
<< "\tGlobalMem Av Virt: " << std::hex << memStatus.ullAvailVirtual
<< std::dec << "\tPerc: " << memStatus.dwMemoryLoad
<< std::dec << " PercPeak: " << percPeak
<< " HasFree: " << hasFree
<< std::endl;
#endif
return hasFree;
}
17 changes: 11 additions & 6 deletions scanners/module_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ namespace pesieve
public:

static const size_t MinUsageCntr = 2; ///< how many times loading of the module must be requested before the module is added to cache
static const size_t MaxCachedModules = 255; ///< how many modules can be stored in the cache at the time

ModulesCache()
{
Expand Down Expand Up @@ -131,14 +130,20 @@ namespace pesieve
return nullptr;
}

bool prepareCacheSpace(bool force_free = false)
bool isCacheAvailable(const size_t neededSize);

bool prepareCacheSpace(const size_t neededSize, bool force_free)
{
util::MutexLocker guard(cacheMutex);
const bool is_cache_available = cachedModules.size() < MaxCachedModules;
if (is_cache_available && !force_free) {
return true;
if (force_free) {
_deleteLeastRecent();
}
while (!isCacheAvailable(neededSize)) {
if (!_deleteLeastRecent()) {
return false; // cannot make free space
}
}
return _deleteLeastRecent();
return true;
}

bool _deleteLeastRecent()
Expand Down

0 comments on commit 90105da

Please sign in to comment.