Every entry into the sleep_heap() should be unique. Any insert()
call that returns a value means we're going to drop a wake-up event.
Add an assert()! that will trigger a panic if this invariant is not
met.
Add back in the ability to pre-unlock a Mutex. This is used for slow
path unlocking without needing to wait for a response.
Signed-off-by: Sean Cross <sean@xobs.io>
This rewrites the Mutex and Condvar backends after gaining a better
understanding of how they're supposed to work.
Additionally, the Ticktimer backend implementation has changed:
* There is now a `recalculate_sleep_offline()` call that skips starting
and stopping the ticktimer. This is an unsafe function because the
user must manually manage the ticktimer state. It is used to perform
multiple operations while the ticktimer is unscheduled.
* Ticktimers now deal in `TimerRequest` types rather than raw `i64`
types. This is a newtype that is distinct from the previous `i64`, but
should behave largely the same.
* Waking a Condvar now reports the number of items that were awoken,
provided the requester sends a blocking scalar value. This allows for
backwards compatibility.
* Attempting to wake 0 Condvars now wakes all pending Condvars.
* We no longer keep track of lock-then-unlock for Mutexes, nor
notify-then-wait for Condvars. This makes those cases undefined
behavior, which puts us in line with Posix. Don't unlock mutexes that
haven't been locked, or notify Condvar recipients when nobody is
waiting.
Signed-off-by: Sean Cross <sean@xobs.io>
all other functions have a .init() routine that handles interrupt
binding.
ticktimer rolls that into a routine that also resets the time
of the ticktimer. A comment is added for maintaner sanity down
the road.
Wait until the outside of `new()` in order to install the irq handler.
This is due to a change in the optimizer for 1.71.0 which has exposed
unsoundness.
Signed-off-by: Sean Cross <sean@xobs.io>
- make the "base" field no longer public. It is accessible, but only
through an `unsafe` method, because, it is unsafe.
- add accessors to offest/mask fields. Because, it's not at all
unsafe to access these, and it can be useful for bit-ops that are
not part of the generic set of UTRA.
- add Arc to AtomicCSR, and require `std` for AtomicCSR types.
This should not break anything, I checked inside @foundation-devices
keyOS and they don't seem to be using AtomicCSR anywhere.
The Arc makes it a bit safer to clone the AtomicCSR base pointer
and share it between threads, but it will have an impact on performance.
The USB stack (which requires AtomicCSR) was regression testing and the
impact seems minimal.
Recall that the main purpose of AtomicCSR is to provide a CSR accessor
that does not require a mutable reference to the base object. This
can make certain Rust idioms a bit cleaner. We wrap the base accessor
in Arc+Atomic to try and improve the safety of throwing the borrow
checker under the bus, but it's still not perfect because hardware
mutable state can have side-effects within hardware itself that cannot
be modeled or checked by Rust's borrow checker.