vm::var replaced, atomic_op simplified

This commit is contained in:
Nekotekina 2015-06-26 17:45:13 +03:00
parent c598fe7aa9
commit ec68e012f9
9 changed files with 165 additions and 258 deletions

View File

@ -61,14 +61,6 @@ template<> struct atomic_op_result_t<void>
}
};
struct break_never_t
{
template<typename RT> inline bool operator()(const atomic_op_result_t<RT>&) const
{
return false;
}
};
template<typename T> union _atomic_base
{
using type = std::remove_cv_t<T>;
@ -152,7 +144,7 @@ public:
}
// perform an atomic operation on data (callable object version, first arg is a reference to atomic type)
template<typename Break_if = break_never_t, typename F, typename... Args> auto atomic_op(F func, Args&&... args) volatile -> decltype(func(std::declval<T&>(), args...))
template<typename F, typename... Args> auto atomic_op(F func, Args&&... args) volatile -> decltype(func(std::declval<T&>(), args...))
{
while (true)
{
@ -165,16 +157,15 @@ public:
// call atomic op for the local copy of the old value and save the return value of the function
atomic_op_result_t<std::result_of_t<F(T&, Args...)>> result(func, to_type(_new), args...);
// 1) check return value using callable object of Break_if type, return if condition met
// 2) atomically compare value with `old`, replace with `_new` and return on success
if (Break_if()(result) || sync_bool_compare_and_swap(&sub_data, old, _new)) return result.move();
// atomically compare value with `old`, replace with `_new` and return on success
if (sync_bool_compare_and_swap(&sub_data, old, _new)) return result.move();
}
}
// perform an atomic operation on data (member function version)
template<typename Break_if = break_never_t, typename CT, typename RT, typename... FArgs, typename... Args, typename = std::enable_if_t<std::is_same<T, CT>::value>> auto atomic_op(RT(CT::* func)(FArgs...), Args&&... args) volatile -> decltype((std::declval<T&>().*func)(args...))
template<typename RT, typename... FArgs, typename CT, typename... Args, typename = std::enable_if_t<std::is_same<T, CT>::value>> auto atomic_op(RT(CT::* func)(FArgs...), Args&&... args) volatile -> decltype((std::declval<T&>().*func)(args...))
{
return atomic_op<Break_if>(std::mem_fn(func), std::forward<Args>(args)...);
return atomic_op(std::mem_fn(func), std::forward<Args>(args)...);
}
// atomic bitwise OR, returns previous data

View File

@ -28,10 +28,10 @@ s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 er
return CELL_HDDGAME_ERROR_PARAM;
}
vm::var<CellHddGameSystemFileParam> param;
vm::var<CellHddGameCBResult> result;
vm::var<CellHddGameStatGet> get;
vm::var<CellHddGameStatSet> set;
vm::stackvar<CellHddGameSystemFileParam> param(CPU);
vm::stackvar<CellHddGameCBResult> result(CPU);
vm::stackvar<CellHddGameStatGet> get(CPU);
vm::stackvar<CellHddGameStatSet> set(CPU);
get->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST;

View File

