feat(libkernel): some semaphore functions impl
This commit is contained in:
parent
e38f76a823
commit
94ab47a417
|
|
@ -12,7 +12,7 @@ Execution reaches `_start`, stack unwinding and exception handling tables are bu
|
|||
Shader initialization via `sceAgcCreate*` passes.
|
||||
Audio output and video output initialization pass
|
||||
|
||||
Now: `sceKernelCreateSema not implemented`.
|
||||
Now: `fopen: open failed: "C:\app0\~INDEX": No such file or directory`.
|
||||
|
||||
On Windows, after printing an unhandled exception the process exits with STATUS_STACK_BUFFER_OVERRUN due to the difficulty of manually [implementing proper exception handling](core/libs/prx/libc/src/exception).
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
#include "prx/libc/include/General.hpp"
|
||||
#include "DirectMemory/DirectMemory.hpp"
|
||||
#include "Equeue/Equeue.hpp"
|
||||
#include "File/include/File.hpp"
|
||||
#include "Semaphore/include/Semaphore.hpp"
|
||||
#include "prx/libkernel/File/include/File.hpp"
|
||||
#include "prx/libkernel/Semaphore/include/Semaphore.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <cstddef>
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
|
@ -20,3 +20,4 @@ int64_t APS5_VABI sceKernelWrite(int d, const void* buf, size_t nbytes);
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +1,62 @@
|
|||
#include "prx/libkernel/File/include/File.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceKernelClose(int d) {
|
||||
(void)d;
|
||||
throw std::runtime_error("sceKernelClose is not implemented");
|
||||
throw std::runtime_error(std::string(__func__) + " is not implemented");
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelLseek(int d, int64_t offset, int whence) {
|
||||
(void)d;
|
||||
(void)offset;
|
||||
(void)whence;
|
||||
throw std::runtime_error("sceKernelLseek is not implemented");
|
||||
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelOpen(const char* path, int flags, uint16_t mode) {
|
||||
(void)path;
|
||||
(void)flags;
|
||||
(void)mode;
|
||||
throw std::runtime_error("sceKernelOpen is not implemented");
|
||||
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t APS5_VABI sceKernelRead(int d, void* buf, size_t nbytes) {
|
||||
(void)d;
|
||||
(void)buf;
|
||||
(void)nbytes;
|
||||
throw std::runtime_error("sceKernelRead is not implemented");
|
||||
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelStat(const char* path, FileStat* sb) {
|
||||
(void)path;
|
||||
(void)sb;
|
||||
throw std::runtime_error("sceKernelStat is not implemented");
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelUnlink(const char* path) {
|
||||
(void)path;
|
||||
throw std::runtime_error("sceKernelUnlink is not implemented");
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t APS5_VABI sceKernelWrite(int d, const void* buf, size_t nbytes) {
|
||||
(void)d;
|
||||
(void)buf;
|
||||
(void)nbytes;
|
||||
throw std::runtime_error("sceKernelWrite is not implemented");
|
||||
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,30 @@
|
|||
#ifndef CORE_LIBS_PRX_LIBKERNEL_SEMAPHORE_SEMAPHORE_HPP
|
||||
#define CORE_LIBS_PRX_LIBKERNEL_SEMAPHORE_SEMAPHORE_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
constexpr int KERNEL_SEMA_OK = 0;
|
||||
constexpr int KERNEL_SEMA_ERROR_EINVAL = static_cast<int>(0x80020016);
|
||||
constexpr int KERNEL_SEMA_ERROR_EBUSY = static_cast<int>(0x80020010);
|
||||
constexpr int KERNEL_SEMA_ERROR_ETIMEDOUT = static_cast<int>(0x8002003C);
|
||||
|
||||
struct KernelSemaPrivate {
|
||||
KernelSemaPrivate(std::int32_t initCount, std::int32_t maxCount, std::string name, bool isFifo);
|
||||
|
||||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
std::string name;
|
||||
std::int32_t tokenCount;
|
||||
std::int32_t maxCount;
|
||||
bool isFifo;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,71 @@
|
|||
#include "prx/libkernel/Semaphore/include/Semaphore.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
KernelSemaPrivate::KernelSemaPrivate(std::int32_t initCount, std::int32_t maxCount, std::string name, bool isFifo)
|
||||
: name(std::move(name)), tokenCount(initCount), maxCount(maxCount), isFifo(isFifo) {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceKernelCreateSema(KernelSema* sem, const char* name, uint32_t attr, int init, int max, void* opt) {
|
||||
(void)sem;
|
||||
(void)name;
|
||||
(void)attr;
|
||||
(void)init;
|
||||
(void)max;
|
||||
(void)opt;
|
||||
throw std::runtime_error("sceKernelCreateSema is not implemented");
|
||||
if (sem == nullptr || name == nullptr || attr > 2 || init < 0 || max <= 0 || init > max) {
|
||||
APS5_INVALID_ARG_EX;
|
||||
}
|
||||
|
||||
*sem = new KernelSemaPrivate(init, max, std::string(name), attr == 1);
|
||||
return KERNEL_SEMA_OK;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelPollSema(KernelSema sem, int need) {
|
||||
(void)sem;
|
||||
(void)need;
|
||||
throw std::runtime_error("sceKernelPollSema is not implemented");
|
||||
if (sem == nullptr || need <= 0) {
|
||||
APS5_INVALID_ARG_EX;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(sem->mutex);
|
||||
if (sem->tokenCount < need) {
|
||||
return KERNEL_SEMA_ERROR_EBUSY;
|
||||
}
|
||||
sem->tokenCount -= need;
|
||||
return KERNEL_SEMA_OK;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelSignalSema(KernelSema sem, int count) {
|
||||
(void)sem;
|
||||
(void)count;
|
||||
throw std::runtime_error("sceKernelSignalSema is not implemented");
|
||||
if (sem == nullptr || count <= 0) {
|
||||
APS5_INVALID_ARG_EX;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(sem->mutex);
|
||||
if (sem->tokenCount + count > sem->maxCount) {
|
||||
return KERNEL_SEMA_ERROR_EINVAL;
|
||||
}
|
||||
sem->tokenCount += count;
|
||||
sem->condition.notify_all();
|
||||
return KERNEL_SEMA_OK;
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelWaitSema(KernelSema sem, int need, KernelUseconds* time) {
|
||||
(void)sem;
|
||||
(void)need;
|
||||
(void)time;
|
||||
throw std::runtime_error("sceKernelWaitSema is not implemented");
|
||||
if (sem == nullptr || need <= 0) {
|
||||
APS5_INVALID_ARG_EX;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(sem->mutex);
|
||||
if (time == nullptr) {
|
||||
sem->condition.wait(lock, [&] { return sem->tokenCount >= need; });
|
||||
sem->tokenCount -= need;
|
||||
return KERNEL_SEMA_OK;
|
||||
}
|
||||
|
||||
auto timeout = std::chrono::microseconds(*time);
|
||||
bool acquired = sem->condition.wait_for(lock, timeout, [&] { return sem->tokenCount >= need; });
|
||||
if (!acquired) {
|
||||
return KERNEL_SEMA_ERROR_ETIMEDOUT;
|
||||
}
|
||||
sem->tokenCount -= need;
|
||||
return KERNEL_SEMA_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue