aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-13 18:04:05 -0500
committerxoviat <[email protected]>2023-06-13 18:04:05 -0500
commitc1fc98c3136299780535bff22a842dd78df4a254 (patch)
tree99ff8a1b505a771a5e31e2884149589676dc2e04
parentc484f0715b28a7692b1c6c3b9d8caec50b84efc9 (diff)
stm32/wpan: fix linked list bug
-rw-r--r--embassy-stm32-wpan/src/sys.rs4
-rw-r--r--embassy-stm32-wpan/src/unsafe_linked_list.rs41
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)]
176unsafe 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}