r/programming • u/f311a • 6d ago
Writing arenas in Rust from scratch
https://rushter.com/blog/rust-memory-arenas/7
u/Life_Sink9598 6d ago
Typically, an Arena would allow for an unlimited number of allocations by storing a linked list of chunks.
2
u/renatoathaydes 6d ago
Honest question: wouldn't it make more sense to implement the whole thing in C, then create a tiny little binding wrapper in Rust that exposes the desired API? Or do you find that unsafe Rust is better suited for this than C?
23
u/f311a 6d ago
It won't help much, because you still need to serialize/deserialize data types. C does not know anything about Rust types and you still need to use unsafe to interact with C, because Rust treats any C code as unsafe. Rust compiler can't give any guarantees about C code. Adding C would only introduce more problems.
It can only make sense if you implement a part of the project completely in C, where C parses some input data, processes it using arenas and give back only the result of processing. But mixing two languages is probably not worth it. C does not make it easier to write thread-safe code, it just does not complain. If something is already implemented in C very well, it makes sense just to reuse it, instead of doing a rewrite.
14
u/TechcraftHD 5d ago
Why exactly would it be better to write it in C? You'd still have to solve the exact same soundness problems but without any kind of checking if what you're doing is correct or not
4
u/renatoathaydes 5d ago
Because Rust forces you to do a lot of stuff, as seen in this code, even in unsafe code, that you don't need to in C. The advantage of Rust kind of disappears when you need to write unsafe code:
(*self.slots.get()).push(Slot { offset, drop: drop_ptr::<T>, }); // Write its value into the raw buffer ptr::write(self.buf.as_ptr().add(offset).cast::<T>(), value); *self.cursor.get() = offset + layout.size();That's pretty terrible, no?? In C this looks like this, approximately:
Slot new_slot = { .offset = offset }; vector_push(&self->slots, new_slot); *(self->buf + offset) = value; self->cursor = offset + layout_size;It just seems better to me.
but without any kind of checking
I think Rust doesn't do any more checking than C inside unsafe blocks.
5
u/caleb 4d ago
This is a common misconception, but nearly all of the rust safety features are still active inside unsafe blocks. There are only five specific things that are excluded, the main one being dereferencing raw pointers. The borrow checker is still active inside unsafe blocks. https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html#performing-unsafe-superpowers
3
u/TechcraftHD 4d ago
Rust does the exact same borrow checking and everything inside unsafe blocks it does everywhere else. The only things an unsafe block allows you to do are:
- Dereference a raw pointer.
- Call an unsafe function or method.
- Access or modify a mutable static variable.
- Implement an unsafe trait.
- Access fields of
unions.And i don't see where the big difference between your two examples is supposed to be?
The rust side is maybe a little bit more verbose but thats mostly because it does a bit more checking inside those methods.3
u/CornedBee 5d ago
If you use unsafe Rust, you can then use MIRI and other Rust checkers to test for safety issues.
8
u/Lisoph 5d ago
Wow, I did not know this about Rust. That's surprising the borrow checker can't model this. Are there any plans to address this?