mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-09 22:56:35 +00:00
kern: Skeleton KSynchronizationObject
This commit is contained in:
parent
2faf3d33b5
commit
7d6b16d7fb
6 changed files with 350 additions and 16 deletions
|
@ -23,24 +23,27 @@ namespace ams::kern {
|
||||||
|
|
||||||
class KProcess;
|
class KProcess;
|
||||||
|
|
||||||
#define MESOSPHERE_AUTOOBJECT_TRAITS(CLASS) \
|
#define MESOSPHERE_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \
|
||||||
|
NON_COPYABLE(CLASS); \
|
||||||
|
NON_MOVEABLE(CLASS); \
|
||||||
private: \
|
private: \
|
||||||
friend class KClassTokenGenerator; \
|
friend class KClassTokenGenerator; \
|
||||||
static constexpr inline auto ObjectType = KClassTokenGenerator::ObjectType::CLASS; \
|
static constexpr inline auto ObjectType = ::ams::kern::KClassTokenGenerator::ObjectType::CLASS; \
|
||||||
static constexpr inline const char * const TypeName = #CLASS; \
|
static constexpr inline const char * const TypeName = #CLASS; \
|
||||||
static constexpr inline ClassTokenType ClassToken = ClassToken<CLASS>; \
|
static constexpr inline ClassTokenType ClassToken() { return ::ams::kern::ClassToken<CLASS>; } \
|
||||||
public: \
|
public: \
|
||||||
static constexpr ALWAYS_INLINE TypeObj GetStaticTypeObj() { return TypeObj(TypeName, ClassToken); } \
|
using BaseClass = BASE_CLASS; \
|
||||||
|
static constexpr ALWAYS_INLINE TypeObj GetStaticTypeObj() { \
|
||||||
|
constexpr ClassTokenType Token = ClassToken(); \
|
||||||
|
return TypeObj(TypeName, Token); \
|
||||||
|
} \
|
||||||
static constexpr ALWAYS_INLINE const char *GetStaticTypeName() { return TypeName; } \
|
static constexpr ALWAYS_INLINE const char *GetStaticTypeName() { return TypeName; } \
|
||||||
virtual TypeObj GetTypeObj() const { return TypeObj(TypeName, ClassToken); } \
|
virtual TypeObj GetTypeObj() const { return GetStaticTypeObj(); } \
|
||||||
virtual const char *GetTypeName() { return TypeName; } \
|
virtual const char *GetTypeName() { return GetStaticTypeName(); } \
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class KAutoObject {
|
class KAutoObject {
|
||||||
NON_COPYABLE(KAutoObject);
|
|
||||||
NON_MOVEABLE(KAutoObject);
|
|
||||||
protected:
|
protected:
|
||||||
class TypeObj {
|
class TypeObj {
|
||||||
private:
|
private:
|
||||||
|
@ -64,6 +67,8 @@ namespace ams::kern {
|
||||||
return (this->GetClassToken() | rhs.GetClassToken()) == this->GetClassToken();
|
return (this->GetClassToken() | rhs.GetClassToken()) == this->GetClassToken();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
|
MESOSPHERE_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject);
|
||||||
private:
|
private:
|
||||||
std::atomic<u32> ref_count;
|
std::atomic<u32> ref_count;
|
||||||
public:
|
public:
|
||||||
|
@ -141,9 +146,6 @@ namespace ams::kern {
|
||||||
this->Destroy();
|
this->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that we have functional type object getters. */
|
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KAutoObject);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class KAutoObjectWithListContainer;
|
class KAutoObjectWithListContainer;
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <mesosphere/kern_k_typed_address.hpp>
|
||||||
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KLinkedListNode : public util::IntrusiveListBaseNode<KLinkedListNode>, public KSlabAllocated<KLinkedListNode> {
|
||||||
|
private:
|
||||||
|
void *item;
|
||||||
|
public:
|
||||||
|
constexpr KLinkedListNode() : util::IntrusiveListBaseNode<KLinkedListNode>(), item(nullptr) { /* ... */ }
|
||||||
|
|
||||||
|
constexpr void Initialize(void *it) {
|
||||||
|
this->item = it;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void *GetItem() const {
|
||||||
|
return this->item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(KLinkedListNode) == sizeof(util::IntrusiveListNode) + sizeof(void *));
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class KLinkedList : private util::IntrusiveListBaseTraits<KLinkedListNode>::ListType {
|
||||||
|
private:
|
||||||
|
using BaseList = util::IntrusiveListBaseTraits<KLinkedListNode>::ListType;
|
||||||
|
public:
|
||||||
|
template<bool Const>
|
||||||
|
class Iterator;
|
||||||
|
|
||||||
|
using value_type = T;
|
||||||
|
using size_type = size_t;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = value_type *;
|
||||||
|
using const_pointer = const value_type *;
|
||||||
|
using reference = value_type &;
|
||||||
|
using const_reference = const value_type &;
|
||||||
|
using iterator = Iterator<false>;
|
||||||
|
using const_iterator = Iterator<true>;
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
template<bool Const>
|
||||||
|
class Iterator {
|
||||||
|
private:
|
||||||
|
using BaseIterator = BaseList::Iterator<Const>;
|
||||||
|
friend class KLinkedList;
|
||||||
|
public:
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = typename KLinkedList::value_type;
|
||||||
|
using difference_type = typename KLinkedList::difference_type;
|
||||||
|
using pointer = typename std::conditional<Const, KLinkedList::const_pointer, KLinkedList::pointer>::type;
|
||||||
|
using reference = typename std::conditional<Const, KLinkedList::const_reference, KLinkedList::reference>::type;
|
||||||
|
private:
|
||||||
|
BaseIterator base_it;
|
||||||
|
public:
|
||||||
|
explicit Iterator(BaseIterator it) : base_it(it) { /* ... */ }
|
||||||
|
|
||||||
|
T *GetItem() const {
|
||||||
|
static_cast<pointer>(this->base_it->GetItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Iterator &rhs) const {
|
||||||
|
return this->base_it == rhs.base_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Iterator &rhs) const {
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->() const {
|
||||||
|
return this->GetItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const {
|
||||||
|
return *this->GetItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator &operator++() {
|
||||||
|
++this->base_it;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator &operator--() {
|
||||||
|
--this->base_it;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator++(int) {
|
||||||
|
const Iterator it{*this};
|
||||||
|
++(*this);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator--(int) {
|
||||||
|
const Iterator it{*this};
|
||||||
|
--(*this);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator Iterator<true>() const {
|
||||||
|
return Iterator<true>(this->base_it);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
constexpr KLinkedList() : BaseList() { /* ... */ }
|
||||||
|
|
||||||
|
/* Iterator accessors. */
|
||||||
|
iterator begin() {
|
||||||
|
return iterator(BaseList::begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return const_iterator(BaseList::begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return iterator(BaseList::end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const {
|
||||||
|
return const_iterator(BaseList::end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cbegin() const {
|
||||||
|
return this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cend() const {
|
||||||
|
return this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_iterator rbegin() {
|
||||||
|
return reverse_iterator(this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator rbegin() const {
|
||||||
|
return const_reverse_iterator(this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_iterator rend() {
|
||||||
|
return reverse_iterator(this->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator rend() const {
|
||||||
|
return const_reverse_iterator(this->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator crbegin() const {
|
||||||
|
return this->rbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator crend() const {
|
||||||
|
return this->rend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content management. */
|
||||||
|
using BaseList::empty;
|
||||||
|
using BaseList::size;
|
||||||
|
|
||||||
|
reference back() {
|
||||||
|
return *(--this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference back() const {
|
||||||
|
return *(--this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
reference front() {
|
||||||
|
return *this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference front() const {
|
||||||
|
return *this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator pos, reference ref) {
|
||||||
|
KLinkedListNode *node = KLinkedListNode::Allocate();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(node != nullptr);
|
||||||
|
node->Initialize(std::addressof(ref));
|
||||||
|
return iterator(BaseList::insert(pos.base_it, *node));
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(reference ref) {
|
||||||
|
this->insert(this->end(), ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_front(reference ref) {
|
||||||
|
this->insert(this->begin(), ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back() {
|
||||||
|
this->erase(--this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_front() {
|
||||||
|
this->erase(this->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator erase(const iterator pos) {
|
||||||
|
KLinkedListNode *freed_node = std::addressof(*pos.base_it);
|
||||||
|
iterator ret = iterator(BaseList::erase(pos.base_it));
|
||||||
|
KLinkedListNode::Free(freed_node);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <mesosphere/kern_k_auto_object.hpp>
|
||||||
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
#include <mesosphere/kern_k_linked_list.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KThread;
|
||||||
|
|
||||||
|
class KSynchronizationObject : public KAutoObjectWithList {
|
||||||
|
MESOSPHERE_AUTOOBJECT_TRAITS(KSynchronizationObject, KAutoObject);
|
||||||
|
public:
|
||||||
|
using ThreadList = KLinkedList<KThread>;
|
||||||
|
using iterator = ThreadList::iterator;
|
||||||
|
private:
|
||||||
|
ThreadList thread_list;
|
||||||
|
protected:
|
||||||
|
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), thread_list() { /* ... */ }
|
||||||
|
virtual ~KSynchronizationObject() { /* ... */ }
|
||||||
|
|
||||||
|
virtual void OnFinalizeSynchronizationObject() { /* ... */ }
|
||||||
|
|
||||||
|
void NotifyAvailable();
|
||||||
|
void NotifyAbort(Result abort_reason);
|
||||||
|
public:
|
||||||
|
virtual void Finalize() override;
|
||||||
|
virtual bool IsSignaled() const = 0;
|
||||||
|
virtual void DebugWaiters();
|
||||||
|
|
||||||
|
iterator AddWaiterThread(KThread *thread);
|
||||||
|
iterator RemoveWaiterThread(iterator it);
|
||||||
|
|
||||||
|
iterator begin();
|
||||||
|
iterator end();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -15,11 +15,12 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <mesosphere/kern_slab_helpers.hpp>
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
#include <mesosphere/kern_k_synchronization_object.hpp>
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject> {
|
||||||
class KThread : KAutoObjectWithSlabHeapAndContainer<KThread, /* TODO: KSynchronizationObject */ KAutoObjectWithList> {
|
MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
|
||||||
public:
|
public:
|
||||||
struct StackParameters {
|
struct StackParameters {
|
||||||
alignas(0x10) u8 svc_permission[0x10];
|
alignas(0x10) u8 svc_permission[0x10];
|
||||||
|
@ -32,7 +33,7 @@ namespace ams::kern {
|
||||||
void *context; /* TODO: KThreadContext * */
|
void *context; /* TODO: KThreadContext * */
|
||||||
};
|
};
|
||||||
static_assert(alignof(StackParameters) == 0x10);
|
static_assert(alignof(StackParameters) == 0x10);
|
||||||
/* TODO: This should be a KAutoObject, and this is a placeholder definition. */
|
/* TODO: This is a placeholder definition. */
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
void NotifyAvailable() {
|
||||||
|
/* TODO: Implement this. */
|
||||||
|
MESOSPHERE_ABORT();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyAbort(Result abort_reason) {
|
||||||
|
MESOSPHERE_ABORT();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSynchronizationObject::Finalize() {
|
||||||
|
this->OnFinalizeSynchronizationObject();
|
||||||
|
KAutoObject::Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSynchronizationObject::DebugWaiters() {
|
||||||
|
/* TODO: Do useful debug operation here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
KSynchronizationObject::iterator KSynchronizationObject::AddWaiterThread(KThread *thread) {
|
||||||
|
return this->thread_list.insert(this->thread_list.end(), *thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
KSynchronizationObject::iterator KSynchronizationObject::RemoveWaiterThread(KSynchronizationObject::iterator it) {
|
||||||
|
return this->thread_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
KSynchronizationObject::iterator KSynchronizationObject::begin() {
|
||||||
|
return this->thread_list.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
KSynchronizationObject::iterator KSynchronizationObject::end() {
|
||||||
|
return this->thread_list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -183,7 +183,7 @@ namespace ams::util {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
IntrusiveListImpl() : root_node() { /* ... */ }
|
constexpr IntrusiveListImpl() : root_node() { /* ... */ }
|
||||||
|
|
||||||
/* Iterator accessors. */
|
/* Iterator accessors. */
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
|
|
Loading…
Reference in a new issue