Use CoreTiming for MemoryWatcher.

This commit is contained in:
spxtr 2016-04-28 21:28:15 -07:00
parent aebff2c161
commit b9e9a5ee3d
3 changed files with 55 additions and 39 deletions

View File

@ -112,10 +112,6 @@ static bool s_request_refresh_info = false;
static int s_pause_and_lock_depth = 0;
static bool s_is_throttler_temp_disabled = false;
#ifdef USE_MEMORYWATCHER
static std::unique_ptr<MemoryWatcher> s_memory_watcher;
#endif
#ifdef ThreadLocalStorage
static ThreadLocalStorage bool tls_is_cpu_thread = false;
#else
@ -289,7 +285,7 @@ void Stop() // - Hammertime!
#endif
#ifdef USE_MEMORYWATCHER
s_memory_watcher.reset();
MemoryWatcher::Shutdown();
#endif
}
@ -361,7 +357,7 @@ static void CpuThread()
#endif
#ifdef USE_MEMORYWATCHER
s_memory_watcher = std::make_unique<MemoryWatcher>();
MemoryWatcher::Init();
#endif
// Enter CPU run loop. When we leave it - we are done.

View File

@ -4,25 +4,48 @@
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <unistd.h>
#include "Common/FileUtil.h"
#include "Common/Thread.h"
#include "Core/CoreTiming.h"
#include "Core/MemoryWatcher.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
// We don't want to kill the cpu, so sleep for this long after polling.
static const int SLEEP_DURATION = 2; // ms
static std::unique_ptr<MemoryWatcher> s_memory_watcher;
static int s_event;
static const int MW_RATE = 600; // Steps per second
static void MWCallback(u64 userdata, s64 cyclesLate)
{
s_memory_watcher->Step();
CoreTiming::ScheduleEvent(
(SystemTimers::GetTicksPerSecond() / MW_RATE) - cyclesLate, s_event);
}
void MemoryWatcher::Init()
{
s_memory_watcher = std::make_unique<MemoryWatcher>();
s_event = CoreTiming::RegisterEvent("MemoryWatcher", MWCallback);
CoreTiming::ScheduleEvent(0, s_event);
}
void MemoryWatcher::Shutdown()
{
CoreTiming::RemoveEvent(s_event);
s_memory_watcher.reset();
}
MemoryWatcher::MemoryWatcher()
{
m_running = false;
if (!LoadAddresses(File::GetUserPath(F_MEMORYWATCHERLOCATIONS_IDX)))
return;
if (!OpenSocket(File::GetUserPath(F_MEMORYWATCHERSOCKET_IDX)))
return;
m_running = true;
m_watcher_thread = std::thread(&MemoryWatcher::WatcherThread, this);
}
MemoryWatcher::~MemoryWatcher()
@ -31,7 +54,6 @@ MemoryWatcher::~MemoryWatcher()
return;
m_running = false;
m_watcher_thread.join();
close(m_fd);
}
@ -85,30 +107,29 @@ std::string MemoryWatcher::ComposeMessage(const std::string& line, u32 value)
return message_stream.str();
}
void MemoryWatcher::WatcherThread()
void MemoryWatcher::Step()
{
while (m_running)
{
for (auto& entry : m_values)
{
std::string address = entry.first;
u32& current_value = entry.second;
if (!m_running)
return;
u32 new_value = ChasePointer(address);
if (new_value != current_value)
{
// Update the value
current_value = new_value;
std::string message = ComposeMessage(address, new_value);
sendto(
m_fd,
message.c_str(),
message.size() + 1,
0,
reinterpret_cast<sockaddr*>(&m_addr),
sizeof(m_addr));
}
for (auto& entry : m_values)
{
std::string address = entry.first;
u32& current_value = entry.second;
u32 new_value = ChasePointer(address);
if (new_value != current_value)
{
// Update the value
current_value = new_value;
std::string message = ComposeMessage(address, new_value);
sendto(
m_fd,
message.c_str(),
message.size() + 1,
0,
reinterpret_cast<sockaddr*>(&m_addr),
sizeof(m_addr));
}
Common::SleepCurrentThread(SLEEP_DURATION);
}
}

View File

@ -4,9 +4,7 @@
#pragma once
#include <atomic>
#include <map>
#include <thread>
#include <vector>
#include <sys/socket.h>
#include <sys/un.h>
@ -24,6 +22,10 @@ class MemoryWatcher final
public:
MemoryWatcher();
~MemoryWatcher();
void Step();
static void Init();
static void Shutdown();
private:
bool LoadAddresses(const std::string& path);
@ -33,10 +35,7 @@ private:
u32 ChasePointer(const std::string& line);
std::string ComposeMessage(const std::string& line, u32 value);
void WatcherThread();
std::thread m_watcher_thread;
std::atomic_bool m_running{false};
bool m_running;
int m_fd;
sockaddr_un m_addr;