[orbis-kernel] Initial osem semaphore implementation

This commit is contained in:
Ivan Chikish 2023-07-17 19:53:48 +03:00
parent 00690fd685
commit 439444d72b
5 changed files with 209 additions and 22 deletions

View file

@ -1,5 +1,6 @@
#pragma once
#include "evf.hpp"
#include "osem.hpp"
#include "utils/LinkedNode.hpp"
#include "utils/SharedCV.hpp"
#include "utils/SharedMutex.hpp"
@ -81,6 +82,28 @@ public:
return {};
}
std::pair<Semaphore *, bool> createSemaphore(utils::kstring name,
std::uint32_t attrs,
std::int32_t initCount,
std::int32_t maxCount) {
std::lock_guard lock(m_sem_mtx);
auto [it, inserted] = m_semaphores.try_emplace(std::move(name), nullptr);
if (inserted) {
it->second = knew<Semaphore>(attrs, initCount, maxCount);
}
return {it->second.get(), inserted};
}
Ref<Semaphore> findSemaphore(std::string_view name) {
std::lock_guard lock(m_sem_mtx);
if (auto it = m_semaphores.find(name); it != m_semaphores.end()) {
return it->second;
}
return {};
}
enum {
c_golden_ratio_prime = 2654404609u,
c_umtx_chains = 512,
@ -122,6 +145,9 @@ private:
shared_mutex m_evf_mtx;
utils::kmap<utils::kstring, Ref<EventFlag>> m_event_flags;
shared_mutex m_sem_mtx;
utils::kmap<utils::kstring, Ref<Semaphore>> m_semaphores;
};
extern KernelContext &g_context;

View file

@ -0,0 +1,45 @@
#pragma once
#include "KernelAllocator.hpp"
#include "thread/Thread.hpp"
#include "utils/SharedCV.hpp"
#include "utils/SharedMutex.hpp"
#include <atomic>
#include <condition_variable>
namespace orbis {
enum {
kSemaAttrThFifo = 1,
kSemaAttrThPrio = 2,
kSemaAttrShared = 256,
};
struct Semaphore final {
char name[32];
bool isDeleted = false;
std::uint8_t attrs;
std::atomic<unsigned> references{0};
std::atomic<sint> value;
const sint maxValue;
utils::shared_mutex mtx;
utils::shared_cv cond;
Semaphore(uint attrs, sint value, sint max)
: attrs(attrs), value(value), maxValue(max) {}
void destroy() {
std::lock_guard lock(mtx);
isDeleted = true;
cond.notify_all(mtx);
}
void incRef() { references.fetch_add(1, std::memory_order::relaxed); }
void decRef() {
if (references.fetch_sub(1, std::memory_order::relaxed) == 1) {
kdelete(this);
}
}
};
} // namespace orbis

View file

@ -635,14 +635,16 @@ 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 */);
SysResult sys_osem_delete(Thread *thread /* TODO */);
SysResult sys_osem_open(Thread *thread /* TODO */);
SysResult sys_osem_close(Thread *thread /* TODO */);
SysResult sys_osem_wait(Thread *thread /* TODO */);
SysResult sys_osem_trywait(Thread *thread /* TODO */);
SysResult sys_osem_post(Thread *thread /* TODO */);
SysResult sys_osem_cancel(Thread *thread /* TODO */);
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);
SysResult sys_osem_open(Thread *thread, ptr<const char[32]> name);
SysResult sys_osem_close(Thread *thread, sint id);
SysResult sys_osem_wait(Thread *thread, sint id, sint need, ptr<uint> pTimeout);
SysResult sys_osem_trywait(Thread *thread, sint id, sint need);
SysResult sys_osem_post(Thread *thread, sint id, sint count);
SysResult sys_osem_cancel(Thread *thread, sint id, sint set,
ptr<uint> pNumWaitThreads);
SysResult sys_namedobj_create(Thread *thread, ptr<const char[32]> name,
ptr<void> object, uint16_t type);
SysResult sys_namedobj_delete(Thread *thread, uint id, uint16_t type);

View file

@ -2,6 +2,7 @@
#include "orbis-config.hpp"
#include "../evf.hpp"
#include "../osem.hpp"
#include "../thread/Thread.hpp"
#include "../thread/types.hpp"
#include "ProcessState.hpp"
@ -57,6 +58,7 @@ struct Process final {
std::uint64_t lastTlsOffset = 0;
utils::RcIdMap<EventFlag, sint, 4097, 1> evfMap;
utils::RcIdMap<Semaphore, sint, 4097, 1> semMap;
utils::RcIdMap<Module, ModuleHandle> modulesMap;
utils::OwningIdMap<Thread, lwpid_t> threadsMap;
utils::RcIdMap<utils::RcBase, sint> fileDescriptors;