Is there another option besides memfd_create? I'm currently using those to implement a circular buffer that avoids having to reconstruct objects if they happen to cross the size boundary by mapping the same memory twice consecutively into the process space.
On Unix-like platforms? sysv shared memory (shmget, etc). https://github.com/gnzlbg/slice_deque/blob/045fb28701d3b674b... does this. (Though that code looks racy to me; unmapping the second half's virtual address space before mapping again is wrong. I guess it does that because shmat's SHM_REMAP flag is Linux-specific. At least it will fail rather than silently overwrite some other mapping. edit: oh, and it retries too, so not bad.)
Seems like you could use shm_open + mmap also.
On Linux, you could probably also do some juggling with mremap + MREMAP_DONTUNMAP, but I don't know why you'd prefer this over memfd_create.
> [...] by being very very good to their users [...]
Helps that they don't have to be very very good to shareholders that don't give a fuck about games and just want money. I'm not really looking forward to find out what happens once Gabe passes on control of the company.
I honestly can’t tell if that’s an elaborate joke response or if that’s really something that works. If it does:
* How do you make sure you capture all mapped memory within a process? Walking something like /proc/self/maps?
* Does this include the stack and if so, doesn’t this cause havok when you write back. And if it doesn’t include the stack, can’t run things out of sync easily?
* This is then a page sized undo/redo, so it isn’t atomic with regards to actions triggered. Wouldn’t partially undoing such changes easily cause an invalid state?
I can't speak to every use case but it's been working great for my game:
1. I don't heap allocate anything after init. All allocations are custom allocated from this memory. I use a linear allocator, but could use some other scheme.
2. I don't account for the stack at all, but it doesn't mess anything up. The only important memory is the app memory, and that persists across frames.
3. It is, but you're computing deltas across frames, so they are atomic wrt user input. It's true that if multiple changes are made to the same page in the same frame then undoing that page undoes all of the changes, but that is often desirable from the user's perspective.
Thanks for your response. Interesting. I can see that working with these restrictions. This basically also assumes the data within that memory area only has pointers to either somewhere else in that area or to static structures outside, correct? Also the write rate is probably quite low as I imagine constantly handling SIGBUS would quickly slow things down? Did you look into userfaultfd?
> TinyKVM can fork itself into copies that use copy-on-write to allow for huge workloads like LLMs to share most memory. As an example, 6GB weights required only 260MB working memory per instance, making it highly scalable.
It’s a bit more than running a program under seccomp strict mode, but conceptually similar, so running anything too complicated likely won't work. You certainly won’t be able to sandbox chromium for taking website snapshots for example.
There's many ways to go about it, but essentially yes, brk and mmap and a few others just to get into main() for some common run-times.
But you can do whatever you want. For example in libriscv I override the global allocator in my guest programs to use a host-managed heap. That way heap usage has native performance in interpreter mode, while also allowing me full control of the heap from the outside. I wrote about this here: https://medium.com/@fwsgonzo/using-c-as-a-scripting-language...
For the Varnish integration I added permission-based access to local files. Network stuff can be accessed through custom APIs. A simple fetch(url, options)-like system call. Just have a look at the VMOD repository. It's something I'd like to move into TinyKVM when I feel like it.
So does the good old Quake 2 rendering API. The game exported a bunch of functions to the renderer via refimport_t and the renderer in return provided functions via refexport_t. The only visible symbol in a rendering DLL is GetRefAPI_t: https://github.com/id-Software/Quake-2/blob/master/client/re...
I somehow suspect that the reason why Quake2 does this lies in the legacy of Quake1 written in DJGPP. DJGPP supports dynamicaly loaded libraries (although the API is technically unsupported and internal-only), but does not have any kind of dynamic linker, thus passing around pair of such structs during library initialization is the only way to make that work.
The deprecation of OMXPlayer has been problematic for one, since I rely on some custom applications which need to be able to have some fairly precise/low latency requirements between when you tell it to start playing vs when the playback actually starts, etc. I haven’t found a suitable mechanism which meets our reqs on a Pi for controlling/playing videos yet since that deprecation.
The lack of a regular HDMI output is mildly annoying but not really a problem. Audio configuration is sometimes problematic, usually not…
If a client wants to use their own Pis, getting them provisioned with our software isn’t always the easiest if the customer is techno-phobic (though that’s partly on us - RPi usage is relatively infrequent for our customers so we haven’t put the time/energy into docs and into baking an image etc).
I love Pi’s, but they just that extra bit more finicky than BrightSigns which are hyper optimized for our use case and prevalent in our customers’ equipment rooms already.
> The deprecation of OMXPlayer has been problematic for one, since I rely on some custom applications which need to be able to have some fairly precise/low latency requirements between when you tell it to start playing vs when the playback actually starts, etc. I haven’t found a suitable mechanism which meets our reqs on a Pi for controlling/playing videos yet since that deprecation.
Yeah. The Pi3 -> Pi4/5 jump was quite a massive change in how things work. I've been writing my own playback engine for 10 years now and that one was quite challenging. Precise playback start is something my software supports: You control everything in Lua and can, for example, preload a video and then start it based on either internal logic or based on an external trigger. Up to the Pi3, my software also supports dynamically adjusting the HDMI clock, so the vsyncs of multiple displays are synchronized. Customers have been using that for almost 10 years for video wall playback.
If you go with the hosted version of the software, provisioning is as simple as extracting a single 60MB zip file to an empty SD card and placing that into the Pi. If needed you can even use the API to preconfigure that ZIP file to include settings like WiFi.
Sounds great! I think I’ve actually stumbled across info-Beamer before. We use pretty much the exact same approach in re: configurable zip deployment for BrightSigns.
reply