mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
c6ed855bfa
Before this patch, Alacritty's PTY reader would always try to read the PTY into a buffer and then wait for the acquisition of the terminal lock to process this data. Since locking for the terminal could take some time, the PTY could fill up with the thread idling while doing so. As a solution, this patch keeps reading to a buffer while the terminal is locked in the renderer and starts processing all buffered data as soon as the lock is released. This has halfed the runtime of a simple `cat` benchmark from ~9 to ~4 seconds when the font size is set to `1`. Running this patch with "normal" grid densities does not appear to make any significant performance differences in either direction. One possible memory optimization for the future would be to use this buffer for synchronized updates, but since this currently uses a dynamic buffer and would be a bit more cluttered, it has not been implemented in this patch.
49 lines
1.3 KiB
Rust
49 lines
1.3 KiB
Rust
//! Synchronization types.
|
|
//!
|
|
//! Most importantly, a fair mutex is included.
|
|
|
|
use parking_lot::{Mutex, MutexGuard};
|
|
|
|
/// A fair mutex.
|
|
///
|
|
/// Uses an extra lock to ensure that if one thread is waiting that it will get
|
|
/// the lock before a single thread can re-lock it.
|
|
pub struct FairMutex<T> {
|
|
/// Data.
|
|
data: Mutex<T>,
|
|
/// Next-to-access.
|
|
next: Mutex<()>,
|
|
}
|
|
|
|
impl<T> FairMutex<T> {
|
|
/// Create a new fair mutex.
|
|
pub fn new(data: T) -> FairMutex<T> {
|
|
FairMutex { data: Mutex::new(data), next: Mutex::new(()) }
|
|
}
|
|
|
|
/// Acquire a lease to reserve the mutex lock.
|
|
///
|
|
/// This will prevent others from acquiring a terminal lock, but block if anyone else is
|
|
/// already holding a lease.
|
|
pub fn lease(&self) -> MutexGuard<'_, ()> {
|
|
self.next.lock()
|
|
}
|
|
|
|
/// Lock the mutex.
|
|
pub fn lock(&self) -> MutexGuard<'_, T> {
|
|
// Must bind to a temporary or the lock will be freed before going
|
|
// into data.lock().
|
|
let _next = self.next.lock();
|
|
self.data.lock()
|
|
}
|
|
|
|
/// Unfairly lock the mutex.
|
|
pub fn lock_unfair(&self) -> MutexGuard<'_, T> {
|
|
self.data.lock()
|
|
}
|
|
|
|
/// Unfairly try to lock the mutex.
|
|
pub fn try_lock_unfair(&self) -> Option<MutexGuard<'_, T>> {
|
|
self.data.try_lock()
|
|
}
|
|
}
|