feat: MaybeUnint sockets to save space by putting sockets in .bss - #1199
feat: MaybeUnint sockets to save space by putting sockets in .bss#1199sigvartmh wants to merge 1 commit into
Conversation
Initialise a slice of uninitialised socket storage in place, returning the
initialised slice.
This exists to keep socket storage out of `.data` on bare-metal targets.
`SocketStorage` is a niche-filled `Option<Item>`: `None` occupies zero
bytes of payload and its bit pattern is chosen by the compiler, so
`EMPTY` is *not* all-zero. A
```
static mut STORAGE: [SocketStorage; N] = [SocketStorage::EMPTY; N];
```
therefore cannot live in `.bss`; it goes in `.data` and the linker emits
an initialiser image of `N * size_of::<SocketStorage>()` bytes into
flash, almost all of which is zeros. Declaring the storage
`MaybeUninit` instead places it in `.bss`, and this function fills it at
startup:
```
static mut STORAGE: MaybeUninit<[SocketStorage; N]> = MaybeUninit::uninit();
let sockets = SocketSet::new(SocketStorage::init_slice(unsafe {
&mut *(core::ptr::addr_of_mut!(STORAGE) as *mut [MaybeUninit<SocketStorage>; N])
}));
```
Measured on thumbv7em-none-eabihf with 7 sockets, `opt-level="z"` and fat
LTO: 3616 bytes of `.data` removed, of which 3584 were zeros, at a cost
of ~380 bytes of `.rodata` and a short init loop. RAM use is unchanged.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1199 +/- ##
==========================================
+ Coverage 82.57% 82.61% +0.03%
==========================================
Files 83 83
Lines 26174 26194 +20
==========================================
+ Hits 21613 21639 +26
+ Misses 4561 4555 -6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I've designed to keep the core of smoltcp (excluding Regarding your particular problem: smoltcp has been originally designed to have its structures allocated on stack, perhaps in |
Sure if I self allocate them on the stack having thme being allocated/initialized from I looked through the code and found a no places of unsafe which is why I assumed this maybe wouldn't go in anyways great work on the stack thanks for making it public 👍 |
Proposal
So this may be a bit more controversial but sockets currently don't get the
00bit patteren meaning they can't be in.bsson embedded targets. Maybe there is a better way of not initializing them but this is the solution I found. Feel free to deny or come with feed back on it. This also addsunsafeto the code which may not be wanted.Commit message:
Initialise a slice of uninitialised socket storage in place, returning the initialised slice.
This exists to keep socket storage out of
.dataon bare-metal targets.SocketStorageis a niche-filledOption<Item>:Noneoccupies zero bytes of payload and its bit pattern is chosen by the compiler, soEMPTYis not all-zero. Atherefore cannot live in
.bss; it goes in.dataand the linker emits an initialiser image ofN * size_of::<SocketStorage>()bytes into flash, almost all of which is zeros. Declaring the storageMaybeUninitinstead places it in.bss, and this function fills it at startup:Measured on thumbv7em-none-eabihf with 7 sockets,
opt-level="z"and fat LTO: 3616 bytes of.dataremoved, of which 3584 were zeros, at a cost of ~380 bytes of.rodataand a short init loop. RAM use is unchanged.