forked from M-Labs/artiq
runtime: use the destination passed by kernel
This commit is contained in:
parent
c087a47e45
commit
171c7a6e11
@ -332,8 +332,9 @@ pub mod subkernel {
|
|||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
let subkernel = unsafe { SUBKERNELS.get(&id) };
|
let subkernel = unsafe { SUBKERNELS.get(&id) };
|
||||||
if subkernel.is_none() || subkernel.unwrap().state != SubkernelState::Running {
|
if subkernel.is_some() && subkernel.unwrap().state != SubkernelState::Running {
|
||||||
// do not add messages for non-existing, non-running or deleted subkernels
|
warn!("received a message for a non-running subkernel #{}", id);
|
||||||
|
// do not add messages for non-running or deleted subkernels
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if status.is_first() {
|
if status.is_first() {
|
||||||
@ -361,8 +362,10 @@ pub mod subkernel {
|
|||||||
|
|
||||||
pub fn message_await(io: &Io, subkernel_mutex: &Mutex, id: u32, timeout: u64
|
pub fn message_await(io: &Io, subkernel_mutex: &Mutex, id: u32, timeout: u64
|
||||||
) -> Result<Message, Error> {
|
) -> Result<Message, Error> {
|
||||||
{
|
let is_subkernel = {
|
||||||
let _lock = subkernel_mutex.lock(io)?;
|
let _lock = subkernel_mutex.lock(io)?;
|
||||||
|
let is_subkernel = unsafe { SUBKERNELS.get(&id).is_some() };
|
||||||
|
if is_subkernel {
|
||||||
match unsafe { SUBKERNELS.get(&id).unwrap().state } {
|
match unsafe { SUBKERNELS.get(&id).unwrap().state } {
|
||||||
SubkernelState::Finished { status: FinishStatus::Ok } |
|
SubkernelState::Finished { status: FinishStatus::Ok } |
|
||||||
SubkernelState::Running => (),
|
SubkernelState::Running => (),
|
||||||
@ -372,6 +375,8 @@ pub mod subkernel {
|
|||||||
_ => return Err(Error::IncorrectState)
|
_ => return Err(Error::IncorrectState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is_subkernel
|
||||||
|
};
|
||||||
let max_time = clock::get_ms() + timeout as u64;
|
let max_time = clock::get_ms() + timeout as u64;
|
||||||
let message = io.until_ok(|| {
|
let message = io.until_ok(|| {
|
||||||
if clock::get_ms() > max_time {
|
if clock::get_ms() > max_time {
|
||||||
@ -387,11 +392,13 @@ pub mod subkernel {
|
|||||||
return Ok(Some(unsafe { MESSAGE_QUEUE.remove(i) }));
|
return Ok(Some(unsafe { MESSAGE_QUEUE.remove(i) }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if is_subkernel {
|
||||||
match unsafe { SUBKERNELS.get(&id).unwrap().state } {
|
match unsafe { SUBKERNELS.get(&id).unwrap().state } {
|
||||||
SubkernelState::Finished { status: FinishStatus::CommLost } |
|
SubkernelState::Finished { status: FinishStatus::CommLost } |
|
||||||
SubkernelState::Finished { status: FinishStatus::Exception(_) } => return Ok(None),
|
SubkernelState::Finished { status: FinishStatus::Exception(_) } => return Ok(None),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Err(())
|
Err(())
|
||||||
});
|
});
|
||||||
match message {
|
match message {
|
||||||
@ -412,15 +419,17 @@ pub mod subkernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_send<'a>(io: &Io, aux_mutex: &Mutex, subkernel_mutex: &Mutex,
|
pub fn message_send<'a>(io: &Io, aux_mutex: &Mutex, subkernel_mutex: &Mutex,
|
||||||
routing_table: &RoutingTable, id: u32, count: u8, tag: &'a [u8], message: *const *const ()
|
routing_table: &RoutingTable, id: u32, destination: Option<u8>, count: u8, tag: &'a [u8], message: *const *const ()
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut writer = Cursor::new(Vec::new());
|
let mut writer = Cursor::new(Vec::new());
|
||||||
let _lock = subkernel_mutex.lock(io)?;
|
|
||||||
let destination = unsafe { SUBKERNELS.get(&id).unwrap().destination };
|
|
||||||
|
|
||||||
// reuse rpc code for sending arbitrary data
|
// reuse rpc code for sending arbitrary data
|
||||||
rpc::send_args(&mut writer, 0, tag, message, false)?;
|
rpc::send_args(&mut writer, 0, tag, message, false)?;
|
||||||
// skip service tag, but overwrite first byte with tag count
|
// skip service tag, but overwrite first byte with tag count
|
||||||
|
let destination = destination.unwrap_or_else(|| {
|
||||||
|
let _lock = subkernel_mutex.lock(io).unwrap();
|
||||||
|
unsafe { SUBKERNELS.get(&id).unwrap().destination }
|
||||||
|
}
|
||||||
|
);
|
||||||
let data = &mut writer.into_inner()[3..];
|
let data = &mut writer.into_inner()[3..];
|
||||||
data[0] = count;
|
data[0] = count;
|
||||||
Ok(drtio::subkernel_send_message(
|
Ok(drtio::subkernel_send_message(
|
||||||
|
@ -704,8 +704,8 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex,
|
|||||||
kern_send(io, &kern::SubkernelAwaitFinishReply { status: status })
|
kern_send(io, &kern::SubkernelAwaitFinishReply { status: status })
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
&kern::SubkernelMsgSend { id, destination: _, count, tag, data } => {
|
&kern::SubkernelMsgSend { id, destination, count, tag, data } => {
|
||||||
subkernel::message_send(io, aux_mutex, _subkernel_mutex, routing_table, id, count, tag, data)?;
|
subkernel::message_send(io, aux_mutex, _subkernel_mutex, routing_table, id, destination, count, tag, data)?;
|
||||||
kern_acknowledge()
|
kern_acknowledge()
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
Loading…
Reference in New Issue
Block a user