mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Lv2 Cond/Mutex rewritten, bugfixes
This commit is contained in:
parent
48c1f0f03d
commit
ef65299dff
@ -116,6 +116,7 @@ enum x64_op_t : u32
|
||||
X64OP_STOS,
|
||||
X64OP_XCHG,
|
||||
X64OP_CMPXCHG,
|
||||
X64OP_LOAD_AND_STORE,
|
||||
};
|
||||
|
||||
void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, size_t& out_size, size_t& out_length)
|
||||
@ -310,6 +311,30 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x20:
|
||||
{
|
||||
if (!oso)
|
||||
{
|
||||
out_op = X64OP_LOAD_AND_STORE;
|
||||
out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code);
|
||||
out_size = 1;
|
||||
out_length += get_modRM_size(code);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x21:
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
out_op = X64OP_LOAD_AND_STORE;
|
||||
out_reg = get_modRM_reg(code, rex);
|
||||
out_size = get_op_size(rex, oso);
|
||||
out_length += get_modRM_size(code);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x86:
|
||||
{
|
||||
if (!oso) // XCHG r8/m8, r8
|
||||
@ -1013,6 +1038,29 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case X64OP_LOAD_AND_STORE:
|
||||
{
|
||||
u64 value;
|
||||
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: value = vm::priv_ref<atomic_le_t<u8>>(addr) &= value; break;
|
||||
case 2: value = vm::priv_ref<atomic_le_t<u16>>(addr) &= value; break;
|
||||
case 4: value = vm::priv_ref<atomic_le_t<u32>>(addr) &= value; break;
|
||||
case 8: value = vm::priv_ref<atomic_le_t<u64>>(addr) &= value; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
if (!set_x64_cmp_flags(context, d_size, value, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size);
|
||||
|
@ -67,7 +67,7 @@ std::shared_ptr<CPUThread> CPUThreadManager::AddThread(CPUThreadType type)
|
||||
|
||||
if (new_thread)
|
||||
{
|
||||
new_thread->SetId(Emu.GetIdManager().GetNewID(new_thread->GetTypeString() + " Thread", new_thread));
|
||||
new_thread->SetId(Emu.GetIdManager().GetNewID(new_thread));
|
||||
|
||||
m_threads.push_back(new_thread);
|
||||
SendDbgCommand(DID_CREATE_THREAD, new_thread.get());
|
||||
|
@ -991,15 +991,13 @@ void SPUThread::stop_and_signal(u32 code)
|
||||
}
|
||||
|
||||
// protocol is ignored in current implementation
|
||||
queue->waiters++;
|
||||
assert(queue->waiters > 0);
|
||||
queue->waiters++; assert(queue->waiters > 0);
|
||||
|
||||
while (queue->events.empty())
|
||||
{
|
||||
if (queue->waiters < 0)
|
||||
{
|
||||
queue->waiters--;
|
||||
assert(queue->waiters < 0);
|
||||
queue->waiters--; assert(queue->waiters < 0);
|
||||
ch_in_mbox.push_uncond(CELL_ECANCELED);
|
||||
return;
|
||||
}
|
||||
@ -1020,8 +1018,7 @@ void SPUThread::stop_and_signal(u32 code)
|
||||
ch_in_mbox.push_uncond((u32)event.data3);
|
||||
|
||||
queue->events.pop_front();
|
||||
queue->waiters--;
|
||||
assert(queue->waiters >= 0);
|
||||
queue->waiters--; assert(queue->waiters >= 0);
|
||||
|
||||
if (queue->events.size())
|
||||
{
|
||||
@ -1050,7 +1047,8 @@ void SPUThread::stop_and_signal(u32 code)
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group = tg.lock();
|
||||
if (group)
|
||||
|
||||
if (!group)
|
||||
{
|
||||
LOG_ERROR(SPU, "sys_spu_thread_group_exit(status=0x%x): invalid group", value);
|
||||
throw __FUNCTION__;
|
||||
|
@ -48,60 +48,56 @@ public:
|
||||
m_destr(m_ptr);
|
||||
}
|
||||
|
||||
template<typename T> std::shared_ptr<T> get()
|
||||
template<typename T> std::shared_ptr<T> get() const
|
||||
{
|
||||
return *(std::shared_ptr<T>*)m_ptr;
|
||||
}
|
||||
|
||||
template<typename T> std::shared_ptr<const T> get() const
|
||||
{
|
||||
return *(std::shared_ptr<const T>*)m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
class ID
|
||||
{
|
||||
std::string m_name;
|
||||
const std::type_info& m_info;
|
||||
IDData* m_data;
|
||||
IDType m_type;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
ID(const std::string& name, std::shared_ptr<T>& data, const IDType type)
|
||||
: m_name(name)
|
||||
ID(std::shared_ptr<T>& data, const IDType type)
|
||||
: m_info(typeid(T))
|
||||
, m_type(type)
|
||||
{
|
||||
m_data = new IDData(new std::shared_ptr<T>(data), [](void *ptr) -> void { delete (std::shared_ptr<T>*)ptr; });
|
||||
}
|
||||
|
||||
ID() : m_data(nullptr)
|
||||
ID()
|
||||
: m_info(typeid(nullptr_t))
|
||||
, m_data(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ID(ID&& other)
|
||||
ID(const ID& right) = delete;
|
||||
|
||||
ID(ID&& right)
|
||||
: m_info(right.m_info)
|
||||
, m_data(right.m_data)
|
||||
, m_type(right.m_type)
|
||||
{
|
||||
m_name = other.m_name;
|
||||
m_type = other.m_type;
|
||||
m_data = other.m_data;
|
||||
other.m_data = nullptr;
|
||||
right.m_data = nullptr;
|
||||
}
|
||||
|
||||
ID& operator=(ID&& other)
|
||||
{
|
||||
std::swap(m_name,other.m_name);
|
||||
std::swap(m_type,other.m_type);
|
||||
std::swap(m_data,other.m_data);
|
||||
return *this;
|
||||
}
|
||||
ID& operator=(ID&& other) = delete;
|
||||
|
||||
void Kill()
|
||||
~ID()
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
delete m_data;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& GetName() const
|
||||
const std::type_info& GetInfo() const
|
||||
{
|
||||
return m_name;
|
||||
return m_info;
|
||||
}
|
||||
|
||||
IDData* GetData() const
|
||||
@ -147,10 +143,6 @@ public:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
for(auto& i : m_id_map) {
|
||||
i.second.Kill();
|
||||
}
|
||||
|
||||
m_id_map.clear();
|
||||
m_cur_id = s_first_id;
|
||||
}
|
||||
@ -160,11 +152,11 @@ public:
|
||||
= char
|
||||
#endif
|
||||
>
|
||||
u32 GetNewID(const std::string& name = "", std::shared_ptr<T>& data = nullptr, const IDType type = TYPE_OTHER)
|
||||
u32 GetNewID(std::shared_ptr<T>& data = nullptr, const IDType type = TYPE_OTHER)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
m_id_map[m_cur_id] = ID(name, data, type);
|
||||
m_id_map.emplace(m_cur_id, ID(data, type));
|
||||
if (type < TYPE_OTHER) {
|
||||
m_types[type].insert(m_cur_id);
|
||||
}
|
||||
@ -185,7 +177,7 @@ public:
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
if (f == m_id_map.end()) {
|
||||
if (f == m_id_map.end() || f->second.GetInfo() != typeid(T)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -219,7 +211,6 @@ public:
|
||||
m_types[item->second.GetType()].erase(id);
|
||||
}
|
||||
|
||||
item->second.Kill();
|
||||
m_id_map.erase(item);
|
||||
|
||||
return true;
|
||||
|
@ -599,23 +599,3 @@ void Module::SetName(const std::string& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
bool Module::CheckID(u32 id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && Emu.GetIdManager().GetID(id).GetName() == GetName();
|
||||
}
|
||||
|
||||
bool Module::CheckID(u32 id, ID*& _id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && (_id = &Emu.GetIdManager().GetID(id))->GetName() == GetName();
|
||||
}
|
||||
|
||||
bool Module::RemoveId(u32 id)
|
||||
{
|
||||
return Emu.GetIdManager().RemoveID(id);
|
||||
}
|
||||
|
||||
IdManager& Module::GetIdManager() const
|
||||
{
|
||||
return Emu.GetIdManager();
|
||||
}
|
||||
|
@ -76,8 +76,6 @@ class Module : public LogBase
|
||||
bool m_is_loaded;
|
||||
void(*m_init)();
|
||||
|
||||
IdManager& GetIdManager() const;
|
||||
|
||||
Module() = delete;
|
||||
|
||||
public:
|
||||
@ -104,42 +102,6 @@ public:
|
||||
|
||||
virtual const std::string& GetName() const override;
|
||||
void SetName(const std::string& name);
|
||||
|
||||
public:
|
||||
bool CheckID(u32 id) const;
|
||||
|
||||
template<typename T> bool CheckId(u32 id, std::shared_ptr<T>& data)
|
||||
{
|
||||
ID* id_data;
|
||||
|
||||
if(!CheckID(id, id_data)) return false;
|
||||
|
||||
data = id_data->GetData()->get<T>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> bool CheckId(u32 id, std::shared_ptr<T>& data, IDType& type)
|
||||
{
|
||||
ID* id_data;
|
||||
|
||||
if(!CheckID(id, id_data)) return false;
|
||||
|
||||
data = id_data->GetData()->get<T>();
|
||||
type = id_data->GetType();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckID(u32 id, ID*& _id) const;
|
||||
|
||||
template<typename T>
|
||||
u32 GetNewId(std::shared_ptr<T>& data, IDType type = TYPE_OTHER)
|
||||
{
|
||||
return GetIdManager().GetNewID<T>(GetName(), data, type);
|
||||
}
|
||||
|
||||
bool RemoveId(u32 id);
|
||||
};
|
||||
|
||||
u32 add_ppu_func(ModuleFunc func);
|
||||
|
@ -219,7 +219,7 @@ u32 adecOpen(AudioDecoder* adec_ptr)
|
||||
std::shared_ptr<AudioDecoder> sptr(adec_ptr);
|
||||
AudioDecoder& adec = *adec_ptr;
|
||||
|
||||
u32 adec_id = cellAdec.GetNewId(sptr);
|
||||
u32 adec_id = Emu.GetIdManager().GetNewID(sptr);
|
||||
|
||||
adec.id = adec_id;
|
||||
|
||||
|
@ -790,7 +790,7 @@ int cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
return CELL_AUDIO_ERROR_EVENT_QUEUE;
|
||||
}
|
||||
|
||||
*id = cellAudio.GetNewId(eq);
|
||||
*id = Emu.GetIdManager().GetNewID(eq);
|
||||
*key = event_key;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -301,7 +301,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
|
||||
std::shared_ptr<Demuxer> sptr(dmux_ptr);
|
||||
Demuxer& dmux = *dmux_ptr;
|
||||
|
||||
u32 dmux_id = cellDmux.GetNewId(sptr);
|
||||
u32 dmux_id = Emu.GetIdManager().GetNewID(sptr);
|
||||
|
||||
dmux.id = dmux_id;
|
||||
|
||||
@ -990,7 +990,7 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr<const CellCodecEsFilterId> esFil
|
||||
esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2,
|
||||
esCb->cbEsMsgFunc.to_le(), esCb->cbArg, esSpecificInfo_addr));
|
||||
|
||||
u32 id = cellDmux.GetNewId(es);
|
||||
u32 id = Emu.GetIdManager().GetNewID(es);
|
||||
es->id = id;
|
||||
*esHandle = id;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
|
||||
@ -52,7 +53,7 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellGifDecSrc
|
||||
}
|
||||
|
||||
// From now, every u32 subHandle argument is a pointer to a CellGifDecSubHandle struct.
|
||||
*subHandle = cellGifDec.GetNewId(current_subHandle);
|
||||
*subHandle = Emu.GetIdManager().GetNewID(current_subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -63,7 +64,7 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellGifDecInfo>
|
||||
mainHandle, subHandle, info.addr());
|
||||
|
||||
std::shared_ptr<CellGifDecSubHandle> subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
@ -113,7 +114,7 @@ int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellGifD
|
||||
mainHandle, subHandle, inParam.addr(), outParam.addr());
|
||||
|
||||
std::shared_ptr<CellGifDecSubHandle> subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
CellGifDecInfo& current_info = subHandle_data->info;
|
||||
@ -145,7 +146,7 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP;
|
||||
|
||||
std::shared_ptr<CellGifDecSubHandle> subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
@ -260,11 +261,11 @@ int cellGifDecClose(u32 mainHandle, u32 subHandle)
|
||||
mainHandle, subHandle);
|
||||
|
||||
std::shared_ptr<CellGifDecSubHandle> subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
cellGifDec.RemoveId(subHandle);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
|
||||
@ -58,7 +59,7 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellJpgDecSrc
|
||||
}
|
||||
|
||||
// From now, every u32 subHandle argument is a pointer to a CellJpgDecSubHandle struct.
|
||||
*subHandle = cellJpgDec.GetNewId(current_subHandle);
|
||||
*subHandle = Emu.GetIdManager().GetNewID(current_subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -69,11 +70,11 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||
mainHandle, subHandle);
|
||||
|
||||
std::shared_ptr<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
cellJpgDec.RemoveId(subHandle);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -83,7 +84,7 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDecInfo>
|
||||
cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr());
|
||||
|
||||
std::shared_ptr<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
@ -152,7 +153,7 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
|
||||
dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP;
|
||||
std::shared_ptr<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
@ -282,7 +283,7 @@ int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellJpgD
|
||||
mainHandle, subHandle, inParam.addr(), outParam.addr());
|
||||
|
||||
std::shared_ptr<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||
|
@ -209,7 +209,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
|
||||
std::shared_ptr<VideoDecoder> sptr(vdec_ptr);
|
||||
VideoDecoder& vdec = *vdec_ptr;
|
||||
|
||||
u32 vdec_id = cellVdec.GetNewId(sptr);
|
||||
u32 vdec_id = Emu.GetIdManager().GetNewID(sptr);
|
||||
|
||||
vdec.id = vdec_id;
|
||||
|
||||
|
@ -29,7 +29,7 @@ int cellVpostQueryAttr(vm::ptr<const CellVpostCfgParam> cfgParam, vm::ptr<CellVp
|
||||
u32 vpostOpen(VpostInstance* data)
|
||||
{
|
||||
std::shared_ptr<VpostInstance> data_ptr(data);
|
||||
u32 id = cellVpost.GetNewId(data_ptr);
|
||||
u32 id = Emu.GetIdManager().GetNewID(data_ptr);
|
||||
|
||||
cellVpost.Notice("*** Vpost instance created (to_rgba=%d): id = %d", data->to_rgba, id);
|
||||
|
||||
|
@ -226,7 +226,7 @@ int _sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size)
|
||||
sysPrxForUser.Warning("_sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size);
|
||||
|
||||
std::shared_ptr<HeapInfo> heap(new HeapInfo(heap_addr, align, size));
|
||||
u32 heap_id = sysPrxForUser.GetNewId(heap);
|
||||
u32 heap_id = Emu.GetIdManager().GetNewID(heap);
|
||||
sysPrxForUser.Warning("*** sys_heap created: id = %d", heap_id);
|
||||
return heap_id;
|
||||
}
|
||||
@ -236,7 +236,7 @@ u32 _sys_heap_malloc(const u32 heap_id, const u32 size)
|
||||
sysPrxForUser.Warning("_sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size);
|
||||
|
||||
std::shared_ptr<HeapInfo> heap;
|
||||
if(!sysPrxForUser.CheckId(heap_id, heap)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(heap_id, heap)) return CELL_ESRCH;
|
||||
|
||||
return (u32)Memory.Alloc(size, 1);
|
||||
}
|
||||
@ -246,7 +246,7 @@ u32 _sys_heap_memalign(u32 heap_id, u32 align, u32 size)
|
||||
sysPrxForUser.Warning("_sys_heap_memalign(heap_id=%d, align=0x%x, size=0x%x)", heap_id, align, size);
|
||||
|
||||
std::shared_ptr<HeapInfo> heap;
|
||||
if(!sysPrxForUser.CheckId(heap_id, heap)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(heap_id, heap)) return CELL_ESRCH;
|
||||
|
||||
return (u32)Memory.Alloc(size, align);
|
||||
}
|
||||
@ -267,9 +267,7 @@ s32 sys_interrupt_thread_disestablish(PPUThread& CPU, u32 ih)
|
||||
{
|
||||
sysPrxForUser.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih);
|
||||
|
||||
vm::stackvar<u64> r13(CPU);
|
||||
|
||||
return _sys_interrupt_thread_disestablish(ih, r13);
|
||||
return _sys_interrupt_thread_disestablish(ih, vm::stackvar<u64>(CPU));
|
||||
}
|
||||
|
||||
int sys_process_is_stack(u32 p)
|
||||
|
@ -50,20 +50,20 @@ std::string SyncPrimManager::GetSyncPrimName(u32 id, IDType type)
|
||||
|
||||
case TYPE_MUTEX:
|
||||
{
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
if (Emu.GetIdManager().GetIDData(id, mutex))
|
||||
{
|
||||
return std::string((const char*)&mutex->queue.name, 8);
|
||||
return std::string((const char*)&mutex->name, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_COND:
|
||||
{
|
||||
std::shared_ptr<Cond> cond;
|
||||
std::shared_ptr<cond_t> cond;
|
||||
if (Emu.GetIdManager().GetIDData(id, cond))
|
||||
{
|
||||
return std::string((const char*)&cond->queue.name, 8);
|
||||
return std::string((const char*)&cond->name, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -33,14 +33,6 @@
|
||||
|
||||
#include "SysCalls.h"
|
||||
|
||||
namespace detail
|
||||
{
|
||||
bool CheckIdID(u32 id, ID*& _id, const std::string &name)
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && (_id = &Emu.GetIdManager().GetID(id))->GetName() == name;
|
||||
}
|
||||
}
|
||||
|
||||
void null_func(PPUThread& CPU);
|
||||
|
||||
const int kSyscallTableLength = 1024;
|
||||
@ -952,13 +944,3 @@ void SysCalls::DoSyscall(PPUThread& CPU, u64 code)
|
||||
|
||||
CPU.m_last_syscall = old_last_syscall;
|
||||
}
|
||||
|
||||
IdManager& SysCallBase::GetIdManager() const
|
||||
{
|
||||
return Emu.GetIdManager();
|
||||
}
|
||||
|
||||
bool SysCallBase::RemoveId(u32 id)
|
||||
{
|
||||
return Emu.GetIdManager().RemoveID(id);
|
||||
}
|
||||
|
@ -5,32 +5,14 @@
|
||||
|
||||
//#define SYSCALLS_DEBUG
|
||||
|
||||
class SysCallBase;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
bool CheckIdID(u32 id, ID*& _id, const std::string& name);
|
||||
|
||||
template<typename T> bool CheckId(u32 id, std::shared_ptr<T>& data, const std::string& name)
|
||||
{
|
||||
ID* id_data;
|
||||
if(!CheckIdID(id, id_data, name)) return false;
|
||||
data = id_data->GetData()->get<T>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SysCallBase : public LogBase
|
||||
{
|
||||
private:
|
||||
std::string m_module_name;
|
||||
//u32 m_id;
|
||||
IdManager& GetIdManager() const;
|
||||
|
||||
public:
|
||||
SysCallBase(const std::string& name/*, u32 id*/)
|
||||
SysCallBase(const std::string& name)
|
||||
: m_module_name(name)
|
||||
//, m_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -38,25 +20,6 @@ public:
|
||||
{
|
||||
return m_module_name;
|
||||
}
|
||||
|
||||
bool CheckId(u32 id) const
|
||||
{
|
||||
return GetIdManager().CheckID(id) && GetIdManager().GetID(id).GetName() == GetName();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool CheckId(u32 id, std::shared_ptr<T>& data) const
|
||||
{
|
||||
return detail::CheckId(id, data, GetName());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
u32 GetNewId(std::shared_ptr<T>& data, IDType type = TYPE_OTHER)
|
||||
{
|
||||
return GetIdManager().GetNewID<T>(GetName(), data, type);
|
||||
}
|
||||
|
||||
bool RemoveId(u32 id);
|
||||
};
|
||||
|
||||
extern bool dump_enable;
|
||||
|
@ -115,7 +115,7 @@ s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::p
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
u32 id = sys_fs.GetNewId(stream, TYPE_FS_FILE);
|
||||
u32 id = Emu.GetIdManager().GetNewID(stream, TYPE_FS_FILE);
|
||||
*fd = id;
|
||||
sys_fs.Notice("cellFsOpen(): '%s' opened, id -> 0x%x", path.get_ptr(), id);
|
||||
|
||||
@ -127,7 +127,7 @@ s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<be_t<u64>> nread)
|
||||
sys_fs.Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
if (nbytes != (u32)nbytes)
|
||||
@ -147,7 +147,7 @@ s32 cellFsWrite(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrite
|
||||
sys_fs.Log("cellFsWrite(fd=0x%x, buf=0x%x, nbytes=0x%llx, nwrite=0x%x)", fd, buf, nbytes, nwrite);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH;
|
||||
|
||||
if (nbytes != (u32)nbytes) return CELL_ENOMEM;
|
||||
|
||||
@ -181,7 +181,7 @@ s32 cellFsOpendir(vm::ptr<const char> path, vm::ptr<u32> fd)
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
*fd = sys_fs.GetNewId(dir, TYPE_FS_DIR);
|
||||
*fd = Emu.GetIdManager().GetNewID(dir, TYPE_FS_DIR);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ s32 cellFsReaddir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
|
||||
sys_fs.Warning("cellFsReaddir(fd=0x%x, dir=0x%x, nread=0x%x)", fd, dir, nread);
|
||||
|
||||
std::shared_ptr<vfsDirBase> directory;
|
||||
if (!sys_fs.CheckId(fd, directory))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, directory))
|
||||
return CELL_ESRCH;
|
||||
|
||||
const DirEntryInfo* info = directory->Read();
|
||||
@ -306,9 +306,8 @@ s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
|
||||
{
|
||||
sys_fs.Warning("cellFsFstat(fd=0x%x, sb=0x%x)", fd, sb);
|
||||
|
||||
IDType type;
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE)
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
sb->st_mode =
|
||||
@ -452,9 +451,8 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr<be_t<u64>> pos)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
IDType type;
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE)
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
*pos = file->Seek(offset, seek_mode);
|
||||
@ -465,9 +463,8 @@ s32 cellFsFtruncate(u32 fd, u64 size)
|
||||
{
|
||||
sys_fs.Warning("cellFsFtruncate(fd=0x%x, size=0x%llx)", fd, size);
|
||||
|
||||
IDType type;
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE)
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
u64 initialSize = file->GetSize();
|
||||
@ -526,7 +523,7 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_siz
|
||||
sys_fs.Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=0x%x, block_size=0x%x)", fd, sector_size, block_size);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
*sector_size = 4096; // ?
|
||||
@ -563,7 +560,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32
|
||||
sys_fs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=0x%x, entries_size=0x%x, data_count=0x%x)", fd, entries, entries_size, data_count);
|
||||
|
||||
std::shared_ptr<vfsDirBase> directory;
|
||||
if (!sys_fs.CheckId(fd, directory))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, directory))
|
||||
return CELL_ESRCH;
|
||||
|
||||
const DirEntryInfo* info = directory->Read();
|
||||
@ -599,7 +596,7 @@ s32 cellFsStReadInit(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
|
||||
sys_fs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=0x%x)", fd, ringbuf);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
fs_config.m_ring_buffer = *ringbuf;
|
||||
@ -624,7 +621,7 @@ s32 cellFsStReadFinish(u32 fd)
|
||||
sys_fs.Warning("cellFsStReadFinish(fd=0x%x)", fd);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
Memory.Free(fs_config.m_buffer);
|
||||
@ -638,7 +635,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
|
||||
sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=0x%x)", fd, ringbuf);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
*ringbuf = fs_config.m_ring_buffer;
|
||||
@ -653,7 +650,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
|
||||
sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=0x%x)", fd, status);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
*status = fs_config.m_fs_status;
|
||||
@ -666,7 +663,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
|
||||
sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=0x%x)", fd, regid);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
*regid = fs_config.m_regid;
|
||||
@ -679,7 +676,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
|
||||
sys_fs.Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
fs_config.m_current_addr = fs_config.m_buffer + (u32)offset;
|
||||
@ -693,7 +690,7 @@ s32 cellFsStReadStop(u32 fd)
|
||||
sys_fs.Warning("cellFsStReadStop(fd=0x%x)", fd);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
fs_config.m_fs_status = CELL_FS_ST_STOP;
|
||||
@ -706,7 +703,7 @@ s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
|
||||
sys_fs.Warning("cellFsStRead(fd=0x%x, buf=0x%x, size=0x%llx, rsize=0x%x)", fd, buf, size, rsize);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// TODO: use ringbuffer (fs_config)
|
||||
@ -725,7 +722,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<vm::ptr<u8>> addr, vm::ptr<u64> s
|
||||
sys_fs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=0x%x, size=0x%x)", fd, addr, size);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
@ -736,7 +733,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
|
||||
sys_fs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=0x%x, size=0x%llx)", fd, addr, size);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
@ -747,7 +744,7 @@ s32 cellFsStReadWait(u32 fd, u64 size)
|
||||
sys_fs.Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
@ -758,7 +755,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr<void(int xfd, u64 xsize)>
|
||||
sys_fs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=0x%x)", fd, size, func);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
@ -882,7 +879,7 @@ s32 cellFsSdataOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd,
|
||||
int ret = sdata_unpack(path, unpacked_path);
|
||||
if (ret) return ret;
|
||||
|
||||
fd = sys_fs.GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE);
|
||||
fd = Emu.GetIdManager().GetNewID(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE);
|
||||
|
||||
return CELL_OK;*/
|
||||
|
||||
@ -918,7 +915,7 @@ void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(vm::ptr<Cel
|
||||
u64 res = 0;
|
||||
{
|
||||
std::shared_ptr<vfsStream> orig_file;
|
||||
if (!sys_fs.CheckId(fd, orig_file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, orig_file))
|
||||
{
|
||||
sys_fs.Error("Wrong fd (%s)", fd);
|
||||
Emu.Pause();
|
||||
@ -969,7 +966,7 @@ s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, vm::ptr<void(vm::ptr<
|
||||
std::shared_ptr<vfsStream> orig_file;
|
||||
u32 fd = aio->fd;
|
||||
|
||||
if (!sys_fs.CheckId(fd, orig_file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, orig_file))
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
@ -1039,7 +1036,7 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type
|
||||
sys_fs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type);
|
||||
|
||||
std::shared_ptr<vfsStream> file;
|
||||
if (!sys_fs.CheckId(fd, file))
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -12,30 +12,34 @@
|
||||
|
||||
SysCallBase sys_cond("sys_cond");
|
||||
|
||||
s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribute> attr)
|
||||
s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribute_t> attr)
|
||||
{
|
||||
sys_cond.Log("sys_cond_create(cond_id_addr=0x%x, mutex_id=%d, attr_addr=0x%x)", cond_id.addr(), mutex_id, attr.addr());
|
||||
sys_cond.Warning("sys_cond_create(cond_id=*0x%x, mutex_id=%d, attr=*0x%x)", cond_id, mutex_id, attr);
|
||||
|
||||
if (attr->pshared.data() != se32(0x200))
|
||||
{
|
||||
sys_cond.Error("Unknown pshared attribute (0x%x)", attr->pshared);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<Cond> cond(new Cond(mutex, attr->name_u64));
|
||||
if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data())
|
||||
{
|
||||
sys_cond.Error("sys_cond_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const u32 id = sys_cond.GetNewId(cond, TYPE_COND);
|
||||
cond->queue.set_full_name(fmt::Format("Cond(%d, mutex_id=%d)", id, mutex_id));
|
||||
*cond_id = id;
|
||||
mutex->cond_count++; // TODO: check safety
|
||||
if (!++mutex->cond_count)
|
||||
{
|
||||
throw __FUNCTION__;
|
||||
}
|
||||
|
||||
std::shared_ptr<cond_t> cond(new cond_t(mutex, attr->name_u64));
|
||||
|
||||
*cond_id = Emu.GetIdManager().GetNewID(cond, TYPE_COND);
|
||||
|
||||
sys_cond.Warning("*** cond created [%s] (mutex_id=%d): id = %d", std::string(attr->name, 8).c_str(), mutex_id, id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -43,19 +47,27 @@ s32 sys_cond_destroy(u32 cond_id)
|
||||
{
|
||||
sys_cond.Warning("sys_cond_destroy(cond_id=%d)", cond_id);
|
||||
|
||||
std::shared_ptr<Cond> cond;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<cond_t> cond;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (cond->queue.count()) // TODO: safely make object unusable
|
||||
if (cond->waiters || cond->signaled)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
cond->mutex->cond_count--; // TODO: check safety
|
||||
if (!cond->mutex->cond_count--)
|
||||
{
|
||||
throw __FUNCTION__;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(cond_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -63,13 +75,22 @@ s32 sys_cond_signal(u32 cond_id)
|
||||
{
|
||||
sys_cond.Log("sys_cond_signal(cond_id=%d)", cond_id);
|
||||
|
||||
std::shared_ptr<Cond> cond;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<cond_t> cond;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
u32 target = cond->queue.signal(cond->mutex->protocol);
|
||||
if (cond->waiters)
|
||||
{
|
||||
cond->signaled++;
|
||||
cond->waiters--;
|
||||
cond->mutex->cv.notify_one();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -77,21 +98,19 @@ s32 sys_cond_signal_all(u32 cond_id)
|
||||
{
|
||||
sys_cond.Log("sys_cond_signal_all(cond_id=%d)", cond_id);
|
||||
|
||||
std::shared_ptr<Cond> cond;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<cond_t> cond;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
Mutex* mutex = cond->mutex.get();
|
||||
|
||||
while (u32 target = cond->queue.signal(mutex->protocol))
|
||||
if (cond->waiters)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
sys_cond.Warning("sys_cond_signal_all(id=%d) aborted", cond_id);
|
||||
break;
|
||||
}
|
||||
cond->signaled += cond->waiters.exchange(0);
|
||||
cond->mutex->cv.notify_all();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -99,9 +118,12 @@ s32 sys_cond_signal_all(u32 cond_id)
|
||||
|
||||
s32 sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
||||
{
|
||||
sys_cond.Log("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id);
|
||||
sys_cond.Todo("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id);
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<cond_t> cond;
|
||||
|
||||
std::shared_ptr<Cond> cond;
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
@ -112,10 +134,14 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (!cond->queue.signal_selected(thread_id))
|
||||
if (!cond->waiters)
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
cond->signaled++;
|
||||
cond->waiters--;
|
||||
cond->mutex->cv.notify_one();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -125,62 +151,38 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout)
|
||||
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
std::shared_ptr<Cond> cond;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<cond_t> cond;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
Mutex* mutex = cond->mutex.get();
|
||||
std::shared_ptr<CPUThread> thread = Emu.GetCPU().GetThread(CPU.GetId());
|
||||
|
||||
const u32 tid = CPU.GetId();
|
||||
if (mutex->owner.read_sync() != tid)
|
||||
if (cond->mutex->owner.owner_before(thread) || thread.owner_before(cond->mutex->owner)) // check equality
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
cond->queue.push(tid, mutex->protocol);
|
||||
// protocol is ignored in current implementation
|
||||
cond->waiters++; assert(cond->waiters > 0);
|
||||
|
||||
auto old_recursive = mutex->recursive_count.load();
|
||||
mutex->recursive_count = 0;
|
||||
if (!mutex->owner.compare_and_swap_test(tid, mutex->queue.signal(mutex->protocol)))
|
||||
{
|
||||
assert(!"sys_cond_wait() failed");
|
||||
}
|
||||
// unlock mutex
|
||||
cond->mutex->owner.reset();
|
||||
|
||||
bool pushed_in_sleep_queue = false, signaled = false;
|
||||
while (true)
|
||||
{
|
||||
if ((signaled = signaled || cond->queue.pop(tid, mutex->protocol))) // check if signaled
|
||||
{
|
||||
if (mutex->owner.compare_and_swap_test(0, tid)) // try to lock
|
||||
{
|
||||
break;
|
||||
}
|
||||
// not sure whether the recursive value is precisely saved
|
||||
const u32 recursive_value = cond->mutex->recursive_count.exchange(0);
|
||||
|
||||
if (!pushed_in_sleep_queue)
|
||||
while (!cond->mutex->owner.expired() || !cond->signaled)
|
||||
{
|
||||
mutex->queue.push(tid, mutex->protocol);
|
||||
pushed_in_sleep_queue = true;
|
||||
}
|
||||
|
||||
auto old_owner = mutex->owner.compare_and_swap(0, tid);
|
||||
if (!old_owner || old_owner == tid)
|
||||
if (!cond->signaled && timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
|
||||
if (timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
if (!cond->queue.invalidate(tid, mutex->protocol))
|
||||
{
|
||||
assert(!"sys_cond_wait() failed (timeout)");
|
||||
}
|
||||
CPU.owned_mutexes--; // ???
|
||||
return CELL_ETIMEDOUT; // mutex not locked
|
||||
// TODO: mutex not locked, timeout is possible only when signaled == 0
|
||||
cond->waiters--; assert(cond->waiters >= 0);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
@ -188,12 +190,15 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout)
|
||||
sys_cond.Warning("sys_cond_wait(id=%d) aborted", cond_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
cond->mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
if (pushed_in_sleep_queue && !mutex->queue.invalidate(tid, mutex->protocol) && !mutex->queue.pop(tid, mutex->protocol))
|
||||
{
|
||||
assert(!"sys_cond_wait() failed (locking)");
|
||||
}
|
||||
mutex->recursive_count = old_recursive;
|
||||
// restore mutex owner
|
||||
cond->mutex->owner = thread;
|
||||
cond->mutex->recursive_count = recursive_value;
|
||||
|
||||
cond->signaled--; assert(cond->signaled >= 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
struct sys_cond_attribute
|
||||
struct mutex_t;
|
||||
|
||||
struct sys_cond_attribute_t
|
||||
{
|
||||
be_t<u32> pshared;
|
||||
be_t<u64> ipc_key;
|
||||
be_t<s32> flags;
|
||||
be_t<u64> ipc_key;
|
||||
|
||||
union
|
||||
{
|
||||
char name[8];
|
||||
@ -12,14 +15,20 @@ struct sys_cond_attribute
|
||||
};
|
||||
};
|
||||
|
||||
struct Cond
|
||||
struct cond_t
|
||||
{
|
||||
std::shared_ptr<Mutex> mutex; // associated with mutex
|
||||
sleep_queue_t queue;
|
||||
const u64 name;
|
||||
const std::shared_ptr<mutex_t> mutex; // associated mutex
|
||||
|
||||
Cond(std::shared_ptr<Mutex>& mutex, u64 name)
|
||||
// TODO: use sleep queue
|
||||
std::atomic<s32> waiters;
|
||||
std::atomic<s32> signaled;
|
||||
|
||||
cond_t(std::shared_ptr<mutex_t>& mutex, u64 name)
|
||||
: mutex(mutex)
|
||||
, queue(name)
|
||||
, name(name)
|
||||
, waiters(0)
|
||||
, signaled(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -27,7 +36,7 @@ struct Cond
|
||||
class PPUThread;
|
||||
|
||||
// SysCalls
|
||||
s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribute> attr);
|
||||
s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribute_t> attr);
|
||||
s32 sys_cond_destroy(u32 cond_id);
|
||||
s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout);
|
||||
s32 sys_cond_signal(u32 cond_id);
|
||||
|
@ -18,7 +18,7 @@ u32 event_queue_create(u32 protocol, s32 type, u64 name_u64, u64 event_queue_key
|
||||
|
||||
Emu.GetEventManager().RegisterKey(queue, event_queue_key);
|
||||
|
||||
return sys_event.GetNewId(queue, TYPE_EVENT_QUEUE);
|
||||
return Emu.GetIdManager().GetNewID(queue, TYPE_EVENT_QUEUE);
|
||||
}
|
||||
|
||||
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr> attr, u64 event_queue_key, s32 size)
|
||||
@ -35,10 +35,10 @@ s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr>
|
||||
switch (protocol)
|
||||
{
|
||||
case SYS_SYNC_PRIORITY: break;
|
||||
case SYS_SYNC_RETRY: sys_event.Error("Invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL;
|
||||
case SYS_SYNC_PRIORITY_INHERIT: sys_event.Error("Invalid protocol (SYS_SYNC_PRIORITY_INHERIT)"); return CELL_EINVAL;
|
||||
case SYS_SYNC_RETRY: sys_event.Error("sys_event_queue_create(): invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL;
|
||||
case SYS_SYNC_PRIORITY_INHERIT: sys_event.Error("sys_event_queue_create(): invalid protocol (SYS_SYNC_PRIORITY_INHERIT)"); return CELL_EINVAL;
|
||||
case SYS_SYNC_FIFO: break;
|
||||
default: sys_event.Error("Unknown protocol (0x%x)", protocol); return CELL_EINVAL;
|
||||
default: sys_event.Error("sys_event_queue_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const u32 type = attr->type;
|
||||
@ -47,7 +47,7 @@ s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr>
|
||||
{
|
||||
case SYS_PPU_QUEUE: break;
|
||||
case SYS_SPU_QUEUE: break;
|
||||
default: sys_event.Error("Unknown event queue type (0x%x)", type); return CELL_EINVAL;
|
||||
default: sys_event.Error("sys_event_queue_create(): unknown type (0x%x)", type); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
LV2_LOCK;
|
||||
@ -64,7 +64,7 @@ s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr>
|
||||
return CELL_EAGAIN;
|
||||
}
|
||||
|
||||
*equeue_id = sys_event.GetNewId(queue, TYPE_EVENT_QUEUE);
|
||||
*equeue_id = Emu.GetIdManager().GetNewID(queue, TYPE_EVENT_QUEUE);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -170,22 +170,19 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr<sys_event_t>
|
||||
}
|
||||
|
||||
// protocol is ignored in current implementation
|
||||
queue->waiters++;
|
||||
assert(queue->waiters > 0);
|
||||
queue->waiters++; assert(queue->waiters > 0);
|
||||
|
||||
while (queue->events.empty())
|
||||
{
|
||||
if (queue->waiters < 0)
|
||||
{
|
||||
queue->waiters--;
|
||||
assert(queue->waiters < 0);
|
||||
queue->waiters--; assert(queue->waiters < 0);
|
||||
return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
if (timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
queue->waiters--;
|
||||
assert(queue->waiters >= 0);
|
||||
queue->waiters--; assert(queue->waiters >= 0);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -206,8 +203,7 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr<sys_event_t>
|
||||
CPU.GPR[7] = event.data3;
|
||||
|
||||
queue->events.pop_front();
|
||||
queue->waiters--;
|
||||
assert(queue->waiters >= 0);
|
||||
queue->waiters--; assert(queue->waiters >= 0);
|
||||
|
||||
if (queue->events.size())
|
||||
{
|
||||
@ -239,7 +235,7 @@ u32 event_port_create(u64 name)
|
||||
{
|
||||
std::shared_ptr<event_port_t> eport(new event_port_t(SYS_EVENT_PORT_LOCAL, name));
|
||||
|
||||
return sys_event.GetNewId(eport, TYPE_EVENT_PORT);
|
||||
return Emu.GetIdManager().GetNewID(eport, TYPE_EVENT_PORT);
|
||||
}
|
||||
|
||||
s32 sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name)
|
||||
@ -256,7 +252,7 @@ s32 sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name)
|
||||
|
||||
std::shared_ptr<event_port_t> eport(new event_port_t(port_type, name));
|
||||
|
||||
*eport_id = sys_event.GetNewId(eport, TYPE_EVENT_PORT);
|
||||
*eport_id = Emu.GetIdManager().GetNewID(eport, TYPE_EVENT_PORT);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -27,15 +27,15 @@ s32 sys_event_flag_create(vm::ptr<u32> id, vm::ptr<sys_event_flag_attr> attr, u6
|
||||
switch (protocol)
|
||||
{
|
||||
case SYS_SYNC_PRIORITY: break;
|
||||
case SYS_SYNC_RETRY: sys_event_flag.Todo("SYS_SYNC_RETRY"); break;
|
||||
case SYS_SYNC_PRIORITY_INHERIT: sys_event_flag.Todo("SYS_SYNC_PRIORITY_INHERIT"); break;
|
||||
case SYS_SYNC_RETRY: sys_event_flag.Todo("sys_event_flag_create(): SYS_SYNC_RETRY"); break;
|
||||
case SYS_SYNC_PRIORITY_INHERIT: sys_event_flag.Todo("sys_event_flag_create(): SYS_SYNC_PRIORITY_INHERIT"); break;
|
||||
case SYS_SYNC_FIFO: break;
|
||||
default: sys_event_flag.Error("Unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL;
|
||||
default: sys_event_flag.Error("sys_event_flag_create(): unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (attr->pshared.data() != se32(0x200))
|
||||
if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data())
|
||||
{
|
||||
sys_event_flag.Error("Unknown pshared attribute (0x%x)", attr->pshared);
|
||||
sys_event_flag.Error("sys_event_flag_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
@ -45,12 +45,12 @@ s32 sys_event_flag_create(vm::ptr<u32> id, vm::ptr<sys_event_flag_attr> attr, u6
|
||||
{
|
||||
case SYS_SYNC_WAITER_SINGLE: break;
|
||||
case SYS_SYNC_WAITER_MULTIPLE: break;
|
||||
default: sys_event_flag.Error("Unknown event flag type (0x%x)", attr->type); return CELL_EINVAL;
|
||||
default: sys_event_flag.Error("sys_event_flag_create(): unknown type (0x%x)", attr->type); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_flag_t> ef(new event_flag_t(init, protocol, type, attr->name_u64));
|
||||
|
||||
*id = sys_event_flag.GetNewId(ef, TYPE_EVENT_FLAG);
|
||||
*id = Emu.GetIdManager().GetNewID(ef, TYPE_EVENT_FLAG);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -151,15 +151,19 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr<u64> result, u64 t
|
||||
|
||||
if (ef->waiters <= 0)
|
||||
{
|
||||
ef->waiters++;
|
||||
assert(ef->waiters <= 0);
|
||||
ef->waiters++; assert(ef->waiters <= 0);
|
||||
|
||||
if (!ef->waiters)
|
||||
{
|
||||
ef->cv.notify_all();
|
||||
}
|
||||
|
||||
return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
if (timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
ef->waiters--;
|
||||
assert(ef->waiters >= 0);
|
||||
ef->waiters--; assert(ef->waiters >= 0);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -182,8 +186,7 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr<u64> result, u64 t
|
||||
ef->flags = 0;
|
||||
}
|
||||
|
||||
ef->waiters--;
|
||||
assert(ef->waiters >= 0);
|
||||
ef->waiters--; assert(ef->waiters >= 0);
|
||||
|
||||
if (ef->flags)
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u64 intrthread,
|
||||
};
|
||||
}
|
||||
|
||||
*ih = sys_interrupt.GetNewId(handler, TYPE_INTR_SERVICE_HANDLE);
|
||||
*ih = Emu.GetIdManager().GetNewID(handler, TYPE_INTR_SERVICE_HANDLE);
|
||||
ppu.Exec();
|
||||
|
||||
return CELL_OK;
|
||||
@ -132,7 +132,7 @@ s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr<u64> r13)
|
||||
sys_interrupt.Todo("_sys_interrupt_thread_disestablish(ih=%d)", ih);
|
||||
|
||||
std::shared_ptr<interrupt_handler_t> handler;
|
||||
if (!sys_interrupt.CheckId(ih, handler))
|
||||
if (!Emu.GetIdManager().GetIDData(ih, handler))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ s32 lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name_u64)
|
||||
|
||||
std::shared_ptr<Lwcond> lw(new Lwcond(name_u64, addr));
|
||||
|
||||
const u32 id = sys_lwcond.GetNewId(lw, TYPE_LWCOND);
|
||||
const u32 id = Emu.GetIdManager().GetNewID(lw, TYPE_LWCOND);
|
||||
|
||||
lw->queue.set_full_name(fmt::Format("Lwcond(%d, addr=0x%x)", id, lw->addr));
|
||||
lwcond.lwmutex.set(addr);
|
||||
|
@ -19,7 +19,7 @@ s32 lwmutex_create(sys_lwmutex_t& lwmutex, u32 protocol, u32 recursive, u64 name
|
||||
lwmutex.waiter.write_relaxed(be_t<u32>::make(~0));
|
||||
lwmutex.attribute = protocol | recursive;
|
||||
lwmutex.recursive_count.write_relaxed(be_t<u32>::make(0));
|
||||
u32 sq_id = sys_lwmutex.GetNewId(sq, TYPE_LWMUTEX);
|
||||
u32 sq_id = Emu.GetIdManager().GetNewID(sq, TYPE_LWMUTEX);
|
||||
lwmutex.sleep_queue = sq_id;
|
||||
sq->set_full_name(fmt::Format("Lwmutex(%d, addr=0x%x)", sq_id, vm::get_addr(&lwmutex)));
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
@ -44,7 +45,7 @@ s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_a
|
||||
|
||||
// Check if this container ID is valid.
|
||||
std::shared_ptr<MemoryContainerInfo> ct;
|
||||
if (!sys_memory.CheckId(cid, ct))
|
||||
if (!Emu.GetIdManager().GetIDData(cid, ct))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Check page size.
|
||||
@ -120,7 +121,7 @@ s32 sys_memory_container_create(vm::ptr<u32> cid, u32 yield_size)
|
||||
|
||||
// Wrap the allocated memory in a memory container.
|
||||
std::shared_ptr<MemoryContainerInfo> ct(new MemoryContainerInfo(addr, yield_size));
|
||||
u32 id = sys_memory.GetNewId(ct, TYPE_MEM);
|
||||
u32 id = Emu.GetIdManager().GetNewID(ct, TYPE_MEM);
|
||||
*cid = id;
|
||||
|
||||
sys_memory.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, id);
|
||||
@ -134,12 +135,12 @@ s32 sys_memory_container_destroy(u32 cid)
|
||||
|
||||
// Check if this container ID is valid.
|
||||
std::shared_ptr<MemoryContainerInfo> ct;
|
||||
if (!sys_memory.CheckId(cid, ct))
|
||||
if (!Emu.GetIdManager().GetIDData(cid, ct))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Release the allocated memory and remove the ID.
|
||||
Memory.Free(ct->addr);
|
||||
sys_memory.RemoveId(cid);
|
||||
Emu.GetIdManager().RemoveID(cid);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -150,7 +151,7 @@ s32 sys_memory_container_get_size(vm::ptr<sys_memory_info_t> mem_info, u32 cid)
|
||||
|
||||
// Check if this container ID is valid.
|
||||
std::shared_ptr<MemoryContainerInfo> ct;
|
||||
if (!sys_memory.CheckId(cid, ct))
|
||||
if (!Emu.GetIdManager().GetIDData(cid, ct))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// HACK: Return all memory.
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
@ -76,7 +77,7 @@ s32 sys_mmapper_allocate_memory(u32 size, u64 flags, vm::ptr<u32> mem_id)
|
||||
|
||||
// Generate a new mem ID.
|
||||
std::shared_ptr<mmapper_info> info(new mmapper_info(size, flags));
|
||||
*mem_id = sys_mmapper.GetNewId(info);
|
||||
*mem_id = Emu.GetIdManager().GetNewID(info);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -88,7 +89,7 @@ s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm:
|
||||
|
||||
// Check if this container ID is valid.
|
||||
std::shared_ptr<MemoryContainerInfo> ct;
|
||||
if(!sys_mmapper.CheckId(cid, ct))
|
||||
if(!Emu.GetIdManager().GetIDData(cid, ct))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Check page granularity.
|
||||
@ -112,7 +113,7 @@ s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm:
|
||||
|
||||
// Generate a new mem ID.
|
||||
std::shared_ptr<mmapper_info> info(new mmapper_info(ct->size, flags));
|
||||
*mem_id = sys_mmapper.GetNewId(info, TYPE_MEM);
|
||||
*mem_id = Emu.GetIdManager().GetNewID(info, TYPE_MEM);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -141,11 +142,11 @@ s32 sys_mmapper_free_memory(u32 mem_id)
|
||||
|
||||
// Check if this mem ID is valid.
|
||||
std::shared_ptr<mmapper_info> info;
|
||||
if(!sys_mmapper.CheckId(mem_id, info))
|
||||
if(!Emu.GetIdManager().GetIDData(mem_id, info))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Release the allocated memory and remove the ID.
|
||||
sys_mmapper.RemoveId(mem_id);
|
||||
Emu.GetIdManager().RemoveID(mem_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -156,7 +157,7 @@ s32 sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
|
||||
|
||||
// Check if this mem ID is valid.
|
||||
std::shared_ptr<mmapper_info> info;
|
||||
if(!sys_mmapper.CheckId(mem_id, info))
|
||||
if(!Emu.GetIdManager().GetIDData(mem_id, info))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Map the memory into the process address.
|
||||
@ -176,7 +177,7 @@ s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_
|
||||
|
||||
// Check if this mem ID is valid.
|
||||
std::shared_ptr<mmapper_info> info;
|
||||
if(!sys_mmapper.CheckId(mem_id, info))
|
||||
if(!Emu.GetIdManager().GetIDData(mem_id, info))
|
||||
return CELL_ESRCH;
|
||||
|
||||
// Search for a mappable address.
|
||||
|
@ -11,143 +11,124 @@
|
||||
|
||||
SysCallBase sys_mutex("sys_mutex");
|
||||
|
||||
Mutex::~Mutex()
|
||||
s32 sys_mutex_create(vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute_t> attr)
|
||||
{
|
||||
if (u32 tid = owner.read_sync())
|
||||
sys_mutex.Warning("sys_mutex_create(mutex_id=*0x%x, attr=*0x%x)", mutex_id, attr);
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
if (!mutex_id || !attr)
|
||||
{
|
||||
sys_mutex.Notice("Mutex(%d) was owned by thread %d (recursive=%d)", id.read_relaxed(), tid, recursive_count.load());
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (u32 count = queue.count())
|
||||
{
|
||||
sys_mutex.Notice("Mutex(%d) was waited by %d threads", id.read_relaxed(), count);
|
||||
}
|
||||
}
|
||||
const u32 protocol = attr->protocol;
|
||||
|
||||
s32 sys_mutex_create(PPUThread& CPU, vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute> attr)
|
||||
{
|
||||
sys_mutex.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.addr(), attr.addr());
|
||||
|
||||
switch (attr->protocol.data())
|
||||
switch (protocol)
|
||||
{
|
||||
case se32(SYS_SYNC_FIFO): break;
|
||||
case se32(SYS_SYNC_PRIORITY): break;
|
||||
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mutex.Todo("SYS_SYNC_PRIORITY_INHERIT"); break;
|
||||
case se32(SYS_SYNC_RETRY): sys_mutex.Error("Invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL;
|
||||
default: sys_mutex.Error("Unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL;
|
||||
case SYS_SYNC_FIFO: break;
|
||||
case SYS_SYNC_PRIORITY: break;
|
||||
case SYS_SYNC_PRIORITY_INHERIT: sys_mutex.Todo("sys_mutex_create(): SYS_SYNC_PRIORITY_INHERIT"); break;
|
||||
case SYS_SYNC_RETRY: sys_mutex.Error("sys_mutex_create(): invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL;
|
||||
default: sys_mutex.Error("sys_mutex_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
bool is_recursive;
|
||||
switch (attr->recursive.data())
|
||||
{
|
||||
case se32(SYS_SYNC_RECURSIVE): is_recursive = true; break;
|
||||
case se32(SYS_SYNC_NOT_RECURSIVE): is_recursive = false; break;
|
||||
default: sys_mutex.Error("Unknown recursive attribute (0x%x)", attr->recursive); return CELL_EINVAL;
|
||||
}
|
||||
const bool recursive = attr->recursive.data() == se32(SYS_SYNC_RECURSIVE);
|
||||
|
||||
if (attr->pshared.data() != se32(0x200))
|
||||
if ((!recursive && attr->recursive.data() != se32(SYS_SYNC_NOT_RECURSIVE)) || attr->pshared.data() != se32(0x200) || attr->adaptive.data() != se32(0x2000) || attr->ipc_key.data() || attr->flags.data())
|
||||
{
|
||||
sys_mutex.Error("Unknown pshared attribute (0x%x)", attr->pshared);
|
||||
sys_mutex.Error("sys_mutex_create(): unknown attributes (recursive=0x%x, pshared=0x%x, adaptive=0x%x, ipc_key=0x%llx, flags=0x%x)",
|
||||
attr->recursive, attr->pshared, attr->adaptive, attr->ipc_key, attr->flags);
|
||||
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<Mutex> mutex(new Mutex(attr->protocol, is_recursive, attr->name_u64));
|
||||
std::shared_ptr<mutex_t> mutex(new mutex_t(recursive, protocol, attr->name_u64));
|
||||
|
||||
const u32 id = sys_mutex.GetNewId(mutex, TYPE_MUTEX);
|
||||
mutex->id.exchange(id);
|
||||
*mutex_id = id;
|
||||
mutex->queue.set_full_name(fmt::Format("Mutex(%d)", id));
|
||||
*mutex_id = Emu.GetIdManager().GetNewID(mutex, TYPE_MUTEX);
|
||||
|
||||
sys_mutex.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", std::string(attr->name, 8).c_str(), attr->protocol, is_recursive, id);
|
||||
// TODO: unlock mutex when owner thread does exit
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id)
|
||||
s32 sys_mutex_destroy(u32 mutex_id)
|
||||
{
|
||||
sys_mutex.Warning("sys_mutex_destroy(mutex_id=%d)", mutex_id);
|
||||
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
// check if associated condition variable exists
|
||||
if (mutex->cond_count) // TODO: check safety
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
if (!mutex->owner.compare_and_swap_test(0, ~0)) // check if locked and make unusable
|
||||
if (!mutex->owner.expired())
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
// assuming that the mutex is locked immediately by another waiting thread when unlocked
|
||||
if (mutex->waiters)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
if (mutex->cond_count)
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(mutex_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout)
|
||||
{
|
||||
sys_mutex.Log("sys_mutex_lock(mutex_id=%d, timeout=%lld)", mutex_id, timeout);
|
||||
sys_mutex.Log("sys_mutex_lock(mutex_id=%d, timeout=0x%llx)", mutex_id, timeout);
|
||||
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
const u32 tid = CPU.GetId();
|
||||
std::shared_ptr<CPUThread> thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU);
|
||||
|
||||
const u32 old_owner = mutex->owner.compare_and_swap(0, tid);
|
||||
if (!~old_owner)
|
||||
if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality
|
||||
{
|
||||
return CELL_ESRCH; // mutex is going to be destroyed
|
||||
}
|
||||
if (old_owner == tid)
|
||||
if (mutex->recursive)
|
||||
{
|
||||
if (mutex->is_recursive)
|
||||
{
|
||||
if (!~mutex->recursive_count)
|
||||
if (mutex->recursive_count == 0xffffffffu)
|
||||
{
|
||||
return CELL_EKRESOURCE;
|
||||
}
|
||||
mutex->recursive_count++;
|
||||
|
||||
if (!mutex->recursive_count++)
|
||||
{
|
||||
throw __FUNCTION__;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return CELL_EDEADLK;
|
||||
}
|
||||
}
|
||||
else if (!old_owner)
|
||||
|
||||
// protocol is ignored in current implementation
|
||||
mutex->waiters++; assert(mutex->waiters > 0);
|
||||
|
||||
while (!mutex->owner.expired())
|
||||
{
|
||||
mutex->recursive_count = 1;
|
||||
CPU.owned_mutexes++;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
mutex->queue.push(tid, mutex->protocol);
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto old_owner = mutex->owner.compare_and_swap(0, tid);
|
||||
if (!old_owner || old_owner == tid)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
|
||||
if (timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
if (!mutex->queue.invalidate(tid, mutex->protocol))
|
||||
{
|
||||
assert(!"sys_mutex_lock() failed (timeout)");
|
||||
}
|
||||
mutex->waiters--; assert(mutex->waiters >= 0);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -156,14 +137,14 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout)
|
||||
sys_mutex.Warning("sys_mutex_lock(id=%d) aborted", mutex_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
if (!mutex->queue.invalidate(tid, mutex->protocol) && !mutex->queue.pop(tid, mutex->protocol))
|
||||
{
|
||||
assert(!"sys_mutex_lock() failed (locking)");
|
||||
}
|
||||
mutex->owner = thread;
|
||||
mutex->recursive_count = 1;
|
||||
CPU.owned_mutexes++;
|
||||
mutex->waiters--; assert(mutex->waiters >= 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -171,80 +152,78 @@ s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id)
|
||||
{
|
||||
sys_mutex.Log("sys_mutex_trylock(mutex_id=%d)", mutex_id);
|
||||
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
const u32 tid = CPU.GetId();
|
||||
std::shared_ptr<CPUThread> thread = Emu.GetCPU().GetThread(CPU.GetId());
|
||||
|
||||
const u32 old_owner = mutex->owner.compare_and_swap(0, tid);
|
||||
if (!~old_owner)
|
||||
if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality
|
||||
{
|
||||
return CELL_ESRCH; // mutex is going to be destroyed
|
||||
}
|
||||
if (old_owner == tid)
|
||||
if (mutex->recursive)
|
||||
{
|
||||
if (mutex->is_recursive)
|
||||
{
|
||||
if (!~mutex->recursive_count)
|
||||
if (mutex->recursive_count == 0xffffffffu)
|
||||
{
|
||||
return CELL_EKRESOURCE;
|
||||
}
|
||||
mutex->recursive_count++;
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
|
||||
if (!mutex->recursive_count++)
|
||||
{
|
||||
return CELL_EDEADLK;
|
||||
throw __FUNCTION__;
|
||||
}
|
||||
}
|
||||
else if (!old_owner)
|
||||
{
|
||||
mutex->recursive_count = 1;
|
||||
CPU.owned_mutexes++;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
return CELL_EDEADLK;
|
||||
}
|
||||
|
||||
if (!mutex->owner.expired())
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
mutex->owner = thread;
|
||||
mutex->recursive_count = 1;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id)
|
||||
{
|
||||
sys_mutex.Log("sys_mutex_unlock(mutex_id=%d)", mutex_id);
|
||||
|
||||
std::shared_ptr<Mutex> mutex;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
const u32 tid = CPU.GetId();
|
||||
std::shared_ptr<CPUThread> thread = Emu.GetCPU().GetThread(CPU.GetId());
|
||||
|
||||
const u32 owner = mutex->owner.read_sync();
|
||||
if (!~owner)
|
||||
{
|
||||
return CELL_ESRCH; // mutex is going to be destroyed
|
||||
}
|
||||
if (owner != tid)
|
||||
if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check equality
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
if (!mutex->recursive_count || (mutex->recursive_count != 1 && !mutex->is_recursive))
|
||||
if (!mutex->recursive_count || (!mutex->recursive && mutex->recursive_count != 1))
|
||||
{
|
||||
sys_mutex.Error("sys_mutex_unlock(%d): wrong recursive value fixed (%d)", mutex_id, mutex->recursive_count.load());
|
||||
mutex->recursive_count = 1;
|
||||
throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (!--mutex->recursive_count)
|
||||
{
|
||||
if (!mutex->owner.compare_and_swap_test(tid, mutex->queue.signal(mutex->protocol)))
|
||||
{
|
||||
assert(!"sys_mutex_unlock() failed");
|
||||
}
|
||||
CPU.owned_mutexes--;
|
||||
mutex->owner.reset();
|
||||
mutex->cv.notify_one();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
struct sys_mutex_attribute
|
||||
struct sys_mutex_attribute_t
|
||||
{
|
||||
be_t<u32> protocol; // SYS_SYNC_FIFO, SYS_SYNC_PRIORITY or SYS_SYNC_PRIORITY_INHERIT
|
||||
be_t<u32> recursive; // SYS_SYNC_RECURSIVE or SYS_SYNC_NOT_RECURSIVE
|
||||
be_t<u32> pshared; // always 0x200 (not shared)
|
||||
be_t<u32> pshared;
|
||||
be_t<u32> adaptive;
|
||||
be_t<u64> ipc_key;
|
||||
be_t<s32> flags;
|
||||
be_t<u32> pad;
|
||||
|
||||
union
|
||||
{
|
||||
char name[8];
|
||||
@ -16,34 +17,36 @@ struct sys_mutex_attribute
|
||||
};
|
||||
};
|
||||
|
||||
struct Mutex
|
||||
struct mutex_t
|
||||
{
|
||||
atomic_le_t<u32> id;
|
||||
atomic_le_t<u32> owner;
|
||||
std::atomic<u32> recursive_count; // recursive locks count
|
||||
std::atomic<u32> cond_count; // count of condition variables associated
|
||||
sleep_queue_t queue;
|
||||
|
||||
const bool recursive;
|
||||
const u32 protocol;
|
||||
const bool is_recursive;
|
||||
const u64 name;
|
||||
|
||||
Mutex(u32 protocol, bool is_recursive, u64 name)
|
||||
: protocol(protocol)
|
||||
, is_recursive(is_recursive)
|
||||
, queue(name)
|
||||
std::atomic<u32> cond_count; // count of condition variables associated
|
||||
std::atomic<u32> recursive_count;
|
||||
std::weak_ptr<CPUThread> owner;
|
||||
|
||||
// TODO: use sleep queue, possibly remove condition variable
|
||||
std::condition_variable cv;
|
||||
std::atomic<s32> waiters;
|
||||
|
||||
mutex_t(bool recursive, u32 protocol, u64 name)
|
||||
: recursive(recursive)
|
||||
, protocol(protocol)
|
||||
, name(name)
|
||||
, cond_count(0)
|
||||
, recursive_count(0)
|
||||
, waiters(0)
|
||||
{
|
||||
owner.write_relaxed(0);
|
||||
}
|
||||
|
||||
~Mutex();
|
||||
};
|
||||
|
||||
class PPUThread;
|
||||
|
||||
// SysCalls
|
||||
s32 sys_mutex_create(PPUThread& CPU, vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute> attr);
|
||||
s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id);
|
||||
s32 sys_mutex_create(vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute_t> attr);
|
||||
s32 sys_mutex_destroy(u32 mutex_id);
|
||||
s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout);
|
||||
s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id);
|
||||
s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id);
|
||||
|
@ -39,7 +39,7 @@ s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_loa
|
||||
// Load the PRX into memory
|
||||
f.Read(vm::get_ptr(prx->address), prx->size);
|
||||
|
||||
u32 id = sys_prx.GetNewId(prx, TYPE_PRX);
|
||||
u32 id = Emu.GetIdManager().GetNewID(prx, TYPE_PRX);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ s32 sys_rwlock_create(vm::ptr<u32> rw_lock_id, vm::ptr<sys_rwlock_attribute_t> a
|
||||
}
|
||||
|
||||
std::shared_ptr<RWLock> rw(new RWLock(attr->protocol, attr->name_u64));
|
||||
const u32 id = sys_rwlock.GetNewId(rw, TYPE_RWLOCK);
|
||||
const u32 id = Emu.GetIdManager().GetNewID(rw, TYPE_RWLOCK);
|
||||
*rw_lock_id = id;
|
||||
rw->wqueue.set_full_name(fmt::Format("Rwlock(%d)", id));
|
||||
|
||||
@ -49,7 +49,7 @@ s32 sys_rwlock_destroy(u32 rw_lock_id)
|
||||
sys_rwlock.Warning("sys_rwlock_destroy(rw_lock_id=%d)", rw_lock_id);
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -70,7 +70,7 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -114,7 +114,7 @@ s32 sys_rwlock_tryrlock(u32 rw_lock_id)
|
||||
sys_rwlock.Log("sys_rwlock_tryrlock(rw_lock_id=%d)", rw_lock_id);
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -142,7 +142,7 @@ s32 sys_rwlock_runlock(u32 rw_lock_id)
|
||||
sys_rwlock.Log("sys_rwlock_runlock(rw_lock_id=%d)", rw_lock_id);
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -172,7 +172,7 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout)
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -229,7 +229,7 @@ s32 sys_rwlock_trywlock(PPUThread& CPU, u32 rw_lock_id)
|
||||
sys_rwlock.Log("sys_rwlock_trywlock(rw_lock_id=%d)", rw_lock_id);
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -254,7 +254,7 @@ s32 sys_rwlock_wunlock(PPUThread& CPU, u32 rw_lock_id)
|
||||
sys_rwlock.Log("sys_rwlock_wunlock(rw_lock_id=%d)", rw_lock_id);
|
||||
|
||||
std::shared_ptr<RWLock> rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw))
|
||||
if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ u32 semaphore_create(s32 initial_count, s32 max_count, u32 protocol, u64 name_u6
|
||||
{
|
||||
std::shared_ptr<Semaphore> sem(new Semaphore(initial_count, max_count, protocol, name_u64));
|
||||
|
||||
const u32 id = sys_semaphore.GetNewId(sem, TYPE_SEMAPHORE);
|
||||
const u32 id = Emu.GetIdManager().GetNewID(sem, TYPE_SEMAPHORE);
|
||||
sem->queue.set_full_name(fmt::Format("Semaphore(%d)", id));
|
||||
|
||||
sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol, id);
|
||||
|
@ -221,7 +221,7 @@ u32 spu_thread_group_create(const std::string& name, u32 num, s32 prio, s32 type
|
||||
|
||||
std::shared_ptr<spu_group_t> group(new spu_group_t(name, num, prio, type, container));
|
||||
|
||||
return sys_spu.GetNewId(group);
|
||||
return Emu.GetIdManager().GetNewID(group);
|
||||
}
|
||||
|
||||
s32 sys_spu_thread_group_create(vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_spu_thread_group_attribute> attr)
|
||||
|
@ -13,7 +13,7 @@ s32 sys_timer_create(vm::ptr<u32> timer_id)
|
||||
sys_timer.Warning("sys_timer_create(timer_id_addr=0x%x)", timer_id.addr());
|
||||
|
||||
std::shared_ptr<timer> timer_data(new timer);
|
||||
*timer_id = sys_timer.GetNewId(timer_data, TYPE_TIMER);
|
||||
*timer_id = Emu.GetIdManager().GetNewID(timer_data, TYPE_TIMER);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ s32 sys_timer_destroy(u32 timer_id)
|
||||
{
|
||||
sys_timer.Todo("sys_timer_destroy(timer_id=%d)", timer_id);
|
||||
|
||||
if(!sys_timer.CheckId(timer_id)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().CheckID(timer_id)) return CELL_ESRCH;
|
||||
|
||||
Emu.GetIdManager().RemoveID(timer_id);
|
||||
return CELL_OK;
|
||||
@ -32,7 +32,7 @@ s32 sys_timer_get_information(u32 timer_id, vm::ptr<sys_timer_information_t> inf
|
||||
sys_timer.Warning("sys_timer_get_information(timer_id=%d, info_addr=0x%x)", timer_id, info.addr());
|
||||
|
||||
std::shared_ptr<timer> timer_data = nullptr;
|
||||
if(!sys_timer.CheckId(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
||||
|
||||
*info = timer_data->timer_information_t;
|
||||
return CELL_OK;
|
||||
@ -43,7 +43,7 @@ s32 sys_timer_start(u32 timer_id, s64 base_time, u64 period)
|
||||
sys_timer.Warning("sys_timer_start_periodic_absolute(timer_id=%d, basetime=%lld, period=%lld)", timer_id, base_time, period);
|
||||
|
||||
std::shared_ptr<timer> timer_data = nullptr;
|
||||
if(!sys_timer.CheckId(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
||||
|
||||
if(timer_data->timer_information_t.timer_state != SYS_TIMER_STATE_STOP) return CELL_EBUSY;
|
||||
if(period < 100) return CELL_EINVAL;
|
||||
@ -67,7 +67,7 @@ s32 sys_timer_stop(u32 timer_id)
|
||||
sys_timer.Todo("sys_timer_stop()");
|
||||
|
||||
std::shared_ptr<timer> timer_data = nullptr;
|
||||
if(!sys_timer.CheckId(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
||||
|
||||
timer_data->timer_information_t.timer_state = SYS_TIMER_STATE_STOP;
|
||||
return CELL_OK;
|
||||
@ -80,8 +80,8 @@ s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data
|
||||
|
||||
std::shared_ptr<timer> timer_data = nullptr;
|
||||
std::shared_ptr<event_queue_t> equeue = nullptr;
|
||||
if(!sys_timer.CheckId(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!sys_timer.CheckId(queue_id, equeue)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(queue_id, equeue)) return CELL_ESRCH;
|
||||
|
||||
//TODO: ?
|
||||
|
||||
@ -93,7 +93,7 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id)
|
||||
sys_timer.Todo("sys_timer_disconnect_event_queue(timer_id=%d)", timer_id);
|
||||
|
||||
std::shared_ptr<timer> timer_data = nullptr;
|
||||
if(!sys_timer.CheckId(timer_id, timer_data)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
||||
|
||||
//TODO: ?
|
||||
|
||||
|
@ -39,7 +39,7 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a
|
||||
{
|
||||
// Check memory container.
|
||||
std::shared_ptr<MemoryContainerInfo> ct;
|
||||
if(!sys_vm.CheckId(cid, ct)) return CELL_ESRCH;
|
||||
if(!Emu.GetIdManager().GetIDData(cid, ct)) return CELL_ESRCH;
|
||||
|
||||
current_ct = ct;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user