-
Notifications
You must be signed in to change notification settings - Fork 101
Conversation
7408c0e sketches what I mean by "reference counting" of critical sections (a poor choice of words). |
a53c68b is another refinement. |
static mut irq_level : uint = 0; | ||
|
||
#[inline(always)] | ||
pub fn disable_irqs() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add some documentation here about which irqs are/aren't disabled. cpsid i
doesn't disable Reset, HardFault or NMI. cpsid f
doesn't disable NMI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
The cortex M3/M4 should be using LDREX to get the lock. Only the M0/M0+/M1 need to disable/enable interrupts. Also thinking this would be more flexible (and easier to review) if you start with a lock primitive in cortex_m3 and build the mutex/condition variable on top of that. Also needs a rebase/squash. |
@bharrisau, thanks! I'll rework things a bit more and try my hand at using LDREX. |
@bharrisau, how does this look? As far as I can tell, |
That one looks nice, I'll drop a few style comments in a moment. |
#[must_use] | ||
pub struct Guard<'a>(&'a Lock); | ||
|
||
pub static STATIC_Lock: Lock = Lock { locked: Unsafe { value: false, marker1: InvariantType } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be STATIC_LOCK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duly noted.
Also, a few generic comments: use 2-space idents and make sure you have licence headers in all new files. Would it be reasonable to make |
*/ | ||
pub fn lock<'a>(&'a self) -> Guard<'a> { | ||
unsafe { | ||
// we need the critical section until the end of this function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra space before //
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh!
This is a basic locking primitive for buillding synchronization primitives.
This implements a simple abstraction for critical sections where interrupts must be disabled.
This is a simple container for thread-safe state with access guarded by a CritSection.
This implements a simple thread-safe queue.
pub fn try_lock<'a>(&'a self) -> Option<Guard<'a>> { | ||
unsafe { | ||
match *self.owner.get() { | ||
None => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None => {
LGTM |
Added a few synchronization primitives.
Good job. Once we get a solution for bit-banded access we can add a third method for handling locks - bit band writes are atomic so you can do a 32 position lock with low overhead. |
Here is the current state of my mutex support. Progress on this has been pretty sporatic and things are still in a state of minor disarray but I've cleaned things up the best I can and rebased against master for reference.
There are a few things I should point out there,
IrqDisabled
token is reasonable given how it is abused inMutex::lock
. The idea here is that operations onQueue
(which is ideally thread-safe) require that you prove that the caller is in a critical section with interrupts disabled. It might be better to instead use a reference-counting approach here instead.task
could use some cleaning up. At the moment I've just marked a few things aspub
to get things to compile but things could be a bit cleaner.