From 30ac42de3f09d44540ea24a40f45d732814537ab Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 3 Mar 2017 06:31:37 +0000 Subject: [PATCH] ksupport: fix an exception safety issue. Raising from inside a recv! will never send an acknowledgement. --- artiq/firmware/ksupport/lib.rs | 40 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index b142bcada..8b54b8111 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -318,17 +318,31 @@ extern fn dma_playback(timestamp: i64, name: CSlice) { send(&DmaPlaybackRequest(name)); let succeeded = recv!(&DmaPlaybackReply(data) => unsafe { - // Here, we take advantage of the fact that DmaPlaybackReply always refers - // to an entire heap allocation, which is 4-byte-aligned. - let data = match data { Some(bytes) => bytes, None => return false }; - csr::rtio_dma::base_address_write(data.as_ptr() as u64); + match data { + Some(bytes) => { + // Here, we take advantage of the fact that DmaPlaybackReply always refers + // to an entire heap allocation, which is 4-byte-aligned. + csr::rtio_dma::base_address_write(bytes.as_ptr() as u64); + csr::rtio_dma::time_offset_write(timestamp as u64); - csr::rtio_dma::time_offset_write(timestamp as u64); - rtio_arb_dma(); - csr::rtio_dma::enable_write(1); - while csr::rtio_dma::enable_read() != 0 {} - rtio_arb_regular(); + rtio_arb_dma(); + csr::rtio_dma::enable_write(1); + while csr::rtio_dma::enable_read() != 0 {} + rtio_arb_regular(); + true + } + None => false + } + }); + + if !succeeded { + println!("DMA trace called {:?} not found", name); + raise!("DMAError", + "DMA trace not found"); + } + + unsafe { let status = csr::rtio_dma::error_status_read(); let timestamp = csr::rtio_dma::error_timestamp_read(); let channel = csr::rtio_dma::error_channel_read(); @@ -356,14 +370,6 @@ extern fn dma_playback(timestamp: i64, name: CSlice) { "RTIO busy on channel {0}", channel as i64, 0, 0) } - - true - }); - - if !succeeded { - println!("DMA trace called {:?} not found", name); - raise!("DMAError", - "DMA trace not found"); } }