Merge pull request #939 from shuffle2/fix-memcard-flush2

move the decision to delay raw memcard flushes out of the thread.
This commit is contained in:
shuffle2 2014-09-02 00:28:31 -07:00
commit cc6db8cf26
2 changed files with 14 additions and 22 deletions

View File

@ -12,6 +12,8 @@
#define SIZE_TO_Mb (1024 * 8 * 16) #define SIZE_TO_Mb (1024 * 8 * 16)
#define MC_HDR_SIZE 0xA000 #define MC_HDR_SIZE 0xA000
const std::chrono::seconds MemoryCard::s_flush_interval{ 15 };
MemoryCard::MemoryCard(std::string filename, int _card_index, u16 sizeMb) MemoryCard::MemoryCard(std::string filename, int _card_index, u16 sizeMb)
: MemoryCardBase(_card_index, sizeMb) : MemoryCardBase(_card_index, sizeMb)
, m_filename(filename) , m_filename(filename)
@ -44,6 +46,7 @@ MemoryCard::MemoryCard(std::string filename, int _card_index, u16 sizeMb)
// Class members (including inherited ones) have now been initialized, so // Class members (including inherited ones) have now been initialized, so
// it's safe to startup the flush thread (which reads them). // it's safe to startup the flush thread (which reads them).
m_last_flush = std::chrono::steady_clock::now();
m_flush_buffer = std::make_unique<u8[]>(memory_card_size); m_flush_buffer = std::make_unique<u8[]>(memory_card_size);
m_flush_thread = std::thread(&MemoryCard::FlushThread, this); m_flush_thread = std::thread(&MemoryCard::FlushThread, this);
} }
@ -75,29 +78,10 @@ void MemoryCard::FlushThread()
Common::SetCurrentThreadName( Common::SetCurrentThreadName(
StringFromFormat("Memcard%x-Flush", card_index).c_str()); StringFromFormat("Memcard%x-Flush", card_index).c_str());
const auto flush_interval = std::chrono::seconds(15);
auto last_flush = std::chrono::steady_clock::now();
bool dirty = false;
for (;;) for (;;)
{ {
bool triggered = m_flush_trigger.WaitFor(flush_interval); m_flush_trigger.Wait();
bool do_exit = m_is_exiting.IsSet(); bool do_exit = m_is_exiting.IsSet();
if (triggered)
{
dirty = true;
}
// Delay the flush if we're not exiting or if the event timed out and
// the state isn't dirty.
if (!do_exit)
{
auto now = std::chrono::steady_clock::now();
if (now - last_flush < flush_interval || !dirty)
{
continue;
}
last_flush = now;
}
// Opening the file is purposefully done each iteration to ensure the // Opening the file is purposefully done each iteration to ensure the
// file doesn't disappear out from under us after the first check. // file doesn't disappear out from under us after the first check.
@ -134,8 +118,6 @@ void MemoryCard::FlushThread()
pFile.WriteBytes(&m_flush_buffer[0], memory_card_size); pFile.WriteBytes(&m_flush_buffer[0], memory_card_size);
} }
dirty = false;
if (!do_exit) if (!do_exit)
{ {
Core::DisplayMessage( Core::DisplayMessage(
@ -156,6 +138,13 @@ void MemoryCard::FlushThread()
// be done now. // be done now.
void MemoryCard::TryFlush() void MemoryCard::TryFlush()
{ {
auto now = std::chrono::steady_clock::now();
if (now - m_last_flush < s_flush_interval)
{
return;
}
m_last_flush = now;
if (m_flush_mutex.try_lock()) if (m_flush_mutex.try_lock())
{ {
memcpy(&m_flush_buffer[0], &m_memcard_data[0], memory_card_size); memcpy(&m_flush_buffer[0], &m_memcard_data[0], memory_card_size);

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <chrono>
#include <memory> #include <memory>
#include "Common/Event.h" #include "Common/Event.h"
#include "Common/Flag.h" #include "Common/Flag.h"
@ -34,4 +35,6 @@ private:
Common::Event m_flush_trigger; Common::Event m_flush_trigger;
Common::Flag m_is_exiting; Common::Flag m_is_exiting;
std::unique_ptr<u8[]> m_flush_buffer; std::unique_ptr<u8[]> m_flush_buffer;
std::chrono::steady_clock::time_point m_last_flush;
static const std::chrono::seconds s_flush_interval;
}; };