Skip to content

Commit

Permalink
Merge pull request #12 from DegateCommunity/attached-project-type
Browse files Browse the repository at this point in the history
Add a new project type: attached mode.
  • Loading branch information
DorianBDev committed Sep 17, 2023
2 parents 3dc2861 + 3a9dd86 commit da20d5f
Show file tree
Hide file tree
Showing 40 changed files with 1,671 additions and 598 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ build/*
.idea/
.vs/
.vscode/
.cache/

etc/installer/packages/Degate/data/*
!etc/installer/packages/Degate/data/.keepme
Expand All @@ -17,5 +18,4 @@ etc/installer/packages/Degate/meta/package.xml
doc/build/*
!doc/build/.keepme
doc/config/DoxyFile

.cache
.cache
14 changes: 11 additions & 3 deletions src/Core/Configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@
#define _CRT_SECURE_NO_WARNINGS 1

#include "Core/Configuration.h"
#include "Core/Utils/FileSystem.h"
#include "GUI/Preferences/PreferencesHandler.h"

#include <boost/lexical_cast.hpp>

using namespace degate;

Configuration::Configuration() = default;
Expand All @@ -35,3 +32,14 @@ uint_fast64_t Configuration::get_max_tile_cache_size()
{
return static_cast<uint_fast64_t>(PREFERENCES_HANDLER.get_preferences().cache_size);
}

unsigned int Configuration::get_max_concurrent_thread_count()
{
const auto& pref = PREFERENCES_HANDLER.get_preferences();

// Check default value (0 = use ideal thread count)
if (pref.max_concurrent_thread_count == 0)
return QThread::idealThreadCount();

return pref.max_concurrent_thread_count;
}
39 changes: 23 additions & 16 deletions src/Core/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,33 @@
#include "Globals.h"
#include "Core/Primitive/SingletonBase.h"

namespace degate {

class Configuration : public SingletonBase<Configuration> {

friend class SingletonBase<Configuration>;

private:
namespace degate
{
/**
* @class Configuration
* @brief Singleton class to store important parameters needed everywhere.
*/
class Configuration : public SingletonBase<Configuration>
{

Configuration();
friend class SingletonBase<Configuration>;

public:
private:
Configuration();

/**
* Get the cache size for image tiles in MB.
* @return Returns the maximum cache size (in Mb) from the preferences.
*/
static uint_fast64_t get_max_tile_cache_size();
public:
/**
* Get the cache size for image tiles in MB.
* @return Returns the maximum cache size (in Mb) from the preferences.
*/
static uint_fast64_t get_max_tile_cache_size();

};
/**
* Get the maximum number of threads allowed to run concurrently.
*/
static unsigned int get_max_concurrent_thread_count();
};

}
} // namespace degate

#endif
254 changes: 254 additions & 0 deletions src/Core/Image/GlobalTileCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
/**
* This file is part of the IC reverse engineering tool Degate.
*
* Copyright 2008, 2009, 2010 by Martin Schobert
* Copyright 2021 Dorian Bachelot
*
* Degate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Degate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with degate. If not, see <http://www.gnu.org/licenses/>.
*
*/

#ifndef __GLOBALTILECACHE_H__
#define __GLOBALTILECACHE_H__

#include "Core/Image/TileCacheBase.h"
#include "Core/Primitive/SingletonBase.h"

#include <cstddef>
#include <utility>
#include <iostream>
#include <iomanip>

namespace degate
{
/**
* @class GlobalTileCache
* @brief Keep in memory all the used memory at any instant (by tile caches).
*
* This can ask for every single tile cache to release memory if needed.
*
* @warning This is a singleton, only one instance can exists.
*/
template <class PixelPolicy>
class GlobalTileCache : public SingletonBase<GlobalTileCache<PixelPolicy>>
{
friend class SingletonBase<GlobalTileCache>;

private:
uint_fast64_t max_cache_memory;
uint_fast64_t allocated_memory;

typedef std::pair<struct timespec, uint_fast64_t> cache_entry_t;
typedef std::map<TileCacheBase*, cache_entry_t> cache_t;

cache_t cache;

private:

/**
* Create a new global tile cache object (singleton).
*/
GlobalTileCache() : allocated_memory(0)
{
if (Configuration::get_max_tile_cache_size() < MINIMUM_CACHE_SIZE)
max_cache_memory = MINIMUM_CACHE_SIZE * uint_fast64_t(1024) * uint_fast64_t(1024);
else
max_cache_memory = Configuration::get_max_tile_cache_size() * uint_fast64_t(1024) * uint_fast64_t(1024);
}

/**
* Search for the oldest cache that requested memory and make it release memory.
*/
void remove_oldest()
{
struct timespec now;
GET_CLOCK(now);

TileCacheBase* oldest = nullptr;

// Search for oldest cache
for (auto iter = cache.begin(); iter != cache.end(); ++iter)
{
cache_entry_t& entry = iter->second;
if (entry.first < now)
{
now.tv_sec = entry.first.tv_sec;
now.tv_nsec = entry.first.tv_nsec;
oldest = iter->first;
}
}

if (oldest != nullptr)
{
#ifdef TILECACHE_DEBUG
debug(TM, "Will call cleanup on %p", oldest);
#endif

// If found, make the oldest release memory
oldest->cleanup_cache();
}
else
{
#ifdef TILECACHE_DEBUG
debug(TM, "there is nothing to free.");
print_table();
#endif
}
}

public:

/**
* Print a status table about the global tile cache.
*/
void print_table() const
{
std::cout << "Global Image Tile Cache:\n"
<< "Used memory : " << allocated_memory << " bytes\n"
<< "Max memory : " << max_cache_memory << " bytes\n\n"
<< "Holder | Last access (sec,nsec) | Amount of memory\n"
<< "-----------------+---------------------------+------------------------------------\n";

for (auto iter = cache.begin(); iter != cache.end(); ++iter)
{
cache_entry_t const& entry = iter->second;
std::cout << std::setw(16) << std::hex << static_cast<void*>(iter->first);
std::cout << " | ";
std::cout << std::setw(12) << entry.first.tv_sec;
std::cout << ".";
std::cout << std::setw(12) << entry.first.tv_nsec;
std::cout << " | ";
std::cout << entry.second / static_cast<unsigned long>(1024 * 1024) << " M (" << entry.second << " bytes)\n";
iter->first->print();
}
std::cout << "\n";
}

/**
* Request memory from the cache (this is virtual).
*
* If too less memory remaining, then will call remove_oldest().
*/
bool request_cache_memory(TileCacheBase* requestor, uint_fast64_t amount)
{
#ifdef TILECACHE_DEBUG
debug(TM, "Local cache %p requests %d bytes.", requestor, amount);
#endif
while (allocated_memory + amount > max_cache_memory)
{
#ifdef TILECACHE_DEBUG
debug(TM, "Try to free memory");
#endif
remove_oldest();
}

if (allocated_memory + amount <= max_cache_memory)
{
struct timespec now{};
GET_CLOCK(now);

auto found = cache.find(requestor);
if (found == cache.end())
{
cache[requestor] = std::make_pair(now, amount);
}
else
{
cache_entry_t& entry = found->second;
entry.first.tv_sec = now.tv_sec;
entry.first.tv_nsec = now.tv_nsec;
entry.second += amount;
}

allocated_memory += amount;
#ifdef TILECACHE_DEBUG
print_table();
#endif
return true;
}

debug(TM, "Can't free memory.");

print_table();
return false;
}

/**
* Release memory from the cache (virtual).
*/
void release_cache_memory(TileCacheBase* requestor, uint_fast64_t amount)
{
#ifdef TILECACHE_DEBUG
debug(TM, "Local cache %p releases %d bytes.", requestor, amount);
#endif

auto found = cache.find(requestor);

if (found == cache.end())
{
debug(TM, "Unknown memory should be released.");
print_table();
assert(1 == 0);
}
else
{
cache_entry_t& entry = found->second;

if (entry.second >= amount)
{
entry.second -= amount;
assert(allocated_memory >= amount);
if (allocated_memory >= amount)
allocated_memory -= amount;
else
{
debug(TM, "More mem to release than available.");
print_table();
assert(1 == 0);
}
}
else
{
print_table();
assert(entry.second >= amount); // will break
}

if (entry.second == 0)
{
#ifdef TILECACHE_DEBUG
debug(TM, "Memory completely released. Remove entry from global cache.");
#endif
cache.erase(found);
}
}
}

inline uint_fast64_t get_max_cache_memory() const
{
return max_cache_memory;
}

inline uint_fast64_t get_allocated_memory() const
{
return allocated_memory;
}

inline bool is_full(uint_fast64_t amount) const
{
return allocated_memory + amount > max_cache_memory;
}
};
}

#endif //__GLOBALTILECACHE_H__
Loading

0 comments on commit da20d5f

Please sign in to comment.