mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-02-20 06:35:05 +01:00
[orbis-kernel] Implement kfree
Incomplete implementation.
This commit is contained in:
parent
5f6647540c
commit
9744c41ebb
|
|
@ -37,6 +37,8 @@ template <typename T> using kvector = std::vector<T, kallocator<T>>;
|
|||
template <typename T> using kdeque = std::deque<T, kallocator<T>>;
|
||||
template <typename K, typename T, typename Cmp = std::less<>>
|
||||
using kmap = std::map<K, T, Cmp, kallocator<std::pair<const K, T>>>;
|
||||
template <typename K, typename T, typename Cmp = std::less<>>
|
||||
using kmultimap = std::multimap<K, T, Cmp, kallocator<std::pair<const K, T>>>;
|
||||
template <typename K, typename T, typename Hash = std::hash<K>,
|
||||
typename Pred = std::equal_to<K>>
|
||||
using kunmap =
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
#include "evf.hpp"
|
||||
#include "utils/LinkedNode.hpp"
|
||||
#include "utils/SharedMutex.hpp"
|
||||
#include "evf.hpp"
|
||||
|
||||
#include "orbis/thread/types.hpp"
|
||||
#include "KernelAllocator.hpp"
|
||||
#include "orbis/thread/types.hpp"
|
||||
#include <algorithm>
|
||||
#include <pthread.h>
|
||||
#include <utility>
|
||||
|
||||
namespace orbis {
|
||||
|
|
@ -20,13 +21,15 @@ public:
|
|||
void deleteProcess(Process *proc);
|
||||
Process *findProcessById(pid_t pid) const;
|
||||
|
||||
static void *kalloc(std::size_t size,
|
||||
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
|
||||
static void kfree(void *ptr, std::size_t size);
|
||||
void *kalloc(std::size_t size,
|
||||
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
|
||||
void kfree(void *ptr, std::size_t size);
|
||||
|
||||
std::pair<EventFlag *, bool> createEventFlag(utils::kstring name, std::int32_t flags) {
|
||||
auto [it, inserted] = m_event_flags.try_emplace(std::move(name), knew<EventFlag>(flags));
|
||||
return { it->second.get(), inserted };
|
||||
std::pair<EventFlag *, bool> createEventFlag(utils::kstring 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) {
|
||||
|
|
@ -34,22 +37,19 @@ public:
|
|||
return it->second;
|
||||
}
|
||||
|
||||
return{};
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
mutable pthread_mutex_t m_heap_mtx;
|
||||
void *m_heap_next = this + 1;
|
||||
bool m_heap_is_freeing = false;
|
||||
utils::kmultimap<std::size_t, void *> m_free_heap;
|
||||
utils::kmultimap<std::size_t, void *> m_used_node;
|
||||
|
||||
mutable shared_mutex m_proc_mtx;
|
||||
utils::LinkedNode<Process> *m_processes = nullptr;
|
||||
utils::kmap<utils::kstring, Ref<EventFlag>> m_event_flags;
|
||||
|
||||
struct node {
|
||||
std::size_t size;
|
||||
node *next;
|
||||
};
|
||||
|
||||
mutable shared_mutex m_heap_mtx;
|
||||
void *m_heap_next = this + 1;
|
||||
node *m_free_list = nullptr;
|
||||
};
|
||||
|
||||
extern KernelContext &g_context;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,14 @@ KernelContext &g_context = *[]() -> KernelContext * {
|
|||
}();
|
||||
|
||||
KernelContext::KernelContext() {
|
||||
// Initialize recursive heap mutex
|
||||
pthread_mutexattr_t mtx_attr;
|
||||
pthread_mutexattr_init(&mtx_attr);
|
||||
pthread_mutexattr_settype(&mtx_attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutexattr_setpshared(&mtx_attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutex_init(&m_heap_mtx, &mtx_attr);
|
||||
pthread_mutexattr_destroy(&mtx_attr);
|
||||
|
||||
std::printf("orbis::KernelContext initialized, addr=%p", this);
|
||||
}
|
||||
KernelContext::~KernelContext() {}
|
||||
|
|
@ -66,28 +74,53 @@ Process *KernelContext::findProcessById(pid_t pid) const {
|
|||
}
|
||||
|
||||
void *KernelContext::kalloc(std::size_t size, std::size_t align) {
|
||||
std::lock_guard lock(g_context.m_heap_mtx);
|
||||
align = std::max(align, sizeof(node));
|
||||
auto heap = reinterpret_cast<std::uintptr_t>(g_context.m_heap_next);
|
||||
pthread_mutex_lock(&m_heap_mtx);
|
||||
if (!m_heap_is_freeing) {
|
||||
// Try to reuse previously freed block
|
||||
for (auto [it, end] = m_free_heap.equal_range(size); it != end; it++) {
|
||||
auto result = it->second;
|
||||
if (!(reinterpret_cast<std::uintptr_t>(result) & (align - 1))) {
|
||||
m_used_node.insert(m_free_heap.extract(it));
|
||||
pthread_mutex_unlock(&m_heap_mtx);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
align = std::max<std::size_t>(align, __STDCPP_DEFAULT_NEW_ALIGNMENT__);
|
||||
auto heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
|
||||
heap = (heap + (align - 1)) & ~(align - 1);
|
||||
auto result = reinterpret_cast<void *>(heap);
|
||||
g_context.m_heap_next = reinterpret_cast<void *>(heap + size);
|
||||
m_heap_next = reinterpret_cast<void *>(heap + size);
|
||||
pthread_mutex_unlock(&m_heap_mtx);
|
||||
return result;
|
||||
}
|
||||
|
||||
void KernelContext::kfree(void *ptr, std::size_t size) {
|
||||
std::lock_guard lock(g_context.m_heap_mtx);
|
||||
pthread_mutex_lock(&m_heap_mtx);
|
||||
if (!size)
|
||||
std::abort();
|
||||
// TODO: create node and put it into
|
||||
if (m_heap_is_freeing)
|
||||
std::abort();
|
||||
m_heap_is_freeing = true;
|
||||
if (!m_used_node.empty()) {
|
||||
auto node = m_used_node.extract(m_used_node.begin());
|
||||
node.key() = size;
|
||||
node.mapped() = ptr;
|
||||
m_free_heap.insert(std::move(node));
|
||||
} else {
|
||||
m_free_heap.emplace(size, ptr);
|
||||
}
|
||||
m_heap_is_freeing = false;
|
||||
pthread_mutex_unlock(&m_heap_mtx);
|
||||
}
|
||||
|
||||
inline namespace utils {
|
||||
void kfree(void *ptr, std::size_t size) {
|
||||
return KernelContext::kfree(ptr, size);
|
||||
return g_context.kfree(ptr, size);
|
||||
}
|
||||
void *kalloc(std::size_t size, std::size_t align) {
|
||||
return KernelContext::kalloc(size, align);
|
||||
return g_context.kalloc(size, align);
|
||||
}
|
||||
} // namespace utils
|
||||
} // namespace orbis
|
||||
|
|
|
|||
Loading…
Reference in a new issue