diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 9310bea613..aa131b69a6 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -5,7 +5,7 @@ static const volatile bool sq_no_wait = true; template class SQueue { - std::mutex m_mutex; + mutable std::mutex m_mutex; u32 m_pos; u32 m_count; T m_data[SQSize]; @@ -17,11 +17,16 @@ public: { } - const u32 GetSize() const + u32 GetSize() const { return SQSize; } + bool IsFull() const volatile + { + return m_count == SQSize; + } + bool Push(const T& data, const volatile bool* do_exit) { while (true) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index d45fe55fd8..b7df2a5c96 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -3,6 +3,38 @@ #include "Log.h" #include "Thread.h" +#ifdef _WIN32 +#include +#endif + +void SetCurrentThreadDebugName(const char* threadName) +{ +#ifdef _WIN32 // this is VS-specific way to set thread names for the debugger + #pragma pack(push,8) + struct THREADNAME_INFO + { + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; + } info; + #pragma pack(pop) + + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } +#endif +} + thread_local NamedThreadBase* g_tls_this_thread = nullptr; std::atomic g_thread_count(0); @@ -85,6 +117,8 @@ void ThreadBase::Start() m_executor = new std::thread([this]() { + SetCurrentThreadDebugName(GetThreadName().c_str()); + SetCurrentNamedThread(this); g_thread_count++; @@ -172,6 +206,8 @@ void thread::start(std::function func) m_thr = std::thread([func, name]() { + SetCurrentThreadDebugName(name.c_str()); + NamedThreadBase info(name); SetCurrentNamedThread(&info); g_thread_count++; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index dd415ddb0a..9ae92e6dc6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -97,7 +97,7 @@ next: { u8 code1 = vm::read8(adec.reader.addr + 2); u8 code2 = vm::read8(adec.reader.addr + 3); - adec.channels = code1 >> 2; + adec.channels = (code1 >> 2) & 0x7; adec.frame_size = ((((u32)code1 & 0x3) << 8) | (u32)code2) * 8 + 8; adec.sample_rate = at3freq[code1 >> 5]; diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 8e311358ff..57ee842309 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -14,7 +14,7 @@ PesHeader::PesHeader(DemuxerStream& stream) : pts(0xffffffffffffffffull) , dts(0xffffffffffffffffull) , size(0) - , new_au(false) + , has_ts(false) { u16 header; stream.get(header); @@ -33,13 +33,13 @@ PesHeader::PesHeader(DemuxerStream& stream) if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only { - new_au = true; + has_ts = true; pts = stream.get_ts(v); stream.skip(size - empty - 5); } else { - new_au = true; + has_ts = true; if ((v & 0xF0) != 0x30 || (size - empty) < 10) { cellDmux->Error("PesHeader(): pts not found"); @@ -58,23 +58,31 @@ PesHeader::PesHeader(DemuxerStream& stream) } } -bool ElementaryStream::is_full() +bool ElementaryStream::is_full(u32 space) { if (released < put_count) { - u32 first; - if (!entries.Peek(first, &dmux->is_closed)) + if (entries.IsFull()) { - return false; + return true; } - if (first >= put) + + u32 first = 0; + if (!entries.Peek(first, &dmux->is_closed) || !first) { - return (first - put) < GetMaxAU(); + throw "es::is_full() error: entries.Peek() failed"; + } + else if (first >= put) + { + return first - put < space + 128; + } + else if (put + space + 128 > memAddr + memSize) + { + return first - memAddr < space + 128; } else { - // probably, always false - return (put + GetMaxAU()) > (memAddr + memSize); + return false; } } else @@ -83,206 +91,148 @@ bool ElementaryStream::is_full() } } -const u32 ElementaryStream::GetMaxAU() const -{ - return (fidMajor == 0xbd) ? 4096 : 640 * 1024 + 128; // TODO -} - -u32 ElementaryStream::freespace() -{ - if (size > GetMaxAU()) - { - cellDmux->Error("es::freespace(): last_size too big (size=0x%x, max_au=0x%x)", size, GetMaxAU()); - Emu.Pause(); - return 0; - } - return GetMaxAU() - size; -} - -bool ElementaryStream::hasunseen() +bool ElementaryStream::isfull(u32 space) { std::lock_guard lock(m_mutex); - return peek_count < put_count; + return is_full(space); } -bool ElementaryStream::hasdata() -{ - std::lock_guard lock(m_mutex); - return size != 0; -} - -bool ElementaryStream::isfull() -{ - std::lock_guard lock(m_mutex); - return is_full(); -} - -void ElementaryStream::finish(DemuxerStream& stream) // not multithread-safe (or safe?) +void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool rap, u32 specific) { u32 addr; { std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + + if (is_full(size)) + { + throw "es::push_au() error: buffer is full"; + } + + if (put + size + 128 > memAddr + memSize) + { + put = memAddr; + } + + memcpy(vm::get_ptr(put + 128), raw_data.data(), size); + raw_data.erase(raw_data.begin(), raw_data.begin() + size); + + auto info = vm::ptr::make(put); + info->auAddr = put + 128; + info->auSize = size; + info->dts.lower = (u32)(dts); + info->dts.upper = (u32)(dts >> 32); + info->pts.lower = (u32)(pts); + info->pts.upper = (u32)(pts >> 32); + info->isRap = rap; + info->reserved = 0; + info->userData = userdata; + + auto spec = vm::ptr::make(put + sizeof(CellDmuxAuInfoEx)); + *spec = specific; + + auto inf = vm::ptr::make(put + 64); + inf->auAddr = put + 128; + inf->auSize = size; + inf->dtsLower = (u32)(dts); + inf->dtsUpper = (u32)(dts >> 32); + inf->ptsLower = (u32)(pts); + inf->ptsUpper = (u32)(pts >> 32); + inf->auMaxSize = 0; // ????? + inf->userData = userdata; addr = put; - auto info = vm::ptr::make(put); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::finish(): (%s) size = 0x%x, info_addr=0x%x, pts = 0x%x", - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), - //(u32)info->auSize, put, (u32)info->ptsLower); - - u32 new_addr = a128(put + 128 + size); - put = ((new_addr + GetMaxAU()) > (memAddr + memSize)) - ? memAddr : new_addr; - - size = 0; + put = a128(put + 128 + size); put_count++; - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); } - if (!entries.Push(addr, &sq_no_wait)) + if (!entries.Push(addr, &dmux->is_closed)) { - cellDmux->Error("es::finish() aborted (no space)"); - Emu.Pause(); + throw "es::push_au() error: entries.Push() failed"; } } -void ElementaryStream::push(DemuxerStream& stream, u32 sz, PesHeader& pes) +void ElementaryStream::push(DemuxerStream& stream, u32 size) { - std::lock_guard lock(m_mutex); + auto const old_size = raw_data.size(); - if (is_full()) - { - cellDmux->Error("es::push(): buffer is full"); - Emu.Pause(); - return; - } + raw_data.resize(old_size + size); - u32 data_addr = put + 128 + size; - size += sz; - memcpy(vm::get_ptr(data_addr), vm::get_ptr(stream.addr), sz); - stream.skip(sz); + memcpy(raw_data.data() + old_size, vm::get_ptr(stream.addr), size); // append bytes - auto info = vm::ptr::make(put); - info->auAddr = put + 128; - info->auSize = size; - if (pes.new_au) - { - info->dts.lower = (u32)pes.dts; - info->dts.upper = (u32)(pes.dts >> 32); - info->pts.lower = (u32)pes.pts; - info->pts.upper = (u32)(pes.pts >> 32); - info->isRap = false; // TODO: set valid value - info->reserved = 0; - info->userData = stream.userdata; - } - - auto tail = vm::ptr::make(put + sizeof(CellDmuxAuInfoEx)); - tail->reserved1 = 0; - - auto inf = vm::ptr::make(put + 64); - inf->auAddr = put + 128; - inf->auSize = size; - if (pes.new_au) - { - inf->dtsLower = (u32)pes.dts; - inf->dtsUpper = (u32)(pes.dts >> 32); - inf->ptsLower = (u32)pes.pts; - inf->ptsUpper = (u32)(pes.pts >> 32); - inf->auMaxSize = 0; // ????? - inf->userData = stream.userdata; - } + stream.skip(size); } bool ElementaryStream::release() { std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); if (released >= put_count) { - cellDmux->Error("es::release(): buffer is empty"); + cellDmux->Error("es::release() error: buffer is empty"); + Emu.Pause(); + return false; + } + if (released >= got_count) + { + cellDmux->Error("es::release() error: buffer has not been seen yet"); Emu.Pause(); return false; } - u32 addr; - if (!entries.Peek(addr, &dmux->is_closed)) + u32 addr = 0; + if (!entries.Pop(addr, &dmux->is_closed) || !addr) { - return false; // ??? - } - - auto info = vm::ptr::make(addr); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::release(): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, first, (u32)info->ptsLower); - - if (released >= peek_count) - { - cellDmux->Error("es::release(): buffer has not been seen yet"); + cellDmux->Error("es::release() error: entries.Pop() failed"); Emu.Pause(); return false; } released++; - if (!entries.Pop(addr, &sq_no_wait)) - { - cellDmux->Error("es::release(): entries.Pop() aborted (no entries found)"); - Emu.Pause(); - return false; - } - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); return true; } bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index) { std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); - if (peek_count >= put_count) return false; - - if (peek_count < released) + if (got_count < released) { - cellDmux->Error("es::peek(): sequence error: peek_count < released (peek_count=%d, released=%d)", peek_count, released); + cellDmux->Error("es::peek() error: got_count(%d) < released(%d) (put_count=%d)", got_count, released, put_count); + Emu.Pause(); + return false; + } + if (got_count >= put_count) + { + return false; + } + + u32 addr = 0; + if (!entries.Peek(addr, &dmux->is_closed, got_count - released) || !addr) + { + cellDmux->Error("es::peek() error: entries.Peek() failed"); Emu.Pause(); return false; } - u32 addr; - if (!entries.Peek(addr, &dmux->is_closed, peek_count - released)) - { - return false; // ??? - } - - auto info = vm::ptr::make(addr); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::peek(%sAu(Ex)): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", - //wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, peek, (u32)info->ptsLower); - - out_data = addr; - out_spec = out_data + sizeof(CellDmuxAuInfoEx); - if (no_ex) out_data += 64; + out_data = no_ex ? addr + 64 : addr; + out_spec = addr + sizeof(CellDmuxAuInfoEx); if (update_index) { - peek_count++; + got_count++; } - - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); return true; } void ElementaryStream::reset() { std::lock_guard lock(m_mutex); - //first = 0; - //peek = 0; put = memAddr; - size = 0; entries.Clear(); put_count = 0; + got_count = 0; released = 0; - peek_count = 0; + raw_data.clear(); + raw_pos = 0; } void dmuxQueryAttr(u32 info_addr /* may be 0 */, vm::ptr attr) @@ -409,7 +359,7 @@ u32 dmuxOpen(Demuxer* data) if (esATX[ch]) { ElementaryStream& es = *esATX[ch]; - if (es.isfull()) + if (es.raw_data.size() > 1024 * 1024) { stream = backup; std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -419,14 +369,41 @@ u32 dmuxOpen(Demuxer* data) stream.skip(4); len -= 4; - es.push(stream, len - pes.size - 3, pes); - es.finish(stream); - //LOG_NOTICE(HLE, "*** AT3+ AU sent (len=0x%x, pts=0x%llx)", len - pes.size - 3, pes.pts); + if (pes.has_ts) + { + es.last_dts = pes.dts; + es.last_pts = pes.pts; + } + + es.push(stream, len - pes.size - 3); + + while (true) + { + auto const size = es.raw_data.size() - es.raw_pos; // size of available new data + auto const data = es.raw_data.data() + es.raw_pos; // pointer to available data + + if (size < 8) break; // skip if cannot read ATS header + + if (data[0] != 0x0f || data[1] != 0xd0) + { + cellDmux->Error("ATX: 0x0fd0 header not found (ats=0x%llx)", ((be_t*)data)->ToLE()); + Emu.Pause(); + return; + } + + u32 frame_size = ((((u32)data[2] & 0x3) << 8) | (u32)data[3]) * 8 + 8; + + if (size < frame_size + 8) break; // skip non-complete AU + + if (es.isfull(frame_size + 8)) break; // skip if cannot push AU - auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); - esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; - esMsg->supplementalInfo = stream.userdata; - es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + es.push_au(frame_size + 8, es.last_dts, es.last_pts, stream.userdata, false /* TODO: set correct value */, 0); + + auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); + esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; + esMsg->supplementalInfo = stream.userdata; + es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + } } else { @@ -445,48 +422,43 @@ u32 dmuxOpen(Demuxer* data) if (esAVC[ch]) { ElementaryStream& es = *esAVC[ch]; - if (es.isfull()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - continue; - } - DemuxerStream backup = stream; stream.skip(4); stream.get(len); PesHeader pes(stream); - if (es.freespace() < (u32)(len + 6)) - { - pes.new_au = true; - } - - if (pes.new_au && es.hasdata()) // new AU detected - { - es.finish(stream); - // callback - auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); - esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; - esMsg->supplementalInfo = stream.userdata; - es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); - } - - if (pes.new_au) - { - //LOG_NOTICE(HLE, "*** AVC AU detected (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts); - } - - if (es.isfull()) + const u32 old_size = (u32)es.raw_data.size(); + if (es.isfull(old_size)) { stream = backup; std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } - //reconstruction of MPEG2-PS stream for vdec module + if ((pes.has_ts && old_size) || old_size >= 0x70000) + { + // push AU if it becomes too big or the next packet contains ts data + es.push_au(old_size, es.last_dts, es.last_pts, stream.userdata, false /* TODO: set correct value */, 0); + + // callback + auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); + esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; + esMsg->supplementalInfo = stream.userdata; + es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + } + + if (pes.has_ts) + { + // preserve dts/pts for next AU + es.last_dts = pes.dts; + es.last_pts = pes.pts; + } + + // reconstruction of MPEG2-PS stream for vdec module + const u32 size = len + 6 /*- pes.size - 3*/; stream = backup; - es.push(stream, len + 6 /*- pes.size - 3*/, pes); + es.push(stream, size); } else { @@ -624,15 +596,30 @@ u32 dmuxOpen(Demuxer* data) { ElementaryStream& es = *task.es.es_ptr; - if (es.hasdata()) + const u32 old_size = (u32)es.raw_data.size(); + if (old_size && (es.fidMajor & 0xf0) == 0xe0) { - es.finish(stream); + // TODO (it's only for AVC, some ATX data may be lost) + while (es.isfull(old_size)) + { + if (Emu.IsStopped() || dmux.is_closed) break; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + es.push_au(old_size, es.last_dts, es.last_pts, stream.userdata, false, 0); + // callback auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); } + + if (es.raw_data.size()) + { + cellDmux->Error("dmuxFlushEs: 0x%x bytes lost (es_id=%d)", (u32)es.raw_data.size(), es.id); + } // callback auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 0eca5daef0..5da9258bb0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -358,7 +358,7 @@ struct PesHeader u64 pts; u64 dts; u8 size; - bool new_au; + bool has_ts; PesHeader(DemuxerStream& stream); }; @@ -438,15 +438,12 @@ class ElementaryStream SQueue entries; // AU starting addresses u32 put_count; // number of AU written + u32 got_count; // number of AU obtained by GetAu(Ex) u32 released; // number of AU released - u32 peek_count; // number of AU obtained by GetAu(Ex) u32 put; // AU that is being written now - u32 size; // number of bytes written (after 128b header) - //u32 first; // AU that will be released - //u32 peek; // AU that will be obtained by GetAu(Ex)/PeekAu(Ex) - bool is_full(); + bool is_full(u32 space); public: Demuxer* dmux; @@ -461,6 +458,13 @@ public: const u32 cbArg; const u32 spec; //addr + std::vector raw_data; // demultiplexed data stream (managed by demuxer thread) + size_t raw_pos; // should be <= raw_data.size() + u64 last_dts; + u64 last_pts; + + void push(DemuxerStream& stream, u32 size); // called by demuxer thread (not multithread-safe) + ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec) : dmux(dmux) , memAddr(a128(addr)) @@ -472,29 +476,19 @@ public: , cbFunc(cbFunc) , cbArg(cbArg) , spec(spec) - //, first(0) - //, peek(0) , put(memAddr) - , size(0) , put_count(0) + , got_count(0) , released(0) - , peek_count(0) + , raw_pos(0) + , last_dts(0xffffffffffffffffull) + , last_pts(0xffffffffffffffffull) { } - const u32 GetMaxAU() const; + bool isfull(u32 space); - u32 freespace(); - - bool hasunseen(); - - bool hasdata(); - - bool isfull(); - - void finish(DemuxerStream& stream); - - void push(DemuxerStream& stream, u32 sz, PesHeader& pes); + void push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool rap, u32 specific); bool release(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 0d447dea1d..4248c35d74 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -37,7 +37,10 @@ s64 spursCreateLv2EventQueue(vm::ptr spurs, u32& queue_id, vm::ptrm.nSpus = nSpus; spurs->m.spuPriority = spuPriority; #ifdef PRX_DEBUG - assert(spu_image_import(spurs->m.spuImg, vm::read32(libsre_rtoc - (isSecond ? 0x7E94 : 0x7E98)), 1) == CELL_OK); + if (s32 res = spu_image_import(spurs->m.spuImg, vm::read32(libsre_rtoc - (isSecond ? 0x7E94 : 0x7E98)), 1)) + { + assert(!"spu_image_import() failed"); + } #else spurs->m.spuImg.addr = Memory.Alloc(0x40000, 4096); #endif @@ -492,8 +498,14 @@ s64 spursInit( } } - assert(lwmutex_create(spurs->m.mutex, SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, *(u64*)"_spuPrv") == CELL_OK); - assert(lwcond_create(spurs->m.cond, spurs->m.mutex, *(u64*)"_spuPrv") == CELL_OK); + if (s32 res = lwmutex_create(spurs->m.mutex, SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, *(u64*)"_spuPrv")) + { + assert(!"lwmutex_create() failed"); + } + if (s32 res = lwcond_create(spurs->m.cond, spurs->m.mutex, *(u64*)"_spuPrv")) + { + assert(!"lwcond_create() failed"); + } spurs->m.flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_IS_SECOND : 0); spurs->m.flagRecv.write_relaxed(0xff); @@ -504,14 +516,20 @@ s64 spursInit( spurs->m.ppuPriority = ppuPriority; u32 queue; - assert(spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv") == CELL_OK); + if (s32 res = spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv")) + { + assert(!"spursCreateLv2EventQueue() failed"); + } spurs->m.queue = queue; u32 port = event_port_create(0); assert(port && ~port); spurs->m.port = port; - assert(sys_event_port_connect_local(port, queue) == CELL_OK); + if (s32 res = sys_event_port_connect_local(port, queue)) + { + assert(!"sys_event_port_connect_local() failed"); + } name = std::string(prefix, prefixSize); @@ -536,10 +554,16 @@ s64 spursInit( if (spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) { - assert(sys_lwmutex_lock(spurs->get_lwmutex(), 0) == CELL_OK); + if (s32 res = sys_lwmutex_lock(spurs->get_lwmutex(), 0)) + { + assert(!"sys_lwmutex_lock() failed"); + } if (spurs->m.xD66.read_relaxed()) { - assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + if (s32 res = sys_lwmutex_unlock(spurs->get_lwmutex())) + { + assert(!"sys_lwmutex_unlock() failed"); + } return; } else while (true) @@ -590,28 +614,40 @@ s64 spursInit( spurs->m.xD65.exchange(1); if (spurs->m.xD64.read_relaxed() == 0) { - assert(sys_lwcond_wait(spurs->get_lwcond(), 0) == CELL_OK); + if (s32 res = sys_lwcond_wait(spurs->get_lwcond(), 0)) + { + assert(!"sys_lwcond_wait() failed"); + } } spurs->m.xD65.exchange(0); if (spurs->m.xD66.read_relaxed()) { - assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + if (s32 res = sys_lwmutex_unlock(spurs->get_lwmutex())) + { + assert(!"sys_lwmutex_unlock() failed"); + } return; } } - assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + if (s32 res = sys_lwmutex_unlock(spurs->get_lwmutex())) + { + assert(!"sys_lwmutex_unlock() failed"); + } } if (Emu.IsStopped()) continue; - assert(sys_spu_thread_group_start(spurs->m.spuTG) == CELL_OK); + if (s32 res = sys_spu_thread_group_start(spurs->m.spuTG)) + { + assert(!"sys_spu_thread_group_start() failed"); + } if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::ptr::make(0), vm::ptr::make(0))) { if (res == CELL_ESTAT) { return; } - assert(res == CELL_OK); + assert(!"sys_spu_thread_group_join() failed"); } if (Emu.IsStopped()) continue; @@ -635,7 +671,10 @@ s64 spursInit( // enable exception event handler if (spurs->m.enableEH.compare_and_swap_test(be_t::make(0), be_t::make(1))) { - assert(sys_spu_thread_group_connect_event(spurs->m.spuTG, spurs->m.queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION) == CELL_OK); + if (s32 res = sys_spu_thread_group_connect_event(spurs->m.spuTG, spurs->m.queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION)) + { + assert(!"sys_spu_thread_group_connect_event() failed"); + } } spurs->m.unk22 = 0; @@ -997,7 +1036,10 @@ s64 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po } s32 sdk_ver; - assert(process_get_sdk_version(process_getpid(), sdk_ver) == CELL_OK); + if (s32 res = process_get_sdk_version(process_getpid(), sdk_ver)) + { + assert(!"process_get_sdk_version() failed"); + } if (sdk_ver == -1) sdk_ver = 0x460000; u8 _port = 0x3f; @@ -1236,9 +1278,18 @@ s64 spursWakeUp(vm::ptr spurs) spurs->m.xD64.exchange(1); if (spurs->m.xD65.read_sync()) { - assert(sys_lwmutex_lock(spurs->get_lwmutex(), 0) == 0); - assert(sys_lwcond_signal(spurs->get_lwcond()) == 0); - assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == 0); + if (s32 res = sys_lwmutex_lock(spurs->get_lwmutex(), 0)) + { + assert(!"sys_lwmutex_lock() failed"); + } + if (s32 res = sys_lwcond_signal(spurs->get_lwcond())) + { + assert(!"sys_lwcond_signal() failed"); + } + if (s32 res = sys_lwmutex_unlock(spurs->get_lwmutex())) + { + assert(!"sys_lwmutex_unlock() failed"); + } } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index cf754b28a0..afac57e65e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1086,7 +1086,10 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } } - assert(sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0) == CELL_OK); + if (s32 res = sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0)) + { + assert(!"sys_event_queue_receive() failed"); + } var1 = 1; } } @@ -1106,7 +1109,7 @@ s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 { // TODO //pointer = 0; - assert(0); + assert(!"syncLFQueueGetPushPointer2()"); return CELL_OK; } @@ -1268,7 +1271,7 @@ s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, { // TODO //if (fpSendSignal) return fpSendSignal(0, 0); - assert(0); + assert(!"syncLFQueueCompletePushPointer2()"); return CELL_OK; } @@ -1465,7 +1468,10 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } } - assert(sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0) == CELL_OK); + if (s32 res = sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0)) + { + assert(!"sys_event_queue_receive() failed"); + } var1 = 1; } } @@ -1485,7 +1491,7 @@ s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 { // TODO //pointer = 0; - assert(0); + assert(!"syncLFQueueGetPopPointer2()"); return CELL_OK; } @@ -1647,7 +1653,7 @@ s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, { // TODO //if (fpSendSignal) fpSendSignal(0, 0); - assert(0); + assert(!"syncLFQueueCompletePopPointer2()"); return CELL_OK; } @@ -1906,7 +1912,7 @@ s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr _sys_strcat(vm::ptr dest, vm::ptr source) { sysPrxForUser->Log("_sys_strcat(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); - assert(strcat(dest.get_ptr(), source.get_ptr()) == dest.get_ptr()); + if (strcat(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) + { + assert(!"strcat(): unexpected result"); + } return dest; } @@ -213,7 +216,10 @@ vm::ptr _sys_strncat(vm::ptr dest, vm::ptr source, u32 l { sysPrxForUser->Log("_sys_strncat(dest_addr=0x%x, source_addr=0x%x, len=%d)", dest.addr(), source.addr(), len); - assert(strncat(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr()); + if (strncat(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) + { + assert(!"strncat(): unexpected result"); + } return dest; } @@ -221,7 +227,10 @@ vm::ptr _sys_strcpy(vm::ptr dest, vm::ptr source) { sysPrxForUser->Log("_sys_strcpy(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); - assert(strcpy(dest.get_ptr(), source.get_ptr()) == dest.get_ptr()); + if (strcpy(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) + { + assert(!"strcpy(): unexpected result"); + } return dest; } @@ -234,7 +243,10 @@ vm::ptr _sys_strncpy(vm::ptr dest, vm::ptr source, u32 l return vm::ptr::make(0); } - assert(strncpy(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr()); + if (strncpy(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) + { + assert(!"strncpy(): unexpected result"); + } return dest; }