mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
vm::atomic initial structure
This commit is contained in:
parent
dbd49a55c6
commit
b6f8700b8b
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "Emu/Memory/vm_atomic.h"
|
||||
|
||||
bool SM_IsAborted();
|
||||
void SM_Sleep();
|
||||
@ -24,9 +25,9 @@ template
|
||||
>
|
||||
class SMutexBase
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(std::atomic<T>), "Invalid SMutexBase type");
|
||||
static_assert(sizeof(T) == sizeof(vm::atomic_le<T>), "Invalid SMutexBase type");
|
||||
T owner;
|
||||
typedef std::atomic<T> AT;
|
||||
typedef vm::atomic_le<T> AT;
|
||||
|
||||
public:
|
||||
static const T GetFreeValue()
|
||||
@ -46,11 +47,6 @@ public:
|
||||
owner = GetFreeValue();
|
||||
}
|
||||
|
||||
//SMutexBase()
|
||||
//{
|
||||
// initialize();
|
||||
//}
|
||||
|
||||
void finalize()
|
||||
{
|
||||
owner = GetDeadValue();
|
||||
@ -67,9 +63,9 @@ public:
|
||||
{
|
||||
return SMR_ABORT;
|
||||
}
|
||||
T old = GetFreeValue();
|
||||
T old = reinterpret_cast<AT&>(owner).compare_and_swap(GetFreeValue(), tid);
|
||||
|
||||
if (!reinterpret_cast<AT&>(owner).compare_exchange_strong(old, tid))
|
||||
if (old != GetFreeValue())
|
||||
{
|
||||
if (old == tid)
|
||||
{
|
||||
@ -91,9 +87,9 @@ public:
|
||||
{
|
||||
return SMR_ABORT;
|
||||
}
|
||||
T old = tid;
|
||||
T old = reinterpret_cast<AT&>(owner).compare_and_swap(tid, to);
|
||||
|
||||
if (!reinterpret_cast<AT&>(owner).compare_exchange_strong(old, to))
|
||||
if (old != tid)
|
||||
{
|
||||
if (old == GetFreeValue())
|
||||
{
|
||||
@ -132,5 +128,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef SMutexBase<u32>
|
||||
SMutex;
|
||||
typedef SMutexBase<u32> SMutex;
|
||||
|
@ -204,4 +204,5 @@ namespace vm
|
||||
|
||||
#include "vm_ref.h"
|
||||
#include "vm_ptr.h"
|
||||
#include "vm_var.h"
|
||||
#include "vm_var.h"
|
||||
#include "vm_atomic.h"
|
||||
|
63
rpcs3/Emu/Memory/vm_atomic.h
Normal file
63
rpcs3/Emu/Memory/vm_atomic.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename T, size_t size = sizeof(T)>
|
||||
struct _to_atomic
|
||||
{
|
||||
static_assert(size == 4 || size == 8, "Invalid atomic type");
|
||||
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _to_atomic<T, 4>
|
||||
{
|
||||
typedef uint32_t type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _to_atomic<T, 8>
|
||||
{
|
||||
typedef uint64_t type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class _atomic_base
|
||||
{
|
||||
T data;
|
||||
typedef typename _to_atomic<T, sizeof(T)>::type atomic_type;
|
||||
|
||||
public:
|
||||
T compare_and_swap(T cmp, T exch)
|
||||
{
|
||||
const atomic_type res = InterlockedCompareExchange((volatile atomic_type*)&data, (atomic_type&)exch, (atomic_type&)cmp);
|
||||
return (T&)res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T> struct atomic_le : public _atomic_base<T>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T> struct atomic_be : public _atomic_base<typename to_be_t<T>::type>
|
||||
{
|
||||
};
|
||||
|
||||
namespace ps3
|
||||
{
|
||||
template<typename T> struct atomic : public atomic_be<T>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace psv
|
||||
{
|
||||
template<typename T> struct atomic : public atomic_le<T>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
using namespace ps3;
|
||||
}
|
@ -207,6 +207,37 @@ s64 spursInit(
|
||||
assert(ppu1);
|
||||
spurs->m.ppu1 = ppu1->GetId();
|
||||
|
||||
// enable exception event handler
|
||||
if (spurs->m.enableEH.compare_and_swap(be_t<u32>::MakeFromBE(0), be_t<u32>::MakeFromBE(se32(1))).ToBE() != 0)
|
||||
{
|
||||
assert(sys_spu_thread_group_connect_event(spurs->m.spuTG, spurs->m.queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION) == CELL_OK);
|
||||
}
|
||||
|
||||
spurs->m.unk22 = 0;
|
||||
// can also use cellLibprof if available (omitted)
|
||||
|
||||
// some unknown subroutine
|
||||
spurs->m.sub3.unk1 = spurs.addr() + 0xc9;
|
||||
spurs->m.sub3.unk2 = 3; // unknown const
|
||||
spurs->m.sub3.port = (u64)spurs->m.port;
|
||||
|
||||
if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) // initialize system workload
|
||||
{
|
||||
s32 res;
|
||||
#ifdef PRX_DEBUG
|
||||
res = cb_call<s32, vm::ptr<CellSpurs>, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x10428, libsre_rtoc,
|
||||
spurs, Memory.RealToVirtualAddr(swlPriority), swlMaxSpu, swlIsPreem);
|
||||
#else
|
||||
res = -1;
|
||||
#endif
|
||||
assert(res == CELL_OK);
|
||||
}
|
||||
else if (flags & SAF_EXIT_IF_NO_WORK) // wakeup
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
return cb_call<s32, vm::ptr<CellSpurs>>(GetCurrentPPUThread(), libsre + 0x84D8, libsre_rtoc, spurs);
|
||||
#endif
|
||||
}
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
@ -1657,7 +1688,7 @@ s64 cellSpursAddWorkload()
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 cellSpursWakeUp()
|
||||
s64 cellSpursWakeUp(vm::ptr<CellSpurs> spurs)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellSpurs->Warning("%s()", __FUNCTION__);
|
||||
|
@ -149,8 +149,21 @@ struct CellSpurs
|
||||
{
|
||||
static const uint size = 0x80;
|
||||
|
||||
be_t<u64> sem;
|
||||
u8 unk_[0x78];
|
||||
u8 unk0[0x20];
|
||||
be_t<u64> sem; // 0x20
|
||||
u8 unk_[0x58];
|
||||
};
|
||||
|
||||
struct _sub_str2
|
||||
{
|
||||
static const uint size = 0x80;
|
||||
|
||||
be_t<u32> unk0;
|
||||
be_t<u32> unk1;
|
||||
be_t<u32> unk2;
|
||||
be_t<u32> unk3;
|
||||
be_t<u64> port; // 0x10
|
||||
u8 unk_[0x68];
|
||||
};
|
||||
|
||||
union
|
||||
@ -173,9 +186,10 @@ struct CellSpurs
|
||||
be_t<u32> unk0; // 0x0B0
|
||||
u8 unknown2[0xC0 - 0xB4];
|
||||
u8 unk6[0x10]; // 0x0C0
|
||||
u8 unknown1[0x120 - 0x0D0];
|
||||
_sub_str1 sub1[0x10]; // 0x120
|
||||
u8 unknown7[0x980 - 0x920];
|
||||
u8 unknown1[0x100 - 0x0D0];
|
||||
_sub_str1 sub1[0x10]; // 0x100
|
||||
be_t<u64> unk22; // 0x900
|
||||
u8 unknown7[0x980 - 0x908];
|
||||
be_t<u64> semPrv; // 0x980
|
||||
be_t<u32> unk11; // 0x988
|
||||
be_t<u32> unk12; // 0x98C
|
||||
@ -193,7 +207,9 @@ struct CellSpurs
|
||||
u8 unknown3[0xD5C - 0xD54];
|
||||
be_t<u32> queue; // 0xD5C
|
||||
be_t<u32> port; // 0xD60
|
||||
u8 unk19[0xC]; // 0xD64
|
||||
be_t<u32> unk19; // 0xD64
|
||||
vm::atomic<u32> enableEH; // 0xD68
|
||||
be_t<u32> unk21; // 0xD6C
|
||||
sys_spu_image spuImg; // 0xD70
|
||||
be_t<u32> flags; // 0xD80
|
||||
be_t<s32> spuPriority;// 0xD84
|
||||
@ -206,8 +222,10 @@ struct CellSpurs
|
||||
u8 unknown8[0xDB0 - 0xDA8];
|
||||
sys_lwmutex_t mutex; // 0xDB0
|
||||
sys_lwcond_t cond; // 0xDC8
|
||||
u8 unknown6[0x1220 - 0xDD0];
|
||||
_sub_str1 sub2[0x10]; // 0x1220
|
||||
u8 unknown9[0xF00 - 0xDD0];
|
||||
_sub_str2 sub3; // 0xF00
|
||||
u8 unknown6[0x1200 - 0xF80];
|
||||
_sub_str1 sub2[0x10]; // 0x1200
|
||||
// ...
|
||||
} m;
|
||||
|
||||
|
@ -210,12 +210,12 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> init)
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<vm::atomic<u32>> once_ctrl, vm::ptr<void(*)()> init)
|
||||
{
|
||||
sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, init_addr=0x%x)", once_ctrl.addr(), init.addr());
|
||||
|
||||
be_t<u32> old = be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT));
|
||||
if (once_ctrl->compare_exchange_weak(old, be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT))))
|
||||
auto cmp = to_be<u32>(SYS_PPU_THREAD_ONCE_INIT);
|
||||
if (once_ctrl->compare_and_swap(cmp, to_be<u32>(SYS_PPU_THREAD_DONE_INIT)) == cmp)
|
||||
{
|
||||
init.call(CPU);
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
class PPUThread;
|
||||
|
||||
enum
|
||||
enum : u32
|
||||
{
|
||||
SYS_PPU_THREAD_ONCE_INIT,
|
||||
SYS_PPU_THREAD_DONE_INIT,
|
||||
SYS_PPU_THREAD_ONCE_INIT = 0,
|
||||
SYS_PPU_THREAD_DONE_INIT = 1,
|
||||
};
|
||||
|
||||
enum ppu_thread_flags : u64
|
||||
@ -30,6 +30,6 @@ s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr);
|
||||
s32 sys_ppu_thread_stop(u64 thread_id);
|
||||
s32 sys_ppu_thread_restart(u64 thread_id);
|
||||
s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> init);
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<vm::atomic<u32>> once_ctrl, vm::ptr<void(*)()> init);
|
||||
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<be_t<u64>> thread_id);
|
||||
s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name);
|
||||
|
@ -18,6 +18,20 @@ enum
|
||||
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SYS_SPU_THREAD_GROUP_EVENT_RUN = 1,
|
||||
SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION = 2,
|
||||
SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE = 4,
|
||||
};
|
||||
|
||||
enum : u64
|
||||
{
|
||||
SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY = 0xFFFFFFFF53505500ull,
|
||||
SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull,
|
||||
SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY = 0xFFFFFFFF53505504ull,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED,
|
||||
|
@ -311,6 +311,7 @@
|
||||
<ClInclude Include="Emu\Io\PadHandler.h" />
|
||||
<ClInclude Include="Emu\Memory\Memory.h" />
|
||||
<ClInclude Include="Emu\Memory\MemoryBlock.h" />
|
||||
<ClInclude Include="Emu\Memory\vm_atomic.h" />
|
||||
<ClInclude Include="Emu\RSX\GCM.h" />
|
||||
<ClInclude Include="Emu\RSX\GL\GLBuffers.h" />
|
||||
<ClInclude Include="Emu\RSX\GL\GLFragmentProgram.h" />
|
||||
|
@ -1219,5 +1219,8 @@
|
||||
<ClInclude Include="Emu\SysCalls\SyncPrimitivesManager.h">
|
||||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Memory\vm_atomic.h">
|
||||
<Filter>Emu\Memory</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user