feat(libkernel): some semaphore functions impl

This commit is contained in:
boykopovar 2026-09-12 19:27:53 +03:00
parent e38f76a823
commit 94ab47a417
6 changed files with 95 additions and 28 deletions

View File

@ -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).

View File

@ -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" {

View File

@ -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

View File

@ -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;
}
}

View File

@ -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" {

View File

@ -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;
}
}