mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-29 11:06:07 +00:00
semaphore: Use binary_semaphore instead of condvar
Some checks failed
Build and Release / reuse (push) Has been cancelled
Build and Release / clang-format (push) Has been cancelled
Build and Release / get-info (push) Has been cancelled
Build and Release / windows-sdl (push) Has been cancelled
Build and Release / windows-qt (push) Has been cancelled
Build and Release / macos-sdl (push) Has been cancelled
Build and Release / macos-qt (push) Has been cancelled
Build and Release / linux-sdl (push) Has been cancelled
Build and Release / linux-qt (push) Has been cancelled
Build and Release / pre-release (push) Has been cancelled
Some checks failed
Build and Release / reuse (push) Has been cancelled
Build and Release / clang-format (push) Has been cancelled
Build and Release / get-info (push) Has been cancelled
Build and Release / windows-sdl (push) Has been cancelled
Build and Release / windows-qt (push) Has been cancelled
Build and Release / macos-sdl (push) Has been cancelled
Build and Release / macos-qt (push) Has been cancelled
Build and Release / linux-sdl (push) Has been cancelled
Build and Release / linux-qt (push) Has been cancelled
Build and Release / pre-release (push) Has been cancelled
* Seems more reliable
This commit is contained in:
parent
a4ea20c273
commit
85dc57b868
|
@ -49,7 +49,9 @@ public:
|
||||||
const auto it = AddWaiter(&waiter);
|
const auto it = AddWaiter(&waiter);
|
||||||
|
|
||||||
// Perform the wait.
|
// Perform the wait.
|
||||||
const s32 result = waiter.Wait(lk, timeout);
|
lk.unlock();
|
||||||
|
const s32 result = waiter.Wait(timeout);
|
||||||
|
lk.lock();
|
||||||
if (result == SCE_KERNEL_ERROR_ETIMEDOUT) {
|
if (result == SCE_KERNEL_ERROR_ETIMEDOUT) {
|
||||||
wait_list.erase(it);
|
wait_list.erase(it);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,7 @@ public:
|
||||||
}
|
}
|
||||||
it = wait_list.erase(it);
|
it = wait_list.erase(it);
|
||||||
token_count -= waiter->need_count;
|
token_count -= waiter->need_count;
|
||||||
waiter->cv.notify_one();
|
waiter->sema.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -85,7 +87,7 @@ public:
|
||||||
}
|
}
|
||||||
for (auto* waiter : wait_list) {
|
for (auto* waiter : wait_list) {
|
||||||
waiter->was_cancled = true;
|
waiter->was_cancled = true;
|
||||||
waiter->cv.notify_one();
|
waiter->sema.release();
|
||||||
}
|
}
|
||||||
wait_list.clear();
|
wait_list.clear();
|
||||||
token_count = set_count < 0 ? init_count : set_count;
|
token_count = set_count < 0 ? init_count : set_count;
|
||||||
|
@ -96,20 +98,20 @@ public:
|
||||||
std::scoped_lock lk{mutex};
|
std::scoped_lock lk{mutex};
|
||||||
for (auto* waiter : wait_list) {
|
for (auto* waiter : wait_list) {
|
||||||
waiter->was_deleted = true;
|
waiter->was_deleted = true;
|
||||||
waiter->cv.notify_one();
|
waiter->sema.release();
|
||||||
}
|
}
|
||||||
wait_list.clear();
|
wait_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct WaitingThread {
|
struct WaitingThread {
|
||||||
std::condition_variable cv;
|
std::binary_semaphore sema;
|
||||||
u32 priority;
|
u32 priority;
|
||||||
s32 need_count;
|
s32 need_count;
|
||||||
bool was_deleted{};
|
bool was_deleted{};
|
||||||
bool was_cancled{};
|
bool was_cancled{};
|
||||||
|
|
||||||
explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} {
|
explicit WaitingThread(s32 need_count, bool is_fifo) : sema{0}, need_count{need_count} {
|
||||||
// Retrieve calling thread priority for sorting into waiting threads list.
|
// Retrieve calling thread priority for sorting into waiting threads list.
|
||||||
if (!is_fifo) {
|
if (!is_fifo) {
|
||||||
priority = g_curthread->attr.prio;
|
priority = g_curthread->attr.prio;
|
||||||
|
@ -129,24 +131,24 @@ public:
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wait(std::unique_lock<std::mutex>& lk, u32* timeout) {
|
int Wait(u32* timeout) {
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
// Wait indefinitely until we are woken up.
|
// Wait indefinitely until we are woken up.
|
||||||
cv.wait(lk);
|
sema.acquire();
|
||||||
return GetResult(false);
|
return GetResult(false);
|
||||||
}
|
}
|
||||||
// Wait until timeout runs out, recording how much remaining time there was.
|
// Wait until timeout runs out, recording how much remaining time there was.
|
||||||
const auto start = std::chrono::high_resolution_clock::now();
|
const auto start = std::chrono::high_resolution_clock::now();
|
||||||
const auto status = cv.wait_for(lk, std::chrono::microseconds(*timeout));
|
const auto sema_timeout = !sema.try_acquire_for(std::chrono::microseconds(*timeout));
|
||||||
const auto end = std::chrono::high_resolution_clock::now();
|
const auto end = std::chrono::high_resolution_clock::now();
|
||||||
const auto time =
|
const auto time =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
|
std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
|
||||||
if (status == std::cv_status::timeout) {
|
if (sema_timeout) {
|
||||||
*timeout = 0;
|
*timeout = 0;
|
||||||
} else {
|
} else {
|
||||||
*timeout -= time;
|
*timeout -= time;
|
||||||
}
|
}
|
||||||
return GetResult(status == std::cv_status::timeout);
|
return GetResult(sema_timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue