mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-23 11:16:57 -04:00
os: implement ReadWriteLock
This commit is contained in:
parent
6eb77e69c4
commit
97cba5e881
20 changed files with 941 additions and 66 deletions
|
@ -23,8 +23,8 @@ namespace ams::svc::arch::arm64 {
|
|||
|
||||
struct ThreadLocalRegion {
|
||||
u32 message_buffer[MessageBufferSize / sizeof(u32)];
|
||||
u16 disable_count;
|
||||
u16 preemption_state;
|
||||
volatile u16 disable_count;
|
||||
volatile u16 interrupt_flag;
|
||||
/* TODO: How should we handle libnx vs Nintendo user thread local space? */
|
||||
uintptr_t TODO[(0x200 - 0x108) / sizeof(uintptr_t)];
|
||||
};
|
||||
|
|
|
@ -58,11 +58,11 @@ namespace ams::svc::ipc {
|
|||
private:
|
||||
util::BitPack32 header[2];
|
||||
public:
|
||||
constexpr ALWAYS_INLINE MessageHeader() : header({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
constexpr ALWAYS_INLINE MessageHeader() : header({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
this->header[0].Set<Tag>(NullTag);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
this->header[0].Set<Tag>(tag);
|
||||
this->header[0].Set<PointerCount>(ptr);
|
||||
this->header[0].Set<SendCount>(send);
|
||||
|
@ -74,11 +74,11 @@ namespace ams::svc::ipc {
|
|||
this->header[1].Set<HasSpecialHeader>(special);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
buf.Get(0, this->header, util::size(this->header));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header({util::BitPack32(msg[0]), util::BitPack32(msg[1])}) { /* ... */ }
|
||||
ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header({util::BitPack32{msg[0]}, util::BitPack32{msg[1]}}) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE u16 GetTag() const {
|
||||
return this->header[0].Get<Tag>();
|
||||
|
@ -143,13 +143,13 @@ namespace ams::svc::ipc {
|
|||
util::BitPack32 header;
|
||||
bool has_header;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE explicit SpecialHeader(bool pid, s32 copy, s32 move) : header(0), has_header(true) {
|
||||
constexpr ALWAYS_INLINE explicit SpecialHeader(bool pid, s32 copy, s32 move) : header{0}, has_header(true) {
|
||||
this->header.Set<HasProcessId>(pid);
|
||||
this->header.Set<CopyHandleCount>(copy);
|
||||
this->header.Set<MoveHandleCount>(move);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE explicit SpecialHeader(const MessageBuffer &buf, const MessageHeader &hdr) : header(0), has_header(hdr.GetHasSpecialHeader()) {
|
||||
ALWAYS_INLINE explicit SpecialHeader(const MessageBuffer &buf, const MessageHeader &hdr) : header{0}, has_header(hdr.GetHasSpecialHeader()) {
|
||||
if (this->has_header) {
|
||||
buf.Get(MessageHeader::GetDataSize() / sizeof(util::BitPack32), std::addressof(this->header), sizeof(this->header) / sizeof(util::BitPack32));
|
||||
}
|
||||
|
@ -219,9 +219,9 @@ namespace ams::svc::ipc {
|
|||
private:
|
||||
util::BitPack32 data[3];
|
||||
public:
|
||||
constexpr ALWAYS_INLINE MapAliasDescriptor() : data({util::BitPack32(0), util::BitPack32(0), util::BitPack32(0)}) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE MapAliasDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data({util::BitPack32(0), util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
const u64 address = reinterpret_cast<u64>(buffer);
|
||||
const u64 size = static_cast<u64>(_size);
|
||||
this->data[0] = { static_cast<u32>(size) };
|
||||
|
@ -233,7 +233,7 @@ namespace ams::svc::ipc {
|
|||
this->data[2].Set<AddressHigh>(GetAddressHigh(address));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32(0), util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
buf.Get(index, this->data, util::size(this->data));
|
||||
}
|
||||
|
||||
|
@ -283,9 +283,9 @@ namespace ams::svc::ipc {
|
|||
private:
|
||||
util::BitPack32 data[2];
|
||||
public:
|
||||
constexpr ALWAYS_INLINE PointerDescriptor() : data({util::BitPack32(0), util::BitPack32(0)}) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE PointerDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
const u64 address = reinterpret_cast<u64>(buffer);
|
||||
|
||||
this->data[0].Set<Index>(index);
|
||||
|
@ -296,7 +296,7 @@ namespace ams::svc::ipc {
|
|||
this->data[1] = { static_cast<u32>(address) };
|
||||
}
|
||||
|
||||
ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
buf.Get(index, this->data, util::size(this->data));
|
||||
}
|
||||
|
||||
|
@ -338,9 +338,9 @@ namespace ams::svc::ipc {
|
|||
private:
|
||||
util::BitPack32 data[2];
|
||||
public:
|
||||
constexpr ALWAYS_INLINE ReceiveListEntry() : data({util::BitPack32(0), util::BitPack32(0)}) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE ReceiveListEntry() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data({util::BitPack32(0), util::BitPack32(0)}) {
|
||||
ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data({util::BitPack32{0}, util::BitPack32{0}}) {
|
||||
const u64 address = reinterpret_cast<u64>(buffer);
|
||||
|
||||
this->data[0] = { static_cast<u32>(address) };
|
||||
|
@ -349,7 +349,7 @@ namespace ams::svc::ipc {
|
|||
this->data[1].Set<Size>(size);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data({util::BitPack32(a), util::BitPack32(b)}) { /* ... */ }
|
||||
ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data({util::BitPack32{a}, util::BitPack32{b}}) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE uintptr_t GetAddress() {
|
||||
const u64 address = (static_cast<u64>(this->data[1].Get<AddressHigh>()) << AddressLow::Count) | this->data[0].Get<AddressLow>();
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace ams::util {
|
|||
namespace impl {
|
||||
|
||||
template<typename IntegralStorageType>
|
||||
class BitPack {
|
||||
struct BitPack {
|
||||
IntegralStorageType value;
|
||||
private:
|
||||
static_assert(std::is_integral<IntegralStorageType>::value);
|
||||
static_assert(std::is_unsigned<IntegralStorageType>::value);
|
||||
|
@ -49,16 +50,13 @@ namespace ams::util {
|
|||
static constexpr size_t Next = Index + Count;
|
||||
|
||||
using BitPackType = BitPack<IntegralStorageType>;
|
||||
static_assert(std::is_pod<BitPackType>::value);
|
||||
|
||||
static_assert(Mask<Index, Count> != 0);
|
||||
static_assert(std::is_integral<T>::value || std::is_enum<T>::value);
|
||||
static_assert(!std::is_same<T, bool>::value || Count == 1);
|
||||
};
|
||||
private:
|
||||
IntegralStorageType value;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE BitPack(IntegralStorageType v) : value(v) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE void Clear() {
|
||||
constexpr IntegralStorageType Zero = IntegralStorageType(0);
|
||||
this->value = Zero;
|
||||
|
@ -86,6 +84,10 @@ namespace ams::util {
|
|||
using BitPack32 = impl::BitPack<u32>;
|
||||
using BitPack64 = impl::BitPack<u64>;
|
||||
|
||||
static_assert(std::is_pod<BitPack8>::value);
|
||||
static_assert(std::is_pod<BitPack16>::value);
|
||||
static_assert(std::is_pod<BitPack32>::value);
|
||||
static_assert(std::is_pod<BitPack64>::value);
|
||||
static_assert(std::is_trivially_destructible<BitPack8 >::value);
|
||||
static_assert(std::is_trivially_destructible<BitPack16>::value);
|
||||
static_assert(std::is_trivially_destructible<BitPack32>::value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue