diff options
| author | ivmarkov <[email protected]> | 2022-10-24 09:17:43 +0300 |
|---|---|---|
| committer | ivmarkov <[email protected]> | 2022-10-24 09:17:43 +0300 |
| commit | 4d5550070fe5e80ff2296a71239c568c774b9ceb (patch) | |
| tree | 3248eb5c70b9dd5402c5edc049cafc31a5f66ed3 /embassy-executor/src | |
| parent | 53608a87ac4b6c8c60b5508551d12f5ba76ca2f6 (diff) | |
Change time Driver contract to never fire the alarm synchronously
Diffstat (limited to 'embassy-executor/src')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index e1258ebb5..5bcb1e6e7 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -354,46 +354,54 @@ impl Executor { | |||
| 354 | /// somehow schedule for `poll()` to be called later, at a time you know for sure there's | 354 | /// somehow schedule for `poll()` to be called later, at a time you know for sure there's |
| 355 | /// no `poll()` already running. | 355 | /// no `poll()` already running. |
| 356 | pub unsafe fn poll(&'static self) { | 356 | pub unsafe fn poll(&'static self) { |
| 357 | #[cfg(feature = "integrated-timers")] | 357 | loop { |
| 358 | self.timer_queue.dequeue_expired(Instant::now(), |task| wake_task(task)); | 358 | #[cfg(feature = "integrated-timers")] |
| 359 | self.timer_queue.dequeue_expired(Instant::now(), |task| wake_task(task)); | ||
| 359 | 360 | ||
| 360 | self.run_queue.dequeue_all(|p| { | 361 | self.run_queue.dequeue_all(|p| { |
| 361 | let task = p.as_ref(); | 362 | let task = p.as_ref(); |
| 362 | 363 | ||
| 363 | #[cfg(feature = "integrated-timers")] | 364 | #[cfg(feature = "integrated-timers")] |
| 364 | task.expires_at.set(Instant::MAX); | 365 | task.expires_at.set(Instant::MAX); |
| 365 | 366 | ||
| 366 | let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); | 367 | let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); |
| 367 | if state & STATE_SPAWNED == 0 { | 368 | if state & STATE_SPAWNED == 0 { |
| 368 | // If task is not running, ignore it. This can happen in the following scenario: | 369 | // If task is not running, ignore it. This can happen in the following scenario: |
| 369 | // - Task gets dequeued, poll starts | 370 | // - Task gets dequeued, poll starts |
| 370 | // - While task is being polled, it gets woken. It gets placed in the queue. | 371 | // - While task is being polled, it gets woken. It gets placed in the queue. |
| 371 | // - Task poll finishes, returning done=true | 372 | // - Task poll finishes, returning done=true |
| 372 | // - RUNNING bit is cleared, but the task is already in the queue. | 373 | // - RUNNING bit is cleared, but the task is already in the queue. |
| 373 | return; | 374 | return; |
| 374 | } | 375 | } |
| 375 | 376 | ||
| 376 | #[cfg(feature = "rtos-trace")] | 377 | #[cfg(feature = "rtos-trace")] |
| 377 | trace::task_exec_begin(p.as_ptr() as u32); | 378 | trace::task_exec_begin(p.as_ptr() as u32); |
| 378 | 379 | ||
| 379 | // Run the task | 380 | // Run the task |
| 380 | task.poll_fn.read()(p as _); | 381 | task.poll_fn.read()(p as _); |
| 381 | 382 | ||
| 382 | #[cfg(feature = "rtos-trace")] | 383 | #[cfg(feature = "rtos-trace")] |
| 383 | trace::task_exec_end(); | 384 | trace::task_exec_end(); |
| 385 | |||
| 386 | // Enqueue or update into timer_queue | ||
| 387 | #[cfg(feature = "integrated-timers")] | ||
| 388 | self.timer_queue.update(p); | ||
| 389 | }); | ||
| 384 | 390 | ||
| 385 | // Enqueue or update into timer_queue | ||
| 386 | #[cfg(feature = "integrated-timers")] | 391 | #[cfg(feature = "integrated-timers")] |
| 387 | self.timer_queue.update(p); | 392 | { |
| 388 | }); | 393 | // If this is already in the past, set_alarm might return false |
| 394 | // In that case do another poll loop iteration. | ||
| 395 | let next_expiration = self.timer_queue.next_expiration(); | ||
| 396 | if driver::set_alarm(self.alarm, next_expiration.as_ticks()) { | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | } | ||
| 389 | 400 | ||
| 390 | #[cfg(feature = "integrated-timers")] | 401 | #[cfg(not(feature = "integrated-timers"))] |
| 391 | { | 402 | { |
| 392 | // If this is already in the past, set_alarm will immediately trigger the alarm. | 403 | break; |
| 393 | // This will cause `signal_fn` to be called, which will cause `poll()` to be called again, | 404 | } |
| 394 | // so we immediately do another poll loop iteration. | ||
| 395 | let next_expiration = self.timer_queue.next_expiration(); | ||
| 396 | driver::set_alarm(self.alarm, next_expiration.as_ticks()); | ||
| 397 | } | 405 | } |
| 398 | 406 | ||
| 399 | #[cfg(feature = "rtos-trace")] | 407 | #[cfg(feature = "rtos-trace")] |
