Skip to content

Commit 6baba85

Browse files
authored
Only lock scheduler once in mutex ops (#4176)
1 parent 0180a38 commit 6baba85

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

esp-preempt/src/semaphore.rs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use alloc::boxed::Box;
22
use core::ptr::NonNull;
33

4-
use esp_hal::time::{Duration, Instant};
4+
use esp_hal::{
5+
system::Cpu,
6+
time::{Duration, Instant},
7+
};
58
use esp_radio_preempt_driver::{
69
register_semaphore_implementation,
710
semaphore::{SemaphoreImplementation, SemaphoreKind, SemaphorePtr},
@@ -10,7 +13,7 @@ use esp_sync::NonReentrantMutex;
1013

1114
use crate::{
1215
SCHEDULER,
13-
task::{TaskExt, TaskPtr, current_task},
16+
task::{TaskExt, TaskPtr},
1417
wait_queue::WaitQueue,
1518
};
1619

@@ -47,30 +50,30 @@ impl SemaphoreInner {
4750
original_priority,
4851
..
4952
} => {
50-
let current = current_task();
51-
if let Some(owner) = owner {
52-
if *owner == current && *recursive {
53-
*lock_counter += 1;
54-
true
55-
} else {
56-
// We can't lock the mutex. Make sure the mutex holder has a high enough
57-
// priority to avoid priority inversion.
58-
SCHEDULER.with(|scheduler| {
53+
SCHEDULER.with(|scheduler| {
54+
let current_cpu = Cpu::current() as usize;
55+
let current = unwrap!(scheduler.per_cpu[current_cpu].current_task);
56+
if let Some(owner) = owner {
57+
if *owner == current && *recursive {
58+
*lock_counter += 1;
59+
true
60+
} else {
61+
// We can't lock the mutex. Make sure the mutex holder has a high enough
62+
// priority to avoid priority inversion.
5963
let current_priority = current.priority(&mut scheduler.run_queue);
6064
if owner.priority(&mut scheduler.run_queue) < current_priority {
6165
owner.set_priority(&mut scheduler.run_queue, current_priority);
6266
scheduler.resume_task(*owner);
6367
}
6468
false
65-
})
69+
}
70+
} else {
71+
*owner = Some(current);
72+
*lock_counter += 1;
73+
*original_priority = current.priority(&mut scheduler.run_queue);
74+
true
6675
}
67-
} else {
68-
*owner = Some(current);
69-
*lock_counter += 1;
70-
*original_priority =
71-
SCHEDULER.with(|scheduler| current.priority(&mut scheduler.run_queue));
72-
true
73-
}
76+
})
7477
}
7578
}
7679
}
@@ -90,23 +93,22 @@ impl SemaphoreInner {
9093
lock_counter,
9194
original_priority,
9295
..
93-
} => {
94-
let current = current_task();
96+
} => SCHEDULER.with(|scheduler| {
97+
let current_cpu = Cpu::current() as usize;
98+
let current = unwrap!(scheduler.per_cpu[current_cpu].current_task);
9599

96100
if *owner == Some(current) && *lock_counter > 0 {
97101
*lock_counter -= 1;
98-
if *lock_counter == 0 {
99-
if let Some(owner) = owner.take() {
100-
SCHEDULER.with(|scheduler| {
101-
owner.set_priority(&mut scheduler.run_queue, *original_priority);
102-
});
103-
}
102+
if *lock_counter == 0
103+
&& let Some(owner) = owner.take()
104+
{
105+
owner.set_priority(&mut scheduler.run_queue, *original_priority);
104106
}
105107
true
106108
} else {
107109
false
108110
}
109-
}
111+
}),
110112
}
111113
}
112114

0 commit comments

Comments
 (0)