mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
[rpcsx-os/orbis-kernel] random bugfixes
ipmi: fixed respond sync, get message, try get message, try send message event: detach event emitter from file signals: basic implementation linker: fixed zero symbol relocation, fixed exec relocation shared_cv/mutex: implement eintr response support shared_cv: fixed possible loop instead of wait ipmi: implement invoke async, respond async, get result, get client app id, client get name rpcsx-os: add safemode flag
This commit is contained in:
parent
8791312d4f
commit
65e653f5ef
81 changed files with 2586 additions and 761 deletions
|
|
@ -1,16 +1,15 @@
|
|||
#pragma once
|
||||
#include "AudioOut.hpp"
|
||||
#include "KernelAllocator.hpp"
|
||||
#include "evf.hpp"
|
||||
#include "ipmi.hpp"
|
||||
#include "orbis/utils/IdMap.hpp"
|
||||
#include "osem.hpp"
|
||||
#include "thread/types.hpp"
|
||||
#include "utils/IdMap.hpp"
|
||||
#include "utils/LinkedNode.hpp"
|
||||
#include "utils/SharedCV.hpp"
|
||||
#include "utils/SharedMutex.hpp"
|
||||
|
||||
#include "AudioOut.hpp"
|
||||
#include "KernelAllocator.hpp"
|
||||
#include "orbis/thread/types.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <pthread.h>
|
||||
|
|
@ -175,6 +174,10 @@ public:
|
|||
AudioOut *audioOut = nullptr;
|
||||
uint sdkVersion{};
|
||||
uint fwSdkVersion{};
|
||||
uint safeMode{};
|
||||
|
||||
shared_mutex regMgrMtx;
|
||||
kmap<std::uint32_t, std::uint32_t> regMgrInt;
|
||||
|
||||
private:
|
||||
mutable pthread_mutex_t m_heap_mtx;
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ struct FileOps {
|
|||
Thread *thread) = nullptr;
|
||||
ErrorCode (*sendmsg)(orbis::File *file, msghdr *msg, sint flags,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*recvfrom)(orbis::File *file, void *buf, size_t len,
|
||||
sint flags, SocketAddress *from, uint32_t *fromlenaddr,
|
||||
ErrorCode (*recvfrom)(orbis::File *file, void *buf, size_t len, sint flags,
|
||||
SocketAddress *from, uint32_t *fromlenaddr,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*recvmsg)(orbis::File *file, msghdr *msg, sint flags,
|
||||
Thread *thread) = nullptr;
|
||||
|
|
@ -75,11 +75,15 @@ struct FileOps {
|
|||
|
||||
struct File : RcBase {
|
||||
shared_mutex mtx;
|
||||
EventEmitter event;
|
||||
Ref<EventEmitter> event;
|
||||
const FileOps *ops = nullptr;
|
||||
Ref<RcBase> device;
|
||||
std::uint64_t nextOff = 0;
|
||||
int flags = 0;
|
||||
int mode = 0;
|
||||
int hostFd = -1;
|
||||
utils::kvector<Dirent> dirEntries;
|
||||
|
||||
bool noBlock() const { return (flags & 4) != 0; }
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct Thread;
|
|||
|
||||
struct IpmiServer : RcBase {
|
||||
struct IpmiPacketInfo {
|
||||
ptr<void> userData;
|
||||
ulong inputSize;
|
||||
uint type;
|
||||
uint clientKid;
|
||||
ptr<void> eventHandler;
|
||||
|
|
@ -26,6 +26,8 @@ struct IpmiServer : RcBase {
|
|||
|
||||
struct Packet {
|
||||
IpmiPacketInfo info;
|
||||
lwpid_t clientTid;
|
||||
Ref<IpmiSession> session;
|
||||
kvector<std::byte> message;
|
||||
};
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ struct IpmiServer : RcBase {
|
|||
slong serverTid{};
|
||||
};
|
||||
|
||||
kmap<std::uint32_t, std::uint32_t> tidToClientTid;
|
||||
kstring name;
|
||||
ptr<void> serverImpl;
|
||||
ptr<void> eventHandler;
|
||||
|
|
@ -51,24 +54,36 @@ struct IpmiServer : RcBase {
|
|||
};
|
||||
|
||||
struct IpmiClient : RcBase {
|
||||
struct MessageQueue {
|
||||
shared_cv messageCv;
|
||||
kdeque<kvector<std::byte>> messages;
|
||||
};
|
||||
|
||||
struct AsyncResponse {
|
||||
uint methodId;
|
||||
sint errorCode;
|
||||
kvector<kvector<std::byte>> data;
|
||||
};
|
||||
|
||||
kstring name;
|
||||
ptr<void> clientImpl;
|
||||
ptr<void> userData;
|
||||
Ref<IpmiSession> session;
|
||||
shared_mutex mutex;
|
||||
shared_cv sessionCv;
|
||||
sint pid;
|
||||
kdeque<kvector<std::byte>> messages;
|
||||
Process *process;
|
||||
kdeque<MessageQueue> messageQueues;
|
||||
kdeque<EventFlag> eventFlags;
|
||||
shared_cv messageCv;
|
||||
kdeque<AsyncResponse> asyncResponses;
|
||||
|
||||
explicit IpmiClient(kstring name) : name(std::move(name)) {}
|
||||
};
|
||||
|
||||
struct IpmiSession : RcBase {
|
||||
struct MessageResponse {
|
||||
struct SyncResponse {
|
||||
sint errorCode;
|
||||
kvector<std::byte> data;
|
||||
std::uint32_t callerTid;
|
||||
kvector<kvector<std::byte>> data;
|
||||
};
|
||||
|
||||
ptr<void> sessionImpl;
|
||||
|
|
@ -77,9 +92,9 @@ struct IpmiSession : RcBase {
|
|||
Ref<IpmiServer> server;
|
||||
shared_mutex mutex;
|
||||
shared_cv responseCv;
|
||||
kdeque<MessageResponse> messageResponses;
|
||||
kdeque<SyncResponse> syncResponses;
|
||||
shared_cv connectCv;
|
||||
bool expectedOutput = false; // TODO: verify
|
||||
uint expectedOutput{0};
|
||||
sint connectionStatus{0};
|
||||
};
|
||||
|
||||
|
|
@ -108,20 +123,19 @@ static_assert(sizeof(IpmiCreateClientConfig) == 0x150);
|
|||
|
||||
struct IpmiBufferInfo {
|
||||
ptr<void> data;
|
||||
uint64_t capacity;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
|
||||
struct IpmiDataInfo {
|
||||
ptr<void> data;
|
||||
uint64_t size;
|
||||
uint64_t capacity; //?
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiBufferInfo) == 0x10);
|
||||
static_assert(sizeof(IpmiDataInfo) == 0x18);
|
||||
// static_assert(sizeof(IpmiBufferInfo) == 0x18);
|
||||
// static_assert(sizeof(IpmiDataInfo) == 0x10);
|
||||
|
||||
struct IpmiSyncMessageHeader {
|
||||
struct [[gnu::packed]] IpmiSyncMessageHeader {
|
||||
orbis::ptr<void> sessionImpl;
|
||||
orbis::uint pid;
|
||||
orbis::uint methodId;
|
||||
|
|
@ -129,10 +143,18 @@ struct IpmiSyncMessageHeader {
|
|||
orbis::uint numOutData;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] IpmiAsyncMessageHeader {
|
||||
orbis::ptr<void> sessionImpl;
|
||||
orbis::uint methodId;
|
||||
orbis::uint pid;
|
||||
orbis::uint numInData;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiSyncMessageHeader) == 0x18);
|
||||
|
||||
ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name,
|
||||
const IpmiCreateClientConfig &config, Ref<IpmiClient> &result);
|
||||
const IpmiCreateClientConfig &config,
|
||||
Ref<IpmiClient> &result);
|
||||
ErrorCode ipmiCreateServer(Process *proc, void *serverImpl, const char *name,
|
||||
const IpmiCreateServerConfig &config,
|
||||
Ref<IpmiServer> &result);
|
||||
|
|
@ -162,9 +184,10 @@ SysResult sysIpmiSessionRespondSync(Thread *thread, ptr<uint> result, uint kid,
|
|||
SysResult sysIpmiClientInvokeAsyncMethod(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetResult(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysImpiSessionRespondAsync(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetResult(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
|
|
@ -181,10 +204,15 @@ SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result,
|
|||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientConnect(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionGetClientAppId(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionGetUserData(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiServerGetName(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientGetName(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientWaitEventFlag(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr<uint> result, uint kid,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ struct KNote {
|
|||
~KNote();
|
||||
};
|
||||
|
||||
struct EventEmitter {
|
||||
struct EventEmitter : orbis::RcBase {
|
||||
shared_mutex mutex;
|
||||
std::set<KNote *, std::less<>, kallocator<KNote *>> notes;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "orbis-config.hpp"
|
||||
#include <orbis/error.hpp>
|
||||
#include <orbis/thread.hpp>
|
||||
#include <orbis/time.hpp>
|
||||
#include <orbis/module/ModuleHandle.hpp>
|
||||
#include <orbis/thread/cpuset.hpp>
|
||||
#include <orbis/thread/types.hpp>
|
||||
|
||||
namespace orbis {
|
||||
using acl_type_t = sint;
|
||||
|
|
@ -11,17 +13,24 @@ using cpuwhich_t = sint;
|
|||
using cpulevel_t = sint;
|
||||
using SceKernelModule = ModuleHandle;
|
||||
|
||||
struct Thread;
|
||||
struct AuthInfo;
|
||||
struct MemoryProtection;
|
||||
struct ModuleInfo;
|
||||
struct ModuleInfoEx;
|
||||
struct KEvent;
|
||||
struct timespec;
|
||||
struct timesec;
|
||||
struct timezone;
|
||||
struct timeval;
|
||||
struct Stat;
|
||||
struct stack_t;
|
||||
struct IoVec;
|
||||
struct BatchMapEntry;
|
||||
struct UContext;
|
||||
struct SigSet;
|
||||
struct SigAction;
|
||||
struct SocketAddress;
|
||||
|
||||
SysResult nosys(Thread *thread);
|
||||
|
||||
|
|
@ -29,7 +38,7 @@ SysResult sys_exit(Thread *thread, sint status);
|
|||
SysResult sys_fork(Thread *thread);
|
||||
SysResult sys_read(Thread *thread, sint fd, ptr<void> buf, size_t nbyte);
|
||||
SysResult sys_write(Thread *thread, sint fd, ptr<const void> buf, size_t nbyte);
|
||||
SysResult sys_open(Thread *thread, ptr<char> path, sint flags, sint mode);
|
||||
SysResult sys_open(Thread *thread, ptr<const char> path, sint flags, sint mode);
|
||||
SysResult sys_close(Thread *thread, sint fd);
|
||||
SysResult sys_wait4(Thread *thread, sint pid, ptr<sint> status, sint options,
|
||||
ptr<struct rusage> rusage);
|
||||
|
|
@ -125,15 +134,14 @@ SysResult sys_bind(Thread *thread, sint s, caddr_t name, sint namelen);
|
|||
SysResult sys_setsockopt(Thread *thread, sint s, sint level, sint name,
|
||||
caddr_t val, sint valsize);
|
||||
SysResult sys_listen(Thread *thread, sint s, sint backlog);
|
||||
SysResult sys_gettimeofday(Thread *thread, ptr<orbis::timeval> tp,
|
||||
ptr<orbis::timezone> tzp);
|
||||
SysResult sys_gettimeofday(Thread *thread, ptr<timeval> tp, ptr<timezone> tzp);
|
||||
SysResult sys_getrusage(Thread *thread, sint who, ptr<struct rusage> rusage);
|
||||
SysResult sys_getsockopt(Thread *thread, sint s, sint level, sint name,
|
||||
caddr_t val, ptr<sint> avalsize);
|
||||
SysResult sys_readv(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt);
|
||||
SysResult sys_writev(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt);
|
||||
SysResult sys_settimeofday(Thread *thread, ptr<struct timeval> tp,
|
||||
ptr<orbis::timezone> tzp);
|
||||
ptr<timezone> tzp);
|
||||
SysResult sys_fchown(Thread *thread, sint fd, sint uid, sint gid);
|
||||
SysResult sys_fchmod(Thread *thread, sint fd, sint mode);
|
||||
SysResult sys_setreuid(Thread *thread, sint ruid, sint euid);
|
||||
|
|
@ -230,8 +238,8 @@ SysResult sys_ktimer_settime(Thread *thread, sint timerid, sint flags,
|
|||
SysResult sys_ktimer_gettime(Thread *thread, sint timerid,
|
||||
ptr<struct itimerspec> value);
|
||||
SysResult sys_ktimer_getoverrun(Thread *thread, sint timerid);
|
||||
SysResult sys_nanosleep(Thread *thread, cptr<orbis::timespec> rqtp,
|
||||
ptr<orbis::timespec> rmtp);
|
||||
SysResult sys_nanosleep(Thread *thread, cptr<timespec> rqtp,
|
||||
ptr<timespec> rmtp);
|
||||
SysResult sys_ntp_gettime(Thread *thread, ptr<struct ntptimeval> ntvp);
|
||||
SysResult sys_minherit(Thread *thread, ptr<void> addr, size_t len,
|
||||
sint inherit);
|
||||
|
|
@ -305,14 +313,14 @@ SysResult sys_jail(Thread *thread, ptr<struct jail> jail);
|
|||
SysResult sys_nnpfs_syscall(Thread *thread, sint operation, ptr<char> a_pathP,
|
||||
sint opcode, ptr<void> a_paramsP,
|
||||
sint a_followSymlinks);
|
||||
SysResult sys_sigprocmask(Thread *thread, sint how, ptr<uint64_t> set,
|
||||
ptr<uint64_t> oset);
|
||||
SysResult sys_sigsuspend(Thread *thread, ptr<const struct sigset> set);
|
||||
SysResult sys_sigpending(Thread *thread, ptr<struct sigset> set);
|
||||
SysResult sys_sigtimedwait(Thread *thread, ptr<const struct sigset> set,
|
||||
SysResult sys_sigprocmask(Thread *thread, sint how, ptr<SigSet> set,
|
||||
ptr<SigSet> oset);
|
||||
SysResult sys_sigsuspend(Thread *thread, ptr<const SigSet> set);
|
||||
SysResult sys_sigpending(Thread *thread, ptr<SigSet> set);
|
||||
SysResult sys_sigtimedwait(Thread *thread, ptr<const SigSet> set,
|
||||
ptr<struct siginfo> info,
|
||||
ptr<const timespec> timeout);
|
||||
SysResult sys_sigwaitinfo(Thread *thread, ptr<const struct sigset> set,
|
||||
SysResult sys_sigwaitinfo(Thread *thread, ptr<const SigSet> set,
|
||||
ptr<struct siginfo> info);
|
||||
SysResult sys___acl_get_file(Thread *thread, ptr<char> path, acl_type_t type,
|
||||
ptr<struct acl> aclp);
|
||||
|
|
@ -412,13 +420,13 @@ SysResult sys_extattr_delete_link(Thread *thread, ptr<const char> path,
|
|||
sint attrnamespace, ptr<const char> attrname);
|
||||
SysResult sys___mac_execve(Thread *thread, ptr<char> fname, ptr<ptr<char>> argv,
|
||||
ptr<ptr<char>> envv, ptr<struct mac> mac_p);
|
||||
SysResult sys_sigaction(Thread *thread, sint sig, ptr<struct sigaction> act,
|
||||
ptr<struct sigaction> oact);
|
||||
SysResult sys_sigreturn(Thread *thread, ptr<struct ucontext> sigcntxp);
|
||||
SysResult sys_getcontext(Thread *thread, ptr<struct ucontext> ucp);
|
||||
SysResult sys_setcontext(Thread *thread, ptr<struct ucontext> ucp);
|
||||
SysResult sys_swapcontext(Thread *thread, ptr<struct ucontext> oucp,
|
||||
ptr<struct ucontext> ucp);
|
||||
SysResult sys_sigaction(Thread *thread, sint sig, ptr<SigAction> act,
|
||||
ptr<SigAction> oact);
|
||||
SysResult sys_sigreturn(Thread *thread, ptr<UContext> sigcntxp);
|
||||
SysResult sys_getcontext(Thread *thread, ptr<UContext> ucp);
|
||||
SysResult sys_setcontext(Thread *thread, ptr<UContext> ucp);
|
||||
SysResult sys_swapcontext(Thread *thread, ptr<UContext> oucp,
|
||||
ptr<UContext> ucp);
|
||||
SysResult sys_swapoff(Thread *thread, ptr<const char> name);
|
||||
SysResult sys___acl_get_link(Thread *thread, ptr<const char> path,
|
||||
acl_type_t type, ptr<struct acl> aclp);
|
||||
|
|
@ -428,10 +436,9 @@ SysResult sys___acl_delete_link(Thread *thread, ptr<const char> path,
|
|||
acl_type_t type);
|
||||
SysResult sys___acl_aclcheck_link(Thread *thread, ptr<const char> path,
|
||||
acl_type_t type, ptr<struct acl> aclp);
|
||||
SysResult sys_sigwait(Thread *thread, ptr<const struct sigset> set,
|
||||
ptr<sint> sig);
|
||||
SysResult sys_thr_create(Thread *thread, ptr<struct ucontext> ctxt,
|
||||
ptr<slong> arg, sint flags);
|
||||
SysResult sys_sigwait(Thread *thread, ptr<const SigSet> set, ptr<sint> sig);
|
||||
SysResult sys_thr_create(Thread *thread, ptr<UContext> ctxt, ptr<slong> arg,
|
||||
sint flags);
|
||||
SysResult sys_thr_exit(Thread *thread, ptr<slong> state);
|
||||
SysResult sys_thr_self(Thread *thread, ptr<slong> id);
|
||||
SysResult sys_thr_kill(Thread *thread, slong id, sint sig);
|
||||
|
|
@ -636,8 +643,9 @@ SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
|||
ptr<sint> pNumWaitThreads);
|
||||
SysResult sys_query_memory_protection(Thread *thread, ptr<void> address,
|
||||
ptr<MemoryProtection> protection);
|
||||
SysResult sys_batch_map(Thread *thread, sint unk, sint flags, ptr<BatchMapEntry> entries,
|
||||
sint entriesCount, ptr<sint> processedCount);
|
||||
SysResult sys_batch_map(Thread *thread, sint unk, sint flags,
|
||||
ptr<BatchMapEntry> entries, sint entriesCount,
|
||||
ptr<sint> processedCount);
|
||||
SysResult sys_osem_create(Thread *thread, ptr<const char[32]> name, uint attrs,
|
||||
sint initCount, sint maxCount);
|
||||
SysResult sys_osem_delete(Thread *thread, sint id);
|
||||
|
|
@ -746,15 +754,16 @@ SysResult sys_physhm_unlink(Thread *thread /* TODO */);
|
|||
SysResult sys_resume_internal_hdd(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_suspend_ucontext(Thread *thread, lwpid_t tid);
|
||||
SysResult sys_thr_resume_ucontext(Thread *thread, lwpid_t tid);
|
||||
SysResult sys_thr_get_ucontext(Thread *thread, lwpid_t tid, ptr<UContext> context);
|
||||
SysResult sys_thr_set_ucontext(Thread *thread, lwpid_t tid, ptr<UContext> context);
|
||||
SysResult sys_thr_get_ucontext(Thread *thread, lwpid_t tid,
|
||||
ptr<UContext> context);
|
||||
SysResult sys_thr_set_ucontext(Thread *thread, lwpid_t tid,
|
||||
ptr<UContext> context);
|
||||
SysResult sys_set_timezone_info(Thread *thread /* TODO */);
|
||||
SysResult sys_set_phys_fmem_limit(Thread *thread /* TODO */);
|
||||
SysResult sys_utc_to_localtime(Thread *thread, int64_t time, int64_t *localtime,
|
||||
orbis::timesec *_sec, int *_dst_sec);
|
||||
timesec *_sec, int *_dst_sec);
|
||||
SysResult sys_localtime_to_utc(Thread *thread, int64_t time, uint unk,
|
||||
int64_t *ptime, orbis::timesec *_sec,
|
||||
int *_dst_sec);
|
||||
int64_t *ptime, timesec *_sec, int *_dst_sec);
|
||||
SysResult sys_set_uevt(Thread *thread /* TODO */);
|
||||
SysResult sys_get_cpu_usage_proc(Thread *thread /* TODO */);
|
||||
SysResult sys_get_map_statistics(Thread *thread /* TODO */);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ struct Process final {
|
|||
bool isInSandbox = false;
|
||||
EventEmitter event;
|
||||
|
||||
std::uint32_t sdkVersion = -1;
|
||||
std::uint64_t nextTlsSlot = 1;
|
||||
std::uint64_t lastTlsOffset = 0;
|
||||
|
||||
|
|
@ -81,6 +82,8 @@ struct Process final {
|
|||
utils::kmap<void *, utils::kstring> namedObjNames;
|
||||
utils::OwningIdMap<NamedObjInfo, uint, 65535, 1> namedObjIds;
|
||||
|
||||
utils::kmap<std::int32_t, SigAction> sigActions;
|
||||
|
||||
// Named memory ranges for debugging
|
||||
utils::shared_mutex namedMemMutex;
|
||||
utils::kmap<NamedMemoryRange, utils::kstring> namedMem;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ struct timespec;
|
|||
struct File;
|
||||
struct MemoryProtection;
|
||||
struct IoVec;
|
||||
struct UContext;
|
||||
|
||||
struct ProcessOps {
|
||||
SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot,
|
||||
|
|
@ -64,7 +65,7 @@ struct ProcessOps {
|
|||
uint64_t arg3);
|
||||
SysResult (*dynlib_unload_prx)(Thread *thread, ModuleHandle handle);
|
||||
|
||||
SysResult (*thr_create)(Thread *thread, ptr<struct ucontext> ctxt,
|
||||
SysResult (*thr_create)(Thread *thread, ptr<UContext> ctxt,
|
||||
ptr<slong> arg, sint flags);
|
||||
SysResult (*thr_new)(Thread *thread, ptr<thr_param> param, sint param_size);
|
||||
SysResult (*thr_exit)(Thread *thread, ptr<slong> state);
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ enum class RegisterId {
|
|||
rax,
|
||||
rsp,
|
||||
rflags,
|
||||
rip,
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@
|
|||
#include "orbis-config.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#include "../KernelAllocator.hpp"
|
||||
#include "../ucontext.hpp"
|
||||
#include "../utils/SharedCV.hpp"
|
||||
#include "../utils/SharedMutex.hpp"
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
namespace orbis {
|
||||
struct Process;
|
||||
|
||||
struct Thread {
|
||||
utils::shared_mutex mtx;
|
||||
Process *tproc = nullptr;
|
||||
|
|
@ -21,8 +25,14 @@ struct Thread {
|
|||
uint64_t gsBase{};
|
||||
char name[32]{};
|
||||
|
||||
uint64_t sigMask[4] = {0x7fff'ffff, 0};
|
||||
SigSet sigMask = {0x7fff'ffff, ~0u, ~0u, ~0u};
|
||||
utils::shared_mutex suspend_mtx;
|
||||
utils::shared_cv suspend_cv;
|
||||
kdeque<int> signalQueue;
|
||||
kvector<UContext> sigReturns;
|
||||
std::atomic<unsigned> suspended{0};
|
||||
|
||||
std::int64_t hostTid = -1;
|
||||
lwpid_t tid = -1;
|
||||
ThreadState state = ThreadState::INACTIVE;
|
||||
std::thread handle;
|
||||
|
|
@ -35,6 +45,10 @@ struct Thread {
|
|||
// Print backtrace
|
||||
void where();
|
||||
|
||||
void suspend();
|
||||
void resume();
|
||||
void sendSignal(int signo);
|
||||
|
||||
// FIXME: implement thread destruction
|
||||
void incRef() {}
|
||||
void decRef() {}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,20 @@ struct Stack {
|
|||
};
|
||||
|
||||
struct SigSet {
|
||||
ulong bits[2];
|
||||
static constexpr auto min = 1;
|
||||
static constexpr auto max = 128;
|
||||
|
||||
uint bits[4];
|
||||
|
||||
bool test(unsigned signal) const {
|
||||
return (bits[(signal - 1) >> 5] & (1 << ((signal - 1) & 31))) != 0;
|
||||
}
|
||||
void set(unsigned signal) {
|
||||
bits[(signal - 1) >> 5] |= (1 << ((signal - 1) & 31));
|
||||
}
|
||||
void clear(unsigned signal) {
|
||||
bits[(signal - 1) >> 5] &= ~(1 << ((signal - 1) & 31));
|
||||
}
|
||||
};
|
||||
|
||||
struct UContext {
|
||||
|
|
@ -67,4 +80,87 @@ struct UContext {
|
|||
sint spare[4];
|
||||
sint unk1[3];
|
||||
};
|
||||
|
||||
static_assert(sizeof(UContext) == 0x500);
|
||||
|
||||
|
||||
enum Signal {
|
||||
kSigHup = 1,
|
||||
kSigInt = 2,
|
||||
kSigQuit = 3,
|
||||
kSigIll = 4,
|
||||
kSigTrap = 5,
|
||||
kSigAbrt = 6,
|
||||
kSigEmt = 7,
|
||||
kSigFpe = 8,
|
||||
kSigKill = 9,
|
||||
kSigBus = 10,
|
||||
kSigSegv = 11,
|
||||
kSigSys = 12,
|
||||
kSigPipe = 13,
|
||||
kSigAlrm = 14,
|
||||
kSigUrg = 16,
|
||||
kSigStop = 17,
|
||||
kSigTstp = 18,
|
||||
kSigCont = 19,
|
||||
kSigChld = 20,
|
||||
kSigTtin = 21,
|
||||
kSigTtou = 22,
|
||||
kSigIo = 23,
|
||||
kSigXcpu = 24,
|
||||
kSigXfsz = 25,
|
||||
kSigVtalrm = 26,
|
||||
kSigProf = 27,
|
||||
kSigWinch = 28,
|
||||
kSigInfo = 29,
|
||||
kSigUsr1 = 30,
|
||||
kSigUsr2 = 31,
|
||||
kSigThr = 32,
|
||||
};
|
||||
|
||||
struct SigAction {
|
||||
ptr<void(int32_t, void *, void *)> handler;
|
||||
sint flags;
|
||||
SigSet mask;
|
||||
};
|
||||
|
||||
union SigVal {
|
||||
sint integer;
|
||||
ptr<void> pointer;
|
||||
};
|
||||
|
||||
struct SigInfo {
|
||||
sint signo;
|
||||
sint errno_;
|
||||
sint code;
|
||||
sint pid;
|
||||
slong uid;
|
||||
sint status;
|
||||
ptr<void> addr;
|
||||
SigVal value;
|
||||
|
||||
union {
|
||||
struct {
|
||||
sint trapno;
|
||||
} fault;
|
||||
|
||||
struct {
|
||||
sint timerid;
|
||||
sint overrun;
|
||||
} timer;
|
||||
|
||||
struct {
|
||||
sint mqd;
|
||||
} mesgq;
|
||||
|
||||
struct {
|
||||
slong band;
|
||||
} poll;
|
||||
|
||||
struct {
|
||||
slong spare1;
|
||||
sint spare2[7];
|
||||
} spare;
|
||||
} reason;
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ protected:
|
|||
}
|
||||
|
||||
// Internal waiting function
|
||||
void impl_wait(shared_mutex &mutex, unsigned _val,
|
||||
int impl_wait(shared_mutex &mutex, unsigned _val,
|
||||
std::uint64_t usec_timeout) noexcept;
|
||||
|
||||
// Try to notify up to _count threads
|
||||
|
|
@ -43,14 +43,14 @@ protected:
|
|||
public:
|
||||
constexpr shared_cv() = default;
|
||||
|
||||
void wait(shared_mutex &mutex, std::uint64_t usec_timeout = -1) noexcept {
|
||||
int wait(shared_mutex &mutex, std::uint64_t usec_timeout = -1) noexcept {
|
||||
const unsigned _val = add_waiter();
|
||||
if (!_val) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
impl_wait(mutex, _val, usec_timeout);
|
||||
return impl_wait(mutex, _val, usec_timeout);
|
||||
}
|
||||
|
||||
// Wake one thread
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class shared_mutex final {
|
|||
|
||||
void impl_lock_shared(unsigned val);
|
||||
void impl_unlock_shared(unsigned old);
|
||||
void impl_wait();
|
||||
int impl_wait();
|
||||
void impl_signal();
|
||||
void impl_lock(unsigned val);
|
||||
void impl_unlock(unsigned old);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue