mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-28 22:13:24 +00:00
Minor cleanup
This commit is contained in:
parent
3064cf8101
commit
22e1da5e76
@ -1307,6 +1307,7 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
|
||||
}
|
||||
|
||||
//ctrl->set_current(false);
|
||||
vm::reservation_free();
|
||||
|
||||
g_thread_count--;
|
||||
|
||||
|
@ -81,7 +81,7 @@ void armv7_free_tls(u32 thread)
|
||||
}
|
||||
|
||||
ARMv7Thread::ARMv7Thread(const std::string& name)
|
||||
: CPUThread(CPU_THREAD_ARMv7, name, [this]{ return fmt::format("%s[0x%x] Thread (%s)[0x%08x]", GetTypeString(), GetId(), GetName(), PC); })
|
||||
: CPUThread(CPU_THREAD_ARMv7, name, WRAP_EXPR(fmt::format("ARMv7[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC)))
|
||||
, ARMv7Context({})
|
||||
{
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
|
||||
, m_type(type)
|
||||
, m_name(name)
|
||||
{
|
||||
start(thread_name, [this]
|
||||
start(std::move(thread_name), [this]
|
||||
{
|
||||
SendDbgCommand(DID_CREATE_THREAD, this);
|
||||
|
||||
|
@ -78,7 +78,7 @@ std::shared_ptr<RawSPUThread> CPUThreadManager::NewRawSPUThread()
|
||||
{
|
||||
if (m_raw_spu[i].expired())
|
||||
{
|
||||
m_raw_spu[i] = result = Emu.GetIdManager().make_ptr<RawSPUThread>("RawSPU " + std::to_string(i), i);
|
||||
m_raw_spu[i] = result = Emu.GetIdManager().make_ptr<RawSPUThread>(std::to_string(i), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ void fill_ppu_exec_map(u32 addr, u32 size)
|
||||
}
|
||||
|
||||
PPUThread::PPUThread(const std::string& name)
|
||||
: CPUThread(CPU_THREAD_PPU, name, [this]{ return fmt::format("%s[0x%x] Thread (%s)[0x%08x]", GetTypeString(), GetId(), GetName(), PC); })
|
||||
: CPUThread(CPU_THREAD_PPU, name, WRAP_EXPR(fmt::format("PPU[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC)))
|
||||
{
|
||||
InitRotateMask();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
thread_local spu_mfc_arg_t raw_spu_mfc[8] = {};
|
||||
|
||||
RawSPUThread::RawSPUThread(const std::string& name, u32 index)
|
||||
: SPUThread(CPU_THREAD_RAW_SPU, name, index, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index)
|
||||
: SPUThread(CPU_THREAD_RAW_SPU, name, WRAP_EXPR(fmt::format("RawSPU[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC)), index, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index)
|
||||
{
|
||||
Memory.Map(offset, 0x40000);
|
||||
}
|
||||
@ -23,18 +23,16 @@ RawSPUThread::~RawSPUThread()
|
||||
|
||||
void RawSPUThread::start()
|
||||
{
|
||||
bool do_start;
|
||||
|
||||
status.atomic_op([&do_start](u32& status)
|
||||
const bool do_start = status.atomic_op([](u32& status) -> bool
|
||||
{
|
||||
if (status & SPU_STATUS_RUNNING)
|
||||
{
|
||||
do_start = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = SPU_STATUS_RUNNING;
|
||||
do_start = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -166,6 +164,7 @@ bool RawSPUThread::WriteReg(const u32 addr, const u32 value)
|
||||
case SPU_In_MBox_offs:
|
||||
{
|
||||
ch_in_mbox.push_uncond(value);
|
||||
cv.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -57,15 +57,15 @@ public:
|
||||
}
|
||||
g_spu_inter_func_list;
|
||||
|
||||
SPUThread::SPUThread(CPUThreadType type, const std::string& name, u32 index, u32 offset)
|
||||
: CPUThread(type, name, [this]{ return fmt::format("%s[0x%x] Thread (%s)[0x%08x]", GetTypeString(), GetId(), GetName(), PC); })
|
||||
SPUThread::SPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name, u32 index, u32 offset)
|
||||
: CPUThread(type, name, std::move(thread_name))
|
||||
, index(index)
|
||||
, offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
SPUThread::SPUThread(const std::string& name, u32 index)
|
||||
: CPUThread(CPU_THREAD_SPU, name, [this]{ return fmt::format("%s[0x%x] Thread (%s)[0x%08x]", GetTypeString(), GetId(), GetName(), PC); })
|
||||
: CPUThread(CPU_THREAD_SPU, name, WRAP_EXPR(fmt::format("SPU[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC)))
|
||||
, index(index)
|
||||
, offset(Memory.MainMem.AllocAlign(0x40000))
|
||||
{
|
||||
|
@ -571,6 +571,8 @@ public:
|
||||
ch_snr2.push_uncond(value);
|
||||
}
|
||||
}
|
||||
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
void do_dma_transfer(u32 cmd, spu_mfc_arg_t args);
|
||||
@ -630,7 +632,7 @@ public:
|
||||
std::function<void(SPUThread& SPU)> m_custom_task;
|
||||
|
||||
protected:
|
||||
SPUThread(CPUThreadType type, const std::string& name, u32 index, u32 offset);
|
||||
SPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name, u32 index, u32 offset);
|
||||
|
||||
public:
|
||||
SPUThread(const std::string& name, u32 index);
|
||||
|
@ -22,11 +22,13 @@ public:
|
||||
const std::shared_ptr<void> data;
|
||||
const std::type_info& info;
|
||||
const u32 type;
|
||||
const u32 id;
|
||||
|
||||
template<typename T> force_inline ID_data_t(std::shared_ptr<T> data, u32 type)
|
||||
template<typename T> force_inline ID_data_t(std::shared_ptr<T> data, u32 type, u32 id)
|
||||
: data(std::move(data))
|
||||
, info(typeid(T))
|
||||
, type(type)
|
||||
, id(id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,6 +36,7 @@ public:
|
||||
: data(right.data)
|
||||
, info(right.info)
|
||||
, type(right.type)
|
||||
, id(right.id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -43,6 +46,7 @@ public:
|
||||
: data(std::move(const_cast<std::shared_ptr<void>&>(right.data)))
|
||||
, info(right.info)
|
||||
, type(right.type)
|
||||
, id(right.id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -101,9 +105,9 @@ public:
|
||||
|
||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
|
||||
m_id_map.emplace(m_cur_id++, ID_data_t(ptr, type));
|
||||
m_id_map.emplace(m_cur_id, ID_data_t(ptr, type, m_cur_id));
|
||||
|
||||
return std::move(ptr);
|
||||
return m_cur_id++, std::move(ptr);
|
||||
}
|
||||
|
||||
// add new ID of specified type with specified constructor arguments (returns id)
|
||||
@ -113,7 +117,7 @@ public:
|
||||
|
||||
const u32 type = ID_type<T>::type;
|
||||
|
||||
m_id_map.emplace(m_cur_id, ID_data_t(std::make_shared<T>(std::forward<Args>(args)...), type));
|
||||
m_id_map.emplace(m_cur_id, ID_data_t(std::make_shared<T>(std::forward<Args>(args)...), type, m_cur_id));
|
||||
|
||||
return m_cur_id++;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ namespace vm
|
||||
{
|
||||
atomic<const thread_ctrl_t*> m_owner{};
|
||||
std::condition_variable m_cv;
|
||||
std::mutex m_cv_mutex;
|
||||
std::mutex m_mutex;
|
||||
|
||||
public:
|
||||
reservation_mutex_t()
|
||||
@ -95,18 +95,18 @@ namespace vm
|
||||
{
|
||||
auto owner = get_current_thread_ctrl();
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex, std::defer_lock);
|
||||
|
||||
while (auto old = m_owner.compare_and_swap(nullptr, owner))
|
||||
{
|
||||
std::unique_lock<std::mutex> cv_lock(m_cv_mutex);
|
||||
|
||||
m_cv.wait_for(cv_lock, std::chrono::milliseconds(1));
|
||||
|
||||
if (old == owner)
|
||||
{
|
||||
throw EXCEPTION("Deadlock");
|
||||
}
|
||||
|
||||
old = nullptr;
|
||||
if (!lock) lock.lock();
|
||||
|
||||
m_cv.wait_for(lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
do_notify = true;
|
||||
@ -195,7 +195,7 @@ namespace vm
|
||||
return _reservation_break(addr);
|
||||
}
|
||||
|
||||
bool reservation_acquire(void* data, u32 addr, u32 size, const std::function<void()>& callback)
|
||||
bool reservation_acquire(void* data, u32 addr, u32 size, std::function<void()> callback)
|
||||
{
|
||||
//const auto stamp0 = get_time();
|
||||
|
||||
@ -232,7 +232,7 @@ namespace vm
|
||||
g_reservation_addr = addr;
|
||||
g_reservation_size = size;
|
||||
g_reservation_owner = get_current_thread_ctrl();
|
||||
g_reservation_cb = callback;
|
||||
g_reservation_cb = std::move(callback);
|
||||
|
||||
// copy data
|
||||
memcpy(data, vm::get_ptr(addr), size);
|
||||
@ -243,7 +243,7 @@ namespace vm
|
||||
|
||||
bool reservation_acquire_no_cb(void* data, u32 addr, u32 size)
|
||||
{
|
||||
return reservation_acquire(data, addr, size);
|
||||
return reservation_acquire(data, addr, size, nullptr);
|
||||
}
|
||||
|
||||
bool reservation_update(u32 addr, const void* data, u32 size)
|
||||
@ -303,10 +303,10 @@ namespace vm
|
||||
|
||||
void reservation_free()
|
||||
{
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
if (g_reservation_owner == get_current_thread_ctrl())
|
||||
{
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
_reservation_break(g_reservation_addr);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace vm
|
||||
// break the reservation, return true if it was successfully broken
|
||||
bool reservation_break(u32 addr);
|
||||
// read memory and reserve it for further atomic update, return true if the previous reservation was broken
|
||||
bool reservation_acquire(void* data, u32 addr, u32 size, const std::function<void()>& callback = nullptr);
|
||||
bool reservation_acquire(void* data, u32 addr, u32 size, std::function<void()> callback = nullptr);
|
||||
// same as reservation_acquire but does not have the callback argument
|
||||
// used by the PPU LLVM JIT since creating a std::function object in LLVM IR is too complicated
|
||||
bool reservation_acquire_no_cb(void* data, u32 addr, u32 size);
|
||||
|
@ -9,44 +9,36 @@
|
||||
#include "Emu/CPU/CPUThreadManager.h"
|
||||
#include "Callback.h"
|
||||
|
||||
void CallbackManager::Register(std::function<s32(PPUThread& PPU)> func)
|
||||
void CallbackManager::Register(check_cb_t func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_cb_list.push_back([=](CPUThread& CPU) -> s32
|
||||
{
|
||||
if (CPU.GetType() != CPU_THREAD_PPU) throw EXCEPTION("PPU thread expected");
|
||||
return func(static_cast<PPUThread&>(CPU));
|
||||
});
|
||||
m_check_cb.emplace(std::move(func));
|
||||
}
|
||||
|
||||
void CallbackManager::Async(std::function<void(CPUThread& CPU)> func)
|
||||
void CallbackManager::Async(async_cb_t func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_async_list.push_back([=](CPUThread& CPU)
|
||||
{
|
||||
func(CPU);
|
||||
});
|
||||
m_async_cb.emplace(std::move(func));
|
||||
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
||||
bool CallbackManager::Check(CPUThread& CPU, s32& result)
|
||||
CallbackManager::check_cb_t CallbackManager::Check()
|
||||
{
|
||||
std::function<s32(CPUThread& CPU)> func;
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_check_cb.size())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
check_cb_t func = std::move(m_check_cb.front());
|
||||
|
||||
if (m_cb_list.size())
|
||||
{
|
||||
func = std::move(m_cb_list.front());
|
||||
m_cb_list.erase(m_cb_list.begin());
|
||||
}
|
||||
m_check_cb.pop();
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
return func ? result = func(CPU), true : false;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CallbackManager::Init()
|
||||
@ -57,26 +49,25 @@ void CallbackManager::Init()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
while (!CPU.CheckStatus())
|
||||
while (true)
|
||||
{
|
||||
std::function<void(CPUThread& CPU)> func;
|
||||
|
||||
if (m_async_list.size())
|
||||
{
|
||||
func = std::move(m_async_list.front());
|
||||
m_async_list.erase(m_async_list.begin());
|
||||
}
|
||||
|
||||
if (func)
|
||||
{
|
||||
if (lock) lock.unlock();
|
||||
|
||||
func(*m_cb_thread);
|
||||
continue;
|
||||
}
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
if (!lock) lock.lock();
|
||||
|
||||
if (m_async_cb.size())
|
||||
{
|
||||
async_cb_t func = std::move(m_async_cb.front());
|
||||
|
||||
m_async_cb.pop();
|
||||
|
||||
if (lock) lock.unlock();
|
||||
|
||||
func(CPU);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
m_cv.wait_for(lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
};
|
||||
@ -109,46 +100,9 @@ void CallbackManager::Clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_cb_list.clear();
|
||||
m_async_list.clear();
|
||||
m_pause_cb_list.clear();
|
||||
m_check_cb = {};
|
||||
m_async_cb = {};
|
||||
|
||||
m_cb_thread.reset();
|
||||
}
|
||||
|
||||
u64 CallbackManager::AddPauseCallback(std::function<PauseResumeCB> func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_pause_cb_list.push_back({ func, next_tag });
|
||||
return next_tag++;
|
||||
}
|
||||
|
||||
void CallbackManager::RemovePauseCallback(const u64 tag)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
for (auto& data : m_pause_cb_list)
|
||||
{
|
||||
if (data.tag == tag)
|
||||
{
|
||||
m_pause_cb_list.erase(m_pause_cb_list.begin() + (&data - m_pause_cb_list.data()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(!"CallbackManager()::RemovePauseCallback(): tag not found");
|
||||
}
|
||||
|
||||
void CallbackManager::RunPauseCallbacks(const bool is_paused)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
for (auto& data : m_pause_cb_list)
|
||||
{
|
||||
if (data.cb)
|
||||
{
|
||||
data.cb(is_paused);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,66 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
class CPUThread;
|
||||
class PPUThread;
|
||||
|
||||
typedef void(PauseResumeCB)(bool is_paused);
|
||||
|
||||
class CallbackManager
|
||||
{
|
||||
using check_cb_t = std::function<s32(CPUThread&)>;
|
||||
using async_cb_t = std::function<void(CPUThread&)>;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cv;
|
||||
|
||||
std::vector<std::function<s32(CPUThread&)>> m_cb_list;
|
||||
std::vector<std::function<void(CPUThread&)>> m_async_list;
|
||||
std::queue<check_cb_t> m_check_cb;
|
||||
std::queue<async_cb_t> m_async_cb;
|
||||
|
||||
std::shared_ptr<CPUThread> m_cb_thread;
|
||||
|
||||
struct PauseResumeCBS
|
||||
{
|
||||
std::function<PauseResumeCB> cb;
|
||||
u64 tag;
|
||||
};
|
||||
|
||||
u64 next_tag; // not initialized, only increased
|
||||
std::vector<PauseResumeCBS> m_pause_cb_list;
|
||||
|
||||
public:
|
||||
void Register(std::function<s32(PPUThread& CPU)> func); // register callback (called in Check() method)
|
||||
// register checked callback (accepts CPUThread&, returns s32)
|
||||
void Register(check_cb_t func);
|
||||
|
||||
void Async(std::function<void(CPUThread& CPU)> func); // register callback for callback thread (called immediately)
|
||||
// register async callback, called in callback thread (accepts CPUThread&)
|
||||
void Async(async_cb_t func);
|
||||
|
||||
bool Check(CPUThread& CPU, s32& result); // call one callback registered by Register() method
|
||||
// get one registered callback
|
||||
check_cb_t Check();
|
||||
|
||||
void Init();
|
||||
|
||||
void Clear();
|
||||
|
||||
u64 AddPauseCallback(std::function<PauseResumeCB> func); // register callback for pausing/resuming emulation events
|
||||
void RemovePauseCallback(const u64 tag); // unregister callback (uses the result of AddPauseCallback() function)
|
||||
void RunPauseCallbacks(const bool is_paused);
|
||||
};
|
||||
|
||||
class PauseCallbackRegisterer
|
||||
{
|
||||
CallbackManager& cb_manager;
|
||||
u64 cb_tag;
|
||||
|
||||
private:
|
||||
PauseCallbackRegisterer() = delete;
|
||||
PauseCallbackRegisterer(const PauseCallbackRegisterer& right) = delete;
|
||||
PauseCallbackRegisterer(PauseCallbackRegisterer&& right) = delete;
|
||||
|
||||
PauseCallbackRegisterer& operator =(const PauseCallbackRegisterer& right) = delete;
|
||||
PauseCallbackRegisterer& operator =(PauseCallbackRegisterer&& right) = delete;
|
||||
|
||||
public:
|
||||
PauseCallbackRegisterer(CallbackManager& cb_manager, const std::function<PauseResumeCB>& func)
|
||||
: cb_manager(cb_manager)
|
||||
, cb_tag(cb_manager.AddPauseCallback(func))
|
||||
{
|
||||
}
|
||||
|
||||
~PauseCallbackRegisterer()
|
||||
{
|
||||
cb_manager.RemovePauseCallback(cb_tag);
|
||||
}
|
||||
};
|
||||
|
@ -35,7 +35,6 @@ s32 cellAudioInit()
|
||||
}
|
||||
|
||||
// reset variables
|
||||
g_audio.start_time = 0;
|
||||
g_audio.counter = 0;
|
||||
g_audio.keys.clear();
|
||||
g_audio.start_time = get_system_time();
|
||||
@ -137,22 +136,6 @@ s32 cellAudioInit()
|
||||
Emu.GetAudioManager().GetAudioOut().Quit();
|
||||
});
|
||||
|
||||
u64 last_pause_time;
|
||||
std::atomic<u64> added_time(0);
|
||||
|
||||
PauseCallbackRegisterer pcb(Emu.GetCallbackManager(), [&last_pause_time, &added_time](bool is_paused)
|
||||
{
|
||||
if (is_paused)
|
||||
{
|
||||
last_pause_time = get_system_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
added_time += get_system_time() - last_pause_time;
|
||||
g_audio.thread.cv.notify_one();
|
||||
}
|
||||
});
|
||||
|
||||
while (g_audio.state.load() == AUDIO_STATE_INITIALIZED && !Emu.IsStopped())
|
||||
{
|
||||
if (Emu.IsPaused())
|
||||
@ -161,40 +144,32 @@ s32 cellAudioInit()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (added_time)
|
||||
{
|
||||
g_audio.start_time += added_time.exchange(0);
|
||||
}
|
||||
|
||||
const u64 stamp0 = get_system_time();
|
||||
|
||||
const u64 time_pos = stamp0 - g_audio.start_time - Emu.GetPauseTime();
|
||||
|
||||
// TODO: send beforemix event (in ~2,6 ms before mixing)
|
||||
|
||||
// precise time of sleeping: 5,(3) ms (or 256/48000 sec)
|
||||
const u64 expected_time = g_audio.counter * AUDIO_SAMPLES * MHZ / 48000;
|
||||
if (expected_time >= stamp0 - g_audio.start_time)
|
||||
if (expected_time >= time_pos)
|
||||
{
|
||||
g_audio.thread.cv.wait_for(lock, std::chrono::milliseconds(1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// crutch to hide giant lags caused by debugger
|
||||
const u64 missed_time = stamp0 - g_audio.start_time - expected_time;
|
||||
if (missed_time > AUDIO_SAMPLES * MHZ / 48000)
|
||||
{
|
||||
cellAudio.Notice("%f ms adjusted", (float)missed_time / 1000);
|
||||
g_audio.start_time += missed_time;
|
||||
}
|
||||
//// crutch to hide giant lags caused by debugger
|
||||
//const u64 missed_time = time_pos - expected_time;
|
||||
//if (missed_time > AUDIO_SAMPLES * MHZ / 48000)
|
||||
//{
|
||||
// cellAudio.Notice("%f ms adjusted", (float)missed_time / 1000);
|
||||
// g_audio.start_time += missed_time;
|
||||
//}
|
||||
|
||||
g_audio.counter++;
|
||||
|
||||
const u32 out_pos = g_audio.counter % BUFFER_NUM;
|
||||
|
||||
//if (Emu.IsPaused())
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
|
||||
bool first_mix = true;
|
||||
|
||||
// mixing:
|
||||
@ -427,7 +402,7 @@ s32 cellAudioInit()
|
||||
}
|
||||
|
||||
//LOG_NOTICE(HLE, "Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
//stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
//time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
}
|
||||
});
|
||||
|
||||
@ -679,7 +654,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_audio.thread.mutex);
|
||||
|
||||
*stamp = g_audio.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000;
|
||||
*stamp = g_audio.start_time + Emu.GetPauseTime() + (port.counter + (tag - port.tag)) * 256000000 / 48000;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -146,9 +146,9 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
{
|
||||
const s32 status = g_msg_dialog->status;
|
||||
|
||||
Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32
|
||||
Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32
|
||||
{
|
||||
callback(PPU, status, userData);
|
||||
callback(static_cast<PPUThread&>(CPU), status, userData);
|
||||
return CELL_OK;
|
||||
});
|
||||
}
|
||||
|
@ -302,8 +302,8 @@ struct sys_callback
|
||||
{
|
||||
vm::ptr<CellSysutilCallback> func;
|
||||
vm::ptr<void> arg;
|
||||
|
||||
} g_sys_callback[4];
|
||||
}
|
||||
g_sys_callback[4];
|
||||
|
||||
void sysutilSendSystemCommand(u64 status, u64 param)
|
||||
{
|
||||
@ -312,9 +312,9 @@ void sysutilSendSystemCommand(u64 status, u64 param)
|
||||
{
|
||||
if (cb.func)
|
||||
{
|
||||
Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32
|
||||
Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32
|
||||
{
|
||||
cb.func(PPU, status, param, cb.arg);
|
||||
cb.func(static_cast<PPUThread&>(CPU), status, param, cb.arg);
|
||||
return CELL_OK;
|
||||
});
|
||||
}
|
||||
@ -325,26 +325,16 @@ s32 cellSysutilCheckCallback(PPUThread& CPU)
|
||||
{
|
||||
cellSysutil.Log("cellSysutilCheckCallback()");
|
||||
|
||||
s32 res;
|
||||
u32 count = 0;
|
||||
|
||||
while (Emu.GetCallbackManager().Check(CPU, res))
|
||||
while (auto func = Emu.GetCallbackManager().Check())
|
||||
{
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
count++;
|
||||
|
||||
if (res)
|
||||
if (s32 res = func(CPU))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count && !g_sys_callback[0].func && !g_sys_callback[1].func && !g_sys_callback[2].func && !g_sys_callback[3].func)
|
||||
{
|
||||
LOG_WARNING(TTY, "System warning: no callback registered\n");
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -694,6 +694,7 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||
}
|
||||
|
||||
thread->ch_in_mbox.push_uncond(value);
|
||||
thread->cv.notify_one();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ static const std::string& BreakPointsDBName = "BreakPoints.dat";
|
||||
static const u16 bpdb_version = 0x1000;
|
||||
extern std::atomic<u32> g_thread_count;
|
||||
|
||||
extern u64 get_system_time();
|
||||
extern void finalize_ppu_exec_map();
|
||||
|
||||
extern void finalize_psv_modules();
|
||||
extern void clear_all_psv_objects();
|
||||
|
||||
@ -64,17 +64,6 @@ Emulator::Emulator()
|
||||
|
||||
Emulator::~Emulator()
|
||||
{
|
||||
delete m_thread_manager;
|
||||
delete m_pad_manager;
|
||||
delete m_keyboard_manager;
|
||||
delete m_mouse_manager;
|
||||
delete m_id_manager;
|
||||
delete m_gs_manager;
|
||||
delete m_audio_manager;
|
||||
delete m_callback_manager;
|
||||
delete m_event_manager;
|
||||
delete m_module_manager;
|
||||
delete m_vfs;
|
||||
}
|
||||
|
||||
void Emulator::Init()
|
||||
@ -144,7 +133,11 @@ void Emulator::Load()
|
||||
|
||||
GetModuleManager().Init();
|
||||
|
||||
if (!fs::is_file(m_path)) return;
|
||||
if (!fs::is_file(m_path))
|
||||
{
|
||||
m_status = Stopped;
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string elf_dir = m_path.substr(0, m_path.find_last_of("/\\", std::string::npos, 2) + 1);
|
||||
|
||||
@ -177,6 +170,7 @@ void Emulator::Load()
|
||||
|
||||
if (!DecryptSelf(m_path, elf_dir + full_name))
|
||||
{
|
||||
m_status = Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -238,12 +232,14 @@ void Emulator::Load()
|
||||
if (!f.IsOpened())
|
||||
{
|
||||
LOG_ERROR(LOADER, "Opening '%s' failed", m_path.c_str());
|
||||
m_status = Stopped;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_loader.load(f))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Loading '%s' failed", m_path.c_str());
|
||||
m_status = Stopped;
|
||||
vm::close();
|
||||
return;
|
||||
}
|
||||
@ -276,6 +272,8 @@ void Emulator::Run()
|
||||
|
||||
SendDbgCommand(DID_START_EMU);
|
||||
|
||||
m_pause_start_time = 0;
|
||||
m_pause_amend_time = 0;
|
||||
m_status = Running;
|
||||
|
||||
GetCPU().Exec();
|
||||
@ -284,28 +282,48 @@ void Emulator::Run()
|
||||
|
||||
void Emulator::Pause()
|
||||
{
|
||||
if (!IsRunning()) return;
|
||||
const u64 start = get_system_time();
|
||||
|
||||
// try to set Paused status
|
||||
if (!sync_bool_compare_and_swap(&m_status, Running, Paused))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// update pause start time
|
||||
if (m_pause_start_time.exchange(start))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Pause(): Concurrent access");
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_PAUSE_EMU);
|
||||
|
||||
if (sync_bool_compare_and_swap(&m_status, Running, Paused))
|
||||
for (auto& t : GetCPU().GetAllThreads())
|
||||
{
|
||||
for (auto& t : GetCPU().GetAllThreads())
|
||||
{
|
||||
t->Sleep(); // trigger status check
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_PAUSED_EMU);
|
||||
|
||||
GetCallbackManager().RunPauseCallbacks(true);
|
||||
t->Sleep(); // trigger status check
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_PAUSED_EMU);
|
||||
}
|
||||
|
||||
void Emulator::Resume()
|
||||
{
|
||||
if (!IsPaused()) return;
|
||||
SendDbgCommand(DID_RESUME_EMU);
|
||||
// try to resume
|
||||
if (!sync_bool_compare_and_swap(&m_status, Paused, Running))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_status = Running;
|
||||
if (const u64 time = m_pause_start_time.exchange(0))
|
||||
{
|
||||
m_pause_amend_time += get_system_time() - time;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Resume(): Concurrent access");
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_RESUME_EMU);
|
||||
|
||||
for (auto& t : GetCPU().GetAllThreads())
|
||||
{
|
||||
@ -313,15 +331,16 @@ void Emulator::Resume()
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_RESUMED_EMU);
|
||||
|
||||
GetCallbackManager().RunPauseCallbacks(false);
|
||||
}
|
||||
|
||||
extern std::map<u32, std::string> g_armv7_dump;
|
||||
|
||||
void Emulator::Stop()
|
||||
{
|
||||
if(IsStopped()) return;
|
||||
if (sync_lock_test_and_set(&m_status, Stopped) == Stopped)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_STOP_EMU);
|
||||
|
||||
|
@ -54,6 +54,9 @@ class Emulator
|
||||
volatile u32 m_status;
|
||||
uint m_mode;
|
||||
|
||||
std::atomic<u64> m_pause_start_time; // set when paused
|
||||
std::atomic<u64> m_pause_amend_time; // increased when resumed
|
||||
|
||||
u32 m_rsx_callback;
|
||||
u32 m_cpu_thr_stop;
|
||||
|
||||
@ -62,17 +65,17 @@ class Emulator
|
||||
|
||||
std::mutex m_core_mutex;
|
||||
|
||||
CPUThreadManager* m_thread_manager;
|
||||
PadManager* m_pad_manager;
|
||||
KeyboardManager* m_keyboard_manager;
|
||||
MouseManager* m_mouse_manager;
|
||||
ID_manager* m_id_manager;
|
||||
GSManager* m_gs_manager;
|
||||
AudioManager* m_audio_manager;
|
||||
CallbackManager* m_callback_manager;
|
||||
EventManager* m_event_manager;
|
||||
ModuleManager* m_module_manager;
|
||||
VFS* m_vfs;
|
||||
std::unique_ptr<CPUThreadManager> m_thread_manager;
|
||||
std::unique_ptr<PadManager> m_pad_manager;
|
||||
std::unique_ptr<KeyboardManager> m_keyboard_manager;
|
||||
std::unique_ptr<MouseManager> m_mouse_manager;
|
||||
std::unique_ptr<ID_manager> m_id_manager;
|
||||
std::unique_ptr<GSManager> m_gs_manager;
|
||||
std::unique_ptr<AudioManager> m_audio_manager;
|
||||
std::unique_ptr<CallbackManager> m_callback_manager;
|
||||
std::unique_ptr<EventManager> m_event_manager;
|
||||
std::unique_ptr<ModuleManager> m_module_manager;
|
||||
std::unique_ptr<VFS> m_vfs;
|
||||
|
||||
EmuInfo m_info;
|
||||
loader::loader m_loader;
|
||||
@ -117,8 +120,12 @@ public:
|
||||
m_emu_path = path;
|
||||
}
|
||||
|
||||
std::mutex& GetCoreMutex() { return m_core_mutex; }
|
||||
u64 GetPauseTime()
|
||||
{
|
||||
return m_pause_amend_time;
|
||||
}
|
||||
|
||||
std::mutex& GetCoreMutex() { return m_core_mutex; }
|
||||
CPUThreadManager& GetCPU() { return *m_thread_manager; }
|
||||
PadManager& GetPadManager() { return *m_pad_manager; }
|
||||
KeyboardManager& GetKeyboardManager() { return *m_keyboard_manager; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user