4 ms·
Then you'd have to save and load the file. Here you can, at runtime just write code that works as usual. You can kill the process, and come back in a day, and s
by jauntywundrkind 3y ago
Then you'd have to save and load the file. Here you can, at runtime just write code that works as usual. You can kill the process, and come back in a day, and start a new process that has the same objects saved & ready for use. (Ed: ah, systemd limitation, it will only hold data while restarting, alas, but no concrete reason it has to be so short.)
This seems like way less work, seems way less convoluted than writing a whole intermediary layer to serialize objects out into some whatever format on disk, & read them back. The objects are just there, primed, ready to go. It harkens back to single level store days, when disk-backing memory was done by the OS (multics). https://gunkies.org/wiki/Single-level_store https://gunkies.org/wiki/Single-level_store
Another way of looking at this is as a return to the old days before we made everything convoluted.
- Diggsey 3y agoNot really - you have to completely change your data model to avoid pointers which won't save correctly (eg. using a byte array for name in the article) compared to just slapping `#[derive(Serialize, Deserialize)]` on your structs. Not to mention all the extra unsafe code.
- gpm 3y agoIf you changed the global allocator to this... and put the stack on it... any reason you couldn't use pointers mostly as normal. You'd run into issues as soon as a library used mmap, but other than that...
- dathinab 3y agoIf you put the global allocator on this there is a huge load of other issues you can have. Like needing to allocate a fixed amount of memory for your whole program upfront or juggling multiple fds. Or that there is some state you can not carry over even with that and if you try you can easily run into soundness issues. Or that the state saved might be "in between" operations in a very unexpected way and in turn unsound. etc.
- gpm 3y ago> Like needing to allocate a fixed amount of memory for your whole program upfront Can I not do the normal virtual memory thing and allocate far more memory than I actually have hardware for? > Or that there is some state you can not carry over even with that and if you try you can easily run into soundness issues. I mean, fair... you're going to have to be careful what you save either way but making saving things the default does seem like more of a footgun. > Or that the state saved might be "in between" operations in a very unexpected way and in turn unsound. This applies even if you only use it for some structs? This whole mechanism seems like it would only be sound if it was only used after clean exits.
- dathinab 3y ago> sound if it was only used after clean exits. yes, except maybe if a Drop constructor is run unexpectedly on the exit or similar generally I think using it with anything which has pointers and/or runs Drop in it is brittle and prone to bugs in turn most things which do not have pointers should be fine with a clean exit and anything which only consists of memory where any bit combination is always valid should always be sound even on a abort (e.g. a `[u8]` allocated directly in that memory region or a `[T]` where `T` only has primitive non-allocating types)
- throwaway09223 3y agoThe common place to use something like this would be to mmap an existing external data structure. There are a number of existing mmap-able 0copy k/v library/db formats that fit the bill here.
- planede 3y agoYou are better off with CRIU at this point, IMO.
- jauntywundrkind 3y agoI love CRIU and think it's way under appreciated. Both Node and JVM have some cool snapshotting of their stdlibs too that is somewhat similar, and if you really want to optimize your load times, you can go bundle more stuff into these ready to go snapshots, which is so super cool to me. Checkpoint Restore In Vm-space! The patterns here rock. I do think though that these patterns of having file descriptors of stuff that can be passed around, and having semi-seamless "just map in the object whole" have a ton of super powered ultra-high performance wins to it that deserve a lot of exploration & effort that justify their pursuit. But Checkpoint Restore in Userspace/criu just works & is great for fast loading a thing. Still, we need at least some fd passing for apps like no-downtime-restart (or smart draining + SO_REUSEPORT); that's a real need. Going further and passing around memfd's is cool. It's gotten dropped, but for example Apache Arrow had a Plasma object store for this stuff for a while, that I wish was still on the scene (or something like it). Arrow is a particular data-format with it's own libraries, versus what we have here which is coding-as-usual(-ish); 1/2 patterns. The second might be harder but I still think it has potential.
- jauntywundrkind 3y agoEasy to cast stones. (Unsafe code especially seems like a very low quality dig to me, for an allocator: theres going to be some low level base to a system. And not like glibc was authored in a memory safe language either.) Sure there's problems. Unix won and multics lost, and we have half a century of accrued complexity around that, and a couple weekends of hacking isn't going to get us all the way back to a perfect Single Level Store. Is this something we can and should all switch to? No. The costs are high, it's not practical. But I think over time, especially with the rise of CXL and rdma resurgent, we'll see zero-cooy zero-serialize techniques like this grow back & be huge performance wins for us, be much simpler to handle, even with the adaption we'll have to do.
- threeseed 3y agoExcept that a lot of use third party code who have structs that aren't serializable. I'm working on a project now where I'm maintaining half a dozen forks just to add a single line.
- autoexecbat 3y agoI imagine it would also be an interesting way to recover/continue on from a panic/segfault
- dmitrygr 3y agoSure..assuming the cause of your segfault was not somewhere in that data...as it surely was
- not2b 3y agoYes, you'd need a "safe mode" restart to avoid repeatedly failing and restarting in a tight loop.
- dmitrygr 3y agoSo sort of like…copying a good safe state of .data from an ELF file to RAM, clearing .bss in RAM, and jumping to a good safe instruction address, like the entry point as specified by the ELF file? </sarc>
- dathinab 3y agoThe problem is that this can "carry over" structures which are in a unsound state. Especially if abort was done due to runtime sanity/soundness checks failing. Or a segfault due to unsound structures etc. As far as I can tell you should only use it for "splatted" data, maybe allowing gaps. E.g. using it to not needing to load again some kind of multiple 1GiB bit mask which are just a 1GiB blob of bits each would probably work grate. Using it on structs which do not contain any pointer (i.e. no Strings, no Vecs, no &str etc.) would work okay. But the moment any pointers are stored in data carried over that way things become a huge mess and are basically fundamentally unsafe as they can easily become unsound.
- throwaway914 3y agoI think I'm misunderstanding what this can be used for, but something I'd love to see become "perfect" is preserving a GUI application state across reboots/logins/etc. Especially with flatpak GUI apps.
- astrange 3y agoThis is called image computing and Lisp/Smalltalk did it. Emacs has a form of it called undump. I dislike it because it violates the "rule of least power". Basically, if you never have to validate your internal data, you can never tell it's corrupt.
- planede 3y agoThis is going to be possible with CRIU and Wayland applications. I saw a PoC with Qt that did this.
- yencabulator 3y agoNo part of systemd FD store is gonna survive a reboot.