steamcompmgr: add support for spewing stats into a pipe

This commit is contained in:
Pierre-Loup A. Griffais 2020-01-24 01:47:26 +00:00
parent dde441b13f
commit 982e61e28d
2 changed files with 132 additions and 19 deletions

View file

@ -58,7 +58,7 @@ int main(int argc, char **argv)
bool bSleepAtStartup = false; bool bSleepAtStartup = false;
while ((o = getopt (argc, argv, ":w:h:W:H:r:slnb")) != -1) while ((o = getopt (argc, argv, ":R:T:w:h:W:H:r:NSvVecslnb")) != -1)
{ {
switch (o) { switch (o) {
case 'w': case 'w':

View file

@ -223,31 +223,51 @@ std::mutex wayland_commit_lock;
std::vector<ResListEntry_t> wayland_commit_queue; std::vector<ResListEntry_t> wayland_commit_queue;
// poor man's semaphore // poor man's semaphore
std::mutex mtx; class sem
std::condition_variable cv;
int count;
std::mutex waitListLock;
std::vector< void * > waitList;
void imageWaitThreadRun( void )
{ {
begin: public:
void wait( void )
{ {
std::unique_lock<std::mutex> lock(mtx); std::unique_lock<std::mutex> lock(mtx);
while(count == 0){ while(count == 0){
cv.wait(lock); cv.wait(lock);
} }
count--; count--;
} }
void signal( void )
{
std::unique_lock<std::mutex> lock(mtx);
count++;
cv.notify_one();
}
private:
std::mutex mtx;
std::condition_variable cv;
int count = 0;
};
sem waitListSem;
std::mutex waitListLock;
std::vector< void * > waitList;
void imageWaitThreadRun( void )
{
wait:
waitListSem.wait();
void *fence = nullptr; void *fence = nullptr;
retry:
{ {
std::unique_lock< std::mutex > lock( waitListLock ); std::unique_lock< std::mutex > lock( waitListLock );
assert( waitList.size() > 0 ); if( waitList.size() == 0 )
{
goto wait;
}
fence = waitList[ 0 ]; fence = waitList[ 0 ];
waitList.erase( waitList.begin() ); waitList.erase( waitList.begin() );
@ -258,10 +278,83 @@ begin:
vulkan_wait_for_fence( fence ); vulkan_wait_for_fence( fence );
gpuvis_trace_printf( "wait fence ended\n" ); gpuvis_trace_printf( "wait fence ended\n" );
goto begin; goto retry;
} }
sem statsThreadSem;
std::mutex statsEventQueueLock;
std::vector< std::string > statsEventQueue;
std::string statsThreadPath;
int statsPipeFD = -1;
void statsThreadRun( void )
{
signal(SIGPIPE, SIG_IGN);
while ( statsPipeFD == -1 )
{
statsPipeFD = open( statsThreadPath.c_str(), O_WRONLY );
if ( statsPipeFD == -1 )
{
sleep( 10 );
}
}
wait:
statsThreadSem.wait();
std::string event;
retry:
{
std::unique_lock< std::mutex > lock( statsEventQueueLock );
if( statsEventQueue.size() == 0 )
{
goto wait;
}
event = statsEventQueue[ 0 ];
statsEventQueue.erase( statsEventQueue.begin() );
}
dprintf( statsPipeFD, "%s", event.c_str() );
goto retry;
}
static inline void stats_printf( const char* format, ...)
{
static char buffer[256];
static std::string eventstr;
va_list args;
va_start (args, format);
vsprintf (buffer,format, args);
va_end (args);
eventstr = buffer;
{
{
std::unique_lock< std::mutex > lock( statsEventQueueLock );
if( statsEventQueue.size() > 50 )
{
// overflow, drop event
return;
}
statsEventQueue.push_back( eventstr );
statsThreadSem.signal();
}
}
}
unsigned int unsigned int
get_time_in_milliseconds (void) get_time_in_milliseconds (void)
{ {
@ -775,11 +868,26 @@ paint_all (Display *dpy)
frameCounter++; frameCounter++;
if (frameCounter == 5) if (frameCounter == 300)
{ {
currentFrameRate = 5 * 1000.0f / (currentTime - lastSampledFrameTime); currentFrameRate = 300 * 1000.0f / (currentTime - lastSampledFrameTime);
lastSampledFrameTime = currentTime; lastSampledFrameTime = currentTime;
frameCounter = 0; frameCounter = 0;
stats_printf( "fps=%f\n", currentFrameRate );
if ( w->isSteam )
{
stats_printf( "focus=steam\n" );
}
else if ( w->isSteamPopup )
{
stats_printf( "focus=steampopup\n" );
}
else
{
stats_printf( "focus=%i\n", w->gameID );
}
} }
ensure_win_resources( w ); ensure_win_resources( w );
@ -1755,9 +1863,7 @@ again:
} }
// Wake up commit wait thread if chilling // Wake up commit wait thread if chilling
std::unique_lock<std::mutex> lock(mtx); waitListSem.signal();
count++;
cv.notify_one();
already_committed.insert( w ); already_committed.insert( w );
@ -1782,12 +1888,19 @@ steamcompmgr_main (int argc, char **argv)
// :/ // :/
optind = 1; optind = 1;
while ((o = getopt (argc, argv, ":R:NSvVec")) != -1) while ((o = getopt (argc, argv, ":R:T:w:h:W:H:r:NSvVecslnb")) != -1)
{ {
switch (o) { switch (o) {
case 'R': case 'R':
readyPipeFD = open( optarg, O_WRONLY ); readyPipeFD = open( optarg, O_WRONLY );
break; break;
case 'T':
statsThreadPath = optarg;
{
std::thread statsThreads( statsThreadRun );
statsThreads.detach();
}
break;
case 'N': case 'N':
doRender = False; doRender = False;
break; break;