@ -92,26 +92,26 @@ s32 cellGifDecReadHeader(
const u64& fileSize = subHandle_data->fileSize;
CellGifDecInfo& current_info = subHandle_data->info;
//Write the header to buffer
vm::var<u8[13]> buffer; // Alloc buffer for GIF header
// Write the header to buffer
u8 buffer[13];
switch(subHandle_data->src.srcSelect.value())
{
case CELL_GIFDEC_BUFFER:
memmove(buffer.begin(), subHandle_data->src.streamPtr.get_ptr(), buffer.size());
std::memcpy(buffer, subHandle_data->src.streamPtr.get_ptr(), sizeof(buffer));
break;
case CELL_GIFDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
file->file->Seek(0);
file->file->Read(buffer.begin(), buffer.size());
file->file->Read(buffer, sizeof(buffer));
break;
}
}
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
if (*(be_t<u32>*)buffer != 0x47494638 ||
(*(le_t<u16>*)(buffer + 4) != 0x6139 && *(le_t<u16>*)(buffer + 4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
{
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
}
@ -190,19 +190,19 @@ s32 cellGifDecDecodeData(
const CellGifDecOutParam& current_outParam = subHandle_data->outParam;
//Copy the GIF file to a buffer
vm::var<unsigned char[]> gif((u32)fileSize);
std::unique_ptr<u8[]> gif(new u8[fileSize]);
switch(subHandle_data->src.srcSelect.value())
{
case CELL_GIFDEC_BUFFER:
memmove(gif.begin(), subHandle_data->src.streamPtr.get_ptr(), gif.size());
std::memcpy(gif.get(), subHandle_data->src.streamPtr.get_ptr(), fileSize);
break;
case CELL_GIFDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
file->file->Seek(0);
file->file->Read(gif.ptr(), gif.size());
file->file->Read(gif.get(), fileSize);
break;
}
}
@ -211,7 +211,7 @@ s32 cellGifDecDecodeData(
int width, height, actual_components;
auto image = std::unique_ptr<unsigned char,decltype(&::free)>
(
stbi_load_from_memory(gif.ptr(), (s32)fileSize, &width, &height, &actual_components, 4),
stbi_load_from_memory(gif.get(), (s32)fileSize, &width, &height, &actual_components, 4),
&::free
);

View File

@ -100,26 +100,26 @@ s32 cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDecInfo>
const u64& fileSize = subHandle_data->fileSize;
CellJpgDecInfo& current_info = subHandle_data->info;
//Write the header to buffer
vm::var<u8[]> buffer((u32)fileSize);
// Write the header to buffer
std::unique_ptr<u8[]> buffer(new u8[fileSize]);
switch(subHandle_data->src.srcSelect.value())
{
case CELL_JPGDEC_BUFFER:
memmove(buffer.begin(), vm::get_ptr<void>(subHandle_data->src.streamPtr), buffer.size());
std::memcpy(buffer.get(), vm::get_ptr(subHandle_data->src.streamPtr), fileSize);
break;
case CELL_JPGDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
file->file->Seek(0);
file->file->Read(buffer.ptr(), buffer.size());
file->file->Read(buffer.get(), fileSize);
break;
}
}
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
if ((le_t<u32>&)(buffer[0]) != 0xE0FFD8FF || // Error: Not a valid SOI header
(le_t<u32>&)(buffer[6]) != 0x4649464A) // Error: Not a valid JFIF string
{
return CELL_JPGDEC_ERROR_HEADER;
}
@ -175,19 +175,19 @@ s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::cp
const CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
//Copy the JPG file to a buffer
vm::var<unsigned char[]> jpg((u32)fileSize);
std::unique_ptr<u8[]> jpg(new u8[fileSize]);
switch(subHandle_data->src.srcSelect.value())
{
case CELL_JPGDEC_BUFFER:
memmove(jpg.begin(), vm::get_ptr<void>(subHandle_data->src.streamPtr), jpg.size());
std::memcpy(jpg.get(), vm::get_ptr(subHandle_data->src.streamPtr), fileSize);
break;
case CELL_JPGDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
file->file->Seek(0);
file->file->Read(jpg.ptr(), jpg.size());
file->file->Read(jpg.get(), fileSize);
break;
}
}
@ -196,7 +196,7 @@ s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::cp
int width, height, actual_components;
auto image = std::unique_ptr<unsigned char,decltype(&::free)>
(
stbi_load_from_memory(jpg.ptr(), (s32)fileSize, &width, &height, &actual_components, 4),
stbi_load_from_memory(jpg.get(), (s32)fileSize, &width, &height, &actual_components, 4),
&::free
);

View File

@ -137,20 +137,19 @@ s32 pngReadHeader(
return CELL_PNGDEC_ERROR_HEADER; // The file is smaller than the length of a PNG header
}
//Write the header to buffer
vm::var<u8[34]> buffer; // Alloc buffer for PNG header
auto buffer_32 = buffer.To<be_t<u32>>();
// Write the header to buffer
u8 buffer[34]; be_t<u32>* buffer_32 = reinterpret_cast<be_t<u32>*>(buffer);
switch (stream->src.srcSelect.value())
{
case CELL_PNGDEC_BUFFER:
memmove(buffer.begin(), stream->src.streamPtr.get_ptr(), buffer.size());
std::memcpy(buffer, stream->src.streamPtr.get_ptr(), sizeof(buffer));
break;
case CELL_PNGDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(stream->fd);
file->file->Seek(0);
file->file->Read(buffer.begin(), buffer.size());
file->file->Read(buffer, sizeof(buffer));
break;
}
}
@ -249,20 +248,20 @@ s32 pngDecodeData(
const u64& fileSize = stream->fileSize;
const CellPngDecOutParam& current_outParam = stream->outParam;
//Copy the PNG file to a buffer
vm::var<unsigned char[]> png((u32)fileSize);
// Copy the PNG file to a buffer
std::unique_ptr<u8[]> png(new u8[fileSize]);
switch (stream->src.srcSelect.value())
{
case CELL_PNGDEC_BUFFER:
memmove(png.begin(), stream->src.streamPtr.get_ptr(), png.size());
std::memcpy(png.get(), stream->src.streamPtr.get_ptr(), fileSize);
break;
case CELL_PNGDEC_FILE:
{
auto file = Emu.GetIdManager().get<lv2_file_t>(stream->fd);
file->file->Seek(0);
file->file->Read(png.ptr(), png.size());
file->file->Read(png.get(), fileSize);
break;
}
}
@ -271,7 +270,7 @@ s32 pngDecodeData(
int width, height, actual_components;
auto image = std::unique_ptr<unsigned char, decltype(&::free)>
(
stbi_load_from_memory(png.ptr(), (s32)fileSize, &width, &height, &actual_components, 4),
stbi_load_from_memory(png.get(), (s32)fileSize, &width, &height, &actual_components, 4),
&::free
);
if (!image)

View File

@ -714,7 +714,7 @@ void SetFlipHandler(vm::ptr<void(u32)> handler)
}
}
int cellRescSetDisplayMode(u32 displayMode)
int cellRescSetDisplayMode(PPUThread& CPU, u32 displayMode)
{
cellResc.Warning("cellRescSetDisplayMode(displayMode=%d)", displayMode);
@ -765,7 +765,7 @@ int cellRescSetDisplayMode(u32 displayMode)
else m_pCFragmentShader = m_pCFragmentShaderArray[RESC_SHADER_DEFAULT_BILINEAR];
}*/
vm::var<CellVideoOutConfiguration> videocfg;
vm::stackvar<CellVideoOutConfiguration> videocfg(CPU);
videocfg->resolutionId = RescBufferMode2SysutilResolutionId(s_rescInternalInstance->m_dstMode);
videocfg->format = RescDstFormat2SysutilFormat(s_rescInternalInstance->m_pRescDsts->format );
videocfg->aspect = CELL_VIDEO_OUT_ASPECT_AUTO;
@ -1030,7 +1030,7 @@ int cellRescSetWaitFlip()
return CELL_OK;
}
int cellRescSetBufferAddress(vm::ptr<u32> colorBuffers, vm::ptr<u32> vertexArray, vm::ptr<u32> fragmentShader)
int cellRescSetBufferAddress(PPUThread& CPU, vm::ptr<u32> colorBuffers, vm::ptr<u32> vertexArray, vm::ptr<u32> fragmentShader)
{
cellResc.Warning("cellRescSetBufferAddress(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr());
@ -1050,7 +1050,7 @@ int cellRescSetBufferAddress(vm::ptr<u32> colorBuffers, vm::ptr<u32> vertexArray
s_rescInternalInstance->m_vertexArrayEA = vertexArray.addr();
s_rescInternalInstance->m_fragmentUcodeEA = fragmentShader.addr();
vm::var<be_t<u32>> dstOffset;
vm::stackvar<be_t<u32>> dstOffset(CPU);
cellGcmAddressToOffset(s_rescInternalInstance->m_colorBuffersEA, dstOffset);
for (int i=0; i<GetNumColorBuffers(); i++)

View File

@ -148,7 +148,7 @@ s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr<CellSpurs> spurs, vm::ptr<Ce
s32 cellSpursDestroyTaskset2();
s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr<CellSpursTaskset> taskset, vm::ptr<CellSpursTasksetExceptionEventHandler> handler, vm::ptr<u64> arg);
s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr<CellSpursTaskset> taskset);
s32 cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursTaskset> taskset, u32 id);
s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursTaskset> taskset, u32 id);
s32 cellSpursTasksetGetSpursAddress(vm::cptr<CellSpursTaskset> taskset, vm::ptr<u32> spurs);
s32 cellSpursGetTasksetInfo();
s32 _cellSpursTasksetAttributeInitialize(vm::ptr<CellSpursTasksetAttribute> attribute, u32 revision, u32 sdk_version, u64 args, vm::cptr<u8> priority, u32 max_contention);
@ -2902,7 +2902,7 @@ s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr<CellSpursEventFlag> eventFlag,
vm::stackvar<vm::bptr<CellSpursTaskset>> taskset(CPU);
if (eventFlag->isIwl)
{
cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs>::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]);
cellSpursLookUpTasksetAddress(CPU, vm::ptr<CellSpurs>::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]);
}
else
{
@ -3658,7 +3658,7 @@ s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr<CellSpursTaskset> taskset, vm::p
return CELL_SPURS_TASK_ERROR_ALIGN;
}
vm::var<be_t<u32>> tmpTaskId;
vm::stackvar<be_t<u32>> tmpTaskId(CPU);
auto rc = spursCreateTask(taskset, tmpTaskId, vm::ptr<u32>::make(elf_addr), vm::ptr<u32>::make(context_addr), context_size, lsPattern, argument);
if (rc != CELL_OK)
{
@ -3990,7 +3990,7 @@ s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr<CellSpursTaskset> taskset
return CELL_OK;
}
s32 cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursTaskset> taskset, u32 id)
s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursTaskset> taskset, u32 id)
{
cellSpurs.Warning("cellSpursLookUpTasksetAddress(spurs=*0x%x, taskset=**0x%x, id=0x%x)", spurs, taskset, id);
@ -3999,7 +3999,7 @@ s32 cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursTa
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
}
vm::var<be_t<u64>> data;
vm::stackvar<be_t<u64>> data(CPU);
if (s32 rc = cellSpursGetWorkloadData(spurs, data, id))
{
// Convert policy module error code to a task error code

View File

@ -436,7 +436,7 @@ s32 cellSyncQueuePush(vm::ptr<CellSyncQueue> queue, vm::cptr<void> buffer)
u32 position;
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_push, depth, position)));
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_push_begin, depth, position)));
// copy data from the buffer at the position
std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size);
@ -467,7 +467,7 @@ s32 cellSyncQueueTryPush(vm::ptr<CellSyncQueue> queue, vm::cptr<void> buffer)
u32 position;
if (!queue->ctrl.atomic_op(&sync_queue_t::try_push, depth, position))
if (!queue->ctrl.atomic_op(&sync_queue_t::try_push_begin, depth, position))
{
return CELL_SYNC_ERROR_BUSY;
}
@ -501,7 +501,7 @@ s32 cellSyncQueuePop(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buffer)
u32 position;
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_pop, depth, position)));
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_pop_begin, depth, position)));
// copy data at the position to the buffer
std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size);
@ -532,7 +532,7 @@ s32 cellSyncQueueTryPop(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buffer)
u32 position;
if (!queue->ctrl.atomic_op(&sync_queue_t::try_pop, depth, position))
if (!queue->ctrl.atomic_op(&sync_queue_t::try_pop_begin, depth, position))
{
return CELL_SYNC_ERROR_BUSY;
}
@ -566,7 +566,7 @@ s32 cellSyncQueuePeek(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buffer)
u32 position;
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_peek, depth, position)));
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_peek_begin, depth, position)));
// copy data at the position to the buffer
std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size);
@ -597,7 +597,7 @@ s32 cellSyncQueueTryPeek(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buffer)
u32 position;
if (!queue->ctrl.atomic_op(&sync_queue_t::try_peek, depth, position))
if (!queue->ctrl.atomic_op(&sync_queue_t::try_peek_begin, depth, position))
{
return CELL_SYNC_ERROR_BUSY;
}
@ -646,44 +646,11 @@ s32 cellSyncQueueClear(vm::ptr<CellSyncQueue> queue)
return CELL_SYNC_ERROR_ALIGN;
}
const u32 depth = queue->check_depth();
queue->check_depth();
// TODO: optimize if possible
g_sync_queue_wm.wait_op(queue.addr(), [queue, depth]()
{
return CELL_OK == queue->ctrl.atomic_op([depth](sync_queue_t& queue) -> s32
{
const u32 v1 = queue.m_v1;
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_clear_begin_1)));
// extract first byte, repeat if not zero, insert 1
if (v1 >> 24)
{
return CELL_SYNC_ERROR_BUSY;
}
queue.m_v1 = v1 | 0x1000000;
return CELL_OK;
});
});
g_sync_queue_wm.wait_op(queue.addr(), [queue, depth]()
{
return CELL_OK == queue->ctrl.atomic_op([depth](sync_queue_t& queue) -> s32
{
const u32 v2 = queue.m_v2;
// extract 5th byte, repeat if not zero, insert 1
if (v2 >> 24)
{
return CELL_SYNC_ERROR_BUSY;
}
queue.m_v2 = v2 | 0x1000000;
return CELL_OK;
});
});
g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_clear_begin_2)));
queue->ctrl.exchange({});
@ -694,7 +661,7 @@ s32 cellSyncQueueClear(vm::ptr<CellSyncQueue> queue)
// LFQueue functions
void syncLFQueueInit(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
void syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
{
queue->m_size = size;
queue->m_depth = depth;
@ -734,46 +701,54 @@ void syncLFQueueInit(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 siz
queue->m_eq_id = 0;
}
s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
s32 cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
{
cellSync.Warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal);
if (!queue)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (size)
{
if (!buffer)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (size > 0x4000 || size % 16)
{
return CELL_SYNC_ERROR_INVAL;
}
}
if (!depth || (depth >> 15) || direction > 3)
{
return CELL_SYNC_ERROR_INVAL;
}
if (!queue.aligned() || buffer % 16)
{
return CELL_SYNC_ERROR_ALIGN;
}
// prx: get sdk version of current process, return non-zero result of sys_process_get_sdk_version
// get sdk version of current process
s32 sdk_ver;
s32 ret = process_get_sdk_version(process_getpid(), sdk_ver);
if (ret != CELL_OK)
if (s32 ret = process_get_sdk_version(process_getpid(), sdk_ver))
{
return ret;
}
if (sdk_ver == -1)
{
sdk_ver = 0x460000;
}
// prx: reserve u32 at 0x2c offset
// reserve `init`
u32 old_value;
while (true)
{
const auto old = queue->init.load();
@ -785,6 +760,7 @@ s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u3
{
return CELL_SYNC_ERROR_STAT;
}
old_value = old;
}
else
@ -792,6 +768,7 @@ s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u3
if (sdk_ver > 0x17ffff)
{
auto data = vm::get_ptr<u64>(queue.addr());
for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i++)
{
if (data[i])
@ -800,6 +777,7 @@ s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u3
}
}
}
init = 1;
old_value = 1;
}
@ -813,37 +791,31 @@ s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u3
{
return CELL_SYNC_ERROR_INVAL;
}
if (sdk_ver > 0x17ffff)
{
if (queue->m_eaSignal.addr() != eaSignal.addr() || queue->m_direction != direction)
if (queue->m_eaSignal != eaSignal || queue->m_direction != direction)
{
return CELL_SYNC_ERROR_INVAL;
}
}
_mm_mfence();
}
else
{
// prx: call internal function with same arguments
syncLFQueueInit(queue, buffer, size, depth, direction, eaSignal);
syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal);
// prx: sync, clear u32 at 0x2c offset
queue->init.exchange({});
}
// prx: sync
_mm_mfence();
return CELL_OK;
}
s32 cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
s32 _cellSyncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<s32> pointer, u32 isBlocking, u32 useEventQueue)
{
cellSync.Warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal);
cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue);
return syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal);
}
s32 syncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue)
{
if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)
{
return CELL_SYNC_ERROR_PERM;
@ -890,8 +862,9 @@ s32 syncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s3
if (var2 < depth)
{
pointer = (s16)push.m_h8;
if (pointer + 1 >= depth * 2)
const s32 _pointer = (s16)push.m_h8;
*pointer = _pointer;
if (_pointer + 1 >= depth * 2)
{
push.m_h8 = 0;
}
@ -938,38 +911,18 @@ s32 syncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s3
}
}
s32 _cellSyncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> pointer, u32 isBlocking, u32 useEventQueue)
{
cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue);
s32 pointer_value;
s32 result = syncLFQueueGetPushPointer(CPU, queue, pointer_value, isBlocking, useEventQueue);
*pointer = pointer_value;
return result;
}
s32 syncLFQueueGetPushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue)
{
throw __FUNCTION__;
}
s32 _cellSyncLFQueueGetPushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> pointer, u32 isBlocking, u32 useEventQueue)
s32 _cellSyncLFQueueGetPushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<s32> pointer, u32 isBlocking, u32 useEventQueue)
{
// arguments copied from _cellSyncLFQueueGetPushPointer
cellSync.Todo("_cellSyncLFQueueGetPushPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue);
s32 pointer_value;
s32 result = syncLFQueueGetPushPointer2(CPU,queue, pointer_value, isBlocking, useEventQueue);
*pointer = pointer_value;
return result;
throw __FUNCTION__;
}
s32 syncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal)
s32 _cellSyncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal)
{
cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal);
if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)
{
return CELL_SYNC_ERROR_PERM;
@ -1008,7 +961,7 @@ s32 syncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queu
var9_ = 1 << var9_;
}
s32 var9 = cntlz32((u32)(u16)~(var9_ | (u16)push3.m_h6)) - 16; // count leading zeros in u16
s32 var5 = (s32)(u16)push3.m_h6 | var9_;
if (var9 & 0x30)
{
@ -1102,24 +1055,12 @@ s32 syncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queu
}
}
s32 _cellSyncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal)
{
cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal);
return syncLFQueueCompletePushPointer(CPU, queue, pointer, fpSendSignal);
}
s32 syncLFQueueCompletePushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal)
{
throw __FUNCTION__;
}
s32 _cellSyncLFQueueCompletePushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal)
{
// arguments copied from _cellSyncLFQueueCompletePushPointer
cellSync.Todo("_cellSyncLFQueueCompletePushPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal);
return syncLFQueueCompletePushPointer2(CPU, queue, pointer, fpSendSignal);
throw __FUNCTION__;
}
s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::cptr<void> buffer, u32 isBlocking)
@ -1131,12 +1072,13 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm:
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned() || buffer % 16)
{
return CELL_SYNC_ERROR_ALIGN;
}
s32 position;
vm::stackvar<be_t<s32>> position(CPU);
while (true)
{
@ -1144,19 +1086,17 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm:
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
res = syncLFQueueGetPushPointer(CPU, queue, position, isBlocking, 0);
res = _cellSyncLFQueueGetPushPointer(CPU, queue, position, isBlocking, 0);
}
else
{
res = syncLFQueueGetPushPointer2(CPU, queue, position, isBlocking, 0);
res = _cellSyncLFQueueGetPushPointer2(CPU, queue, position, isBlocking, 0);
}
if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN)
{
if (res)
{
return res;
}
if (res) return res;
break;
}
@ -1171,25 +1111,24 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm:
const s32 depth = queue->m_depth;
const s32 size = queue->m_size;
const u32 addr = vm::cast<u64>((queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position));
memcpy(vm::get_ptr<void>(addr), buffer.get_ptr(), size);
s32 res;
const s32 pos = position.value();
const u32 addr = vm::cast<u64>((queue->m_buffer.addr() & ~1ull) + size * (pos >= depth ? pos - depth : pos));
std::memcpy(vm::get_ptr<void>(addr), buffer.get_ptr(), size);
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
res = syncLFQueueCompletePushPointer(CPU, queue, position, nullptr);
return _cellSyncLFQueueCompletePushPointer(CPU, queue, pos, vm::null);
}
else
{
res = syncLFQueueCompletePushPointer2(CPU, queue, position, nullptr);
return _cellSyncLFQueueCompletePushPointer2(CPU, queue, pos, vm::null);
}
return res;
}
s32 syncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue)
s32 _cellSyncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<s32> pointer, u32 isBlocking, u32 arg4, u32 useEventQueue)
{
cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue);
if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)
{
return CELL_SYNC_ERROR_PERM;
@ -1236,8 +1175,9 @@ s32 syncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32
if (var2 > 0)
{
pointer = (s16)pop.m_h4;
if (pointer + 1 >= depth * 2)
const s32 _pointer = (s16)pop.m_h4;
*pointer = _pointer;
if (_pointer + 1 >= depth * 2)
{
pop.m_h4 = 0;
}
@ -1284,38 +1224,19 @@ s32 syncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32
}
}
s32 _cellSyncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> pointer, u32 isBlocking, u32 arg4, u32 useEventQueue)
{
cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue);
s32 pointer_value;
s32 result = syncLFQueueGetPopPointer(CPU, queue, pointer_value, isBlocking, arg4, useEventQueue);
*pointer = pointer_value;
return result;
}
s32 syncLFQueueGetPopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue)
{
throw __FUNCTION__;
}
s32 _cellSyncLFQueueGetPopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> pointer, u32 isBlocking, u32 useEventQueue)
s32 _cellSyncLFQueueGetPopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<s32> pointer, u32 isBlocking, u32 useEventQueue)
{
// arguments copied from _cellSyncLFQueueGetPopPointer
cellSync.Todo("_cellSyncLFQueueGetPopPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue);
s32 pointer_value;
s32 result = syncLFQueueGetPopPointer2(CPU, queue, pointer_value, isBlocking, useEventQueue);
*pointer = pointer_value;
return result;
throw __FUNCTION__;
}
s32 syncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull)
s32 _cellSyncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull)
{
// arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer)
cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull);
if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)
{
return CELL_SYNC_ERROR_PERM;
@ -1447,25 +1368,12 @@ s32 syncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue
}
}
s32 _cellSyncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull)
{
// arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer)
cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull);
return syncLFQueueCompletePopPointer(CPU, queue, pointer, fpSendSignal, noQueueFull);
}
s32 syncLFQueueCompletePopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull)
{
throw __FUNCTION__;
}
s32 _cellSyncLFQueueCompletePopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, vm::ptr<s32(u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull)
{
// arguments copied from _cellSyncLFQueueCompletePopPointer
cellSync.Todo("_cellSyncLFQueueCompletePopPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull);
return syncLFQueueCompletePopPointer2(CPU, queue, pointer, fpSendSignal, noQueueFull);
throw __FUNCTION__;
}
s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer, u32 isBlocking)
@ -1477,31 +1385,31 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned() || buffer % 16)
{
return CELL_SYNC_ERROR_ALIGN;
}
s32 position;
vm::stackvar<be_t<s32>> position(CPU);
while (true)
{
s32 res;
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
res = syncLFQueueGetPopPointer(CPU, queue, position, isBlocking, 0, 0);
res = _cellSyncLFQueueGetPopPointer(CPU, queue, position, isBlocking, 0, 0);
}
else
{
res = syncLFQueueGetPopPointer2(CPU, queue, position, isBlocking, 0);
res = _cellSyncLFQueueGetPopPointer2(CPU, queue, position, isBlocking, 0);
}
if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN)
{
if (res)
{
return res;
}
if (res) return res;
break;
}
@ -1516,21 +1424,18 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::
const s32 depth = queue->m_depth;
const s32 size = queue->m_size;
const u32 addr = vm::cast<u64>((queue->m_buffer.addr() & ~1) + size * (position >= depth ? position - depth : position));
memcpy(buffer.get_ptr(), vm::get_ptr<void>(addr), size);
s32 res;
const s32 pos = position.value();
const u32 addr = vm::cast<u64>((queue->m_buffer.addr() & ~1) + size * (pos >= depth ? pos - depth : pos));
std::memcpy(buffer.get_ptr(), vm::get_ptr<void>(addr), size);
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
res = syncLFQueueCompletePopPointer(CPU, queue, position, nullptr, 0);
return _cellSyncLFQueueCompletePopPointer(CPU, queue, pos, vm::null, 0);
}
else
{
res = syncLFQueueCompletePopPointer2(CPU, queue, position, nullptr, 0);
return _cellSyncLFQueueCompletePopPointer2(CPU, queue, pos, vm::null, 0);
}
return res;
}
s32 cellSyncLFQueueClear(vm::ptr<CellSyncLFQueue> queue)
@ -1541,6 +1446,7 @@ s32 cellSyncLFQueueClear(vm::ptr<CellSyncLFQueue> queue)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
@ -1591,6 +1497,7 @@ s32 cellSyncLFQueueSize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> size)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
@ -1613,6 +1520,7 @@ s32 cellSyncLFQueueSize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> size)
{
*size = var2 - var1 + (u32)queue->m_depth * 2;
}
return CELL_OK;
}
}
@ -1626,12 +1534,14 @@ s32 cellSyncLFQueueDepth(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> depth)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
}
*depth = queue->m_depth;
return CELL_OK;
}
@ -1643,6 +1553,7 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::cptr<CellSyncLFQueue> queue, vm::pptr<v
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
@ -1661,12 +1572,14 @@ s32 cellSyncLFQueueGetDirection(vm::cptr<CellSyncLFQueue> queue, vm::ptr<u32> di
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
}
*direction = queue->m_direction;
return CELL_OK;
}
@ -1678,29 +1591,21 @@ s32 cellSyncLFQueueGetEntrySize(vm::cptr<CellSyncLFQueue> queue, vm::ptr<u32> en
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (!queue.aligned())
{
return CELL_SYNC_ERROR_ALIGN;
}
*entry_size = queue->m_size;
return CELL_OK;
}
s32 syncLFQueueAttachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<CellSyncLFQueue> queue)
{
throw __FUNCTION__;
return CELL_OK;
}
s32 _cellSyncLFQueueAttachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<CellSyncLFQueue> queue)
{
cellSync.Todo("_cellSyncLFQueueAttachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue);
return syncLFQueueAttachLv2EventQueue(spus, num, queue);
}
s32 syncLFQueueDetachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<CellSyncLFQueue> queue)
{
throw __FUNCTION__;
}
@ -1708,7 +1613,7 @@ s32 _cellSyncLFQueueDetachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<Cell
{
cellSync.Todo("_cellSyncLFQueueDetachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue);
return syncLFQueueDetachLv2EventQueue(spus, num, queue);
throw __FUNCTION__;
}
Module cellSync("cellSync", []()

View File

@ -160,7 +160,7 @@ struct sync_queue_t // CellSyncQueue sync var
be_t<u32> m_v1;
be_t<u32> m_v2;
bool try_push(u32 depth, u32& position)
bool try_push_begin(u32 depth, u32& position)
{
const u32 v1 = m_v1;
const u32 v2 = m_v2;
@ -182,7 +182,7 @@ struct sync_queue_t // CellSyncQueue sync var
return true;
}
bool try_pop(u32 depth, u32& position)
bool try_pop_begin(u32 depth, u32& position)
{
const u32 v1 = m_v1;
const u32 v2 = m_v2;
@ -204,7 +204,7 @@ struct sync_queue_t // CellSyncQueue sync var
return true;
}
bool try_peek(u32 depth, u32& position)
bool try_peek_begin(u32 depth, u32& position)
{
const u32 v1 = m_v1;
const u32 v2 = m_v2;
@ -219,6 +219,30 @@ struct sync_queue_t // CellSyncQueue sync var
return true;
}
bool try_clear_begin_1()
{
if (m_v1 & 0xff000000)
{
return false;
}
m_v1 |= 0x1000000;
return true;
}
bool try_clear_begin_2()
{
if (m_v2 & 0xff000000)
{
return false;
}
m_v2 |= 0x1000000;
return true;
}
};
struct set_alignment(32) CellSyncQueue
@ -311,7 +335,7 @@ struct set_alignment(128) CellSyncLFQueue
u8 m_bs[4]; // 0x20
be_t<u32> m_direction; // 0x24 CellSyncQueueDirection
be_t<u32> m_v1; // 0x28
atomic_be_t<u32> init; // 0x2C
atomic_be_t<s32> init; // 0x2C
atomic_be_t<push2_t> push2; // 0x30
be_t<u16> m_hs1[15]; // 0x32
atomic_be_t<pop2_t> pop2; // 0x50
@ -339,15 +363,3 @@ struct set_alignment(128) CellSyncLFQueue
};
CHECK_SIZE_ALIGN(CellSyncLFQueue, 128, 128);
s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal);
s32 syncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue);
s32 syncLFQueueGetPushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue);
s32 syncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal);
s32 syncLFQueueCompletePushPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal);
s32 syncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue);
s32 syncLFQueueGetPopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32& pointer, u32 isBlocking, u32 useEventQueue);
s32 syncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull);
s32 syncLFQueueCompletePopPointer2(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, s32 pointer, std::function<s32(PPUThread& CPU, u32 addr, u32 arg)> fpSendSignal, u32 noQueueFull);
s32 syncLFQueueAttachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<CellSyncLFQueue> queue);
s32 syncLFQueueDetachLv2EventQueue(vm::ptr<u32> spus, u32 num, vm::ptr<CellSyncLFQueue> queue);