[rpcsx-os] fork: implement vm and vfs fork

stub metadbg device
implement notification device
implement sys_pipe
This commit is contained in:
DH 2023-10-31 21:28:40 +03:00
parent 39092c7f16
commit 525ef02e8a
22 changed files with 379 additions and 76 deletions

View file

@ -14,7 +14,7 @@ KernelContext &g_context = *[]() -> KernelContext * {
auto ptr = mmap(reinterpret_cast<void *>(0x200'0000'0000), 0x1'0000'0000,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (!ptr)
if (ptr == MAP_FAILED)
std::abort();
return new (ptr) KernelContext;
@ -163,6 +163,9 @@ void KernelContext::kfree(void *ptr, std::size_t size) {
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if ((uintptr_t)ptr == 0x2000001a2b0) {
std::fprintf(stderr, "free %p-%p (%zu)\n", ptr, (char *)ptr + size, size);
}
std::memset(ptr, 0xcc, size);
pthread_mutex_lock(&m_heap_mtx);

61
orbis-kernel/src/pipe.cpp Normal file
View file

@ -0,0 +1,61 @@
#include "pipe.hpp"
#include "error/ErrorCode.hpp"
#include "file.hpp"
#include "uio.hpp"
#include <span>
#include <thread>
static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto pipe = static_cast<orbis::Pipe *>(file);
while (true) {
if (pipe->data.empty()) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::lock_guard lock(pipe->mtx);
if (pipe->data.empty()) {
continue;
}
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
auto size = std::min<std::size_t>(pipe->data.size(), vec.len);
uio->offset += size;
std::memcpy(vec.base, pipe->data.data(), size);
if (pipe->data.size() == size) {
break;
}
std::memmove(pipe->data.data(), pipe->data.data() + size,
pipe->data.size() - size);
pipe->data.resize(pipe->data.size() - size);
}
break;
}
return {};
}
static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto pipe = static_cast<orbis::Pipe *>(file);
std::lock_guard lock(pipe->mtx);
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
auto offset = pipe->data.size();
pipe->data.resize(offset + vec.len);
std::memcpy(pipe->data.data(), vec.base, vec.len);
}
uio->resid = 0;
return {};
}
static orbis::FileOps pipe_ops = {.read = pipe_read, .write = pipe_write};
orbis::Ref<orbis::Pipe> orbis::createPipe() {
auto result = knew<Pipe>();
result->ops = &pipe_ops;
return result;
}

View file

@ -1,6 +1,5 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <cstdlib>
#include <unistd.h>
@ -11,42 +10,8 @@ orbis::SysResult orbis::sys_pdfork(Thread *thread, ptr<sint> fdp, sint flags) {
orbis::SysResult orbis::sys_vfork(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_rfork(Thread *thread, sint flags) {
ORBIS_LOG_TODO(__FUNCTION__, flags);
int hostPid = ::fork();
if (hostPid) {
thread->retval[0] = 10001;
thread->retval[1] = 0;
} else {
auto process = g_context.createProcess(10001);
std::lock_guard lock(thread->tproc->fileDescriptors.mutex);
process->sysent = thread->tproc->sysent;
process->onSysEnter = thread->tproc->onSysEnter;
process->onSysExit = thread->tproc->onSysExit;
process->ops = thread->tproc->ops;
process->isSystem = thread->tproc->isSystem;
for (auto [id, mod] : thread->tproc->modulesMap) {
if (!process->modulesMap.insert(id, mod)) {
std::abort();
}
}
for (auto [id, mod] : thread->tproc->fileDescriptors) {
if (!process->fileDescriptors.insert(id, mod)) {
std::abort();
}
}
auto [baseId, newThread] = process->threadsMap.emplace();
newThread->tproc = process;
newThread->tid = process->pid + baseId;
newThread->state = orbis::ThreadState::RUNNING;
newThread->context = thread->context;
newThread->fsBase = thread->fsBase;
orbis::g_currentThread = newThread;
newThread->retval[0] = 0;
newThread->retval[1] = 1;
if (auto fork = thread->tproc->ops->fork) {
return fork(thread, flags);
}
return {};
return ErrorCode::NOSYS;
}

View file

@ -1,3 +1,9 @@
#include "sys/sysproto.hpp"
#include <pipe.hpp>
orbis::SysResult orbis::sys_pipe(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_pipe(Thread *thread) {
auto pipe = createPipe();
thread->retval[0] = thread->tproc->fileDescriptors.insert(pipe);
thread->retval[1] = thread->tproc->fileDescriptors.insert(pipe);
return {};
}