use anyhow::Result;
use probe_rs::{CoreType, Error, Session};
use std::net::{SocketAddr, ToSocketAddrs};
use std::sync::Mutex;
use std::time::Duration;
use itertools::Itertools;
use super::target;
const CONNECTION_STRING: &str = "127.0.0.1:1337";
pub struct GdbInstanceConfiguration {
pub core_type: CoreType,
pub cores: Vec<usize>,
pub socket_addrs: Vec<SocketAddr>,
}
impl GdbInstanceConfiguration {
pub fn from_session(
session: &Session,
connection_string: Option<impl Into<String>>,
) -> Vec<Self> {
let connection_string = connection_string
.map(|cs| cs.into())
.unwrap_or_else(|| CONNECTION_STRING.to_owned());
let addrs: Vec<SocketAddr> = connection_string.to_socket_addrs().unwrap().collect();
let groups = session
.target()
.cores
.iter()
.enumerate()
.map(|(i, core)| (core.core_type, i))
.into_group_map();
let ret = groups
.iter()
.enumerate()
.map(|(i, (core_type, cores))| GdbInstanceConfiguration {
core_type: *core_type,
cores: cores.to_vec(),
socket_addrs: adjust_addrs(&addrs, i),
})
.collect();
ret
}
}
pub fn run<'a>(
session: &Mutex<Session>,
instances: impl Iterator<Item = &'a GdbInstanceConfiguration>,
) -> Result<()> {
let mut targets = instances
.map(|instance| {
target::RuntimeTarget::new(session, instance.cores.to_vec(), &instance.socket_addrs[..])
})
.collect::<Result<Vec<target::RuntimeTarget>, Error>>()?;
loop {
let mut wait_time = Duration::ZERO;
for target in targets.iter_mut() {
wait_time = wait_time.min(target.process()?);
}
std::thread::sleep(wait_time);
}
}
fn adjust_addrs(addrs: &[SocketAddr], offset: usize) -> Vec<SocketAddr> {
addrs
.iter()
.map(|addr| {
let mut new_addr = *addr;
new_addr.set_port(new_addr.port() + offset as u16);
new_addr
})
.collect()
}