mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-20 22:05:12 +00:00
semaphore_t, RSX fixes
1) GS_LOCK_WAIT_FLUSH semaphore eliminated 2) GS_LOCK_WAIT_FLIP semaphore left unused 3) cellRescSetWaitFlip/cellGcmSetWaitFlip purged: they don't wait for flip, it's a nonsense, they only generate some RSX command 4) Semaphores rewritten
This commit is contained in:
parent
71a378a3fb
commit
8e1991c1e1
13 changed files with 213 additions and 257 deletions
|
|
@ -1,85 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "Utilities/SSemaphore.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
void SSemaphore::wait()
|
||||
{
|
||||
u32 order;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_count && m_out_order == m_in_order)
|
||||
{
|
||||
m_count--;
|
||||
return;
|
||||
}
|
||||
order = m_in_order++;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> cv_lock(m_cv_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
m_cond.wait_for(cv_lock, std::chrono::milliseconds(1));
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_count)
|
||||
{
|
||||
if (m_out_order == order)
|
||||
{
|
||||
m_count--;
|
||||
m_out_order++;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cond.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SSemaphore::try_wait()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_count && m_in_order == m_out_order)
|
||||
{
|
||||
m_count--;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SSemaphore::post()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_count < m_max)
|
||||
{
|
||||
m_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_cond.notify_one();
|
||||
}
|
||||
|
||||
bool SSemaphore::post_and_wait()
|
||||
{
|
||||
// TODO: merge these functions? Probably has a race condition.
|
||||
if (try_wait()) return false;
|
||||
|
||||
post();
|
||||
wait();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
class SSemaphore
|
||||
{
|
||||
const u32 m_max;
|
||||
u32 m_count;
|
||||
u32 m_in_order;
|
||||
u32 m_out_order;
|
||||
std::mutex m_cv_mutex;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cond;
|
||||
|
||||
public:
|
||||
SSemaphore(u32 value, u32 max = 1)
|
||||
: m_max(max > 0 ? max : 0xffffffff)
|
||||
, m_count(value > m_max ? m_max : value)
|
||||
, m_in_order(0)
|
||||
, m_out_order(0)
|
||||
{
|
||||
}
|
||||
|
||||
SSemaphore()
|
||||
: m_max(0xffffffff)
|
||||
, m_count(0)
|
||||
, m_in_order(0)
|
||||
, m_out_order(0)
|
||||
{
|
||||
}
|
||||
|
||||
~SSemaphore()
|
||||
{
|
||||
}
|
||||
|
||||
void wait();
|
||||
|
||||
bool try_wait();
|
||||
|
||||
void post();
|
||||
|
||||
bool post_and_wait();
|
||||
};
|
||||
120
Utilities/Semaphore.cpp
Normal file
120
Utilities/Semaphore.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
#include "stdafx.h"
|
||||
#include "Utilities/Semaphore.h"
|
||||
|
||||
bool semaphore_t::try_wait()
|
||||
{
|
||||
// check m_value without interlocked op
|
||||
if (m_var.load().value == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to decrement m_value atomically
|
||||
const auto old = m_var.atomic_op([](sync_var_t& var)
|
||||
{
|
||||
if (var.value)
|
||||
{
|
||||
var.value--;
|
||||
}
|
||||
});
|
||||
|
||||
// recheck atomic result
|
||||
if (old.value == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool semaphore_t::try_post()
|
||||
{
|
||||
// check m_value without interlocked op
|
||||
if (m_var.load().value >= max_value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to increment m_value atomically
|
||||
const auto old = m_var.atomic_op([&](sync_var_t& var)
|
||||
{
|
||||
if (var.value < max_value)
|
||||
{
|
||||
var.value++;
|
||||
}
|
||||
});
|
||||
|
||||
// recheck atomic result
|
||||
if (old.value >= max_value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (old.waiters)
|
||||
{
|
||||
// notify waiting thread
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void semaphore_t::wait()
|
||||
{
|
||||
if (m_var.atomic_op([](sync_var_t& var) -> bool
|
||||
{
|
||||
if (var.value)
|
||||
{
|
||||
var.value--;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//var.waiters++;
|
||||
|
||||
return false;
|
||||
}
|
||||
}))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
m_var.atomic_op([](sync_var_t& var)
|
||||
{
|
||||
var.waiters++;
|
||||
});
|
||||
|
||||
while (!m_var.atomic_op([](sync_var_t& var) -> bool
|
||||
{
|
||||
if (var.value)
|
||||
{
|
||||
var.value--;
|
||||
var.waiters--;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}))
|
||||
{
|
||||
m_cv.wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
bool semaphore_t::post_and_wait()
|
||||
{
|
||||
// TODO: merge these functions? Probably has a race condition.
|
||||
if (try_wait()) return false;
|
||||
|
||||
try_post();
|
||||
wait();
|
||||
|
||||
return true;
|
||||
}
|
||||
37
Utilities/Semaphore.h
Normal file
37
Utilities/Semaphore.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
class semaphore_t
|
||||
{
|
||||
// semaphore mutex
|
||||
std::mutex m_mutex;
|
||||
|
||||
// semaphore condition variable
|
||||
std::condition_variable m_cv;
|
||||
|
||||
struct sync_var_t
|
||||
{
|
||||
u32 value; // current semaphore value
|
||||
u32 waiters; // current amount of waiters
|
||||
};
|
||||
|
||||
// current semaphore value
|
||||
atomic_t<sync_var_t> m_var;
|
||||
|
||||
public:
|
||||
// max semaphore value
|
||||
const u32 max_value;
|
||||
|
||||
semaphore_t(u32 max_value = 1, u32 value = 0)
|
||||
: m_var({ value, 0 })
|
||||
, max_value(max_value)
|
||||
{
|
||||
}
|
||||
|
||||
bool try_wait();
|
||||
|
||||
bool try_post();
|
||||
|
||||
void wait();
|
||||
|
||||
bool post_and_wait();
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue