Detect power domains.

This commit is contained in:
Bartosz Taudul 2023-03-10 00:05:18 +01:00
parent 5e2e5eeefb
commit c3e7157cd5
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
2 changed files with 127 additions and 0 deletions

View File

@ -2,21 +2,130 @@
#ifdef TRACY_HAS_SYSPOWER
#include <sys/types.h>
#include <dirent.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include "TracyDebug.hpp"
#include "../common/TracyAlloc.hpp"
namespace tracy
{
SysPower::SysPower()
: m_domains( 4 )
{
ScanDirectory( "/sys/devices/virtual/powercap/intel-rapl", -1 );
}
SysPower::~SysPower()
{
for( auto& v : m_domains )
{
fclose( v.handle );
// Do not release v.name, as it may be still needed
}
}
void SysPower::Tick()
{
}
void SysPower::ScanDirectory( const char* path, int parent )
{
DIR* dir = opendir( path );
if( !dir ) return;
struct dirent* ent;
uint64_t maxRange = 0;
char* name = nullptr;
FILE* handle = nullptr;
while( ( ent = readdir( dir ) ) )
{
if( ent->d_type == DT_REG )
{
if( strcmp( ent->d_name, "max_energy_range_uj" ) == 0 )
{
char tmp[PATH_MAX];
snprintf( tmp, PATH_MAX, "%s/max_energy_range_uj", path );
FILE* f = fopen( tmp, "r" );
if( f )
{
fscanf( f, "%" PRIu64, &maxRange );
fclose( f );
}
}
else if( strcmp( ent->d_name, "name" ) == 0 )
{
char tmp[PATH_MAX];
snprintf( tmp, PATH_MAX, "%s/name", path );
FILE* f = fopen( tmp, "r" );
if( f )
{
char ntmp[128];
if( fgets( ntmp, 128, f ) )
{
// Last character is newline, skip it
const auto sz = strlen( ntmp ) - 1;
if( parent < 0 )
{
name = (char*)tracy_malloc( sz + 1 );
memcpy( name, ntmp, sz );
name[sz] = '\0';
}
else
{
const auto p = m_domains[parent];
const auto psz = strlen( p.name );
name = (char*)tracy_malloc( psz + sz + 2 );
memcpy( name, p.name, psz );
name[psz] = ':';
memcpy( name+psz+1, ntmp, sz );
name[psz+sz+1] = '\0';
}
}
fclose( f );
}
}
else if( strcmp( ent->d_name, "energy_uj" ) == 0 )
{
char tmp[PATH_MAX];
snprintf( tmp, PATH_MAX, "%s/energy_uj", path );
handle = fopen( tmp, "r" );
}
}
if( name && handle && maxRange > 0 ) break;
}
if( name && handle && maxRange > 0 )
{
parent = (int)m_domains.size();
Domain* domain = m_domains.push_next();
domain->value = 0;
domain->overflow = maxRange;
domain->handle = handle;
domain->name = name;
TracyDebug( "Power domain id %i, %s found at %s\n", parent, name, path );
}
else
{
if( name ) tracy_free( name );
if( handle ) fclose( handle );
}
rewinddir( dir );
while( ( ent = readdir( dir ) ) )
{
if( ent->d_type == DT_DIR && strncmp( ent->d_name, "intel-rapl:", 11 ) == 0 )
{
char tmp[PATH_MAX];
snprintf( tmp, PATH_MAX, "%s/%s", path, ent->d_name );
ScanDirectory( tmp, parent );
}
}
closedir( dir );
}
}
#endif

View File

@ -7,16 +7,34 @@
#ifdef TRACY_HAS_SYSPOWER
#include <stdint.h>
#include <stdio.h>
#include "TracyFastVector.hpp"
namespace tracy
{
class SysPower
{
struct Domain
{
uint64_t value;
uint64_t overflow;
FILE* handle;
const char* name;
};
public:
SysPower();
~SysPower();
void Tick();
private:
void ScanDirectory( const char* path, int parent );
FastVector<Domain> m_domains;
};
}