DANGER DANGER. Switching to global critical region.
This changes almost all locks held by guest threads to use a single global critical region. This emulates the behavior on the PPC of disabling interrupts (by calls like KeRaiseIrqlToDpcLevel or masking interrupts), and prevents deadlocks from occuring when threads are suspended or otherwise blocked. This has performance implications and a pass is needed to ensure the locking is as granular as possible. It could also break everything because it's fundamentally unsound. We'll see.
This commit is contained in:
@@ -24,7 +24,7 @@ WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
|
||||
// Register a key listener.
|
||||
input_system_->emulator()->display_window()->on_key_down.AddListener(
|
||||
[this](ui::KeyEvent* evt) {
|
||||
std::lock_guard<std::mutex> lock(key_event_mutex_);
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
KeyEvent key;
|
||||
key.vkey = evt->key_code();
|
||||
@@ -35,7 +35,7 @@ WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
|
||||
});
|
||||
input_system_->emulator()->display_window()->on_key_up.AddListener(
|
||||
[this](ui::KeyEvent* evt) {
|
||||
std::lock_guard<std::mutex> lock(key_event_mutex_);
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
KeyEvent key;
|
||||
key.vkey = evt->key_code();
|
||||
@@ -210,18 +210,17 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||
uint8_t hid_code = 0;
|
||||
|
||||
// Pop from the queue.
|
||||
key_event_mutex_.lock();
|
||||
if (key_events_.size() == 0) {
|
||||
key_event_mutex_.unlock();
|
||||
|
||||
// No keys!
|
||||
return X_ERROR_EMPTY;
|
||||
KeyEvent evt;
|
||||
{
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
if (key_events_.empty()) {
|
||||
// No keys!
|
||||
return X_ERROR_EMPTY;
|
||||
}
|
||||
evt = key_events_.front();
|
||||
key_events_.pop();
|
||||
}
|
||||
|
||||
KeyEvent evt = key_events_.front();
|
||||
key_events_.pop();
|
||||
key_event_mutex_.unlock();
|
||||
|
||||
// TODO: Some other way to toggle this...
|
||||
if (IS_KEY_TOGGLED(VK_CAPITAL)) {
|
||||
// dpad toggled
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#ifndef XENIA_HID_WINKEY_WINKEY_INPUT_DRIVER_H_
|
||||
#define XENIA_HID_WINKEY_WINKEY_INPUT_DRIVER_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
#include "xenia/base/mutex.h"
|
||||
#include "xenia/hid/input_driver.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -40,8 +40,9 @@ class WinKeyInputDriver : public InputDriver {
|
||||
bool transition = false; // going up(false) or going down(true)
|
||||
bool prev_state = false; // down(true) or up(false)
|
||||
};
|
||||
|
||||
xe::global_critical_region global_critical_region_;
|
||||
std::queue<KeyEvent> key_events_;
|
||||
std::mutex key_event_mutex_;
|
||||
|
||||
uint32_t packet_number_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user