-
-
Notifications
You must be signed in to change notification settings - Fork 742
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
357b782
commit ae55e18
Showing
15 changed files
with
311 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#include "mutex.h" | ||
|
||
#include "common/assert.h" | ||
|
||
namespace Libraries::Kernel { | ||
|
||
TimedMutex::TimedMutex() { | ||
#ifdef _WIN64 | ||
mtx = CreateMutex(nullptr, false, nullptr); | ||
ASSERT(mtx); | ||
#endif | ||
} | ||
|
||
TimedMutex::~TimedMutex() { | ||
#ifdef _WIN64 | ||
CloseHandle(mtx); | ||
#endif | ||
} | ||
|
||
void TimedMutex::lock() { | ||
#ifdef _WIN64 | ||
for (;;) { | ||
u64 res = WaitForSingleObjectEx(mtx, INFINITE, true); | ||
if (res == WAIT_OBJECT_0) { | ||
return; | ||
} | ||
} | ||
#else | ||
mtx.lock(); | ||
#endif | ||
} | ||
|
||
bool TimedMutex::try_lock() { | ||
#ifdef _WIN64 | ||
return WaitForSingleObjectEx(mtx, 0, true) == WAIT_OBJECT_0; | ||
#else | ||
return mtx.try_lock(); | ||
#endif | ||
} | ||
|
||
void TimedMutex::unlock() { | ||
#ifdef _WIN64 | ||
ReleaseMutex(mtx); | ||
#else | ||
mtx.unlock(); | ||
#endif | ||
} | ||
|
||
} // namespace Libraries::Kernel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#include <chrono> | ||
|
||
#include "common/types.h" | ||
|
||
#ifdef _WIN64 | ||
#include <windows.h> | ||
#else | ||
#include <mutex> | ||
#endif | ||
|
||
namespace Libraries::Kernel { | ||
|
||
class TimedMutex { | ||
public: | ||
TimedMutex(); | ||
~TimedMutex(); | ||
|
||
void lock(); | ||
bool try_lock(); | ||
|
||
void unlock(); | ||
|
||
template <class Rep, class Period> | ||
bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time) { | ||
#ifdef _WIN64 | ||
constexpr auto zero = std::chrono::duration<Rep, Period>::zero(); | ||
const auto now = std::chrono::steady_clock::now(); | ||
|
||
std::chrono::steady_clock::time_point abs_time = now; | ||
if (rel_time > zero) { | ||
constexpr auto max = (std::chrono::steady_clock::time_point::max)(); | ||
if (abs_time < max - rel_time) { | ||
abs_time += rel_time; | ||
} else { | ||
abs_time = max; | ||
} | ||
} | ||
|
||
return try_lock_until(abs_time); | ||
#else | ||
return mtx.try_lock_for(rel_time); | ||
#endif | ||
} | ||
|
||
template <class Clock, class Duration> | ||
bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time) { | ||
#ifdef _WIN64 | ||
for (;;) { | ||
const auto now = Clock::now(); | ||
if (abs_time <= now) { | ||
return false; | ||
} | ||
|
||
const auto rel_ms = std::chrono::ceil<std::chrono::milliseconds>(abs_time - now); | ||
u64 res = WaitForSingleObjectEx(mtx, static_cast<u64>(rel_ms.count()), true); | ||
if (res == WAIT_OBJECT_0) { | ||
return true; | ||
} else if (res == WAIT_TIMEOUT) { | ||
return false; | ||
} | ||
} | ||
#else | ||
return mtx.try_lock_until(abs_time); | ||
#endif | ||
} | ||
|
||
private: | ||
#ifdef _WIN64 | ||
HANDLE mtx; | ||
#else | ||
std::timed_mutex mtx; | ||
#endif | ||
}; | ||
|
||
} // namespace Libraries::Kernel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#include <atomic> | ||
#include <chrono> | ||
|
||
#include "common/assert.h" | ||
#include "common/types.h" | ||
|
||
#ifdef _WIN64 | ||
#include <windows.h> | ||
#else | ||
#include <semaphore> | ||
#endif | ||
|
||
namespace Libraries::Kernel { | ||
|
||
template <s64 max> | ||
class Semaphore { | ||
public: | ||
Semaphore(s32 initialCount) | ||
#ifndef _WIN64 | ||
: sem{initialCount} | ||
#endif | ||
{ | ||
#ifdef _WIN64 | ||
sem = CreateSemaphore(nullptr, initialCount, max, nullptr); | ||
ASSERT(sem); | ||
#endif | ||
} | ||
|
||
~Semaphore() { | ||
#ifdef _WIN64 | ||
CloseHandle(sem); | ||
#endif | ||
} | ||
|
||
void release() { | ||
#ifdef _WIN64 | ||
ReleaseSemaphore(sem, 1, nullptr); | ||
#else | ||
sem.release(); | ||
#endif | ||
} | ||
|
||
void acquire() { | ||
#ifdef _WIN64 | ||
for (;;) { | ||
u64 res = WaitForSingleObjectEx(sem, INFINITE, true); | ||
if (res == WAIT_OBJECT_0) { | ||
return; | ||
} | ||
} | ||
#else | ||
sem.acquire(); | ||
#endif | ||
} | ||
|
||
bool try_acquire() { | ||
#ifdef _WIN64 | ||
return WaitForSingleObjectEx(sem, 0, true) == WAIT_OBJECT_0; | ||
#else | ||
return sem.try_acquire(); | ||
#endif | ||
} | ||
|
||
template <class Rep, class Period> | ||
bool try_acquire_for(const std::chrono::duration<Rep, Period>& rel_time) { | ||
#ifdef _WIN64 | ||
const auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time); | ||
const u64 timeout_ms = static_cast<u64>(rel_time_ms.count()); | ||
|
||
if (timeout_ms == 0) { | ||
return false; | ||
} | ||
|
||
return WaitForSingleObjectEx(sem, timeout_ms, true) == WAIT_OBJECT_0; | ||
#else | ||
return sem.try_acquire_for(rel_time); | ||
#endif | ||
} | ||
|
||
template <class Clock, class Duration> | ||
bool try_acquire_until(const std::chrono::time_point<Clock, Duration>& abs_time) { | ||
#ifdef _WIN64 | ||
const auto now = Clock::now(); | ||
if (now >= abs_time) { | ||
return false; | ||
} | ||
|
||
const auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - now); | ||
const u64 timeout_ms = static_cast<u64>(rel_time.count()); | ||
if (timeout_ms == 0) { | ||
return false; | ||
} | ||
|
||
u64 res = WaitForSingleObjectEx(sem, static_cast<u64>(timeout_ms), true); | ||
return res == WAIT_OBJECT_0; | ||
#else | ||
return sem.try_acquire_until(abs_time); | ||
#endif | ||
} | ||
|
||
private: | ||
#ifdef _WIN64 | ||
HANDLE sem; | ||
#else | ||
std::counting_semaphore<max> sem; | ||
#endif | ||
}; | ||
|
||
using BinarySemaphore = Semaphore<1>; | ||
using CountingSemaphore = Semaphore<0x7FFFFFFF /*ORBIS_KERNEL_SEM_VALUE_MAX*/>; | ||
|
||
} // namespace Libraries::Kernel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,7 +118,6 @@ class EventFlagInternal { | |
} | ||
|
||
m_bits |= bits; | ||
|
||
m_cond_var.notify_all(); | ||
} | ||
|
||
|
Oops, something went wrong.