10 ms·
>Those things the compiler is angry about? Those are things that would be runtime errors in C. I'm very very aware of that though this is not always true. For
by zaarn 8y ago
>Those things the compiler is angry about? Those are things that would be runtime errors in C.
I'm very very aware of that though this is not always true.
For example Rust doesn't have a sane way to have a reentrant mutex without including std, which is bad because for interrupts in a kernel you need to either have very fine grained locking and fallbacks or rely entirely on lockless operations. Interrupts can occur on top of eachother in which case it behave a lot worse than simply being reentrant.
rustc yells at me a lot for the solutions this requires because the way I solve it violates ownership rules of rust the hard way to make the code simpler and understandable.
Other times it's when for bizarre reason rust wants the code to implement the Sync and Send traits despite the kernel running alone on the core (there is no threading in that kernel) and I would love to be able to tell rustc to just shut up about this and simply ignore Send, possibly even Sync, on a module level.
- richardwhiuk 8y agoLinux's kernel runs on more than one core and is pre-emptible, so that's just not generally true.
- zaarn 8y agoIn the context of a single core, this happens. Multiple cores make it harder because on top of an interrupt taking locks, other cores now also take locks and you can no longer rely on various promises that a single core gives you. While the Linux kernel can do this, it's not easy to write from scratch, especially because Linux is in C so the compiler doesn't complain about weird things you do.
- steveklabnik 8y agoIf you know your types are Send and Sync, then you should implement Send and Sync for them. That's how you "tell rustc to just shut up about this."
- zaarn 8y agoThey aren't Send and Sync, ie not multithreading safe, they are however, reentrant safe, which is all I need. rustc complaints and I don't want to implement traits on types that don't need them and don't adhere to the contract of the trait.
- pcwalton 8y agoYou shouldn't have to worry about Send and Sync if you aren't using generic types that require that their type parameters be Send and Sync. What such types are you using?
- zaarn 8y agoVarious no_std libs use Send+Sync in places which makes things fun. Another would be static mutable variables, which are perfectly safe in a single-threaded environment, doubly so if you map that memory on a per-core basis to ensure each kernel has a unique variable value. Esp if you need lazy_static then there aren't many options other than wrapping the data in a mutex for no good reason.
- eddyb 8y agoIf it's per-core you should look into making `#[thread_local]` statics work, which remove some of the restrictions. `static mut` is not always safe even in a single-threaded environment, because of reentrance - see also https://github.com/rust-lang/rust/issues/53639 https://github.com/rust-lang/rust/issues/53639.
- zaarn 8y agoI'm not sure if Thread local would work since i'm not certain if the bootloader can handle a TLS section in the ELF file, my kernel cannot do this either as I've yet to implement threading. Reentrance is not the issue here, I guard this inside the data structure, interrupts will be worst case reentrance most of the time.
- eddyb 8y agoThen you can use the techniques in the thread I linked. But without guarding mutability behind some way to indicate interrupts are disabled, or an outright lock, and without guaranteeing no data races (Sync), it's not actually safe. And the compiler can't make `static mut` safe to use as any of those requirements could be broken and then it's not safe at all anymore.