os/dd: primitive fixes

This commit is contained in:
Michael Scire
2019-12-03 19:26:43 -08:00
committed by SciresM
parent b1a9e8d0df
commit ad64cb5212
18 changed files with 276 additions and 65 deletions

View File

@@ -17,3 +17,4 @@
#pragma once
#include "dd/dd_io_mappings.hpp"
#include "dd/dd_process_handle.hpp"

View File

@@ -32,4 +32,5 @@ namespace ams::dd {
AMS_ASSERT(io_mapping);
return io_mapping;
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2018-2019 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 <atmosphere/common.hpp>
namespace ams::dd {
::Handle GetCurrentProcessHandle();
}

View File

@@ -18,8 +18,10 @@
#include "os/os_common_types.hpp"
#include "os/os_managed_handle.hpp"
#include "os/os_process_handle.hpp"
#include "os/os_mutex.hpp"
#include "os/os_condvar.hpp"
#include "os/os_rw_lock.hpp"
#include "os/os_semaphore.hpp"
#include "os/os_timeout_helper.hpp"
#include "os/os_event.hpp"

View File

@@ -54,10 +54,6 @@ namespace ams::os {
return process_id;
}
NX_INLINE ProcessId GetCurrentProcessId() {
return GetProcessId(CUR_PROCESS_HANDLE);
}
inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) {
return lhs.value == rhs.value;
}

View File

@@ -19,6 +19,11 @@
namespace ams::os {
enum class ConditionVariableStatus {
TimedOut = 0,
Success = 1,
};
class ConditionVariable {
NON_COPYABLE(ConditionVariable);
NON_MOVEABLE(ConditionVariable);
@@ -29,40 +34,36 @@ namespace ams::os {
condvarInit(&cv);
}
Result TimedWait(::Mutex *m, u64 timeout) {
return condvarWaitTimeout(&cv, m, timeout);
ConditionVariableStatus TimedWait(::Mutex *m, u64 timeout) {
if (timeout > 0) {
/* Abort on any error other than timed out/success. */
R_TRY_CATCH(condvarWaitTimeout(&this->cv, m, timeout)) {
R_CATCH(svc::ResultTimedOut) { return ConditionVariableStatus::TimedOut; }
} R_END_TRY_CATCH_WITH_ASSERT;
return ConditionVariableStatus::Success;
}
return ConditionVariableStatus::TimedOut;
}
Result Wait(::Mutex *m) {
return condvarWait(&cv, m);
void Wait(::Mutex *m) {
R_ASSERT(condvarWait(&this->cv, m));
}
Result TimedWait(os::Mutex *m, u64 timeout) {
return TimedWait(m->GetMutex(), timeout);
ConditionVariableStatus TimedWait(os::Mutex *m, u64 timeout) {
return this->TimedWait(m->GetMutex(), timeout);
}
Result Wait(os::Mutex *m) {
return Wait(m->GetMutex());
void Wait(os::Mutex *m) {
return this->Wait(m->GetMutex());
}
Result Wake(int num) {
return condvarWake(&cv, num);
void Signal() {
condvarWakeOne(&this->cv);
}
Result WakeOne() {
return condvarWakeOne(&cv);
}
Result WakeAll() {
return condvarWakeAll(&cv);
}
Result Signal() {
return this->WakeOne();
}
Result Broadcast() {
return this->WakeAll();
void Broadcast() {
condvarWakeAll(&this->cv);
}
};

View File

@@ -35,21 +35,22 @@ namespace ams::os {
NON_COPYABLE(MessageQueue);
NON_MOVEABLE(MessageQueue);
private:
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitable_object_list_storage;
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_empty;
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_full;
Mutex queue_lock;
ConditionVariable cv_not_full;
ConditionVariable cv_not_empty;
std::unique_ptr<uintptr_t[]> buffer;
size_t capacity;
size_t count = 0;
size_t offset = 0;
size_t count;
size_t offset;
private:
bool IsFull() const {
constexpr inline bool IsFull() const {
return this->count >= this->capacity;
}
bool IsEmpty() const {
constexpr inline bool IsEmpty() const {
return this->count == 0;
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2018-2019 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 "os_managed_handle.hpp"
namespace ams::os {
::Handle GetCurrentProcessHandle();
NX_INLINE ProcessId GetCurrentProcessId() {
return GetProcessId(GetCurrentProcessHandle());
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2018-2019 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 "os_common_types.hpp"
namespace ams::os {
class ReadWriteLock {
NON_COPYABLE(ReadWriteLock);
NON_MOVEABLE(ReadWriteLock);
private:
::RwLock r;
public:
ReadWriteLock() {
rwlockInit(&this->r);
}
bool IsWriteLockHeldByCurrentThread() const {
return rwlockIsWriteLockHeldByCurrentThread(const_cast<::RwLock *>(&this->r));
}
bool IsLockOwner() const {
return rwlockIsOwnedByCurrentThread(const_cast<::RwLock *>(&this->r));
}
void AcquireReadLock() {
rwlockReadLock(&this->r);
}
void ReleaseReadLock() {
rwlockReadUnlock(&this->r);
}
bool TryAcquireReadLock() {
return rwlockTryReadLock(&this->r);
}
void AcquireWriteLock() {
rwlockWriteLock(&this->r);
}
void ReleaseWriteLock() {
rwlockWriteUnlock(&this->r);
}
bool TryAcquireWriteLock() {
return rwlockTryWriteLock(&this->r);
}
void lock_shared() {
this->AcquireReadLock();
}
void unlock_shared() {
this->ReleaseReadLock();
}
bool try_lock_shared() {
return this->TryAcquireReadLock();
}
void lock() {
this->AcquireWriteLock();
}
void unlock() {
this->ReleaseWriteLock();
}
bool try_lock() {
return this->TryAcquireWriteLock();
}
};
}

View File

@@ -41,7 +41,7 @@ namespace ams::os {
return (tick * 625) / 12;
}
bool TimedOut() const {
inline bool TimedOut() const {
if (this->end_tick == 0) {
return true;
}
@@ -49,7 +49,7 @@ namespace ams::os {
return armGetSystemTick() >= this->end_tick;
}
u64 NsUntilTimeout() const {
inline u64 NsUntilTimeout() const {
u64 diff = TickToNs(this->end_tick - armGetSystemTick());
if (this->TimedOut()) {