Temporary crash fix
This commit is contained in:
+51
-42
@@ -40,9 +40,10 @@ namespace vm
|
|||||||
|
|
||||||
// Registered waiters
|
// Registered waiters
|
||||||
std::vector<vm::waiter*> g_waiters;
|
std::vector<vm::waiter*> g_waiters;
|
||||||
|
shared_mutex g_waiters_lock;
|
||||||
|
|
||||||
// Waiters which will be removed once the lock is freed
|
// Waiters which will be removed once the lock is freed
|
||||||
std::mutex g_waiters_to_remove_lock;
|
shared_mutex g_waiters_to_remove_lock;
|
||||||
std::vector<vm::waiter*> g_waiters_to_remove;
|
std::vector<vm::waiter*> g_waiters_to_remove;
|
||||||
|
|
||||||
// Memory mutex core
|
// Memory mutex core
|
||||||
@@ -205,21 +206,6 @@ namespace vm
|
|||||||
{
|
{
|
||||||
if (locked)
|
if (locked)
|
||||||
{
|
{
|
||||||
if (!g_waiters_to_remove.empty())
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(g_waiters_to_remove_lock);
|
|
||||||
for (auto ptr : g_waiters_to_remove)
|
|
||||||
{
|
|
||||||
const auto found = std::find(g_waiters.cbegin(), g_waiters.cend(), ptr);
|
|
||||||
if (found != g_waiters.cend())
|
|
||||||
{
|
|
||||||
g_waiters.erase(found);
|
|
||||||
}
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
g_waiters_to_remove.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex.unlock();
|
g_mutex.unlock();
|
||||||
|
|
||||||
locked = false;
|
locked = false;
|
||||||
@@ -234,8 +220,9 @@ namespace vm
|
|||||||
void waiter::init()
|
void waiter::init()
|
||||||
{
|
{
|
||||||
// Register waiter
|
// Register waiter
|
||||||
writer_lock lock(0);
|
g_waiters_lock.lock();
|
||||||
g_waiters.emplace_back(this);
|
g_waiters.emplace_back(this);
|
||||||
|
g_waiters_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waiter::test() const
|
void waiter::test() const
|
||||||
@@ -265,37 +252,36 @@ namespace vm
|
|||||||
owner_copy->notify();
|
owner_copy->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remove_old_waiters()
|
||||||
|
{
|
||||||
|
if (!g_waiters_to_remove.empty())
|
||||||
|
{
|
||||||
|
g_waiters_to_remove_lock.lock();
|
||||||
|
for (auto ptr : g_waiters_to_remove)
|
||||||
|
{
|
||||||
|
const auto found = std::find(g_waiters.cbegin(), g_waiters.cend(), ptr);
|
||||||
|
if (found != g_waiters.cend())
|
||||||
|
{
|
||||||
|
g_waiters.erase(found);
|
||||||
|
}
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
g_waiters_to_remove.clear();
|
||||||
|
g_waiters_to_remove_lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void waiter::remove()
|
void waiter::remove()
|
||||||
{
|
{
|
||||||
|
this->owner = nullptr; // Iterations of the object will ignore it from now on
|
||||||
// Unregister waiter
|
g_waiters_to_remove_lock.lock();
|
||||||
const writer_lock lock(try_to_lock);
|
g_waiters_to_remove.push_back(this);
|
||||||
|
g_waiters_to_remove_lock.unlock();
|
||||||
if (lock.locked)
|
|
||||||
{
|
|
||||||
// Find waiter
|
|
||||||
const auto found = std::find(g_waiters.cbegin(), g_waiters.cend(), this);
|
|
||||||
|
|
||||||
if (found != g_waiters.cend())
|
|
||||||
{
|
|
||||||
g_waiters.erase(found);
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
verify("Waiter not found during removal"), false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->owner = nullptr; // Iterations of the object will ignore it from now on
|
|
||||||
std::lock_guard<std::mutex> lock(g_waiters_to_remove_lock);
|
|
||||||
g_waiters_to_remove.push_back(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify(u32 addr, u32 size)
|
void notify(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
|
g_waiters_lock.lock_shared();
|
||||||
for (const waiter* ptr : g_waiters)
|
for (const waiter* ptr : g_waiters)
|
||||||
{
|
{
|
||||||
if (ptr->addr / 128 == addr / 128)
|
if (ptr->addr / 128 == addr / 128)
|
||||||
@@ -303,14 +289,37 @@ namespace vm
|
|||||||
ptr->test();
|
ptr->test();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_waiters_to_remove.size() > 10)
|
||||||
|
{
|
||||||
|
g_waiters_lock.lock_upgrade();
|
||||||
|
remove_old_waiters();
|
||||||
|
g_waiters_lock.unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_waiters_lock.unlock_shared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify_all()
|
void notify_all()
|
||||||
{
|
{
|
||||||
|
g_waiters_lock.lock_shared();
|
||||||
for (const waiter* ptr : g_waiters)
|
for (const waiter* ptr : g_waiters)
|
||||||
{
|
{
|
||||||
ptr->test();
|
ptr->test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_waiters_to_remove.size() > 10)
|
||||||
|
{
|
||||||
|
g_waiters_lock.lock_upgrade();
|
||||||
|
remove_old_waiters();
|
||||||
|
g_waiters_lock.unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_waiters_lock.unlock_shared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _page_map(u32 addr, u32 size, u8 flags)
|
void _page_map(u32 addr, u32 size, u8 flags)
|
||||||
|
|||||||
Reference in New Issue
Block a user