Interpreter on MCU: is script-side preemption worth its cost, or is cooperative + host watchdog the sane design?

i make a small embeddable scripting language (zym) with mcu use as a target, runtime only builds, statically provisionable heap, that kind of stuffs. its at 0.3.x and im at a design fork i want opinions on from people who put interpreters on constrained hardware

the vm currently has instruction count preemption that is deterministic and exact. you say fire every N instructions and it fires at instruction N, and both the host and the script can arm it. it also has continuations as a primitive so script can build its own schedulers

exactness costs a counter check on every instruction, measured at about 21% of throughput on dispatch heavy code. checking only at loop back edges and calls recovers 15-17% but the watchdog then overshoots by up to one straight line block instead of firing on the exact instruction

what im considering:

- script side concurrency becomes cooperative fibers/coroutines with explicit yield and native scheduling, no counter involved

- preemption becomes host only, a watchdog and hard stop the embedding code arms to bound runaway or untrusted script. script cannot see or touch it, bounded rather than exact, and it is a compile flag so a fully trusted build drops the check entirely

questions for this crowd specifically:

- for a watchdog on script code, do you need it to fire on an exact instruction, or do you need it to be impossible to outrun and fire within a bounded window? my instinct is bounded is fine for nearly everything but timing determinism people are exactly who i would expect to disagree

- is script side preemption, the script scheduling itself preemptively, something you would actually want on an mcu, or is cooperative plus a host guard the sane shape? i built the script side version and i am not sure anyone needed it

- anyone shipping an interpreter on hardware with a guard on / guard off build split, and did it cause problems later?

these questions have been bugging me for a while so mostly here for the answers, happy to explain any of the reasoning if it helps, have been trying to come to a decision for a few weeks so am reaching out for people that use scripting on their systems and what their expectations are as well as what they actually care about in these regards

website: https://zym-lang.org/

github: https://github.com/zym-lang/

reddit.com
u/anatoledp — 1 day ago

Continuations + preemption vs native fibers: rethinking my embeddable language's concurrency model

posted zym here a while back (embeddable dynamic scripting language, one shot delimited continuations as a primitive, instruction count preemption that host and script can both drive). its at 0.3.2 now with various edges being smoothed over

im now second guessing the concurrency model and wanted to think it through with people who care about this area as i am completely split on where to take this

the current design is continuations and preemption as a pair. it is powerful, you can write whatever scheduler you want in userland. but ive gotten personal reports were people constructing fibers by hand from the raw primitive and hitting capture/resume edge cases. essentially a want for fibers, they just have to build them

the preemption side is exact. it fires at instruction N for both host and script and that requires a counter check on every dispatch, which i measured at ~21% on dispatch heavy code. i tried several ways to make it cheaper (safepoints at back edges and calls, fuel metering with compiler folded costs, dual dispatch tables) and anything that keeps exact firing does not win. back edge safepoints recover 15-17% but overshoot by up to one straight line block

so what im considering is swapping the whole story:

- native cooperative fibers/coroutines as the concurrency model, native scheduling so a switch is cheap and there is nothing to construct

- continuations either kept as an advanced primitive under the fibers or removed from the surface

- preemption becomes host only, a sandbox guard the embedder arms and script cannot observe. once script cannot observe it, bounded firing is acceptable, so the cheaper check is usable and the whole thing can be a compile flag for hosts that do not need it

that gets everyone 15-20% and a model people already know. what it gives up is the primitive being the surface

what i actually dont know:

- do people who use delimited continuations want them exposed, or would they take fibers built on them and not miss it, and the reverse as well would people who use fibers just prefer to use that or would they want flexibility of continuations? i made them one shot delimited for sanity and most languages hide this anyway

- is native yield/resume ever too limiting? effects and handlers people especially, curious whether fibers give up something you would notice, for those that dont use effects would there be a want for them if cooperative scheduling were the baseline

- would you keep the raw primitive as an escape hatch even if almost nobody touches it, or is that surface area for its own sake that would not get used by the vast majority?

happy to go into the measurements or the design, its been a rabbit hole, just has been absolutely bugging me for the past few weeks on that design decision and if people would actually expect or even use this capability over a simpler and more intuitive model but also not as flexible and i am dying for answers to these

language: https://zym-lang.org

github: https://github.com/zym-lang

reddit.com
u/anatoledp — 1 day ago

BALLISTIC - A physics-based competitive drone sport

The video is one uncut scoring cycle from an actual match, from the opening countdown to the first goal, with me flying. It's not a trailer or a highlight reel or anything meant to look flashy, just a short look at a quick point.

Game Title: BALLISTIC

Playable Link: BALLISTIC on itch.io ( https://anatolidp.itch.io/ballistic )

Platform: Windows, Linux, macOS

Description:
BALLISTIC is a competitive drone sport built around physics, momentum, and mastering your machine. Chase the ball, fight your momentum, throw yourself across the arena, and recover before you become part of the scenery.

Getting airborne is easy. Getting good is another matter.

You can fly with Assist controls, which handle stabilization for you, or switch to Acro for full manual flight control. Both can be tuned to fit how you want to fly.

The current pre-alpha includes Free Play, solo matches, LAN multiplayer, AI bots, flexible team sizes from 1v1 up to 4v4, two arenas, and a replay viewer. Uneven teams are supported too, so you can set up things like 1v4 if that's what you want.

BALLISTIC is still actively being developed. More maps, solo drills and ladder progression are on the roadmap, and online multiplayer is currently undergoing private testing.

I'd especially love feedback on how the flight and movement feel, whether the game is easy to understand when you first jump in, and, most importantly, whether you're actually having fun.

Free to Play Status:
[x] Free to play
[ ] Demo/Key available
[ ] Paid

Involvement:
I'm the solo developer of BALLISTIC. This is my first game, and I've built the game and its systems myself.

u/anatoledp — 1 month ago