Skip to content

Commit 6f18fec

Browse files
committed
Everywhere: Use parking_lot's RwLock instead of std
This lets us do timeouts on locking, which simplifies the panic/ctrl-c handler issue!
1 parent 5b09c43 commit 6f18fec

File tree

13 files changed

+110
-58
lines changed

13 files changed

+110
-58
lines changed

Cargo.lock

+48
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

back/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ anyhow = { version = "1.0.70", features = ["std", "backtrace"] }
1111
elf = { path = "../vendor/rust-elf", package = "elf2" }
1212
gimli = "~0.27.2"
1313
ironic-core = { path = "../core" }
14+
parking_lot = { version = "~0.12.1", default-features = false, features = ["nightly", "hardware-lock-elision"] }
1415
log = { version = "0.4.17", default-features = false, features = ["std"] }
1516

1617
[target.'cfg(windows)'.dependencies]

back/src/interp.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ pub mod lut;
88
use anyhow::anyhow;
99
use gimli::{BigEndian, read::*};
1010
use log::{error, info};
11+
use parking_lot::RwLock;
1112

12-
use std::sync::{Arc, RwLock};
13+
use std::sync::Arc;
1314
use std::fs;
15+
use std::time::Duration;
1416

1517
extern crate elf;
1618

@@ -117,7 +119,7 @@ impl InterpBackend {
117119
match self.boot_status {
118120
BootStatus::Boot0 => {
119121
if self.cpu.read_fetch_pc() == 0xfff0_0000 {
120-
if let Ok(bus) = self.bus.try_read() { // Try to detect boot1 version
122+
if let Some(bus) = self.bus.try_read_for(Duration::new(1,0)) { // Try to detect boot1 version
121123
let boot1_otp_hash =
122124
[
123125
bus.hlwd.otp.read(0),
@@ -194,7 +196,7 @@ impl InterpBackend {
194196
// Probably a limitation of their early semihosting hardware
195197
// We buffer that internally until we see a newline, that's our cue to print
196198
let mut line_buf = [0u8; 16];
197-
self.bus.read().map_err(|e| anyhow!(e.to_string()))?.dma_read(paddr, &mut line_buf)?;
199+
self.bus.read().dma_read(paddr, &mut line_buf)?;
198200

199201
let s = std::str::from_utf8(&line_buf)?
200202
.trim_matches(char::from(0));
@@ -268,7 +270,7 @@ impl InterpBackend {
268270
)?;
269271
info!(target: "Other", "DBG hotpatching module entrypoint {paddr:08x}");
270272
info!(target: "Other", "{:?}", self.cpu.reg);
271-
self.bus.write().map_err(|e| anyhow!(e.to_string()))?.dma_write(paddr,
273+
self.bus.write().dma_write(paddr,
272274
&Self::THREAD_CANCEL_PATCH)?;
273275
}
274276
}
@@ -399,17 +401,17 @@ impl Backend for InterpBackend {
399401
}
400402
}
401403
match load_custom_kernel_debuginfo(&kernel_elf) {
402-
Ok(debuginfo) => {self.bus.write().unwrap().install_debuginfo(debuginfo)},
404+
Ok(debuginfo) => {self.bus.write().install_debuginfo(debuginfo)},
403405
Err(err) => {error!(target: "Custom Kernel", "Failed to load debuginfo for kernel: {err}")},
404406
}
405407

406408
match load_custom_kernel_debug_frame(&kernel_elf) {
407-
Ok(debug_frames) => {self.bus.write().unwrap().install_debug_frames(debug_frames)},
409+
Ok(debug_frames) => {self.bus.write().install_debug_frames(debug_frames)},
408410
Err(err) => {error!(target: "Custom Kernel", "Failed to load debug frames for kernel: {err}")},
409411
}
410412

411413
let headers = kernel_elf.phdrs;
412-
let mut bus = self.bus.write().unwrap();
414+
let mut bus = self.bus.write();
413415
// We are relying on the mirror being available
414416
// Or else we would be writing to mask ROM.
415417
bus.rom_disabled = true;
@@ -431,7 +433,7 @@ impl Backend for InterpBackend {
431433
loop {
432434
// Take ownership of the bus to deal with any pending tasks
433435
{
434-
let mut bus = self.bus.write().unwrap();
436+
let mut bus = self.bus.write();
435437
bus.step(self.cpu_cycle)?;
436438
self.bus_cycle += 1;
437439
bus.update_debug_location(Some(self.cpu.reg.pc), Some(self.cpu.reg.r[14]), Some(self.cpu.reg.r[13]));

back/src/interp/arm/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn bkpt(cpu: &mut Cpu, op: BkptBits) -> DispatchRes {
2828
return DispatchRes::RetireOk;
2929
},
3030
0xfb => {
31-
let bus = cpu.bus.read().expect("breakpoint instruction - bus access");
31+
let bus = cpu.bus.read();
3232
match bus.dump_memory("bkpt.bin") {
3333
Ok(path) => {
3434
debug!(target: "Other", "Dumped RAM to {}/*.bkpt.bin", path.to_string_lossy());

back/src/interp/thumb/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn bkpt(cpu: &mut Cpu, op: MiscBits) -> DispatchRes {
3232
return DispatchRes::RetireOk;
3333
},
3434
0xfb => {
35-
let bus = cpu.bus.read().expect("breakpoint instruction - bus access");
35+
let bus = cpu.bus.read();
3636
match bus.dump_memory("bkpt.bin") {
3737
Ok(path) => {
3838
debug!(target: "Other", "Dumped RAM to {}/*.bkpt.bin", path.to_string_lossy());

back/src/ppc.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use ironic_core::dev::hlwd::irq::*;
88
use crate::back::*;
99

1010
use log::{info, error};
11+
use parking_lot::RwLock;
1112

1213
use std::env::temp_dir;
1314
use std::path::PathBuf;
1415
use std::thread;
15-
use std::sync::{Arc, RwLock};
16+
use std::sync::Arc;
1617
use std::net::Shutdown;
1718
use std::io::{Read, Write};
1819
use std::convert::TryInto;
@@ -145,9 +146,9 @@ impl PpcBackend {
145146
fn wait_for_resp(&mut self) -> u32 {
146147
info!(target: "PPC", "waiting for response ...");
147148
loop {
148-
if self.bus.read().unwrap().hlwd.irq.ppc_irq_output {
149+
if self.bus.read().hlwd.irq.ppc_irq_output {
149150
info!(target: "PPC", "got irq");
150-
let mut bus = self.bus.write().unwrap();
151+
let mut bus = self.bus.write();
151152

152153
if bus.hlwd.ipc.state.ppc_ack {
153154
info!(target: "PPC", "got extra ACK");
@@ -167,7 +168,7 @@ impl PpcBackend {
167168
return armmsg;
168169
}
169170

170-
drop(bus); // Drop bus to avoid poisoning the lock.
171+
drop(bus); // Release RwLock
171172
error!(target: "PPC", "Invalid IRQ state");
172173
unreachable!("Invalid IRQ state. You forgot to update your IRQ lines somewhere!");
173174
} else {
@@ -180,9 +181,9 @@ impl PpcBackend {
180181
fn wait_for_ack(&mut self) {
181182
info!(target: "PPC", "waiting for ACK ...");
182183
loop {
183-
if self.bus.read().unwrap().hlwd.irq.ppc_irq_output {
184+
if self.bus.read().hlwd.irq.ppc_irq_output {
184185
info!(target: "PPC", "got irq");
185-
let mut bus = self.bus.write().unwrap();
186+
let mut bus = self.bus.write();
186187

187188
if bus.hlwd.ipc.state.ppc_ack {
188189
bus.hlwd.ipc.state.ppc_ack = false;
@@ -201,7 +202,7 @@ impl PpcBackend {
201202
continue;
202203
}
203204

204-
drop(bus); // Drop bus to avoid poisoning the lock.
205+
drop(bus); // Release RwLock
205206
error!(target: "PPC", "Invalid IRQ state");
206207
unreachable!("Invalid IRQ state. You forgot to update your IRQ lines somewhere!")
207208
} else {
@@ -236,7 +237,7 @@ impl PpcBackend {
236237
/// Read from physical memory.
237238
pub fn handle_read(&mut self, client: &mut UnixStream, req: SocketReq) -> anyhow::Result<()> {
238239
info!(target: "PPC", "read {:x} bytes at {:08x}", req.len, req.addr);
239-
self.bus.read().unwrap().dma_read(req.addr,
240+
self.bus.read().dma_read(req.addr,
240241
&mut self.obuf[0..req.len as usize])?;
241242
let _ = client.write(&self.obuf[0..req.len as usize])?; // maybe FIXME: is it ok to ignore the # of bytes written here?
242243
Ok(())
@@ -246,15 +247,15 @@ impl PpcBackend {
246247
pub fn handle_write(&mut self, client: &mut UnixStream, req: SocketReq) -> anyhow::Result<()> {
247248
info!(target: "PPC", "write {:x} bytes at {:08x}", req.len, req.addr);
248249
let data = &self.ibuf[0xc..(0xc + req.len as usize)];
249-
self.bus.write().unwrap().dma_write(req.addr, data)?;
250+
self.bus.write().dma_write(req.addr, data)?;
250251
let _ = client.write("OK".as_bytes())?; // maybe FIXME: is it ok to ignore the # of bytes written here?
251252
Ok(())
252253
}
253254

254255
/// Tell ARM-world that an IPC request is ready at the location indicated
255256
/// by the pointer in PPC_MSG.
256257
pub fn handle_message(&mut self, client: &mut UnixStream, req: SocketReq) -> anyhow::Result<()> {
257-
let mut bus = self.bus.write().unwrap();
258+
let mut bus = self.bus.write();
258259
bus.hlwd.ipc.ppc_msg = req.addr;
259260
bus.hlwd.ipc.state.arm_req = true;
260261
bus.hlwd.ipc.state.arm_ack = true;
@@ -263,7 +264,7 @@ impl PpcBackend {
263264
}
264265

265266
pub fn handle_ack(&mut self, _req: SocketReq) -> anyhow::Result<()> {
266-
let mut bus = self.bus.write().unwrap();
267+
let mut bus = self.bus.write();
267268
let ppc_ctrl = bus.hlwd.ipc.read_handler(4)? & 0x3c;
268269
bus.hlwd.ipc.write_handler(4, ppc_ctrl | 0x8)?;
269270
Ok(())
@@ -275,10 +276,10 @@ impl PpcBackend {
275276
impl Backend for PpcBackend {
276277
fn run(&mut self) -> anyhow::Result<()> {
277278
info!(target: "PPC", "PPC backend thread started");
278-
self.bus.write().unwrap().hlwd.ipc.state.ppc_ctrl_write(0x36);
279+
self.bus.write().hlwd.ipc.state.ppc_ctrl_write(0x36);
279280

280281
loop {
281-
if self.bus.read().unwrap().hlwd.ppc_on {
282+
if self.bus.read().hlwd.ppc_on {
282283
info!(target: "PPC", "Broadway came online");
283284
break;
284285
}
@@ -289,7 +290,7 @@ impl Backend for PpcBackend {
289290
self.wait_for_ack();
290291

291292
// Send an extra ACK
292-
self.bus.write().unwrap().hlwd.ipc.state.arm_ack = true;
293+
self.bus.write().hlwd.ipc.state.arm_ack = true;
293294
thread::sleep(std::time::Duration::from_millis(100));
294295

295296
// Try binding to the socket

core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ crc32fast = { version = "~1.3.2", default-features = false, features = ["std", "
1717
bincode = { version = "~2.0.0-rc.3" }
1818
lz4_flex = { version = "~0.11.1", default-features = false, features = ["std", "safe-encode", "safe-decode", "frame"] }
1919
iset = { version = "~0.2.2", default-features = false }
20+
parking_lot = { version = "~0.12.1", default-features = false, features = ["nightly", "hardware-lock-elision"] }

core/src/cpu.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ pub mod psr;
66
pub mod mmu;
77
pub mod alu;
88

9-
use std::sync::{Arc,RwLock};
9+
use std::sync::Arc;
10+
use parking_lot::RwLock;
1011

1112
use crate::bus::*;
1213
use crate::cpu::excep::*;

core/src/cpu/coproc.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Coprocessor register definitions and functionality.
22
3-
use std::{cell::RefCell, collections::HashMap, sync::{RwLock, Arc}, hash::BuildHasherDefault};
4-
use anyhow::anyhow;
3+
use std::{cell::RefCell, collections::HashMap, sync::Arc, hash::BuildHasherDefault};
4+
use parking_lot::RwLock;
55

66
use crate::bus::Bus;
77
use fxhash::FxHasher32;
@@ -244,7 +244,7 @@ impl SystemControl {
244244
let val = match tlb_inner.get(&addr) {
245245
Some(val) => *val, // TLB hit
246246
None => { // miss
247-
let val = bus.read().map_err(|e| anyhow!(e.to_string()))?.read32(addr)?;
247+
let val = bus.read().read32(addr)?;
248248
tlb_inner.insert(addr, val);
249249
val
250250
},

core/src/cpu/mmu.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,37 @@ pub mod prim;
55
use crate::cpu::mmu::prim::*;
66
use crate::cpu::Cpu;
77

8-
use anyhow::{anyhow, bail};
8+
use anyhow::bail;
99

1010
/// These are the top-level "public" functions providing read/write accesses.
1111
impl Cpu {
1212
pub fn read32(&self, addr: u32) -> anyhow::Result<u32> {
1313
let paddr = self.translate(TLBReq::new(addr, Access::Read))?;
14-
let res = self.bus.read().unwrap().read32(paddr)?;
14+
let res = self.bus.read().read32(paddr)?;
1515
Ok(res)
1616
}
1717
pub fn read16(&self, addr: u32) -> anyhow::Result<u16> {
1818
let paddr = self.translate(TLBReq::new(addr, Access::Read))?;
19-
let res = self.bus.read().unwrap().read16(paddr)?;
19+
let res = self.bus.read().read16(paddr)?;
2020
Ok(res)
2121
}
2222
pub fn read8(&self, addr: u32) -> anyhow::Result<u8> {
2323
let paddr = self.translate(TLBReq::new(addr, Access::Read))?;
24-
let res = self.bus.read().unwrap().read8(paddr)?;
24+
let res = self.bus.read().read8(paddr)?;
2525
Ok(res)
2626
}
2727

2828
pub fn write32(&mut self, addr: u32, val: u32) -> anyhow::Result<()> {
2929
let paddr = self.translate(TLBReq::new(addr, Access::Write))?;
30-
self.bus.write().unwrap().write32(paddr, val)
30+
self.bus.write().write32(paddr, val)
3131
}
3232
pub fn write16(&mut self, addr: u32, val: u32) -> anyhow::Result<()> {
3333
let paddr = self.translate(TLBReq::new(addr, Access::Write))?;
34-
self.bus.write().unwrap().write16(paddr, val as u16)
34+
self.bus.write().write16(paddr, val as u16)
3535
}
3636
pub fn write8(&mut self, addr: u32, val: u32) -> anyhow::Result<()> {
3737
let paddr = self.translate(TLBReq::new(addr, Access::Write))?;
38-
self.bus.write().unwrap().write8(paddr, val as u8)
38+
self.bus.write().write8(paddr, val as u8)
3939
}
4040
}
4141

@@ -103,7 +103,7 @@ impl Cpu {
103103
},
104104
_ => bail!("l2_fetch requires an L1::Coarse descriptor"),
105105
};
106-
let val = self.bus.read().map_err(|e| anyhow!(e.to_string()))?.read32(addr)?;
106+
let val = self.bus.read().read32(addr)?;
107107
Ok(L2Descriptor::from_u32(val))
108108
}
109109

0 commit comments

Comments
 (0)