diff options
| author | xoviat <[email protected]> | 2023-06-13 18:04:05 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-06-13 18:04:05 -0500 |
| commit | c1fc98c3136299780535bff22a842dd78df4a254 (patch) | |
| tree | 99ff8a1b505a771a5e31e2884149589676dc2e04 | |
| parent | c484f0715b28a7692b1c6c3b9d8caec50b84efc9 (diff) | |
stm32/wpan: fix linked list bug
| -rw-r--r-- | embassy-stm32-wpan/src/sys.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/unsafe_linked_list.rs | 41 |
2 files changed, 28 insertions, 17 deletions
diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs index a7cbbae39..f41fac58a 100644 --- a/embassy-stm32-wpan/src/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs | |||
| @@ -49,14 +49,12 @@ impl Sys { | |||
| 49 | let node_ptr_ptr: *mut _ = &mut node_ptr; | 49 | let node_ptr_ptr: *mut _ = &mut node_ptr; |
| 50 | 50 | ||
| 51 | while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { | 51 | while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { |
| 52 | LinkedListNode::get_next_node(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); | 52 | LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); |
| 53 | 53 | ||
| 54 | let event = node_ptr.cast(); | 54 | let event = node_ptr.cast(); |
| 55 | let event = EvtBox::new(event); | 55 | let event = EvtBox::new(event); |
| 56 | 56 | ||
| 57 | EVT_CHANNEL.try_send(event).unwrap(); | 57 | EVT_CHANNEL.try_send(event).unwrap(); |
| 58 | |||
| 59 | break; | ||
| 60 | } | 58 | } |
| 61 | } | 59 | } |
| 62 | 60 | ||
diff --git a/embassy-stm32-wpan/src/unsafe_linked_list.rs b/embassy-stm32-wpan/src/unsafe_linked_list.rs index 95f4bef44..c4a6c3a72 100644 --- a/embassy-stm32-wpan/src/unsafe_linked_list.rs +++ b/embassy-stm32-wpan/src/unsafe_linked_list.rs | |||
| @@ -87,24 +87,16 @@ impl LinkedListNode { | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /// Remove `node` from the linked list | 89 | /// Remove `node` from the linked list |
| 90 | // pub unsafe fn remove_node(mut node: *mut LinkedListNode) { | ||
| 91 | // interrupt::free(|_| { | ||
| 92 | // (*(*node).prev).next = (*node).next; | ||
| 93 | // (*(*node).next).prev = (*node).prev; | ||
| 94 | // }); | ||
| 95 | // } | ||
| 96 | |||
| 97 | /// Remove `node` from the linked list | ||
| 98 | pub unsafe fn remove_node(mut p_node: *mut LinkedListNode) { | 90 | pub unsafe fn remove_node(mut p_node: *mut LinkedListNode) { |
| 99 | interrupt::free(|_| { | 91 | interrupt::free(|_| { |
| 92 | // Writes must occur sequentially, because if prev node, and next node are the same, both must be updated | ||
| 100 | let node = ptr::read_volatile(p_node); | 93 | let node = ptr::read_volatile(p_node); |
| 101 | let mut node_prev = ptr::read_volatile(node.prev); | 94 | let mut node_prev = ptr::read_volatile(node.prev); |
| 102 | let mut node_next = ptr::read_volatile(node.next); | ||
| 103 | |||
| 104 | node_prev.next = node.next; | 95 | node_prev.next = node.next; |
| 105 | node_next.prev = node.prev; | ||
| 106 | |||
| 107 | ptr::write_volatile(node.prev, node_prev); | 96 | ptr::write_volatile(node.prev, node_prev); |
| 97 | |||
| 98 | let mut node_next = ptr::read_volatile(node.next); | ||
| 99 | node_next.prev = node.prev; | ||
| 108 | ptr::write_volatile(node.next, node_next); | 100 | ptr::write_volatile(node.next, node_next); |
| 109 | }); | 101 | }); |
| 110 | } | 102 | } |
| @@ -116,7 +108,7 @@ impl LinkedListNode { | |||
| 116 | 108 | ||
| 117 | // Allowed because a removed node is not seen by another core | 109 | // Allowed because a removed node is not seen by another core |
| 118 | *p_node = list_head.next; | 110 | *p_node = list_head.next; |
| 119 | Self::remove_node(list_head.next); | 111 | Self::remove_node(*p_node); |
| 120 | }); | 112 | }); |
| 121 | } | 113 | } |
| 122 | 114 | ||
| @@ -127,7 +119,7 @@ impl LinkedListNode { | |||
| 127 | 119 | ||
| 128 | // Allowed because a removed node is not seen by another core | 120 | // Allowed because a removed node is not seen by another core |
| 129 | *p_node = list_tail.prev; | 121 | *p_node = list_tail.prev; |
| 130 | Self::remove_node(list_tail.prev); | 122 | Self::remove_node(*p_node); |
| 131 | }); | 123 | }); |
| 132 | } | 124 | } |
| 133 | 125 | ||
| @@ -179,3 +171,24 @@ impl LinkedListNode { | |||
| 179 | }); | 171 | }); |
| 180 | } | 172 | } |
| 181 | } | 173 | } |
| 174 | |||
| 175 | #[allow(dead_code)] | ||
| 176 | unsafe fn debug_linked_list(mut p_node: *mut LinkedListNode) { | ||
| 177 | info!("iterating list from node: {:x}", p_node); | ||
| 178 | let mut p_current_node = p_node; | ||
| 179 | let mut i = 0; | ||
| 180 | loop { | ||
| 181 | let current_node = ptr::read_volatile(p_current_node); | ||
| 182 | info!( | ||
| 183 | "node (prev, current, next): {:x}, {:x}, {:x}", | ||
| 184 | current_node.prev, p_current_node, current_node.next | ||
| 185 | ); | ||
| 186 | |||
| 187 | i += 1; | ||
| 188 | if i > 10 || current_node.next == p_node { | ||
| 189 | break; | ||
| 190 | } | ||
| 191 | |||
| 192 | p_current_node = current_node.next; | ||
| 193 | } | ||
| 194 | } | ||
