Comments (5)
Is this a problem with spin::lazy::Lazy itself? Or is this a problem with whatever is within it?
The latter. Lazy
(and, indeed, lazy_static
) do no guarantee mutual exclusivity of the final value, which is required to safely get a mutable reference to it. The only thing that they guarantee is synchronised, delayed initialisation of a value (hence the 'lazy' name).
If you want to have the resulting value also be accessible mutable, you need to guarantee mutual exclusion via some other type that performs synchronisation. Most likely, Mutex
or RwLock
. I can see that you're dealing with interrupts, so the implementations in spin
will do (on targets with std
support, use the ones in std::sync
, of course). This would make the final type Lazy<Mutex<IrqList>>
.
This used to work with lazy_static but doesn't work like this for some reason.
I'm not sure how this would have worked without something like Mutex
, lazy_static
also does not guarantee exclusive access to the final value.
As a final note, I see that you're playing with interrupts: be very careful when combining interrupt code with synchronisation, and make sure that you never attempt to take locks (including spinlocks) in an interrupt handler. IRQs are not aware of any synchronisation primitives you have set up, and may well decide to fire when you're already in the critical section of a lock. If the interrupt handler then attempts to take that same lock, a deadlock will result. You can get around this in some specific cases by toggling off interrupts before taking the lock, but this generally results in poor performance unless done extremely carefully. In addition, most architectures have some kind of 'non-maskable interrupt' that can fire even when interrupts are disabled, so this is far from a perfect solution. If you're unsure, it's best to do some reading on the architecture in question and take a look at how similar things have been implemented by others.
from spin-rs.
@zesterer Thank you. In IRQ handlers I gain immutable access to the type. Interrupts are disabled automatically by the processor before entering the handler -- I need to signal it with an EOI before it will give me the next one. This is specifically an x86-only project at the moment. Still, I will take what you said into consideration. (I could always just use an atomic to hold the items; then no locks would be needed at all. But that might not be a good idea either.
from spin-rs.
Atomics are probably a good idea, yes! Just be careful to ensure that you use a truly atomic operation rather than one that secretly does some mutual exclusion behind the scenes. For example, the atomic
crate will actually do this for types larger than those that can be represented with atomic intrinsics.
from spin-rs.
Is there a crate that will actually use atomics for everything? I'm hesitant to go implementing that myself.
from spin-rs.
It's not possible in the general case. Atomic intrinsics usually only work for values up to 64 bits in size on most architectures. atomic
has the following function that allows you to ensure that your operation is actually lock-free though: https://amanieu.github.io/atomic-rs/atomic/struct.Atomic.html#method.is_lock_free
In general, the atomic types in core::sync::atomic
are good and you should use them if you can.
from spin-rs.
Related Issues (20)
- Inconsistent feature name HOT 2
- `lock_api` feature is not available in version 0.7.1 and 0.8.0. HOT 4
- Remove `panicked` field from Once's Finish guard HOT 2
- Implement Once::get_mut_unchecked and Once::into_inner_unchecked HOT 4
- unwrap function in MutexGuard? HOT 4
- Request: Add support for atomic-polyfill HOT 7
- `Once::call_once` doesn't guarantee that the given closure is called only if this is the first time `call_once` has been called. HOT 2
- RwLock::try_read is unsound HOT 2
- MIRI build in CI is failing HOT 4
- portable_atomic feature does not compile HOT 2
- CI: Set minimal permissions on GitHub Workflow HOT 3
- Why was spin 0.9.6 yanked? HOT 2
- Unsoundness in `Once::try_call_once()`
- Are `rwlock` and `spin_mutex` compatible with `portable_atomic`? HOT 11
- `Lazy` panics under bare metal environment HOT 10
- Add a Security-Policy
- Add `std` feature with support for thread yielding HOT 1
- Switching to GitHub actions HOT 1
- Need a spinlock that never uses std::thread::yield_now HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spin-rs.