mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-24 11:43:05 +01:00
cellSpurs draft added
This commit is contained in:
parent
3a00ec7682
commit
1c302433af
@ -53,6 +53,8 @@ u32 adecOpen(AudioDecoder* data)
|
||||
|
||||
adec.id = adec_id;
|
||||
|
||||
adec.adecCb->SetName("Audio Decoder[" + std::to_string(adec_id) + "] Callback");
|
||||
|
||||
thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]()
|
||||
{
|
||||
ConLog.Write("Audio Decoder enter()");
|
||||
|
@ -18,9 +18,9 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t<CellCodecEsFi
|
||||
const u32 esSpecificInfo_addr, mem_ptr_t<CellDmuxEsAttr> attr)
|
||||
{
|
||||
if (esFilterId->filterIdMajor >= 0xe0)
|
||||
attr->memSize = 0x2000000; // 0x45fa49 from ps3
|
||||
attr->memSize = 0x1000000; // 0x45fa49 from ps3
|
||||
else
|
||||
attr->memSize = 0x100000; // 0x73d9 from ps3
|
||||
attr->memSize = 0x200000; // 0x73d9 from ps3
|
||||
|
||||
cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor,
|
||||
(u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2);
|
||||
@ -36,6 +36,8 @@ u32 dmuxOpen(Demuxer* data)
|
||||
|
||||
dmux.id = dmux_id;
|
||||
|
||||
dmux.dmuxCb->SetName("Demuxer[" + std::to_string(dmux_id) + "] Callback");
|
||||
|
||||
thread t("Demuxer[" + std::to_string(dmux_id) + "] Thread", [&]()
|
||||
{
|
||||
ConLog.Write("Demuxer enter (mem=0x%x, size=0x%x, cb=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc, dmux.cbArg);
|
||||
@ -80,8 +82,8 @@ u32 dmuxOpen(Demuxer* data)
|
||||
cb.SetAddr(dmux.cbFunc);
|
||||
cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
|
||||
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
|
||||
//dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
|
||||
//updates_signaled++;
|
||||
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
|
||||
updates_signaled++;
|
||||
}
|
||||
else switch (code.ToLE())
|
||||
{
|
||||
@ -146,6 +148,12 @@ u32 dmuxOpen(Demuxer* data)
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
/*if (es.hasunseen()) // hack, probably useless
|
||||
{
|
||||
stream = backup;
|
||||
continue;
|
||||
}*/
|
||||
|
||||
//ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts);
|
||||
|
||||
es.push(stream, len - pes.size - 3, pes);
|
||||
@ -365,11 +373,11 @@ u32 dmuxOpen(Demuxer* data)
|
||||
}
|
||||
break;
|
||||
|
||||
case dmuxReleaseAu:
|
||||
/*case dmuxReleaseAu:
|
||||
{
|
||||
task.es.es_ptr->release();
|
||||
}
|
||||
break;
|
||||
break;*/
|
||||
|
||||
case dmuxFlushEs:
|
||||
{
|
||||
@ -584,18 +592,7 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize
|
||||
return CELL_DMUX_ERROR_FATAL;
|
||||
}
|
||||
|
||||
if (dmux->is_running) // maximum hack
|
||||
{
|
||||
mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux->memAddr) + 128);
|
||||
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
|
||||
dmuxMsg->supplementalInfo = 0; // !!!
|
||||
Callback cb;
|
||||
cb.SetAddr(dmux->cbFunc);
|
||||
cb.Handle(dmux->id, dmuxMsg.GetAddr(), dmux->cbArg);
|
||||
cb.Branch(true);
|
||||
}
|
||||
|
||||
while (dmux->is_running) // hack
|
||||
while (dmux->is_running) // !!!
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
@ -603,7 +600,7 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize
|
||||
break;
|
||||
}
|
||||
Sleep(1);
|
||||
//return CELL_DMUX_ERROR_BUSY;
|
||||
return CELL_DMUX_ERROR_BUSY;
|
||||
}
|
||||
|
||||
DemuxerTask task(dmuxSetStream);
|
||||
@ -938,14 +935,19 @@ int cellDmuxReleaseAu(u32 esHandle)
|
||||
{
|
||||
cellDmux.Error("cellDmuxReleaseAu: no AU");
|
||||
return CELL_DMUX_ERROR_SEQ;
|
||||
//return CELL_OK;
|
||||
}
|
||||
|
||||
DemuxerTask task(dmuxReleaseAu);
|
||||
/*DemuxerTask task(dmuxReleaseAu);
|
||||
task.es.es = esHandle;
|
||||
task.es.es_ptr = es;
|
||||
|
||||
es->dmux->job.Push(task);
|
||||
es->dmux->job.Push(task);*/
|
||||
|
||||
if (!es->release())
|
||||
{
|
||||
cellDmux.Error("cellDmuxReleaseAu failed");
|
||||
return CELL_DMUX_ERROR_SEQ;
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -426,7 +426,6 @@ enum DemuxerJobType
|
||||
dmuxEnableEs,
|
||||
dmuxDisableEs,
|
||||
dmuxResetEs,
|
||||
dmuxReleaseAu,
|
||||
dmuxFlushEs,
|
||||
dmuxClose,
|
||||
};
|
||||
@ -534,8 +533,9 @@ public:
|
||||
return last_size;
|
||||
}
|
||||
|
||||
bool isfull() // not multithread-safe
|
||||
bool isfull()
|
||||
{
|
||||
SMutexLocker lock(mutex);
|
||||
if (first_addr)
|
||||
{
|
||||
if (first_addr > last_addr)
|
||||
@ -581,7 +581,24 @@ public:
|
||||
{
|
||||
SMutexLocker lock(mutex);
|
||||
//ConLog.Write("es::push(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
||||
if (isfull())
|
||||
bool is_full;
|
||||
if (first_addr)
|
||||
{
|
||||
if (first_addr > last_addr)
|
||||
{
|
||||
is_full = (first_addr - last_addr) < MAX_AU;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_full = (first_addr + MAX_AU) > (memAddr + memSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_full = false;
|
||||
}
|
||||
|
||||
if (is_full)
|
||||
{
|
||||
ConLog.Error("ElementaryStream::push(): buffer is full");
|
||||
Emu.Pause();
|
||||
@ -634,20 +651,26 @@ public:
|
||||
return first_addr;
|
||||
}
|
||||
|
||||
void release()
|
||||
bool release()
|
||||
{
|
||||
SMutexLocker lock(mutex);
|
||||
ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
||||
//ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
||||
if (!canrelease())
|
||||
{
|
||||
ConLog.Error("ElementaryStream::release(): buffer is empty");
|
||||
Emu.Pause();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 size = a128(Memory.Read32(first_addr + 4) + 128);
|
||||
u32 new_addr = first_addr + size;
|
||||
if (peek_addr <= first_addr) peek_addr = new_addr;
|
||||
|
||||
if (peek_addr == first_addr)
|
||||
{
|
||||
ConLog.Error("ElementaryStream::release(): buffer has not been seen yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
//if (peek_addr <= first_addr) peek_addr = new_addr;
|
||||
if (new_addr == last_addr)
|
||||
{
|
||||
first_addr = 0;
|
||||
@ -660,6 +683,8 @@ public:
|
||||
{
|
||||
first_addr = new_addr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index)
|
||||
|
235
rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp
Normal file
235
rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
#include "stdafx.h"
|
||||
#include "cellSpurs.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
void cellSpurs_init();
|
||||
Module cellSpurs(0x000a, cellSpurs_init);
|
||||
|
||||
int _cellSpursAttributeInitialize(mem_ptr_t<CellSpursAttribute> attr, int nSpus, int spuPriority,
|
||||
int ppuPriority, bool exitIfNoWork)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)",
|
||||
attr.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork);
|
||||
if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t<CellSpursAttribute> attr, u32 container)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)",
|
||||
attr.GetAddr(), container);
|
||||
if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttributeSetNamePrefix(mem_ptr_t<CellSpursAttribute> attr, const mem8_t prefix, u32 size)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)",
|
||||
attr.GetAddr(), prefix.GetAddr(), size);
|
||||
if(!attr.IsGood() || !prefix.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
if(size > 15) return CELL_SPURS_CORE_ERROR_INVAL;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t<CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr());
|
||||
if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t<CellSpursAttribute> attr, int type)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%u)", attr.GetAddr(), type);
|
||||
if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttributeEnableSystemWorkload(mem_ptr_t<CellSpursAttribute> attr, const u8 priority[8],
|
||||
uint maxSpu, const bool isPreemptible[8])
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority[%u], maxSpu=%u, isPreemptible[%u])",
|
||||
attr.GetAddr(), priority, maxSpu, isPreemptible);
|
||||
if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
for (int i=0; i<9; i++)
|
||||
if(priority[i] != 1 || maxSpu == 0) return CELL_SPURS_CORE_ERROR_INVAL;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursInitializeWithAttribute2(mem_ptr_t<CellSpurs2> spurs, const mem_ptr_t<CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)",
|
||||
spurs.GetAddr(), attr.GetAddr());
|
||||
if(!attr.IsGood() || !spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursFinalize(mem_ptr_t<CellSpurs> spurs)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.GetAddr());
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursGetSpuThreadGroupId(mem_ptr_t<CellSpurs> spurs, mem32_t group)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)",
|
||||
spurs.GetAddr(), group.GetAddr());
|
||||
if(!spurs.IsGood() || group.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursGetNumSpuThread(mem_ptr_t<CellSpurs> spurs, mem32_t nThreads)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)",
|
||||
spurs.GetAddr(), nThreads.GetAddr());
|
||||
if(!spurs.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursGetSpuThreadId(mem_ptr_t<CellSpurs> spurs, mem32_t thread, mem32_t nThreads)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)",
|
||||
spurs.GetAddr(), thread.GetAddr(), nThreads.GetAddr());
|
||||
if(!spurs.IsGood() || !thread.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursSetMaxContention(mem_ptr_t<CellSpurs> spurs, uint workloadId, uint maxContention)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%u, maxContention=%u)",
|
||||
spurs.GetAddr(), workloadId, maxContention);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursSetPriorities(mem_ptr_t<CellSpurs> spurs, uint workloadId, const u8 priorities[CELL_SPURS_MAX_SPU])
|
||||
{
|
||||
cellSpurs.Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%u, priorities[%u])",
|
||||
spurs.GetAddr(), workloadId, priorities);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursSetPriority(mem_ptr_t<CellSpurs> spurs, uint workloadId, uint spuId, uint priority)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursSetPriority(spurs_addr=0x%x, workloadId=%u, spuId=%u, priority=%u)",
|
||||
spurs.GetAddr(), workloadId, spuId, priority);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursSetPreemptionVictimHints(mem_ptr_t<CellSpurs> spurs, const bool isPreemptible[8])
|
||||
{
|
||||
cellSpurs.Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible[%u])",
|
||||
spurs.GetAddr(), isPreemptible);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursAttachLv2EventQueue(mem_ptr_t<CellSpurs> spurs, u32 queue, mem8_t port, int isDynamic)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%u)",
|
||||
spurs.GetAddr(), queue, port.GetAddr(), isDynamic);
|
||||
if(!spurs.IsGood() || !port.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursDetachLv2EventQueue(mem_ptr_t<CellSpurs> spurs, u8 port)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=0x%x)", spurs.GetAddr(), port);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursEnableExceptionEventHandler(mem_ptr_t<CellSpurs> spurs, bool flag)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%u)", spurs.GetAddr(), flag);
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursSetGlobalExceptionEventHandler(mem_ptr_t<CellSpurs> spurs,
|
||||
mem_func_ptr_t<CellSpursGlobalExceptionEventHandler> eaHandler, mem_ptr_t<void> arg)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x,)",
|
||||
spurs.GetAddr(), eaHandler.GetAddr(), arg.GetAddr());
|
||||
if(!spurs.IsGood() || eaHandler.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t<CellSpurs> spurs)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr());
|
||||
if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSpursGetInfo(mem_ptr_t<CellSpurs> spurs, mem_ptr_t<CellSpursInfo> info)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr());
|
||||
if(!spurs.IsGood() || !info.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Task functions
|
||||
int cellSpursGetTasksetId(mem_ptr_t<CellSpursTaskset> taskset, mem32_t workloadId)
|
||||
{
|
||||
cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr());
|
||||
if(!taskset.IsGood() || !taskset.IsGood()) return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cellSpurs_init()
|
||||
{
|
||||
//libspurs core functions
|
||||
cellSpurs.AddFunc(0x95180230, _cellSpursAttributeInitialize);
|
||||
cellSpurs.AddFunc(0x82275c1c, cellSpursAttributeSetMemoryContainerForSpuThread);
|
||||
cellSpurs.AddFunc(0x07529113, cellSpursAttributeSetNamePrefix);
|
||||
cellSpurs.AddFunc(0x1051d134, cellSpursAttributeEnableSpuPrintfIfAvailable);
|
||||
cellSpurs.AddFunc(0xa839a4d9, cellSpursAttributeSetSpuThreadGroupType);
|
||||
cellSpurs.AddFunc(0x9dcbcb5d, cellSpursAttributeEnableSystemWorkload);
|
||||
cellSpurs.AddFunc(0x30aa96c4, cellSpursInitializeWithAttribute2);
|
||||
cellSpurs.AddFunc(0xca4c4600, cellSpursFinalize);
|
||||
cellSpurs.AddFunc(0x39c173fb, cellSpursGetSpuThreadGroupId);
|
||||
cellSpurs.AddFunc(0xc56defb5, cellSpursGetNumSpuThread);
|
||||
cellSpurs.AddFunc(0x6c960f6d, cellSpursGetSpuThreadId);
|
||||
cellSpurs.AddFunc(0x84d2f6d5,cellSpursSetMaxContention);
|
||||
cellSpurs.AddFunc(0x80a29e27,cellSpursSetPriorities);
|
||||
//cellSpurs.AddFunc(,cellSpursSetPriority);
|
||||
cellSpurs.AddFunc(0x4de203e2, cellSpursSetPreemptionVictimHints);
|
||||
cellSpurs.AddFunc(0xb9bc6207, cellSpursAttachLv2EventQueue);
|
||||
cellSpurs.AddFunc(0x4e66d483, cellSpursDetachLv2EventQueue);
|
||||
cellSpurs.AddFunc(0x32b94add, cellSpursEnableExceptionEventHandler);
|
||||
cellSpurs.AddFunc(0x7517724a, cellSpursSetGlobalExceptionEventHandler);
|
||||
cellSpurs.AddFunc(0x861237f8, cellSpursUnsetGlobalExceptionEventHandler);
|
||||
cellSpurs.AddFunc(0x1f402f8f, cellSpursGetInfo);
|
||||
|
||||
//libspurs task functions
|
||||
}
|
296
rpcs3/Emu/SysCalls/Modules/cellSpurs.h
Normal file
296
rpcs3/Emu/SysCalls/Modules/cellSpurs.h
Normal file
@ -0,0 +1,296 @@
|
||||
#pragma once
|
||||
|
||||
// return codes
|
||||
enum
|
||||
{
|
||||
CELL_SPURS_CORE_ERROR_AGAIN = 0x80410701,
|
||||
CELL_SPURS_CORE_ERROR_INVAL = 0x80410702,
|
||||
CELL_SPURS_CORE_ERROR_NOMEM = 0x80410704,
|
||||
CELL_SPURS_CORE_ERROR_SRCH = 0x80410705,
|
||||
CELL_SPURS_CORE_ERROR_PERM = 0x80410709,
|
||||
CELL_SPURS_CORE_ERROR_BUSY = 0x8041070A,
|
||||
CELL_SPURS_CORE_ERROR_STAT = 0x8041070F,
|
||||
CELL_SPURS_CORE_ERROR_ALIGN = 0x80410710,
|
||||
CELL_SPURS_CORE_ERROR_NULL_POINTER = 0x80410711,
|
||||
};
|
||||
|
||||
//defines
|
||||
enum SPURSKernelInterfaces
|
||||
{
|
||||
CELL_SPURS_MAX_SPU = 8,
|
||||
CELL_SPURS_MAX_WORKLOAD = 16,
|
||||
CELL_SPURS_MAX_WORKLOAD2 = 32,
|
||||
CELL_SPURS_MAX_PRIORITY = 16,
|
||||
CELL_SPURS_NAME_MAX_LENGTH = 15,
|
||||
CELL_SPURS_SIZE = 4096,
|
||||
CELL_SPURS_SIZE2 = 8192,
|
||||
CELL_SPURS_ALIGN = 128,
|
||||
CELL_SPURS_ATTRIBUTE_SIZE = 512,
|
||||
CELL_SPURS_ATTRIBUTE_ALIGN = 8,
|
||||
CELL_SPURS_INTERRUPT_VECTOR = 0x0,
|
||||
CELL_SPURS_LOCK_LINE = 0x80,
|
||||
CELL_SPURS_KERNEL_DMA_TAG_ID = 31,
|
||||
};
|
||||
|
||||
enum RangeofEventQueuePortNumbers
|
||||
{
|
||||
CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15,
|
||||
CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16,
|
||||
CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63,
|
||||
};
|
||||
|
||||
enum SPURSTraceTypes
|
||||
{
|
||||
CELL_SPURS_TRACE_TAG_LOAD = 0x2a,
|
||||
CELL_SPURS_TRACE_TAG_MAP = 0x2b,
|
||||
CELL_SPURS_TRACE_TAG_START = 0x2c,
|
||||
CELL_SPURS_TRACE_TAG_STOP = 0x2d,
|
||||
CELL_SPURS_TRACE_TAG_USER = 0x2e,
|
||||
CELL_SPURS_TRACE_TAG_GUID = 0x2f,
|
||||
};
|
||||
|
||||
struct CellSpursInfo
|
||||
{
|
||||
be_t<int> nSpus;
|
||||
be_t<int> spuThreadGroupPriority;
|
||||
be_t<int> ppuThreadPriority;
|
||||
bool exitIfNoWork;
|
||||
bool spurs2;
|
||||
be_t<u32> traceBuffer_addr; //void *traceBuffer;
|
||||
be_t<u64> traceBufferSize;
|
||||
be_t<u32> traceMode;
|
||||
be_t<u32> spuThreadGroup; //typedef u32 sys_spu_thread_group_t;
|
||||
be_t<u32> spuThreads[8]; //typedef u32 sys_spu_thread_t;
|
||||
be_t<u32> spursHandlerThread0;
|
||||
be_t<u32> spursHandlerThread1;
|
||||
char namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1];
|
||||
be_t<u64> namePrefixLength;
|
||||
be_t<u32> deadlineMissCounter;
|
||||
be_t<u32> deadlineMeetCounter;
|
||||
//u8 padding[];
|
||||
};
|
||||
|
||||
struct CellSpursExceptionInfo
|
||||
{
|
||||
be_t<u32> spu_thread;
|
||||
be_t<u32> spu_npc;
|
||||
be_t<u32> cause;
|
||||
be_t<u64> option;
|
||||
};
|
||||
|
||||
struct CellSpursTraceInfo
|
||||
{
|
||||
be_t<u32> spu_thread[8];
|
||||
be_t<u32> count[8];
|
||||
be_t<u32> spu_thread_grp;
|
||||
be_t<u32> nspu;
|
||||
//u8 padding[];
|
||||
};
|
||||
|
||||
__declspec(align(8)) struct CellTraceHeader
|
||||
{
|
||||
u8 tag;
|
||||
u8 length;
|
||||
u8 cpu;
|
||||
u8 thread;
|
||||
be_t<u32> time;
|
||||
};
|
||||
|
||||
struct CellSpursTracePacket
|
||||
{
|
||||
struct header_struct
|
||||
{
|
||||
u8 tag;
|
||||
u8 length;
|
||||
u8 spu;
|
||||
u8 workload;
|
||||
be_t<u32> time;
|
||||
} header;
|
||||
|
||||
struct data_struct
|
||||
{
|
||||
struct load_struct
|
||||
{
|
||||
be_t<u32> ea;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} load;
|
||||
|
||||
struct map_struct
|
||||
{
|
||||
be_t<u32> offset;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} map;
|
||||
|
||||
struct start_struct
|
||||
{
|
||||
char module[4];
|
||||
be_t<u16> level;
|
||||
be_t<u16> ls;
|
||||
} start;
|
||||
|
||||
be_t<u64> user;
|
||||
be_t<u64> guid;
|
||||
} data;
|
||||
};
|
||||
|
||||
__declspec(align(128)) struct CellSpurs
|
||||
{
|
||||
u8 skip[CELL_SPURS_SIZE];
|
||||
};
|
||||
|
||||
__declspec(align(128)) struct CellSpurs2
|
||||
{
|
||||
u8 skip[CELL_SPURS_SIZE2 - CELL_SPURS_SIZE];
|
||||
};
|
||||
|
||||
__declspec(align(8)) struct CellSpursAttribute
|
||||
{
|
||||
u8 skip[CELL_SPURS_ATTRIBUTE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
//typedef unsigned CellSpursWorkloadId;
|
||||
|
||||
typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t<CellSpurs> spurs, const mem_ptr_t<CellSpursExceptionInfo> info,
|
||||
uint id, mem_ptr_t<void> arg);
|
||||
|
||||
|
||||
// task datatypes and constans
|
||||
enum TaskConstants
|
||||
{
|
||||
CELL_SPURS_MAX_TASK = 128,
|
||||
CELL_SPURS_TASK_TOP = 0x3000,
|
||||
CELL_SPURS_TASK_BOTTOM = 0x40000,
|
||||
CELL_SPURS_MAX_TASK_NAME_LENGTH = 32,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_SPURS_TASK_ERROR_AGAIN = 0x80410901,
|
||||
CELL_SPURS_TASK_ERROR_INVAL = 0x80410902,
|
||||
CELL_SPURS_TASK_ERROR_NOMEM = 0x80410904,
|
||||
CELL_SPURS_TASK_ERROR_SRCH = 0x80410905,
|
||||
CELL_SPURS_TASK_ERROR_NOEXEC = 0x80410907,
|
||||
CELL_SPURS_TASK_ERROR_PERM = 0x80410909,
|
||||
CELL_SPURS_TASK_ERROR_BUSY = 0x8041090A,
|
||||
CELL_SPURS_TASK_ERROR_FAULT = 0x8041090D,
|
||||
CELL_SPURS_TASK_ERROR_STAT = 0x8041090F,
|
||||
CELL_SPURS_TASK_ERROR_ALIGN = 0x80410910,
|
||||
CELL_SPURS_TASK_ERROR_NULL_POINTER = 0x80410911,
|
||||
CELL_SPURS_TASK_ERROR_FATAL = 0x80410914,
|
||||
CELL_SPURS_TASK_ERROR_SHUTDOWN = 0x80410920,
|
||||
};
|
||||
|
||||
|
||||
__declspec(align(128)) struct CellSpursTaskset
|
||||
{
|
||||
u8 skip[6400];
|
||||
};
|
||||
|
||||
typedef void(*CellSpursTasksetExceptionEventHandler)(mem_ptr_t<CellSpurs> spurs, mem_ptr_t<CellSpursTaskset> taskset,
|
||||
uint idTask, const mem_ptr_t<CellSpursExceptionInfo> info, mem_ptr_t<void> arg);
|
||||
|
||||
|
||||
struct CellSpursTasksetInfo
|
||||
{
|
||||
//CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK];
|
||||
be_t<u64> argument;
|
||||
be_t<uint> idWorkload;
|
||||
be_t<uint> idLastScheduledTask; //typedef unsigned CellSpursTaskId
|
||||
be_t<u32> name_addr;
|
||||
CellSpursTasksetExceptionEventHandler exceptionEventHandler;
|
||||
be_t<u32> exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument
|
||||
be_t<u64> sizeTaskset;
|
||||
//be_t<u8> reserved[];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
#define CELL_SPURS_TASKSET_CLASS0_SIZE (128 * 50)
|
||||
#define _CELL_SPURS_TASKSET_CLASS1_EXTENDED_SIZE (128 + 128 * 16 + 128 * 15)
|
||||
#define CELL_SPURS_TASKSET_CLASS1_SIZE (CELL_SPURS_TASKSET_CLASS0_SIZE + _CELL_SPURS_TASKSET_CLASS1_EXTENDED_SIZE)
|
||||
#define CELL_SPURS_TASKSET2_SIZE (CELL_SPURS_TASKSET_CLASS1_SIZE)
|
||||
#define CELL_SPURS_TASKSET2_ALIGN 128
|
||||
#define CELL_SPURS_TASKSET_ALIGN 128
|
||||
#define CELL_SPURS_TASKSET_SIZE CELL_SPURS_TASKSET_CLASS0_SIZE
|
||||
*/
|
||||
|
||||
__declspec(align(128)) struct CellSpursTaskset2
|
||||
{
|
||||
be_t<u8> skip[10496];
|
||||
};
|
||||
|
||||
struct CellSpursTasksetAttribute2
|
||||
{
|
||||
be_t<u32> revision;
|
||||
be_t<u32> name_addr;
|
||||
be_t<u64> argTaskset;
|
||||
u8 priority[8];
|
||||
be_t<u32> maxContention;
|
||||
be_t<s32> enableClearLs;
|
||||
be_t<s32> CellSpursTaskNameBuffer_addr; //??? *taskNameBuffer
|
||||
//be_t<u32> __reserved__[];
|
||||
};
|
||||
|
||||
struct CellSpursTaskNameBuffer
|
||||
{
|
||||
char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CellSpursTraceTaskData
|
||||
{
|
||||
be_t<u32> incident;
|
||||
be_t<u32> task;
|
||||
};
|
||||
|
||||
struct CellSpursTaskArgument
|
||||
{
|
||||
be_t<u32> u32[4];
|
||||
be_t<u64> u64[2];
|
||||
};
|
||||
|
||||
struct CellSpursTaskLsPattern
|
||||
{
|
||||
be_t<u32> u32[4];
|
||||
be_t<u64> u64[2];
|
||||
};
|
||||
|
||||
struct CellSpursTaskAttribute2
|
||||
{
|
||||
be_t<u32> revision;
|
||||
be_t<u32> sizeContext;
|
||||
be_t<u64> eaContext;
|
||||
CellSpursTaskLsPattern lsPattern; //???
|
||||
be_t<u32> name_addr;
|
||||
//be_t<u32> __reserved__[];
|
||||
};
|
||||
|
||||
__declspec(align(128)) struct CellSpursTaskExitCode
|
||||
{
|
||||
unsigned char skip[128];
|
||||
};
|
||||
|
||||
struct CellSpursTaskInfo
|
||||
{
|
||||
CellSpursTaskLsPattern lsPattern;
|
||||
CellSpursTaskArgument argument;
|
||||
const be_t<u32> eaElf_addr; //void *eaElf
|
||||
const be_t<u32> eaContext_addr; //void *eaContext
|
||||
be_t<u32> sizeContext;
|
||||
be_t<u8> state;
|
||||
be_t<u8> hasSignal;
|
||||
const be_t<u32> CellSpursTaskExitCode_addr;
|
||||
u8 guid[8];
|
||||
//be_t<u8> reserved[];
|
||||
};
|
||||
|
||||
struct CellSpursTaskBinInfo
|
||||
{
|
||||
be_t<u64> eaElf;
|
||||
be_t<u32> sizeContext;
|
||||
be_t<u32> __reserved__;
|
||||
CellSpursTaskLsPattern lsPattern;
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
||||
|
||||
int res = 0;
|
||||
|
||||
if (vdec.reader.size < (u32)buf_size)
|
||||
if (vdec.reader.size < (u32)buf_size && !vdec.just_started)
|
||||
{
|
||||
while (vdec.job.IsEmpty())
|
||||
{
|
||||
@ -74,7 +74,10 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
||||
ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type);
|
||||
return 0;
|
||||
}
|
||||
//buf_size = vdec.reader.size;
|
||||
}
|
||||
else if (vdec.reader.size < (u32)buf_size)
|
||||
{
|
||||
buf_size = vdec.reader.size;
|
||||
}
|
||||
|
||||
if (!buf_size)
|
||||
@ -123,6 +126,8 @@ u32 vdecOpen(VideoDecoder* data)
|
||||
|
||||
vdec.id = vdec_id;
|
||||
|
||||
vdec.vdecCb->SetName("Video Decoder[" + std::to_string(vdec_id) + "] Callback");
|
||||
|
||||
thread t("Video Decoder[" + std::to_string(vdec_id) + "] Thread", [&]()
|
||||
{
|
||||
ConLog.Write("Video Decoder enter()");
|
||||
|
@ -77,8 +77,26 @@ int sys_cond_signal(u32 cond_id)
|
||||
|
||||
if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop()))
|
||||
{
|
||||
CPUThread* tt = Emu.GetCPU().GetThread(target);
|
||||
bool valid = tt && tt->IsAlive();
|
||||
if (!valid)
|
||||
{
|
||||
sys_cond.Error("sys_cond_signal(%d): signal to invalid thread(%d)", cond_id, target);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!was_locked) // mutex hasn't been locked (don't care about mutex state)
|
||||
{
|
||||
if (u32 owner = mutex->m_mutex.GetOwner())
|
||||
{
|
||||
tt = Emu.GetCPU().GetThread(owner);
|
||||
valid = tt && tt->IsAlive();
|
||||
if (!valid)
|
||||
{
|
||||
sys_cond.Error("sys_cond_signal(%d): deadlock on invalid thread(%d)", cond_id, owner);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->recursive = 1;
|
||||
mutex->m_mutex.unlock(tid, target);
|
||||
@ -117,8 +135,26 @@ int sys_cond_signal_all(u32 cond_id)
|
||||
|
||||
while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop()))
|
||||
{
|
||||
CPUThread* tt = Emu.GetCPU().GetThread(target);
|
||||
bool valid = tt && tt->IsAlive();
|
||||
if (!valid)
|
||||
{
|
||||
sys_cond.Error("sys_cond_signal_all(%d): signal to invalid thread(%d)", cond_id, target);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!was_locked)
|
||||
{
|
||||
if (u32 owner = mutex->m_mutex.GetOwner())
|
||||
{
|
||||
tt = Emu.GetCPU().GetThread(owner);
|
||||
valid = tt && tt->IsAlive();
|
||||
if (!valid)
|
||||
{
|
||||
sys_cond.Error("sys_cond_signal_all(%d): deadlock on invalid thread(%d)", cond_id, owner);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->recursive = 1;
|
||||
mutex->m_mutex.unlock(tid, target);
|
||||
@ -130,11 +166,11 @@ int sys_cond_signal_all(u32 cond_id)
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->recursive = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_cond_signal_all(id=%d) aborted", cond_id);
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_cond_signal_all(id=%d) aborted", cond_id);
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -169,6 +205,16 @@ int sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
||||
{
|
||||
if (!was_locked)
|
||||
{
|
||||
if (u32 owner = mutex->m_mutex.GetOwner())
|
||||
{
|
||||
CPUThread* tt = Emu.GetCPU().GetThread(owner);
|
||||
bool valid = tt && tt->IsAlive();
|
||||
if (!valid)
|
||||
{
|
||||
sys_cond.Error("sys_cond_signal_to(%d): deadlock on invalid thread(%d)", cond_id, owner);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->recursive = 1;
|
||||
mutex->m_mutex.unlock(tid, target);
|
||||
|
@ -74,17 +74,17 @@ int sys_event_queue_destroy(u32 equeue_id, int mode)
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
eq->sq.m_mutex.lock(tid);
|
||||
eq->sq.m_mutex.lock();
|
||||
eq->owner.lock(tid);
|
||||
// check if some threads are waiting for an event
|
||||
if (!mode && eq->sq.list.GetCount())
|
||||
{
|
||||
eq->owner.unlock(tid);
|
||||
eq->sq.m_mutex.unlock(tid);
|
||||
eq->sq.m_mutex.unlock();
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
eq->owner.unlock(tid, ~0);
|
||||
eq->sq.m_mutex.unlock(tid);
|
||||
eq->sq.m_mutex.unlock();
|
||||
while (eq->sq.list.GetCount())
|
||||
{
|
||||
Sleep(1);
|
||||
@ -136,18 +136,18 @@ int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t<sys_event_data> event_ar
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
eq->sq.m_mutex.lock(tid);
|
||||
eq->sq.m_mutex.lock();
|
||||
eq->owner.lock(tid);
|
||||
if (eq->sq.list.GetCount())
|
||||
{
|
||||
number = 0;
|
||||
eq->owner.unlock(tid);
|
||||
eq->sq.m_mutex.unlock(tid);
|
||||
eq->sq.m_mutex.unlock();
|
||||
return CELL_OK;
|
||||
}
|
||||
number = eq->events.pop_all((sys_event_data*)(Memory + event_array.GetAddr()), size);
|
||||
eq->owner.unlock(tid);
|
||||
eq->sq.m_mutex.unlock(tid);
|
||||
eq->sq.m_mutex.unlock();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -99,13 +99,13 @@ int sys_lwmutex_unlock(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
||||
|
||||
void SleepQueue::push(u32 tid)
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
list.AddCpy(tid);
|
||||
}
|
||||
|
||||
u32 SleepQueue::pop() // SYS_SYNC_FIFO
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -125,7 +125,7 @@ u32 SleepQueue::pop() // SYS_SYNC_FIFO
|
||||
|
||||
u32 SleepQueue::pop_prio() // SYS_SYNC_PRIORITY
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -171,7 +171,7 @@ u32 SleepQueue::pop_prio_inherit() // (TODO)
|
||||
|
||||
bool SleepQueue::invalidate(u32 tid)
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (tid) for (u32 i = 0; i < list.GetCount(); i++)
|
||||
{
|
||||
@ -187,15 +187,13 @@ bool SleepQueue::invalidate(u32 tid)
|
||||
|
||||
bool SleepQueue::finalize()
|
||||
{
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
m_mutex.lock(tid);
|
||||
if (!m_mutex.try_lock()) return false;
|
||||
|
||||
for (u32 i = 0; i < list.GetCount(); i++)
|
||||
{
|
||||
if (list[i])
|
||||
{
|
||||
m_mutex.unlock(tid);
|
||||
m_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -230,7 +228,7 @@ int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
}
|
||||
}
|
||||
|
||||
while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0)
|
||||
/*while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
@ -238,7 +236,7 @@ int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (tid == owner_tid)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ struct SleepQueue
|
||||
q_rec(u32 tid, u64 prio): tid(tid), prio(prio) {}
|
||||
}; */
|
||||
Array<u32> list;
|
||||
SMutex m_mutex;
|
||||
std::mutex m_mutex;
|
||||
u64 m_name;
|
||||
|
||||
SleepQueue(u64 name = 0)
|
||||
|
@ -41,6 +41,7 @@ int sys_mutex_create(mem32_t mutex_id, mem_ptr_t<sys_mutex_attribute> attr)
|
||||
Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64);
|
||||
u32 id = sys_mtx.GetNewId(mutex);
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->id = id;
|
||||
mutex_id = id;
|
||||
mutex->m_mutex.unlock(tid);
|
||||
sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d",
|
||||
@ -120,20 +121,20 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout)
|
||||
{
|
||||
if (!tt->IsAlive())
|
||||
{
|
||||
sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
mutex->m_mutex.unlock(owner, tid);
|
||||
if (owner == mutex->m_mutex.GetOwner()) sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
/*mutex->m_mutex.unlock(owner, tid);
|
||||
mutex->recursive = 1;
|
||||
t.owned_mutexes++;
|
||||
return CELL_OK;
|
||||
return CELL_OK;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
mutex->m_mutex.unlock(owner, tid);
|
||||
/*mutex->m_mutex.unlock(owner, tid);
|
||||
mutex->recursive = 1;
|
||||
t.owned_mutexes++;
|
||||
return CELL_OK;
|
||||
return CELL_OK;*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,20 +203,20 @@ int sys_mutex_trylock(u32 mutex_id)
|
||||
{
|
||||
if (!tt->IsAlive())
|
||||
{
|
||||
sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
mutex->m_mutex.unlock(owner, tid);
|
||||
if (owner == mutex->m_mutex.GetOwner()) sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
/*mutex->m_mutex.unlock(owner, tid);
|
||||
mutex->recursive = 1;
|
||||
t.owned_mutexes++;
|
||||
return CELL_OK;
|
||||
return CELL_OK;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner);
|
||||
mutex->m_mutex.unlock(owner, tid);
|
||||
/*mutex->m_mutex.unlock(owner, tid);
|
||||
mutex->recursive = 1;
|
||||
t.owned_mutexes++;
|
||||
return CELL_OK;
|
||||
return CELL_OK;*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +245,7 @@ int sys_mutex_unlock(u32 mutex_id)
|
||||
{
|
||||
if (!mutex->recursive || (mutex->recursive != 1 && !mutex->is_recursive))
|
||||
{
|
||||
sys_mtx.Error("sys_mutex_unlock(%d): wrong recursive value (%d)", mutex_id, mutex->recursive);
|
||||
sys_mtx.Error("sys_mutex_unlock(%d): wrong recursive value fixed (%d)", mutex_id, mutex->recursive);
|
||||
mutex->recursive = 1;
|
||||
}
|
||||
mutex->recursive--;
|
||||
|
@ -18,6 +18,7 @@ struct sys_mutex_attribute
|
||||
|
||||
struct Mutex
|
||||
{
|
||||
u32 id;
|
||||
SMutex m_mutex;
|
||||
SleepQueue m_queue;
|
||||
u32 recursive; // recursive locks count
|
||||
@ -33,4 +34,21 @@ struct Mutex
|
||||
, cond_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
~Mutex()
|
||||
{
|
||||
if (u32 owner = m_mutex.GetOwner())
|
||||
{
|
||||
ConLog.Write("Mutex(%d) was owned by thread %d (recursive=%d)", id, owner, recursive);
|
||||
}
|
||||
|
||||
if (!m_queue.m_mutex.try_lock()) return;
|
||||
|
||||
for (u32 i = 0; i < m_queue.list.GetCount(); i++)
|
||||
{
|
||||
if (u32 owner = m_queue.list[i]) ConLog.Write("Mutex(%d) was waited by thread %d", id, owner);
|
||||
}
|
||||
|
||||
m_queue.m_mutex.unlock();
|
||||
}
|
||||
};
|
@ -297,6 +297,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSpurs.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSync.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysutil.cpp" />
|
||||
|
@ -436,22 +436,19 @@
|
||||
<ClCompile Include="Crypto\utils.cpp">
|
||||
<Filter>Crypto</Filter>
|
||||
</ClCompile>
|
||||
|
||||
|
||||
<ClCompile Include="Emu\SysCalls\Static.cpp">
|
||||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClCompile>
|
||||
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellNetCtl.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellL10n.cpp">
|
||||
|
||||
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\libmixer.cpp">
|
||||
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSpurs.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user