2023-07-03 13:10:16 +02:00
|
|
|
#pragma once
|
2024-01-13 18:57:02 +01:00
|
|
|
#include "KernelAllocator.hpp"
|
2023-07-06 21:10:15 +02:00
|
|
|
#include "evf.hpp"
|
2023-07-29 23:44:24 +02:00
|
|
|
#include "ipmi.hpp"
|
2024-10-12 04:24:58 +02:00
|
|
|
#include "orbis/note.hpp"
|
2023-07-17 18:53:48 +02:00
|
|
|
#include "osem.hpp"
|
2024-01-13 18:57:02 +01:00
|
|
|
#include "thread/types.hpp"
|
|
|
|
|
#include "utils/IdMap.hpp"
|
2023-07-03 13:10:16 +02:00
|
|
|
#include "utils/LinkedNode.hpp"
|
2023-07-10 12:58:53 +02:00
|
|
|
#include "utils/SharedCV.hpp"
|
2023-07-03 13:10:16 +02:00
|
|
|
#include "utils/SharedMutex.hpp"
|
|
|
|
|
|
2023-07-10 12:58:53 +02:00
|
|
|
#include <cstdint>
|
|
|
|
|
#include <mutex>
|
2023-07-06 21:10:15 +02:00
|
|
|
#include <pthread.h>
|
2023-07-03 13:10:16 +02:00
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
namespace orbis {
|
2023-07-04 18:19:17 +02:00
|
|
|
struct Process;
|
2023-07-10 12:58:53 +02:00
|
|
|
struct Thread;
|
|
|
|
|
|
|
|
|
|
struct UmtxKey {
|
|
|
|
|
// TODO: may contain a reference to a shared memory
|
2023-07-22 11:03:46 +02:00
|
|
|
std::uintptr_t addr;
|
|
|
|
|
orbis::pid_t pid;
|
2023-07-10 12:58:53 +02:00
|
|
|
|
|
|
|
|
auto operator<=>(const UmtxKey &) const = default;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct UmtxCond {
|
|
|
|
|
Thread *thr;
|
|
|
|
|
utils::shared_cv cv;
|
|
|
|
|
|
|
|
|
|
UmtxCond(Thread *thr) : thr(thr) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct UmtxChain {
|
|
|
|
|
utils::shared_mutex mtx;
|
|
|
|
|
utils::kmultimap<UmtxKey, UmtxCond> sleep_queue;
|
|
|
|
|
utils::kmultimap<UmtxKey, UmtxCond> spare_queue;
|
|
|
|
|
|
|
|
|
|
std::pair<const UmtxKey, UmtxCond> *enqueue(UmtxKey &key, Thread *thr);
|
|
|
|
|
void erase(std::pair<const UmtxKey, UmtxCond> *obj);
|
2023-07-11 07:48:12 +02:00
|
|
|
uint notify_one(const UmtxKey &key);
|
|
|
|
|
uint notify_all(const UmtxKey &key);
|
2023-07-10 12:58:53 +02:00
|
|
|
};
|
2023-07-03 13:10:16 +02:00
|
|
|
|
2023-07-04 18:19:17 +02:00
|
|
|
class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
|
|
|
|
|
public:
|
|
|
|
|
KernelContext();
|
|
|
|
|
~KernelContext();
|
2023-07-03 13:10:16 +02:00
|
|
|
|
2023-07-04 18:19:17 +02:00
|
|
|
Process *createProcess(pid_t pid);
|
|
|
|
|
void deleteProcess(Process *proc);
|
|
|
|
|
Process *findProcessById(pid_t pid) const;
|
2023-12-31 16:58:02 +01:00
|
|
|
Process *findProcessByHostId(std::uint64_t pid) const;
|
2023-07-03 13:10:16 +02:00
|
|
|
|
2023-11-13 13:43:13 +01:00
|
|
|
utils::LinkedNode<Process> *getProcessList() { return m_processes; }
|
2023-10-31 19:28:40 +01:00
|
|
|
|
|
|
|
|
long allocatePid() {
|
|
|
|
|
std::lock_guard lock(m_thread_id_mtx);
|
|
|
|
|
return m_thread_id_map.emplace(0).first;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-15 09:15:32 +02:00
|
|
|
long getTscFreq();
|
|
|
|
|
|
2023-07-06 21:10:15 +02:00
|
|
|
void *kalloc(std::size_t size,
|
|
|
|
|
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
|
|
|
|
|
void kfree(void *ptr, std::size_t size);
|
2023-07-03 13:10:16 +02:00
|
|
|
|
2023-07-06 21:10:15 +02:00
|
|
|
std::pair<EventFlag *, bool> createEventFlag(utils::kstring name,
|
2023-07-11 17:25:54 +02:00
|
|
|
std::int32_t flags,
|
|
|
|
|
std::uint64_t initPattern) {
|
2023-07-08 01:21:10 +02:00
|
|
|
std::lock_guard lock(m_evf_mtx);
|
|
|
|
|
|
|
|
|
|
auto [it, inserted] = m_event_flags.try_emplace(std::move(name), nullptr);
|
|
|
|
|
if (inserted) {
|
2023-07-11 17:25:54 +02:00
|
|
|
it->second = knew<EventFlag>(flags, initPattern);
|
2023-07-17 18:15:08 +02:00
|
|
|
std::strncpy(it->second->name, it->first.c_str(), 32);
|
2023-07-08 01:21:10 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-06 21:10:15 +02:00
|
|
|
return {it->second.get(), inserted};
|
2023-07-05 00:43:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ref<EventFlag> findEventFlag(std::string_view name) {
|
2023-07-08 01:21:10 +02:00
|
|
|
std::lock_guard lock(m_evf_mtx);
|
|
|
|
|
|
2023-07-05 00:43:47 +02:00
|
|
|
if (auto it = m_event_flags.find(name); it != m_event_flags.end()) {
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-06 21:10:15 +02:00
|
|
|
return {};
|
2023-07-05 00:43:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-17 18:53:48 +02:00
|
|
|
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 {};
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-11 00:55:00 +01:00
|
|
|
std::pair<Ref<IpmiServer>, ErrorCode> createIpmiServer(utils::kstring name) {
|
2023-07-29 23:44:24 +02:00
|
|
|
std::lock_guard lock(m_sem_mtx);
|
|
|
|
|
auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr);
|
2023-11-11 00:55:00 +01:00
|
|
|
|
|
|
|
|
if (!inserted) {
|
|
|
|
|
return {it->second, ErrorCode::EXIST};
|
2023-07-29 23:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-11-11 00:55:00 +01:00
|
|
|
it->second = knew<IpmiServer>(it->first);
|
|
|
|
|
|
|
|
|
|
if (it->second == nullptr) {
|
|
|
|
|
mIpmiServers.erase(it);
|
|
|
|
|
return {nullptr, ErrorCode::NOMEM};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {it->second, {}};
|
2023-07-29 23:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ref<IpmiServer> findIpmiServer(std::string_view name) {
|
|
|
|
|
std::lock_guard lock(m_sem_mtx);
|
|
|
|
|
if (auto it = mIpmiServers.find(name); it != mIpmiServers.end()) {
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-13 13:43:13 +01:00
|
|
|
std::tuple<utils::kmap<utils::kstring, char[128]> &,
|
|
|
|
|
std::unique_lock<shared_mutex>>
|
|
|
|
|
getKernelEnv() {
|
|
|
|
|
std::unique_lock lock(m_kenv_mtx);
|
|
|
|
|
return {m_kenv, std::move(lock)};
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-31 19:54:29 +02:00
|
|
|
void setKernelEnv(std::string_view key, std::string_view value) {
|
|
|
|
|
auto &kenvValue = m_kenv[utils::kstring(key)];
|
|
|
|
|
auto len = std::min(sizeof(kenvValue) - 1, value.size());
|
|
|
|
|
std::memcpy(kenvValue, value.data(), len);
|
|
|
|
|
kenvValue[len] = '0';
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-10 12:58:53 +02:00
|
|
|
enum {
|
|
|
|
|
c_golden_ratio_prime = 2654404609u,
|
|
|
|
|
c_umtx_chains = 512,
|
|
|
|
|
c_umtx_shifts = 23,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Use getUmtxChain0 or getUmtxChain1
|
|
|
|
|
std::tuple<UmtxChain &, UmtxKey, std::unique_lock<shared_mutex>>
|
2023-07-22 11:03:46 +02:00
|
|
|
getUmtxChainIndexed(int i, Thread *t, uint32_t flags, void *ptr);
|
2023-07-10 12:58:53 +02:00
|
|
|
|
|
|
|
|
// Internal Umtx: Wait/Cv/Sem
|
2023-07-22 11:03:46 +02:00
|
|
|
auto getUmtxChain0(Thread *t, uint32_t flags, void *ptr) {
|
|
|
|
|
return getUmtxChainIndexed(0, t, flags, ptr);
|
2023-07-10 12:58:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Internal Umtx: Mutex/Umtx/Rwlock
|
2023-07-22 11:03:46 +02:00
|
|
|
auto getUmtxChain1(Thread *t, uint32_t flags, void *ptr) {
|
|
|
|
|
return getUmtxChainIndexed(1, t, flags, ptr);
|
2023-07-10 12:58:53 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-12 04:24:58 +02:00
|
|
|
Ref<EventEmitter> deviceEventEmitter;
|
2023-07-29 21:46:28 +02:00
|
|
|
Ref<RcBase> shmDevice;
|
2023-07-30 00:45:28 +02:00
|
|
|
Ref<RcBase> dmemDevice;
|
2023-07-30 13:56:25 +02:00
|
|
|
Ref<RcBase> blockpoolDevice;
|
2024-10-12 04:24:58 +02:00
|
|
|
shared_mutex gpuDeviceMtx;
|
|
|
|
|
Ref<RcBase> gpuDevice;
|
2024-10-15 17:35:17 +02:00
|
|
|
Ref<RcBase> dceDevice;
|
2023-11-10 18:53:41 +01:00
|
|
|
uint sdkVersion{};
|
2023-12-29 14:27:32 +01:00
|
|
|
uint fwSdkVersion{};
|
2024-01-13 18:57:02 +01:00
|
|
|
uint safeMode{};
|
2024-09-02 19:29:31 +02:00
|
|
|
utils::RcIdMap<RcBase, sint, 4097, 1> ipmiMap;
|
2024-01-13 18:57:02 +01:00
|
|
|
|
|
|
|
|
shared_mutex regMgrMtx;
|
|
|
|
|
kmap<std::uint32_t, std::uint32_t> regMgrInt;
|
2023-07-29 21:46:28 +02:00
|
|
|
|
2023-07-03 13:10:16 +02:00
|
|
|
private:
|
2024-08-31 19:52:30 +02:00
|
|
|
shared_mutex m_heap_mtx;
|
|
|
|
|
shared_mutex m_heap_map_mtx;
|
2023-07-06 21:10:15 +02:00
|
|
|
void *m_heap_next = this + 1;
|
2024-08-31 19:52:30 +02:00
|
|
|
|
2023-07-06 21:10:15 +02:00
|
|
|
utils::kmultimap<std::size_t, void *> m_free_heap;
|
|
|
|
|
utils::kmultimap<std::size_t, void *> m_used_node;
|
|
|
|
|
|
2023-07-10 12:58:53 +02:00
|
|
|
UmtxChain m_umtx_chains[2][c_umtx_chains]{};
|
|
|
|
|
|
2023-07-15 09:15:32 +02:00
|
|
|
std::atomic<long> m_tsc_freq{0};
|
|
|
|
|
|
2023-10-31 19:28:40 +01:00
|
|
|
shared_mutex m_thread_id_mtx;
|
|
|
|
|
OwningIdMap<char, long, 256, 0> m_thread_id_map;
|
2023-07-03 13:10:16 +02:00
|
|
|
mutable shared_mutex m_proc_mtx;
|
|
|
|
|
utils::LinkedNode<Process> *m_processes = nullptr;
|
2023-07-17 18:15:08 +02:00
|
|
|
|
|
|
|
|
shared_mutex m_evf_mtx;
|
2023-07-05 12:08:13 +02:00
|
|
|
utils::kmap<utils::kstring, Ref<EventFlag>> m_event_flags;
|
2023-07-17 18:53:48 +02:00
|
|
|
|
|
|
|
|
shared_mutex m_sem_mtx;
|
|
|
|
|
utils::kmap<utils::kstring, Ref<Semaphore>> m_semaphores;
|
2023-07-29 23:44:24 +02:00
|
|
|
|
|
|
|
|
shared_mutex mIpmiServerMtx;
|
|
|
|
|
utils::kmap<utils::kstring, Ref<IpmiServer>> mIpmiServers;
|
2023-11-13 13:43:13 +01:00
|
|
|
|
|
|
|
|
shared_mutex m_kenv_mtx;
|
|
|
|
|
utils::kmap<utils::kstring, char[128]> m_kenv; // max size: 127 + '\0'
|
2023-07-03 13:10:16 +02:00
|
|
|
};
|
2023-07-04 18:19:17 +02:00
|
|
|
|
|
|
|
|
extern KernelContext &g_context;
|
|
|
|
|
} // namespace orbis
|