mirror of https://github.com/m-labs/artiq.git
subkernels: send now_mu when starting a subkernel
This commit is contained in:
parent
33b81d0e2e
commit
4178fed3f7
|
@ -37,6 +37,14 @@ fn recv<R, F: FnOnce(&Message) -> R>(f: F) -> R {
|
|||
result
|
||||
}
|
||||
|
||||
fn try_recv<F: FnOnce(&Message)>(f: F) {
|
||||
let msg_ptr = mailbox::receive();
|
||||
if msg_ptr != 0 {
|
||||
f(unsafe { &*(msg_ptr as *const Message) });
|
||||
mailbox::acknowledge();
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! recv {
|
||||
($p:pat => $e:expr) => {
|
||||
recv(move |request| {
|
||||
|
@ -473,7 +481,15 @@ extern "C-unwind" fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) {
|
|||
|
||||
|
||||
extern "C-unwind" fn subkernel_load_run(id: u32, destination: u8, run: bool) {
|
||||
send(&SubkernelLoadRunRequest { id: id, destination: destination, run: run });
|
||||
let timestamp = unsafe {
|
||||
((csr::rtio::now_hi_read() as u64) << 32) | (csr::rtio::now_lo_read() as u64)
|
||||
};
|
||||
send(&SubkernelLoadRunRequest {
|
||||
id: id,
|
||||
destination: destination,
|
||||
run: run,
|
||||
timestamp: timestamp,
|
||||
});
|
||||
recv!(&SubkernelLoadRunReply { succeeded } => {
|
||||
if !succeeded {
|
||||
raise!("SubkernelError",
|
||||
|
@ -601,6 +617,15 @@ pub unsafe fn main() {
|
|||
},
|
||||
Ok(library) => {
|
||||
send(&LoadReply(Ok(())));
|
||||
// Master kernel would just acknowledge kernel load
|
||||
// Satellites may send UpdateNow
|
||||
try_recv(move |msg| match msg {
|
||||
UpdateNow(timestamp) => unsafe {
|
||||
csr::rtio::now_hi_write((*timestamp >> 32) as u32);
|
||||
csr::rtio::now_lo_write(*timestamp as u32);
|
||||
}
|
||||
_ => unreachable!()
|
||||
});
|
||||
library
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ pub enum Packet {
|
|||
|
||||
SubkernelAddDataRequest { destination: u8, id: u32, status: PayloadStatus, length: u16, data: [u8; MASTER_PAYLOAD_MAX_SIZE] },
|
||||
SubkernelAddDataReply { succeeded: bool },
|
||||
SubkernelLoadRunRequest { source: u8, destination: u8, id: u32, run: bool },
|
||||
SubkernelLoadRunRequest { source: u8, destination: u8, id: u32, run: bool, timestamp: u64 },
|
||||
SubkernelLoadRunReply { destination: u8, succeeded: bool },
|
||||
SubkernelFinished { destination: u8, id: u32, with_exception: bool, exception_src: u8 },
|
||||
SubkernelExceptionRequest { source: u8, destination: u8 },
|
||||
|
@ -354,7 +354,8 @@ impl Packet {
|
|||
source: reader.read_u8()?,
|
||||
destination: reader.read_u8()?,
|
||||
id: reader.read_u32()?,
|
||||
run: reader.read_bool()?
|
||||
run: reader.read_bool()?,
|
||||
timestamp: reader.read_u64()?
|
||||
},
|
||||
0xc5 => Packet::SubkernelLoadRunReply {
|
||||
destination: reader.read_u8()?,
|
||||
|
@ -647,12 +648,13 @@ impl Packet {
|
|||
writer.write_u8(0xc1)?;
|
||||
writer.write_bool(succeeded)?;
|
||||
},
|
||||
Packet::SubkernelLoadRunRequest { source, destination, id, run } => {
|
||||
Packet::SubkernelLoadRunRequest { source, destination, id, run, timestamp } => {
|
||||
writer.write_u8(0xc4)?;
|
||||
writer.write_u8(source)?;
|
||||
writer.write_u8(destination)?;
|
||||
writer.write_u32(id)?;
|
||||
writer.write_bool(run)?;
|
||||
writer.write_u64(timestamp)?;
|
||||
},
|
||||
Packet::SubkernelLoadRunReply { destination, succeeded } => {
|
||||
writer.write_u8(0xc5)?;
|
||||
|
|
|
@ -103,7 +103,7 @@ pub enum Message<'a> {
|
|||
SpiReadReply { succeeded: bool, data: u32 },
|
||||
SpiBasicReply { succeeded: bool },
|
||||
|
||||
SubkernelLoadRunRequest { id: u32, destination: u8, run: bool },
|
||||
SubkernelLoadRunRequest { id: u32, destination: u8, run: bool, timestamp: u64 },
|
||||
SubkernelLoadRunReply { succeeded: bool },
|
||||
SubkernelAwaitFinishRequest { id: u32, timeout: i64 },
|
||||
SubkernelAwaitFinishReply,
|
||||
|
@ -112,6 +112,8 @@ pub enum Message<'a> {
|
|||
SubkernelMsgRecvReply { count: u8 },
|
||||
SubkernelError(SubkernelStatus<'a>),
|
||||
|
||||
UpdateNow(u64),
|
||||
|
||||
Log(fmt::Arguments<'a>),
|
||||
LogSlice(&'a str)
|
||||
}
|
||||
|
|
|
@ -194,14 +194,15 @@ pub mod subkernel {
|
|||
}
|
||||
|
||||
pub fn load(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, subkernel_mutex: &Mutex, routing_table: &RoutingTable,
|
||||
id: u32, run: bool) -> Result<(), Error> {
|
||||
id: u32, run: bool, timestamp: u64) -> Result<(), Error> {
|
||||
let _lock = subkernel_mutex.lock(io)?;
|
||||
let subkernel = unsafe { SUBKERNELS.get_mut(&id).unwrap() };
|
||||
if subkernel.state != SubkernelState::Uploaded {
|
||||
error!("for id: {} expected Uploaded, got: {:?}", id, subkernel.state);
|
||||
return Err(Error::IncorrectState);
|
||||
}
|
||||
drtio::subkernel_load(io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, id, subkernel.destination, run)?;
|
||||
drtio::subkernel_load(io, aux_mutex, ddma_mutex, subkernel_mutex,
|
||||
routing_table, id, subkernel.destination, run, timestamp)?;
|
||||
if run {
|
||||
subkernel.state = SubkernelState::Running;
|
||||
}
|
||||
|
|
|
@ -594,11 +594,14 @@ pub mod drtio {
|
|||
}
|
||||
|
||||
pub fn subkernel_load(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, subkernel_mutex: &Mutex,
|
||||
routing_table: &drtio_routing::RoutingTable, id: u32, destination: u8, run: bool
|
||||
routing_table: &drtio_routing::RoutingTable, id: u32, destination: u8, run: bool, timestamp: u64
|
||||
) -> Result<(), Error> {
|
||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||
let reply = aux_transact(io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, linkno,
|
||||
&drtioaux::Packet::SubkernelLoadRunRequest{ id: id, source: 0, destination: destination, run: run })?;
|
||||
&drtioaux::Packet::SubkernelLoadRunRequest{
|
||||
id: id, source: 0, destination: destination,
|
||||
run: run, timestamp: timestamp
|
||||
})?;
|
||||
match reply {
|
||||
drtioaux::Packet::SubkernelLoadRunReply { destination: 0, succeeded: true } => Ok(()),
|
||||
drtioaux::Packet::SubkernelLoadRunReply { destination: 0, succeeded: false } =>
|
||||
|
|
|
@ -661,9 +661,9 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex,
|
|||
}
|
||||
}
|
||||
#[cfg(has_drtio)]
|
||||
&kern::SubkernelLoadRunRequest { id, destination: _, run } => {
|
||||
&kern::SubkernelLoadRunRequest { id, destination: _, run, timestamp } => {
|
||||
let succeeded = match subkernel::load(
|
||||
io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, id, run) {
|
||||
io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, id, run, timestamp) {
|
||||
Ok(()) => true,
|
||||
Err(e) => { error!("Error loading subkernel: {}", e); false }
|
||||
};
|
||||
|
|
|
@ -363,17 +363,17 @@ impl Manager {
|
|||
unsafe { self.cache.unborrow() }
|
||||
}
|
||||
|
||||
pub fn run(&mut self, source: u8, id: u32) -> Result<(), Error> {
|
||||
pub fn run(&mut self, source: u8, id: u32, timestamp: u64) -> Result<(), Error> {
|
||||
info!("starting subkernel #{}", id);
|
||||
if self.session.kernel_state != KernelState::Loaded
|
||||
|| self.current_id != id {
|
||||
self.load(id)?;
|
||||
}
|
||||
}
|
||||
self.session.source = source;
|
||||
self.session.kernel_state = KernelState::Running;
|
||||
cricon_select(RtioMaster::Kernel);
|
||||
|
||||
kern_acknowledge()
|
||||
kern_send(&kern::UpdateNow(timestamp))
|
||||
}
|
||||
|
||||
pub fn message_handle_incoming(&mut self, status: PayloadStatus, length: usize, id: u32, slice: &[u8; MASTER_PAYLOAD_MAX_SIZE]) {
|
||||
|
@ -825,21 +825,21 @@ impl Manager {
|
|||
// ID equal to -1 indicates wildcard for receiving arguments
|
||||
let id = if id == -1 { self.current_id } else { id as u32 };
|
||||
self.session.kernel_state = KernelState::MsgAwait {
|
||||
id: id, max_time: max_time, tags: tags.to_vec() };
|
||||
id, max_time, tags: tags.to_vec() };
|
||||
Ok(())
|
||||
},
|
||||
|
||||
&kern::SubkernelLoadRunRequest { id, destination: sk_destination, run } => {
|
||||
&kern::SubkernelLoadRunRequest { id, destination: sk_destination, run, timestamp } => {
|
||||
self.session.kernel_state = KernelState::SubkernelAwaitLoad;
|
||||
router.route(drtioaux::Packet::SubkernelLoadRunRequest {
|
||||
source: destination, destination: sk_destination, id: id, run: run
|
||||
source: destination, destination: sk_destination, id, run, timestamp
|
||||
}, routing_table, rank, destination);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
&kern::SubkernelAwaitFinishRequest{ id, timeout } => {
|
||||
&kern::SubkernelAwaitFinishRequest { id, timeout } => {
|
||||
let max_time = if timeout > 0 { clock::get_ms() as i64 + timeout } else { timeout };
|
||||
self.session.kernel_state = KernelState::SubkernelAwaitFinish { max_time: max_time, id: id };
|
||||
self.session.kernel_state = KernelState::SubkernelAwaitFinish { max_time, id };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
drtioaux::send(0,
|
||||
&drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::SubkernelLoadRunRequest { source, destination: _destination, id, run } => {
|
||||
drtioaux::Packet::SubkernelLoadRunRequest { source, destination: _destination, id, run, timestamp } => {
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let mut succeeded = kernelmgr.load(id).is_ok();
|
||||
// allow preloading a kernel with delayed run
|
||||
|
@ -436,7 +436,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
// cannot run kernel while DDMA is running
|
||||
succeeded = false;
|
||||
} else {
|
||||
succeeded |= kernelmgr.run(source, id).is_ok();
|
||||
succeeded |= kernelmgr.run(source, id, timestamp).is_ok();
|
||||
}
|
||||
}
|
||||
router.send(drtioaux::Packet::SubkernelLoadRunReply {
|
||||
|
|
Loading…
Reference in New Issue