1
0
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:
Nekotekina 2014-09-19 23:11:43 +04:00
parent dbd49a55c6
commit b6f8700b8b
10 changed files with 156 additions and 30 deletions

View File

@ -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;

View File

@ -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"

View 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;
}

View File

@ -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__);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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" />

View File

@ -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>