Replace RwLock usage with parking_lot mutexes

The Mutex type provided by the parking_lot crate performs quite a bit
better compared to RwLock, and make various parts of the VM code a bit
easier to deal with.
parent 684c445d
#![macro_use]
/// Acquires a read lock from an RwLock.
macro_rules! read_lock {
($value:expr) => {
$value.read().unwrap()
};
}
/// Acquires a write lock from an RwLock
macro_rules! write_lock {
($value:expr) => {
$value.write().unwrap()
};
}
macro_rules! lock {
($value:expr) => {
$value.lock().unwrap()
};
}
#![macro_use]
pub mod locking;
pub mod numeric_operations;
pub mod objects;
//! Parsing and caching of bytecode modules.
use parking_lot::Mutex;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
use std::sync::Arc;
use bytecode_parser;
use module::Module;
use vm::state::RcState;
pub type RcModuleRegistry = Arc<RwLock<ModuleRegistry>>;
pub type RcModuleRegistry = Arc<Mutex<ModuleRegistry>>;
pub enum ModuleError {
/// The module did exist but could not be parsed.
......@@ -51,7 +52,7 @@ impl<'a> LookupResult<'a> {
impl ModuleRegistry {
pub fn with_rc(state: RcState) -> RcModuleRegistry {
Arc::new(RwLock::new(ModuleRegistry::new(state)))
Arc::new(Mutex::new(ModuleRegistry::new(state)))
}
pub fn new(state: RcState) -> Self {
......
......@@ -5,11 +5,11 @@
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default_derive))]
use parking_lot::{Condvar, Mutex};
use std::cell::UnsafeCell;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Condvar, Mutex};
use std::time::{Duration, Instant};
use process::RcProcess;
......@@ -118,7 +118,7 @@ impl SuspensionList {
let entry =
SuspendedProcess::new(process, timeout.map(duration_from_f64));
lock!(self.outer).insert(entry);
self.outer.lock().insert(entry);
self.condvar.notify_all();
}
......@@ -165,7 +165,7 @@ impl SuspensionList {
fn copy_outer(&self) {
let inner = self.inner_mut();
let mut outer = lock!(self.outer);
let mut outer = self.outer.lock();
for entry in outer.drain() {
inner.insert(entry);
......@@ -191,18 +191,16 @@ impl SuspensionList {
/// processes are scheduled for suspension.
fn wait_for_work(&self, state: &RcState) {
let sleep_for = self.time_to_sleep(state);
let mut outer = lock!(self.outer);
let mut outer = self.outer.lock();
while outer.is_empty() {
let result = self.condvar.wait_timeout(outer, sleep_for).unwrap();
let result = self.condvar.wait_for(&mut outer, sleep_for);
if result.1.timed_out() {
if result.timed_out() {
return;
} else if self.should_wake_up() {
self.reset_wake_up();
return;
} else {
outer = result.0;
}
}
}
......
......@@ -1738,7 +1738,7 @@ impl Machine {
worker.unpin();
}
write_lock!(self.state.process_table).release(process.pid);
self.state.process_table.lock().release(process.pid);
// We must clean up _after_ removing the process from the process table
// to prevent a cleanup from happening while the process is still
......
......@@ -17,7 +17,7 @@ pub fn load_string(
registry: &RcModuleRegistry,
path: &str,
) -> Result<(Block, bool), String> {
let mut registry = write_lock!(registry);
let mut registry = registry.lock();
let lookup = registry.get_or_set(path).map_err(|err| err.message())?;
let module = lookup.module;
......
......@@ -24,7 +24,7 @@ pub fn allocate(
pool_id: u8,
block: &Block,
) -> Result<RcProcess, String> {
let mut process_table = write_lock!(state.process_table);
let mut process_table = state.process_table.lock();
let pid = process_table
.reserve()
......@@ -67,7 +67,7 @@ pub fn send_message(
) -> Result<ObjectPointer, String> {
let pid = pid_ptr.usize_value()?;
if let Some(receiver) = read_lock!(state.process_table).get(pid) {
if let Some(receiver) = state.process_table.lock().get(pid) {
receiver.send_message(&process, msg_ptr);
if receiver.is_waiting_for_message() {
......@@ -97,7 +97,7 @@ pub fn status(
pid_ptr: ObjectPointer,
) -> Result<ObjectPointer, String> {
let pid = pid_ptr.usize_value()?;
let table = read_lock!(state.process_table);
let table = state.process_table.lock();
let status = if let Some(receiver) = table.get(pid) {
receiver.status_integer()
......
......@@ -20,7 +20,7 @@ use pools::Pools;
use process::RcProcess;
use process_table::ProcessTable;
use std::panic::RefUnwindSafe;
use std::sync::{Arc, RwLock};
use std::sync::Arc;
use std::time;
use string_pool::StringPool;
use suspension_list::SuspensionList;
......@@ -59,7 +59,7 @@ pub struct State {
pub config: Config,
/// Table containing all processes.
pub process_table: RwLock<ProcessTable<RcProcess>>,
pub process_table: Mutex<ProcessTable<RcProcess>>,
/// The pool to use for garbage collection.
pub gc_pool: Pool<Request>,
......@@ -221,7 +221,7 @@ impl State {
let mut state = State {
config,
process_table: RwLock::new(ProcessTable::new()),
process_table: Mutex::new(ProcessTable::new()),
process_pools,
gc_pool,
finalizer_pool,
......
......@@ -21,7 +21,7 @@ pub fn setup() -> (Machine, Block, RcProcess) {
code.registers = 1024;
let (block, process) = {
let mut registry = write_lock!(machine.module_registry);
let mut registry = machine.module_registry.lock();
let module_name = if cfg!(windows) { "C:\\test" } else { "/test" };
// To ensure the module sticks around long enough we'll manually store in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment