mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-27 12:35:41 +00:00
Small fixes
This commit is contained in:
parent
c0f13f7084
commit
82781e620a
@ -1012,10 +1012,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: reg_value = vm::priv_ref<atomic<u8>>(addr).exchange((u8)reg_value); break;
|
||||
case 2: reg_value = vm::priv_ref<atomic<u16>>(addr).exchange((u16)reg_value); break;
|
||||
case 4: reg_value = vm::priv_ref<atomic<u32>>(addr).exchange((u32)reg_value); break;
|
||||
case 8: reg_value = vm::priv_ref<atomic<u64>>(addr).exchange((u64)reg_value); break;
|
||||
case 1: reg_value = vm::priv_ref<atomic_t<u8>>(addr).exchange((u8)reg_value); break;
|
||||
case 2: reg_value = vm::priv_ref<atomic_t<u16>>(addr).exchange((u16)reg_value); break;
|
||||
case 4: reg_value = vm::priv_ref<atomic_t<u32>>(addr).exchange((u32)reg_value); break;
|
||||
case 8: reg_value = vm::priv_ref<atomic_t<u64>>(addr).exchange((u64)reg_value); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@ -1035,10 +1035,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: old_value = vm::priv_ref<atomic<u8>>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break;
|
||||
case 2: old_value = vm::priv_ref<atomic<u16>>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break;
|
||||
case 4: old_value = vm::priv_ref<atomic<u32>>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break;
|
||||
case 8: old_value = vm::priv_ref<atomic<u64>>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break;
|
||||
case 1: old_value = vm::priv_ref<atomic_t<u8>>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break;
|
||||
case 2: old_value = vm::priv_ref<atomic_t<u16>>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break;
|
||||
case 4: old_value = vm::priv_ref<atomic_t<u32>>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break;
|
||||
case 8: old_value = vm::priv_ref<atomic_t<u64>>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@ -1058,10 +1058,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: value = vm::priv_ref<atomic<u8>>(addr) &= static_cast<u8>(value); break;
|
||||
case 2: value = vm::priv_ref<atomic<u16>>(addr) &= static_cast<u16>(value); break;
|
||||
case 4: value = vm::priv_ref<atomic<u32>>(addr) &= static_cast<u32>(value); break;
|
||||
case 8: value = vm::priv_ref<atomic<u64>>(addr) &= value; break;
|
||||
case 1: value = vm::priv_ref<atomic_t<u8>>(addr) &= (u8)value; break;
|
||||
case 2: value = vm::priv_ref<atomic_t<u16>>(addr) &= (u16)value; break;
|
||||
case 4: value = vm::priv_ref<atomic_t<u32>>(addr) &= (u32)value; break;
|
||||
case 8: value = vm::priv_ref<atomic_t<u64>>(addr) &= value; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,10 @@ class thread_ctrl_t final
|
||||
// name getter
|
||||
const std::function<std::string()> name;
|
||||
|
||||
// true if TLS of some thread points to owner
|
||||
// true if assigned somewhere in TLS
|
||||
std::atomic<bool> assigned{ false };
|
||||
|
||||
// assign TLS
|
||||
// assign TLS (must be assigned only once)
|
||||
void set_current();
|
||||
|
||||
public:
|
||||
@ -174,7 +174,7 @@ class squeue_t
|
||||
};
|
||||
};
|
||||
|
||||
atomic<squeue_sync_var_t> m_sync;
|
||||
atomic_t<squeue_sync_var_t> m_sync;
|
||||
|
||||
mutable std::mutex m_rcv_mutex;
|
||||
mutable std::mutex m_wcv_mutex;
|
||||
|
@ -37,6 +37,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
|
||||
}
|
||||
catch (CPUThreadReturn)
|
||||
{
|
||||
;
|
||||
}
|
||||
catch (CPUThreadStop)
|
||||
{
|
||||
@ -47,12 +48,21 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
|
||||
m_state |= CPU_STATE_DEAD;
|
||||
break;
|
||||
}
|
||||
catch (const fmt::exception&)
|
||||
{
|
||||
DumpInformation();
|
||||
throw;
|
||||
}
|
||||
|
||||
m_state &= ~CPU_STATE_RETURN;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!lock) lock.lock();
|
||||
if (!lock)
|
||||
{
|
||||
lock.lock();
|
||||
continue;
|
||||
}
|
||||
|
||||
cv.wait(lock);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class CPUDecoder;
|
||||
class CPUThread : protected thread_t, public std::enable_shared_from_this<CPUThread>
|
||||
{
|
||||
protected:
|
||||
atomic<u64> m_state; // thread state flags
|
||||
atomic_t<u64> m_state; // thread state flags
|
||||
|
||||
std::unique_ptr<CPUDecoder> m_dec;
|
||||
|
||||
|
@ -28,43 +28,43 @@ void CPUThreadManager::Close()
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<CPUThread>> CPUThreadManager::GetAllThreads() const
|
||||
std::vector<std::shared_ptr<CPUThread>> CPUThreadManager::GetAllThreads()
|
||||
{
|
||||
std::vector<std::shared_ptr<CPUThread>> result;
|
||||
|
||||
for (auto& v : Emu.GetIdManager().get_data<PPUThread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<PPUThread>())
|
||||
{
|
||||
result.emplace_back(std::static_pointer_cast<CPUThread>(v.data));
|
||||
result.emplace_back(t);
|
||||
}
|
||||
|
||||
for (auto& v : Emu.GetIdManager().get_data<SPUThread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<SPUThread>())
|
||||
{
|
||||
result.emplace_back(std::static_pointer_cast<CPUThread>(v.data));
|
||||
result.emplace_back(t);
|
||||
}
|
||||
|
||||
for (auto& v : Emu.GetIdManager().get_data<RawSPUThread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<RawSPUThread>())
|
||||
{
|
||||
result.emplace_back(std::static_pointer_cast<CPUThread>(v.data));
|
||||
result.emplace_back(t);
|
||||
}
|
||||
|
||||
for (auto& v : Emu.GetIdManager().get_data<ARMv7Thread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<ARMv7Thread>())
|
||||
{
|
||||
result.emplace_back(std::static_pointer_cast<CPUThread>(v.data));
|
||||
result.emplace_back(t);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CPUThreadManager::Exec() const
|
||||
void CPUThreadManager::Exec()
|
||||
{
|
||||
for (auto& v : Emu.GetIdManager().get_data<PPUThread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<PPUThread>())
|
||||
{
|
||||
static_cast<CPUThread*>(v.data.get())->Exec();
|
||||
t->Exec();
|
||||
}
|
||||
|
||||
for (auto& v : Emu.GetIdManager().get_data<ARMv7Thread>())
|
||||
for (auto& t : Emu.GetIdManager().get_all<ARMv7Thread>())
|
||||
{
|
||||
static_cast<CPUThread*>(v.data.get())->Exec();
|
||||
t->Exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ public:
|
||||
|
||||
void Close();
|
||||
|
||||
std::vector<std::shared_ptr<CPUThread>> GetAllThreads() const;
|
||||
static std::vector<std::shared_ptr<CPUThread>> GetAllThreads();
|
||||
|
||||
void Exec() const;
|
||||
static void Exec();
|
||||
|
||||
std::shared_ptr<RawSPUThread> NewRawSPUThread();
|
||||
|
||||
|
@ -507,10 +507,9 @@ void PPUThread::DumpInformation() const
|
||||
{
|
||||
if (~hle_code < 1024)
|
||||
{
|
||||
LOG_SUCCESS(HLE, "Last function: syscall %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code));
|
||||
LOG_SUCCESS(HLE, "Last syscall: %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code));
|
||||
}
|
||||
|
||||
if (hle_code > 0)
|
||||
else if (hle_code)
|
||||
{
|
||||
LOG_SUCCESS(HLE, "Last function: %s (0x%llx)", SysCalls::GetFuncName(hle_code), hle_code);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ union spu_channel_t
|
||||
u32 value;
|
||||
};
|
||||
|
||||
atomic<sync_var_t> sync_var; // atomic variable
|
||||
atomic_t<sync_var_t> sync_var; // atomic variable
|
||||
|
||||
public:
|
||||
bool try_push(u32 value)
|
||||
@ -223,8 +223,8 @@ struct spu_channel_4_t
|
||||
u32 value2;
|
||||
};
|
||||
|
||||
atomic<sync_var_t> sync_var;
|
||||
atomic<u32> value3;
|
||||
atomic_t<sync_var_t> sync_var;
|
||||
atomic_t<u32> value3;
|
||||
|
||||
public:
|
||||
void clear()
|
||||
@ -280,10 +280,10 @@ public:
|
||||
|
||||
struct spu_interrupt_tag_t
|
||||
{
|
||||
atomic<u64> mask;
|
||||
atomic<u64> stat;
|
||||
atomic_t<u64> mask;
|
||||
atomic_t<u64> stat;
|
||||
|
||||
atomic<s32> assigned;
|
||||
atomic_t<s32> assigned;
|
||||
|
||||
std::mutex handler_mutex;
|
||||
std::condition_variable cond;
|
||||
@ -526,14 +526,14 @@ public:
|
||||
spu_channel_t ch_snr2; // SPU Signal Notification Register 2
|
||||
|
||||
u32 ch_event_mask;
|
||||
atomic<u32> ch_event_stat;
|
||||
atomic_t<u32> ch_event_stat;
|
||||
|
||||
u64 ch_dec_start_timestamp; // timestamp of writing decrementer value
|
||||
u32 ch_dec_value; // written decrementer value
|
||||
|
||||
atomic<u32> run_ctrl; // SPU Run Control register (only provided to get latest data written)
|
||||
atomic<u32> status; // SPU Status register
|
||||
atomic<u32> npc; // SPU Next Program Counter register
|
||||
atomic_t<u32> run_ctrl; // SPU Run Control register (only provided to get latest data written)
|
||||
atomic_t<u32> status; // SPU Status register
|
||||
atomic_t<u32> npc; // SPU Next Program Counter register
|
||||
|
||||
spu_interrupt_tag_t int0; // SPU Class 0 Interrupt Management
|
||||
spu_interrupt_tag_t int2; // SPU Class 2 Interrupt Management
|
||||
|
@ -20,13 +20,13 @@ class ID_data_t final
|
||||
{
|
||||
public:
|
||||
const std::shared_ptr<void> data;
|
||||
const std::type_info& info;
|
||||
const std::size_t info;
|
||||
const u32 type;
|
||||
const u32 id;
|
||||
|
||||
template<typename T> force_inline ID_data_t(std::shared_ptr<T> data, u32 type, u32 id)
|
||||
: data(std::move(data))
|
||||
, info(typeid(T))
|
||||
, info(typeid(T).hash_code())
|
||||
, type(type)
|
||||
, id(id)
|
||||
{
|
||||
@ -62,13 +62,23 @@ class ID_manager
|
||||
|
||||
public:
|
||||
// check if ID exists and has specified type
|
||||
template<typename T> bool check_id(const u32 id)
|
||||
template<typename T> bool check_id(u32 id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
return f != m_id_map.end() && f->second.info == typeid(T);
|
||||
return f != m_id_map.end() && f->second.info == typeid(T).hash_code();
|
||||
}
|
||||
|
||||
// check if ID exists and has specified type
|
||||
bool check_id(u32 id, u32 type)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
return f != m_id_map.end() && f->second.type == type;
|
||||
}
|
||||
|
||||
// must be called from the constructor called through make() to get further ID of current object
|
||||
@ -122,14 +132,14 @@ public:
|
||||
return m_cur_id++;
|
||||
}
|
||||
|
||||
// load ID created with type Original, optionally static_cast to T
|
||||
// load ID created with type Orig, optionally static_cast to T
|
||||
template<typename T, typename Orig = T> auto get(u32 id) -> decltype(std::shared_ptr<T>(static_cast<T*>(std::declval<Orig*>())))
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
if (f == m_id_map.end() || f->second.info != typeid(Orig))
|
||||
if (f == m_id_map.end() || f->second.info != typeid(Orig).hash_code())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -137,13 +147,33 @@ public:
|
||||
return std::static_pointer_cast<T>(f->second.data);
|
||||
}
|
||||
|
||||
// load all IDs created with type Orig, optionally static_cast to T
|
||||
template<typename T, typename Orig = T> auto get_all() -> std::vector<decltype(std::shared_ptr<T>(static_cast<T*>(std::declval<Orig*>())))>
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
std::vector<std::shared_ptr<T>> result;
|
||||
|
||||
const std::size_t hash = typeid(Orig).hash_code();
|
||||
|
||||
for (auto& v : m_id_map)
|
||||
{
|
||||
if (v.second.info == hash)
|
||||
{
|
||||
result.emplace_back(std::static_pointer_cast<T>(v.second.data));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T> bool remove(u32 id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
auto item = m_id_map.find(id);
|
||||
|
||||
if (item == m_id_map.end() || item->second.info != typeid(T))
|
||||
if (item == m_id_map.end() || item->second.info != typeid(T).hash_code())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -159,9 +189,11 @@ public:
|
||||
|
||||
u32 result = 0;
|
||||
|
||||
const std::size_t hash = typeid(T).hash_code();
|
||||
|
||||
for (auto& v : m_id_map)
|
||||
{
|
||||
if (v.second.info == typeid(T))
|
||||
if (v.second.info == hash)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
@ -187,15 +219,18 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
// get sorted ID list
|
||||
template<typename T> std::set<u32> get_IDs()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
std::set<u32> result;
|
||||
|
||||
const std::size_t hash = typeid(T).hash_code();
|
||||
|
||||
for (auto& v : m_id_map)
|
||||
{
|
||||
if (v.second.info == typeid(T))
|
||||
if (v.second.info == hash)
|
||||
{
|
||||
result.insert(v.first);
|
||||
}
|
||||
@ -204,6 +239,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
// get sorted ID list
|
||||
std::set<u32> get_IDs(u32 type)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
@ -227,9 +263,11 @@ public:
|
||||
|
||||
std::vector<ID_data_t> result;
|
||||
|
||||
const std::size_t hash = typeid(T).hash_code();
|
||||
|
||||
for (auto& v : m_id_map)
|
||||
{
|
||||
if (v.second.info == typeid(T))
|
||||
if (v.second.info == hash)
|
||||
{
|
||||
result.emplace_back(v.second);
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ template<typename T, typename T2, typename = if_integral_t<T>> inline auto opera
|
||||
});
|
||||
}
|
||||
|
||||
template<typename T> using atomic = _atomic_base<T>; // Atomic Type with native endianness (for emulator memory)
|
||||
template<typename T> using atomic_t = _atomic_base<T>; // Atomic Type with native endianness (for emulator memory)
|
||||
|
||||
template<typename T> using atomic_be_t = _atomic_base<to_be_t<T>>; // Atomic BE Type (for PS3 virtual memory)
|
||||
|
||||
|
@ -74,11 +74,11 @@ namespace vm
|
||||
void* g_base_addr = (atexit(finalize), initialize());
|
||||
void* g_priv_addr;
|
||||
|
||||
std::array<atomic<u8>, 0x100000000ull / 4096> g_page_info = {}; // information about every page
|
||||
std::array<atomic_t<u8>, 0x100000000ull / 4096> g_page_info = {}; // information about every page
|
||||
|
||||
class reservation_mutex_t
|
||||
{
|
||||
atomic<const thread_ctrl_t*> m_owner{};
|
||||
atomic_t<const thread_ctrl_t*> m_owner{};
|
||||
std::condition_variable m_cv;
|
||||
std::mutex m_mutex;
|
||||
|
||||
|
@ -100,7 +100,7 @@ enum AudioPortState : u32
|
||||
struct AudioPortConfig
|
||||
{
|
||||
std::mutex mutex;
|
||||
atomic<AudioPortState> state;
|
||||
atomic_t<AudioPortState> state;
|
||||
|
||||
u32 channel;
|
||||
u32 block;
|
||||
@ -118,12 +118,12 @@ struct AudioPortConfig
|
||||
};
|
||||
|
||||
float level;
|
||||
atomic<level_set_t> level_set;
|
||||
atomic_t<level_set_t> level_set;
|
||||
};
|
||||
|
||||
struct AudioConfig final // custom structure
|
||||
{
|
||||
atomic<AudioState> state;
|
||||
atomic_t<AudioState> state;
|
||||
thread_t thread;
|
||||
|
||||
AudioPortConfig ports[AUDIO_PORT_COUNT];
|
||||
|
@ -34,14 +34,19 @@
|
||||
|
||||
#include "SysCalls.h"
|
||||
|
||||
void null_func(PPUThread& CPU);
|
||||
void null_func(PPUThread& ppu)
|
||||
{
|
||||
const auto code = ppu.GPR[11];
|
||||
LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code));
|
||||
ppu.GPR[3] = 0;
|
||||
}
|
||||
|
||||
// UNS = Unused
|
||||
// ROOT = Root
|
||||
// DBG = Debug
|
||||
// PM = Product Mode
|
||||
// AuthID = Authentication ID
|
||||
const ppu_func_caller sc_table[1024] =
|
||||
const ppu_func_caller g_sc_table[1024] =
|
||||
{
|
||||
null_func,
|
||||
bind_func(sys_process_getpid), //1 (0x001)
|
||||
@ -886,13 +891,6 @@ const ppu_func_caller sc_table[1024] =
|
||||
null_func, null_func, null_func, bind_func(cellGcmCallback), //1023 UNS
|
||||
};
|
||||
|
||||
void null_func(PPUThread& CPU)
|
||||
{
|
||||
const auto code = CPU.GPR[11];
|
||||
LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code));
|
||||
CPU.GPR[3] = 0;
|
||||
}
|
||||
|
||||
void SysCalls::DoSyscall(PPUThread& CPU, u64 code)
|
||||
{
|
||||
if (code >= 1024)
|
||||
@ -908,7 +906,7 @@ void SysCalls::DoSyscall(PPUThread& CPU, u64 code)
|
||||
LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code));
|
||||
}
|
||||
|
||||
sc_table[code](CPU);
|
||||
g_sc_table[code](CPU);
|
||||
|
||||
if (Ini.HLELogging.GetValue())
|
||||
{
|
||||
|
@ -87,14 +87,6 @@ s32 sys_cond_signal(u32 cond_id)
|
||||
// signal one waiting thread; protocol is ignored in current implementation
|
||||
if (thread->Signal())
|
||||
{
|
||||
cond->sent++;
|
||||
|
||||
if (!cond->mutex->owner)
|
||||
{
|
||||
// set the appropriate mutex owner if free; protocol is ignored in current implementation
|
||||
cond->mutex->owner = thread;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
@ -120,13 +112,7 @@ s32 sys_cond_signal_all(u32 cond_id)
|
||||
// signal all waiting threads; protocol is ignored in current implementation
|
||||
if (thread->Signal())
|
||||
{
|
||||
cond->sent++;
|
||||
|
||||
if (!cond->mutex->owner)
|
||||
{
|
||||
// set the appropriate mutex owner if free; protocol is ignored in current implementation
|
||||
cond->mutex->owner = thread;
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,14 +139,6 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
||||
// signal specified thread
|
||||
if (thread->GetId() == thread_id && thread->Signal())
|
||||
{
|
||||
cond->sent++;
|
||||
|
||||
if (!cond->mutex->owner)
|
||||
{
|
||||
// set the appropriate mutex owner if free; protocol is ignored in current implementation
|
||||
cond->mutex->owner = thread;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
@ -228,8 +206,6 @@ s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout)
|
||||
|
||||
CHECK_EMU_STATUS;
|
||||
}
|
||||
|
||||
cond->recv++;
|
||||
}
|
||||
|
||||
// reown the mutex (could be set when notified)
|
||||
|
@ -26,9 +26,6 @@ struct lv2_cond_t
|
||||
|
||||
sleep_queue_t sq;
|
||||
|
||||
std::atomic<u32> sent{ 0 };
|
||||
std::atomic<u32> recv{ 0 };
|
||||
|
||||
lv2_cond_t(const std::shared_ptr<lv2_mutex_t>& mutex, u64 name)
|
||||
: mutex(mutex)
|
||||
, name(name)
|
||||
|
@ -177,7 +177,7 @@ struct lv2_file_t
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
|
||||
atomic<u32> st_status;
|
||||
atomic_t<u32> st_status;
|
||||
|
||||
u64 st_ringbuf_size;
|
||||
u64 st_block_size;
|
||||
@ -191,7 +191,7 @@ struct lv2_file_t
|
||||
std::atomic<u64> st_total_read;
|
||||
std::atomic<u64> st_copied;
|
||||
|
||||
atomic<fs_st_cb_rec_t> st_callback;
|
||||
atomic_t<fs_st_cb_rec_t> st_callback;
|
||||
|
||||
lv2_file_t(std::shared_ptr<vfsStream> file, s32 mode, s32 flags)
|
||||
: file(std::move(file))
|
||||
|
@ -98,10 +98,10 @@ s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u32 intrthread,
|
||||
|
||||
it->custom_task = [thread, &tag, arg](PPUThread& CPU)
|
||||
{
|
||||
const auto pc = CPU.PC;
|
||||
const auto rtoc = CPU.GPR[2];
|
||||
const u32 pc = CPU.PC;
|
||||
const u32 rtoc = CPU.GPR[2];
|
||||
|
||||
std::unique_lock<std::mutex> cond_lock(tag.handler_mutex);
|
||||
std::unique_lock<std::mutex> lock(tag.handler_mutex);
|
||||
|
||||
while (!CPU.IsStopped())
|
||||
{
|
||||
@ -114,7 +114,7 @@ s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u32 intrthread,
|
||||
CPU.FastCall2(pc, rtoc);
|
||||
}
|
||||
|
||||
tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1));
|
||||
tag.cond.wait_for(lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -149,7 +149,7 @@ void sys_interrupt_thread_eoi(PPUThread& CPU)
|
||||
|
||||
// TODO: maybe it should actually unwind the stack of PPU thread?
|
||||
|
||||
CPU.GPR[1] = align(CPU.stack_addr + CPU.stack_size, 0x200) - 0x200; // supercrutch to avoid stack check
|
||||
CPU.GPR[1] = align(CPU.stack_addr + CPU.stack_size, 0x200) - 0x200; // supercrutch to bypass stack check
|
||||
|
||||
CPU.FastStop();
|
||||
}
|
||||
|
@ -11,6 +11,24 @@ SysCallBase sys_mutex("sys_mutex");
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
void lv2_mutex_t::unlock(lv2_lock_type& lv2_lock)
|
||||
{
|
||||
CHECK_LV2_LOCK(lv2_lock);
|
||||
|
||||
owner.reset();
|
||||
|
||||
if (sq.size())
|
||||
{
|
||||
// pick new owner; protocol is ignored in current implementation
|
||||
owner = sq.front();
|
||||
|
||||
if (!owner->Signal())
|
||||
{
|
||||
throw EXCEPTION("Mutex owner not signaled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 sys_mutex_create(vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute_t> attr)
|
||||
{
|
||||
sys_mutex.Warning("sys_mutex_create(mutex_id=*0x%x, attr=*0x%x)", mutex_id, attr);
|
||||
@ -217,19 +235,7 @@ s32 sys_mutex_unlock(PPUThread& ppu, u32 mutex_id)
|
||||
}
|
||||
else
|
||||
{
|
||||
// free the mutex
|
||||
mutex->owner.reset();
|
||||
|
||||
if (mutex->sq.size())
|
||||
{
|
||||
// pick another owner; protocol is ignored in current implementation
|
||||
mutex->owner = mutex->sq.front();
|
||||
|
||||
if (!mutex->owner->Signal())
|
||||
{
|
||||
throw EXCEPTION("Mutex owner not signaled");
|
||||
}
|
||||
}
|
||||
mutex->unlock(lv2_lock);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -39,6 +39,8 @@ struct lv2_mutex_t
|
||||
, name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void unlock(lv2_lock_type& lv2_lock);
|
||||
};
|
||||
|
||||
REG_ID_TYPE(lv2_mutex_t, 0x85); // SYS_MUTEX_OBJECT
|
||||
|
@ -18,23 +18,17 @@ void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode)
|
||||
LV2_LOCK;
|
||||
|
||||
// get all sys_mutex objects
|
||||
for (auto& _id : Emu.GetIdManager().get_data<lv2_mutex_t>())
|
||||
for (auto& mutex : Emu.GetIdManager().get_all<lv2_mutex_t>())
|
||||
{
|
||||
const auto mutex = std::static_pointer_cast<lv2_mutex_t>(_id.data);
|
||||
|
||||
// unlock mutex if locked by this thread
|
||||
if (mutex->owner.get() == &ppu)
|
||||
{
|
||||
mutex->owner.reset();
|
||||
|
||||
if (mutex->sq.size())
|
||||
{
|
||||
mutex->owner = mutex->sq.front();
|
||||
mutex->owner->Signal();
|
||||
}
|
||||
mutex->unlock(lv2_lock);
|
||||
}
|
||||
}
|
||||
|
||||
const auto thread = ppu.shared_from_this();
|
||||
|
||||
if (!ppu.is_joinable)
|
||||
{
|
||||
const u32 id = ppu.GetId();
|
||||
@ -260,8 +254,8 @@ s32 _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> p
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE;
|
||||
const bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT;
|
||||
const bool is_joinable = (flags & SYS_PPU_THREAD_CREATE_JOINABLE) != 0;
|
||||
const bool is_interrupt = (flags & SYS_PPU_THREAD_CREATE_INTERRUPT) != 0;
|
||||
|
||||
if (is_joinable && is_interrupt)
|
||||
{
|
||||
|
@ -4,8 +4,9 @@
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/CPU/CPUThreadManager.h"
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/SysCalls/lv2/sleep_queue.h"
|
||||
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
|
||||
#include "Emu/SysCalls/lv2/sys_lwcond.h"
|
||||
@ -81,6 +82,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Semaphores (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_SEMAPHORE_OBJECT))
|
||||
{
|
||||
const auto sem = Emu.GetIdManager().get<lv2_sema_t>(id);
|
||||
@ -94,6 +96,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Mutexes (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_MUTEX_OBJECT))
|
||||
{
|
||||
const auto mutex = Emu.GetIdManager().get<lv2_mutex_t>(id);
|
||||
@ -107,6 +110,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Lightweight Mutexes (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWMUTEX_OBJECT))
|
||||
{
|
||||
const auto lwm = Emu.GetIdManager().get<lv2_lwmutex_t>(id);
|
||||
@ -120,6 +124,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Condition Variables (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_COND_OBJECT))
|
||||
{
|
||||
const auto cond = Emu.GetIdManager().get<lv2_cond_t>(id);
|
||||
@ -133,6 +138,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Lightweight Condition Variables (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWCOND_OBJECT))
|
||||
{
|
||||
const auto lwc = Emu.GetIdManager().get<lv2_lwcond_t>(id);
|
||||
@ -146,6 +152,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Event Queues (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_QUEUE_OBJECT))
|
||||
{
|
||||
const auto queue = Emu.GetIdManager().get<lv2_event_queue_t>(id);
|
||||
@ -159,6 +166,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Event Ports (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_PORT_OBJECT))
|
||||
{
|
||||
const auto port = Emu.GetIdManager().get<lv2_event_port_t>(id);
|
||||
@ -174,6 +182,7 @@ void KernelExplorer::Update()
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
//sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good
|
||||
//m_tree->AppendItem(node, name);
|
||||
|
||||
for (const auto& id : Emu.GetIdManager().get_IDs(SYS_PRX_OBJECT))
|
||||
{
|
||||
sprintf(name, "PRX: ID = 0x%x", id);
|
||||
@ -186,6 +195,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Memory Containers (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto& id : Emu.GetIdManager().get_IDs(SYS_MEM_OBJECT))
|
||||
{
|
||||
sprintf(name, "Memory Container: ID = 0x%x", id);
|
||||
@ -198,6 +208,7 @@ void KernelExplorer::Update()
|
||||
{
|
||||
sprintf(name, "Event Flags (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto& id : Emu.GetIdManager().get_IDs(SYS_EVENT_FLAG_OBJECT))
|
||||
{
|
||||
sprintf(name, "Event Flag: ID = 0x%x", id);
|
||||
@ -205,71 +216,47 @@ void KernelExplorer::Update()
|
||||
}
|
||||
}
|
||||
|
||||
// PPU / SPU / RawSPU threads
|
||||
// PPU Threads
|
||||
if (u32 count = Emu.GetIdManager().get_count<PPUThread>())
|
||||
{
|
||||
// TODO: add mutexes owners
|
||||
sprintf(name, "PPU Threads (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
//const auto& objects = Emu.GetCPU().GetThreads();
|
||||
u32 ppu_threads_count = 0;
|
||||
u32 spu_threads_count = 0;
|
||||
u32 raw_spu_threads_count = 0;
|
||||
//for (const auto& thread : objects)
|
||||
//{
|
||||
// if (thread->GetType() == CPU_THREAD_PPU)
|
||||
// ppu_threads_count++;
|
||||
for (const auto& thread : Emu.GetIdManager().get_all<PPUThread>())
|
||||
{
|
||||
sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString());
|
||||
m_tree->AppendItem(node, name);
|
||||
}
|
||||
}
|
||||
|
||||
// if (thread->GetType() == CPU_THREAD_SPU)
|
||||
// spu_threads_count++;
|
||||
if (u32 count = Emu.GetIdManager().get_count<SPUThread>())
|
||||
{
|
||||
sprintf(name, "SPU Threads (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
// if (thread->GetType() == CPU_THREAD_RAW_SPU)
|
||||
// raw_spu_threads_count++;
|
||||
//}
|
||||
for (const auto& thread : Emu.GetIdManager().get_all<SPUThread>())
|
||||
{
|
||||
if (thread->GetType() == CPU_THREAD_SPU)
|
||||
{
|
||||
sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString());
|
||||
m_tree->AppendItem(node, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if (ppu_threads_count)
|
||||
//{
|
||||
// sprintf(name, "PPU Threads (%d)", ppu_threads_count);
|
||||
// const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
// for (const auto& thread : objects)
|
||||
// {
|
||||
// if (thread->GetType() == CPU_THREAD_PPU)
|
||||
// {
|
||||
// sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str());
|
||||
// m_tree->AppendItem(node, name);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (spu_threads_count)
|
||||
//{
|
||||
// sprintf(name, "SPU Threads (%d)", spu_threads_count);
|
||||
// const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
// for (const auto& thread : objects)
|
||||
// {
|
||||
// if (thread->GetType() == CPU_THREAD_SPU)
|
||||
// {
|
||||
// sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str());
|
||||
// m_tree->AppendItem(node, name);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (raw_spu_threads_count)
|
||||
//{
|
||||
// sprintf(name, "RawSPU Threads (%d)", raw_spu_threads_count);
|
||||
// const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
// for (const auto& thread : objects)
|
||||
// {
|
||||
// if (thread->GetType() == CPU_THREAD_RAW_SPU)
|
||||
// {
|
||||
// sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str());
|
||||
// m_tree->AppendItem(node, name);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
if (u32 count = Emu.GetIdManager().get_count<RawSPUThread>())
|
||||
{
|
||||
sprintf(name, "RawSPU Threads (%d)", count);
|
||||
const auto& node = m_tree->AppendItem(root, name);
|
||||
|
||||
for (const auto& thread : Emu.GetIdManager().get_all<RawSPUThread>())
|
||||
{
|
||||
if (thread->GetType() == CPU_THREAD_RAW_SPU)
|
||||
{
|
||||
sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString());
|
||||
m_tree->AppendItem(node, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_tree->Expand(root);
|
||||
|
@ -424,7 +424,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor");
|
||||
wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file");
|
||||
wxCheckBox* chbox_audio_conv = new wxCheckBox(p_audio, wxID_ANY, "Convert to 16 bit");
|
||||
wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log all SysCalls");
|
||||
wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log everything");
|
||||
wxCheckBox* chbox_rsx_logging = new wxCheckBox(p_hle, wxID_ANY, "RSX Logging");
|
||||
wxCheckBox* chbox_hle_hook_stfunc = new wxCheckBox(p_hle, wxID_ANY, "Hook static functions");
|
||||
wxCheckBox* chbox_hle_savetty = new wxCheckBox(p_hle, wxID_ANY, "Save TTY output to file");
|
||||
|
Loading…
x
Reference in New Issue
Block a user