mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-14 18:58:29 +12:00
Add all the files
This commit is contained in:
parent
e3db07a16a
commit
d60742f52b
1445 changed files with 430238 additions and 0 deletions
220
src/Cafe/OS/common/OSCommon.cpp
Normal file
220
src/Cafe/OS/common/OSCommon.cpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
#include "Cafe/HW/Espresso/PPCState.h"
|
||||
#include "Cafe/OS/libs/proc_ui/proc_ui.h"
|
||||
#include "Cafe/OS/libs/nsysnet/nsysnet.h"
|
||||
#include "Cafe/OS/libs/nlibnss/nlibnss.h"
|
||||
#include "Cafe/OS/libs/nlibcurl/nlibcurl.h"
|
||||
#include "Cafe/OS/libs/nn_nfp/nn_nfp.h"
|
||||
#include "Cafe/OS/libs/nn_act/nn_act.h"
|
||||
#include "Cafe/OS/libs/nn_acp/nn_acp.h"
|
||||
#include "Cafe/OS/libs/nn_ac/nn_ac.h"
|
||||
#include "Cafe/OS/libs/nn_uds/nn_uds.h"
|
||||
#include "Cafe/OS/libs/nn_nim/nn_nim.h"
|
||||
#include "Cafe/OS/libs/nn_ndm/nn_ndm.h"
|
||||
#include "Cafe/OS/libs/nn_ec/nn_ec.h"
|
||||
#include "Cafe/OS/libs/nn_boss/nn_boss.h"
|
||||
#include "Cafe/OS/libs/nn_fp/nn_fp.h"
|
||||
#include "Cafe/OS/libs/nn_olv/nn_olv.h"
|
||||
#include "Cafe/OS/libs/nn_idbe/nn_idbe.h"
|
||||
#include "Cafe/OS/libs/nn_save/nn_save.h"
|
||||
#include "Cafe/OS/libs/erreula/erreula.h"
|
||||
#include "Cafe/OS/libs/sysapp/sysapp.h"
|
||||
#include "Cafe/OS/libs/dmae/dmae.h"
|
||||
#include "Cafe/OS/libs/snd_core/ax.h"
|
||||
#include "Cafe/OS/libs/gx2/GX2.h"
|
||||
#include "Cafe/OS/libs/vpad/vpad.h"
|
||||
#include "Cafe/OS/libs/nsyskbd/nsyskbd.h"
|
||||
#include "Cafe/OS/libs/nsyshid/nsyshid.h"
|
||||
#include "Cafe/OS/libs/snd_user/snd_user.h"
|
||||
#include "Cafe/OS/libs/zlib125/zlib125.h"
|
||||
#include "Cafe/OS/libs/padscore/padscore.h"
|
||||
#include "Cafe/OS/libs/camera/camera.h"
|
||||
#include "../libs/swkbd/swkbd.h"
|
||||
|
||||
struct osFunctionEntry_t
|
||||
{
|
||||
uint32 libHashA;
|
||||
uint32 libHashB;
|
||||
uint32 funcHashA;
|
||||
uint32 funcHashB;
|
||||
std::string name;
|
||||
HLEIDX hleFunc;
|
||||
|
||||
osFunctionEntry_t(uint32 libHashA, uint32 libHashB, uint32 funcHashA, uint32 funcHashB, std::string_view name, HLEIDX hleFunc) :
|
||||
libHashA(libHashA), libHashB(libHashB), funcHashA(funcHashA), funcHashB(funcHashB), name(name), hleFunc(hleFunc) {};
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 libHashA;
|
||||
uint32 libHashB;
|
||||
uint32 funcHashA;
|
||||
uint32 funcHashB;
|
||||
uint32 vPtr;
|
||||
}osPointerEntry_t;
|
||||
|
||||
std::vector<osFunctionEntry_t>* s_osFunctionTable;
|
||||
std::vector<osPointerEntry_t> osDataTable;
|
||||
|
||||
void osLib_generateHashFromName(const char* name, uint32* hashA, uint32* hashB)
|
||||
{
|
||||
uint32 h1 = 0x688BA2BA;
|
||||
uint32 h2 = 0xF64A71D5;
|
||||
while( *name )
|
||||
{
|
||||
uint32 c = (uint32)*name;
|
||||
h1 += c;
|
||||
h1 = (h1<<3)|((h1>>29));
|
||||
h2 ^= c;
|
||||
h2 = (h2<<7)|((h2>>25));
|
||||
h1 += h2;
|
||||
h2 += c;
|
||||
h2 = (h2<<3)|((h2>>29));
|
||||
name++;
|
||||
}
|
||||
*hashA = h1;
|
||||
*hashB = h2;
|
||||
}
|
||||
|
||||
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
|
||||
{
|
||||
if (!s_osFunctionTable)
|
||||
s_osFunctionTable = new std::vector<osFunctionEntry_t>(); // replace with static allocation + constinit once we have C++20 available
|
||||
// calculate hash
|
||||
uint32 libHashA, libHashB;
|
||||
uint32 funcHashA, funcHashB;
|
||||
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
|
||||
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
|
||||
// if entry already exists, update it
|
||||
for (auto& it : *s_osFunctionTable)
|
||||
{
|
||||
if (it.libHashA == libHashA &&
|
||||
it.libHashB == libHashB &&
|
||||
it.funcHashA == funcHashA &&
|
||||
it.funcHashB == funcHashB)
|
||||
{
|
||||
it.hleFunc = PPCInterpreter_registerHLECall(osFunction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
s_osFunctionTable->emplace_back(libHashA, libHashB, funcHashA, funcHashB, fmt::format("{}.{}", libraryName, functionName), PPCInterpreter_registerHLECall(osFunction));
|
||||
}
|
||||
|
||||
__declspec(dllexport) void osLib_registerHLEFunction(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
|
||||
{
|
||||
osLib_addFunctionInternal(libraryName, functionName, osFunction);
|
||||
}
|
||||
|
||||
sint32 osLib_getFunctionIndex(const char* libraryName, const char* functionName)
|
||||
{
|
||||
uint32 libHashA, libHashB;
|
||||
uint32 funcHashA, funcHashB;
|
||||
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
|
||||
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
|
||||
for (auto& it : *s_osFunctionTable)
|
||||
{
|
||||
if (it.libHashA == libHashA &&
|
||||
it.libHashB == libHashB &&
|
||||
it.funcHashA == funcHashA &&
|
||||
it.funcHashB == funcHashB)
|
||||
{
|
||||
return it.hleFunc;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr)
|
||||
{
|
||||
// calculate hash
|
||||
uint32 libHashA, libHashB;
|
||||
uint32 funcHashA, funcHashB;
|
||||
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
|
||||
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
|
||||
// if entry already exists, update it
|
||||
for (auto& it : osDataTable)
|
||||
{
|
||||
if (it.libHashA == libHashA &&
|
||||
it.libHashB == libHashB &&
|
||||
it.funcHashA == funcHashA &&
|
||||
it.funcHashB == funcHashB)
|
||||
{
|
||||
it.vPtr = vPtr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// add entry
|
||||
auto writeIndex = osDataTable.size();
|
||||
osDataTable.resize(osDataTable.size() + 1);
|
||||
osDataTable[writeIndex].libHashA = libHashA;
|
||||
osDataTable[writeIndex].libHashB = libHashB;
|
||||
osDataTable[writeIndex].funcHashA = funcHashA;
|
||||
osDataTable[writeIndex].funcHashB = funcHashB;
|
||||
osDataTable[writeIndex].vPtr = vPtr;
|
||||
}
|
||||
|
||||
uint32 osLib_getPointer(const char* libraryName, const char* functionName)
|
||||
{
|
||||
uint32 libHashA, libHashB;
|
||||
uint32 funcHashA, funcHashB;
|
||||
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
|
||||
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
|
||||
for (auto& it : osDataTable)
|
||||
{
|
||||
if (it.libHashA == libHashA &&
|
||||
it.libHashB == libHashB &&
|
||||
it.funcHashA == funcHashA &&
|
||||
it.funcHashB == funcHashB)
|
||||
{
|
||||
return it.vPtr;
|
||||
}
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void osLib_returnFromFunction(PPCInterpreter_t* hCPU, uint32 returnValue)
|
||||
{
|
||||
hCPU->gpr[3] = returnValue;
|
||||
hCPU->instructionPointer = hCPU->spr.LR;
|
||||
}
|
||||
|
||||
void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64)
|
||||
{
|
||||
hCPU->gpr[3] = (returnValue64>>32)&0xFFFFFFFF;
|
||||
hCPU->gpr[4] = (returnValue64>>0)&0xFFFFFFFF;
|
||||
hCPU->instructionPointer = hCPU->spr.LR;
|
||||
}
|
||||
|
||||
void osLib_load()
|
||||
{
|
||||
// load HLE modules
|
||||
coreinit_load();
|
||||
zlib::load();
|
||||
gx2_load();
|
||||
dmae_load();
|
||||
padscore::load();
|
||||
vpad::load();
|
||||
snd_core::loadExports();
|
||||
nn::erreula::load();
|
||||
nnAct_load();
|
||||
nn::acp::load();
|
||||
nnAc_load();
|
||||
nnEc_load();
|
||||
nnBoss_load();
|
||||
nn::nfp::load();
|
||||
nnUds_load();
|
||||
nn::nim::load();
|
||||
nn::ndm::load();
|
||||
nn::save::load();
|
||||
nsysnet_load();
|
||||
nn::fp::load();
|
||||
nn::olv::load();
|
||||
nn::idbe::load();
|
||||
nlibnss::load();
|
||||
nlibcurl::load();
|
||||
sysapp_load();
|
||||
nsyshid::load();
|
||||
nsyskbd::nsyskbd_load();
|
||||
swkbd::load();
|
||||
camera::load();
|
||||
procui_load();
|
||||
}
|
25
src/Cafe/OS/common/OSCommon.h
Normal file
25
src/Cafe/OS/common/OSCommon.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
struct PPCInterpreter_t;
|
||||
|
||||
|
||||
#define OSLIB_FUNCTIONTABLE_TYPE_FUNCTION (1)
|
||||
#define OSLIB_FUNCTIONTABLE_TYPE_POINTER (2)
|
||||
|
||||
void osLib_load();
|
||||
void osLib_generateHashFromName(const char* name, uint32* hashA, uint32* hashB);
|
||||
sint32 osLib_getFunctionIndex(const char* libraryName, const char* functionName);
|
||||
uint32 osLib_getPointer(const char* libraryName, const char* functionName);
|
||||
|
||||
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU));
|
||||
#define osLib_addFunction(__p1, __p2, __p3) osLib_addFunctionInternal((const char*)__p1, __p2, __p3)
|
||||
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr);
|
||||
|
||||
void osLib_returnFromFunction(PPCInterpreter_t* hCPU, uint32 returnValue);
|
||||
void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);
|
||||
|
||||
// libs
|
||||
#include "Cafe/OS/libs/coreinit/coreinit.h"
|
||||
|
||||
// utility functions
|
||||
#include "Cafe/OS/common/OSUtil.h"
|
233
src/Cafe/OS/common/OSUtil.h
Normal file
233
src/Cafe/OS/common/OSUtil.h
Normal file
|
@ -0,0 +1,233 @@
|
|||
#pragma once
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
|
||||
#include "Cafe/HW/Espresso/PPCState.h"
|
||||
#include "Cafe/HW/MMU/MMU.h"
|
||||
|
||||
#include <fmt/ostream.h>
|
||||
#include <fmt/compile.h>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
class cafeExportParamWrapper
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
static void getParamWrapper(PPCInterpreter_t* hCPU, int& gprIndex, int& fprIndex, T& v)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<T>)
|
||||
{
|
||||
uint32be addr;
|
||||
if (gprIndex >= 8)
|
||||
addr = memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
|
||||
else
|
||||
addr = hCPU->gpr[3 + gprIndex];
|
||||
|
||||
using TPtr = std::remove_pointer_t<T>;
|
||||
v = MEMPTR<TPtr>(addr).GetPtr();
|
||||
gprIndex++;
|
||||
}
|
||||
else if constexpr (std::is_base_of_v<MEMPTRBase, T>)
|
||||
{
|
||||
uint32be addr;
|
||||
if (gprIndex >= 8)
|
||||
addr = memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
|
||||
else
|
||||
addr = hCPU->gpr[3 + gprIndex];
|
||||
|
||||
v = addr.value();
|
||||
gprIndex++;
|
||||
}
|
||||
else if constexpr (std::is_enum_v<T>)
|
||||
{
|
||||
using TEnum = std::underlying_type_t<T>;
|
||||
getParamWrapper<TEnum>(hCPU, gprIndex, fprIndex, (TEnum&)v);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
{
|
||||
if constexpr (sizeof(T) == sizeof(uint64))
|
||||
{
|
||||
gprIndex = (gprIndex + 1)&~1;
|
||||
if (gprIndex >= 8)
|
||||
v = (T)memory_readU64(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
|
||||
else
|
||||
v = (T)(((uint64)hCPU->gpr[3 + gprIndex]) << 32) | ((uint64)hCPU->gpr[3 + gprIndex + 1]);
|
||||
|
||||
gprIndex += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gprIndex >= 8)
|
||||
v = (T)memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
|
||||
else
|
||||
v = (T)hCPU->gpr[3 + gprIndex];
|
||||
|
||||
gprIndex++;
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T>)
|
||||
{
|
||||
v = (T)ppcInterpreterCurrentInstance->fpr[1 + fprIndex].fpr;
|
||||
fprIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void setReturnResult(PPCInterpreter_t* hCPU, T r)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<T>)
|
||||
{
|
||||
hCPU->gpr[3] = MEMPTR(r).GetMPTR();
|
||||
}
|
||||
else if constexpr (std::is_reference_v<T>)
|
||||
{
|
||||
hCPU->gpr[3] = MEMPTR(&r).GetMPTR();
|
||||
}
|
||||
else if constexpr (std::is_enum_v<T>)
|
||||
{
|
||||
using TEnum = std::underlying_type_t<T>;
|
||||
setReturnResult<TEnum>(hCPU, (TEnum)r);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
{
|
||||
if constexpr(sizeof(T) == 8)
|
||||
{
|
||||
const auto t = static_cast<uint64>(r);
|
||||
hCPU->gpr[3] = (uint32)(t >> 32); // high
|
||||
hCPU->gpr[4] = (uint32)(t); // low
|
||||
}
|
||||
else
|
||||
{
|
||||
hCPU->gpr[3] = (uint32)r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cemu_assert_unimplemented();
|
||||
//static_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto getFormatResult(T r)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<T>)
|
||||
return MEMPTR(r).GetMPTR();
|
||||
else if constexpr (std::is_enum_v<T>)
|
||||
return static_cast<std::underlying_type_t<T>>(r);
|
||||
else if constexpr(!std::is_fundamental_v<T>)
|
||||
return MEMPTR(&r).GetMPTR();
|
||||
else
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T cafeExportGetParamWrapper(PPCInterpreter_t* hCPU, int& gprIndex, int& fprIndex)
|
||||
{
|
||||
T v;
|
||||
cafeExportParamWrapper::getParamWrapper(hCPU, gprIndex, fprIndex, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename R, typename ... Args>
|
||||
static std::tuple<Args...> cafeExportBuildArgTuple(PPCInterpreter_t* hCPU, R(fn)(Args...))
|
||||
{
|
||||
int gprIndex = 0;
|
||||
int fprIndex = 0;
|
||||
return std::tuple<Args...>{ cafeExportGetParamWrapper<Args>(hCPU, gprIndex, fprIndex)... };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
using _CAFE_FORMAT_ARG = std::conditional_t<std::is_pointer_v<T>,
|
||||
std::conditional_t<std::is_same_v<T, char*> || std::is_same_v<T, const char*>, T, MEMPTR<T>>, T>;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
static auto cafeExportBuildFormatTuple(PPCInterpreter_t* hCPU, R(fn)(Args...))
|
||||
{
|
||||
int gprIndex = 0;
|
||||
int fprIndex = 0;
|
||||
return std::tuple<_CAFE_FORMAT_ARG<Args>...>{
|
||||
cafeExportGetParamWrapper<_CAFE_FORMAT_ARG<Args>>(hCPU, gprIndex, fprIndex)...
|
||||
};
|
||||
}
|
||||
|
||||
template<auto fn, typename TNames, LogType TLogType>
|
||||
void cafeExportCallWrapper(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
auto tup = cafeExportBuildArgTuple(hCPU, fn);
|
||||
bool shouldLog = false;
|
||||
if (cemuLog_isLoggingEnabled(TLogType))
|
||||
{
|
||||
const auto format_tup = cafeExportBuildFormatTuple(hCPU, fn);
|
||||
if(cemuLog_advancedPPCLoggingEnabled())
|
||||
{
|
||||
MPTR threadMPTR = memory_getVirtualOffsetFromPointer(coreinit::OSGetCurrentThread());
|
||||
if constexpr (std::tuple_size<decltype(format_tup)>::value > 0)
|
||||
shouldLog = cemuLog_log(TLogType, "{}.{}{} # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), format_tup, hCPU->spr.LR, threadMPTR);
|
||||
else
|
||||
shouldLog = cemuLog_log(TLogType, "{}.{}() # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), hCPU->spr.LR, threadMPTR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (std::tuple_size<decltype(format_tup)>::value > 0)
|
||||
{
|
||||
shouldLog = cemuLog_log(TLogType, "{}.{}{}", TNames::GetLib(), TNames::GetFunc(), format_tup);
|
||||
}
|
||||
else
|
||||
shouldLog = cemuLog_log(TLogType, "{}.{}()", TNames::GetLib(), TNames::GetFunc());
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (!std::is_void<decltype(std::apply(fn, tup))>::value)
|
||||
{
|
||||
// has non-void return type
|
||||
decltype(auto) result = std::apply(fn, tup);
|
||||
cafeExportParamWrapper::setReturnResult<decltype(std::apply(fn, tup))>(hCPU, result);
|
||||
if(shouldLog)
|
||||
cemuLog_log(TLogType, "\t\t{}.{} -> {}", TNames::GetLib(), TNames::GetFunc(), cafeExportParamWrapper::getFormatResult(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
// return type is void
|
||||
std::apply(fn, tup);
|
||||
}
|
||||
// return from func
|
||||
hCPU->instructionPointer = hCPU->spr.LR;
|
||||
}
|
||||
|
||||
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU));
|
||||
|
||||
template<auto fn, typename TNames, LogType TLogType>
|
||||
void cafeExportMakeWrapper(const char* libname, const char* funcname)
|
||||
{
|
||||
osLib_addFunctionInternal(libname, funcname, &cafeExportCallWrapper<fn, TNames, TLogType>);
|
||||
}
|
||||
|
||||
#define cafeExportRegister(__libname, __func, __logtype) \
|
||||
{ \
|
||||
struct StringWrapper { \
|
||||
static const char* GetLib() { return __libname; }; \
|
||||
static const char* GetFunc() { return #__func; }; \
|
||||
}; \
|
||||
cafeExportMakeWrapper<__func, StringWrapper, __logtype>(__libname, # __func);\
|
||||
}
|
||||
|
||||
#define cafeExportRegisterFunc(__func, __libname, __funcname, __logtype) \
|
||||
{\
|
||||
struct StringWrapper { \
|
||||
static const char* GetLib() { return __libname; }; \
|
||||
static const char* GetFunc() { return __funcname; }; \
|
||||
}; \
|
||||
cafeExportMakeWrapper<__func, StringWrapper, __logtype>(__libname, __funcname);\
|
||||
}
|
||||
|
||||
template<auto fn>
|
||||
MPTR makeCallableExport()
|
||||
{
|
||||
return PPCInterpreter_makeCallableExportDepr(&cafeExportCallWrapper<fn, "CALLABLE_EXPORT">);
|
||||
}
|
||||
|
||||
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr);
|
68
src/Cafe/OS/common/PPCConcurrentQueue.h
Normal file
68
src/Cafe/OS/common/PPCConcurrentQueue.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <queue>
|
||||
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
|
||||
|
||||
template <typename T>
|
||||
class PPCConcurrentQueue
|
||||
{
|
||||
public:
|
||||
PPCConcurrentQueue() {}
|
||||
PPCConcurrentQueue(const PPCConcurrentQueue&) = delete;
|
||||
PPCConcurrentQueue& operator=(const PPCConcurrentQueue&) = delete;
|
||||
|
||||
void push(const T& item, OSThread_t* thread)
|
||||
{
|
||||
//if(thread == nullptr)
|
||||
// thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
|
||||
//OSThread_t* currentThread = coreinit::OSGetCurrentThread();
|
||||
//cemu_assert_debug(thread == nullptr || currentThread == thread);
|
||||
|
||||
// forceLogDebug_printf("push suspend count: %d", _swapEndianU32(thread->suspend) - m_suspendCount);
|
||||
|
||||
//__OSLockScheduler();
|
||||
|
||||
__OSLockScheduler();
|
||||
m_queue.push(item);
|
||||
coreinit::__OSResumeThreadInternal(thread, 1);
|
||||
__OSUnlockScheduler();
|
||||
|
||||
//__OSUnlockScheduler();
|
||||
|
||||
//m_prevSuspendCount = _swapEndianU32(thread->suspend) - m_suspendCount;
|
||||
//coreinit_resumeThread(thread, _swapEndianU32(thread->suspend));
|
||||
}
|
||||
|
||||
T pop(OSThread_t* thread = nullptr)
|
||||
{
|
||||
//if (thread == nullptr)
|
||||
// thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
|
||||
|
||||
OSThread_t* currentThread = coreinit::OSGetCurrentThread();
|
||||
cemu_assert_debug(thread == nullptr || currentThread == thread);
|
||||
|
||||
//thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
|
||||
|
||||
// forceLogDebug_printf("pop suspend count: %d", _swapEndianU32(thread->suspend) + m_suspendCount);
|
||||
|
||||
__OSLockScheduler();
|
||||
if (m_queue.empty())
|
||||
coreinit::__OSSuspendThreadInternal(thread);
|
||||
auto val = m_queue.front();
|
||||
m_queue.pop();
|
||||
__OSUnlockScheduler();
|
||||
|
||||
//coreinit_suspendThread(thread, m_suspendCount + m_prevSuspendCount);
|
||||
//m_prevSuspendCount = 0;
|
||||
//PPCCore_switchToScheduler();
|
||||
|
||||
return val;
|
||||
}
|
||||
private:
|
||||
//const int m_suspendCount = 8000;
|
||||
std::queue<T> m_queue;
|
||||
//std::atomic<uint32> m_prevSuspendCount;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue