[orbis-kernel] Implement evf syscalls

This commit is contained in:
DH 2023-07-05 01:43:47 +03:00
parent d279166c0b
commit 14cfdd0eb3
10 changed files with 519 additions and 86 deletions

View file

@ -44,7 +44,7 @@ using kunmap =
template <typename T, typename... Args> T *knew(Args &&...args) {
auto loc = static_cast<T *>(utils::kalloc(sizeof(T), alignof(T)));
auto res = std::construct_at(loc, std::forward<Args>(args)...);
if constexpr (WithRc<T>)
if constexpr (requires(T *t) { t->_total_size = sizeof(T); })
res->_total_size = sizeof(T);
return res;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "utils/LinkedNode.hpp"
#include "utils/SharedMutex.hpp"
#include "evf.hpp"
#include "orbis/thread/types.hpp"
#include "KernelAllocator.hpp"
@ -23,9 +24,23 @@ public:
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
static void kfree(void *ptr, std::size_t size);
std::pair<EventFlag *, bool> createEventFlag(std::string name, std::int32_t flags) {
auto [it, inserted] = m_event_flags.try_emplace(std::move(name), knew<EventFlag>(flags));
return { it->second.get(), inserted };
}
Ref<EventFlag> findEventFlag(std::string_view name) {
if (auto it = m_event_flags.find(name); it != m_event_flags.end()) {
return it->second;
}
return{};
}
private:
mutable shared_mutex m_proc_mtx;
utils::LinkedNode<Process> *m_processes = nullptr;
kmap<std::string, Ref<EventFlag>> m_event_flags;
struct node {
std::size_t size;

View file

@ -0,0 +1,108 @@
#pragma once
#include "thread/Thread.hpp"
#include "utils/SharedMutex.hpp"
#include <atomic>
#include <condition_variable>
namespace orbis {
enum {
kEvfAttrThFifo = 0x01,
kEvfAttrThPrio = 0x02,
kEvfAttrSingle = 0x10,
kEvfAttrMulti = 0x20,
};
enum {
kEvfWaitModeAnd = 0x01,
kEvfWaitModeOr = 0x02,
kEvfWaitModeClearAll = 0x10,
kEvfWaitModeClearPat = 0x20,
};
struct EventFlag {
char name[32];
bool isDeleted = false;
std::uint8_t attrs;
std::atomic<unsigned> references{1};
std::atomic<std::uint64_t> value;
struct WaitingThread {
Thread *thread;
shared_mutex *mtx;
std::uint64_t *patternSet;
bool *isCanceled;
std::uint64_t bitPattern;
std::uint8_t waitMode;
bool test(std::uint64_t value) const {
if (waitMode & kEvfWaitModeAnd) {
return (value & bitPattern) == bitPattern;
}
return (value & bitPattern) != 0;
}
std::uint64_t applyClear(std::uint64_t value) {
if (waitMode & kEvfWaitModeClearAll) {
return 0;
}
if (waitMode & kEvfWaitModeClearPat) {
return value & ~bitPattern;
}
return value;
}
};
WaitingThread waitingThreads[32]; // TODO: create vector?
std::atomic<std::uint32_t> waitingThreadsCount = 0;
shared_mutex queueMtx;
explicit EventFlag(std::int32_t attrs) : attrs(attrs) {}
ErrorCode wait(Thread *thread, std::uint8_t waitMode,
std::uint64_t bitPattern, std::uint64_t *patternSet,
std::uint32_t *timeout);
ErrorCode tryWait(Thread *thread, std::uint8_t waitMode,
std::uint64_t bitPattern, std::uint64_t *patternSet);
std::size_t notify(bool isCancel = false, std::uint64_t cancelValue = 0);
std::size_t destroy() {
isDeleted = true;
return notify();
}
std::size_t cancel(std::uint64_t value) {
return notify(true, value);
}
std::size_t set(std::uint64_t bits) {
{
writer_lock lock(queueMtx);
value.fetch_or(bits, std::memory_order::relaxed);
}
return notify();
}
void clear(std::uint64_t bits) {
{
writer_lock lock(queueMtx);
value.fetch_and(bits, std::memory_order::relaxed);
}
value &= bits;
}
void incRef() { references.fetch_add(1, std::memory_order::relaxed); }
void decRef() {
if (references.fetch_sub(1, std::memory_order::relaxed) == 1) {
delete this;
}
}
};
} // namespace orbis

View file

@ -409,15 +409,15 @@ SysResult sys_jitshm_alias(Thread *thread /* TODO */);
SysResult sys_dl_get_list(Thread *thread /* TODO */);
SysResult sys_dl_get_info(Thread *thread /* TODO */);
SysResult sys_dl_notify_event(Thread *thread /* TODO */);
SysResult sys_evf_create(Thread *thread, ptr<char> name, sint flag, ptr<struct evFlag> evf);
SysResult sys_evf_delete(Thread *thread, sint fd);
SysResult sys_evf_create(Thread *thread, ptr<char> name, sint attrs, ptr<struct evFlag> evf);
SysResult sys_evf_delete(Thread *thread, sint id);
SysResult sys_evf_open(Thread *thread, ptr<char> name);
SysResult sys_evf_close(Thread *thread, sint fd);
SysResult sys_evf_wait(Thread *thread /* TODO */);
SysResult sys_evf_trywait(Thread *thread /* TODO */);
SysResult sys_evf_set(Thread *thread, sint fd);
SysResult sys_evf_clear(Thread *thread, sint fd);
SysResult sys_evf_cancel(Thread *thread, sint fd);
SysResult sys_evf_close(Thread *thread, sint id);
SysResult sys_evf_wait(Thread *thread, sint id, uint64_t patternSet, uint64_t mode, ptr<uint64_t> pPatternSet, ptr<uint> pTimeout);
SysResult sys_evf_trywait(Thread *thread, sint id, uint64_t patternSet, uint64_t mode, ptr<uint64_t> pPatternSet); // FIXME: verify args
SysResult sys_evf_set(Thread *thread, sint id, uint64_t value);
SysResult sys_evf_clear(Thread *thread, sint id, uint64_t value);
SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value, ptr<sint> pNumWaitThreads);
SysResult sys_query_memory_protection(Thread *thread /* TODO */);
SysResult sys_batch_map(Thread *thread /* TODO */);
SysResult sys_osem_create(Thread *thread /* TODO */);

View file

@ -1,11 +1,13 @@
#pragma once
#include "ProcessState.hpp"
#include "orbis-config.hpp"
#include "../evf.hpp"
#include "../thread/Thread.hpp"
#include "../thread/types.hpp"
#include "ProcessState.hpp"
#include "orbis/module/Module.hpp"
#include "orbis/utils/IdMap.hpp"
#include "orbis/utils/SharedMutex.hpp"
#include "../thread/types.hpp"
#include "../thread/Thread.hpp"
#include <mutex>
@ -22,8 +24,10 @@ struct Process {
ProcessState state = ProcessState::NEW;
Process *parentProcess = nullptr;
shared_mutex mtx;
void (*onSysEnter)(Thread *thread, int id, uint64_t *args, int argsCount) = nullptr;
void (*onSysExit)(Thread *thread, int id, uint64_t *args, int argsCount, SysResult result) = nullptr;
void (*onSysEnter)(Thread *thread, int id, uint64_t *args,
int argsCount) = nullptr;
void (*onSysExit)(Thread *thread, int id, uint64_t *args, int argsCount,
SysResult result) = nullptr;
ptr<void> processParam = nullptr;
uint64_t processParamSize = 0;
const ProcessOps *ops = nullptr;
@ -31,6 +35,7 @@ struct Process {
std::uint64_t nextTlsSlot = 1;
std::uint64_t lastTlsOffset = 0;
utils::RcIdMap<EventFlag, sint, 4097, 1> evfMap;
utils::RcIdMap<Module, ModuleHandle> modulesMap;
utils::OwningIdMap<Thread, lwpid_t> threadsMap;
utils::RcIdMap<utils::RcBase, sint> fileDescriptors;