diff options
| -rw-r--r-- | embassy/src/executor/executor.rs | 46 | ||||
| -rw-r--r-- | embassy/src/executor/timer_executor.rs | 4 |
2 files changed, 24 insertions, 26 deletions
diff --git a/embassy/src/executor/executor.rs b/embassy/src/executor/executor.rs index e7bb659fb..2f6bfad58 100644 --- a/embassy/src/executor/executor.rs +++ b/embassy/src/executor/executor.rs | |||
| @@ -258,42 +258,40 @@ impl Executor { | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /// Spawn a future on this executor. | 260 | /// Spawn a future on this executor. |
| 261 | /// | 261 | pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { |
| 262 | /// safety: can only be called from the executor thread | ||
| 263 | pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { | ||
| 264 | let header = token.header; | 262 | let header = token.header; |
| 265 | mem::forget(token); | 263 | mem::forget(token); |
| 266 | 264 | ||
| 267 | match header { | 265 | match header { |
| 268 | Some(header) => { | 266 | Some(header) => unsafe { |
| 269 | let header = header.as_ref(); | 267 | let header = header.as_ref(); |
| 270 | header.executor.set(self); | 268 | header.executor.set(self); |
| 271 | self.enqueue(header as *const _ as _); | 269 | self.enqueue(header as *const _ as _); |
| 272 | Ok(()) | 270 | Ok(()) |
| 273 | } | 271 | }, |
| 274 | None => Err(SpawnError::Busy), | 272 | None => Err(SpawnError::Busy), |
| 275 | } | 273 | } |
| 276 | } | 274 | } |
| 277 | 275 | ||
| 278 | /// Runs the executor until the queue is empty. | 276 | /// Runs the executor until the queue is empty. |
| 279 | /// | 277 | pub fn run(&self) { |
| 280 | /// safety: can only be called from the executor thread | 278 | unsafe { |
| 281 | pub unsafe fn run(&self) { | 279 | self.queue.dequeue_all(|p| { |
| 282 | self.queue.dequeue_all(|p| { | 280 | let header = &*p; |
| 283 | let header = &*p; | 281 | |
| 284 | 282 | let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); | |
| 285 | let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); | 283 | if state & STATE_RUNNING == 0 { |
| 286 | if state & STATE_RUNNING == 0 { | 284 | // If task is not running, ignore it. This can happen in the following scenario: |
| 287 | // If task is not running, ignore it. This can happen in the following scenario: | 285 | // - Task gets dequeued, poll starts |
| 288 | // - Task gets dequeued, poll starts | 286 | // - While task is being polled, it gets woken. It gets placed in the queue. |
| 289 | // - While task is being polled, it gets woken. It gets placed in the queue. | 287 | // - Task poll finishes, returning done=true |
| 290 | // - Task poll finishes, returning done=true | 288 | // - RUNNING bit is cleared, but the task is already in the queue. |
| 291 | // - RUNNING bit is cleared, but the task is already in the queue. | 289 | return; |
| 292 | return; | 290 | } |
| 293 | } | 291 | |
| 294 | 292 | // Run the task | |
| 295 | // Run the task | 293 | header.poll_fn.read()(p as _); |
| 296 | header.poll_fn.read()(p as _); | 294 | }); |
| 297 | }); | 295 | } |
| 298 | } | 296 | } |
| 299 | } | 297 | } |
diff --git a/embassy/src/executor/timer_executor.rs b/embassy/src/executor/timer_executor.rs index 21a81383a..1f89490f2 100644 --- a/embassy/src/executor/timer_executor.rs +++ b/embassy/src/executor/timer_executor.rs | |||
| @@ -34,14 +34,14 @@ impl<A: Alarm> TimerExecutor<A> { | |||
| 34 | /// Spawn a future on this executor. | 34 | /// Spawn a future on this executor. |
| 35 | /// | 35 | /// |
| 36 | /// safety: can only be called from the executor thread | 36 | /// safety: can only be called from the executor thread |
| 37 | pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { | 37 | pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { |
| 38 | self.inner.spawn(token) | 38 | self.inner.spawn(token) |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | /// Runs the executor until the queue is empty. | 41 | /// Runs the executor until the queue is empty. |
| 42 | /// | 42 | /// |
| 43 | /// safety: can only be called from the executor thread | 43 | /// safety: can only be called from the executor thread |
| 44 | pub unsafe fn run(&'static self) { | 44 | pub fn run(&'static self) { |
| 45 | with_timer_queue(&self.timer_queue, || { | 45 | with_timer_queue(&self.timer_queue, || { |
| 46 | self.timer_queue.check_expirations(); | 46 | self.timer_queue.check_expirations(); |
| 47 | self.inner.run(); | 47 | self.inner.run(); |
